Skip to content

Commit 64b5be6

Browse files
committed
v4: several breaking changes for changeset APIs to be consistent with...
...the OSM API's new json endpoints.
1 parent 17593fc commit 64b5be6

File tree

9 files changed

+55
-100
lines changed

9 files changed

+55
-100
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## 4.0.0 (----------)
11+
12+
- 💥 BREAKING CHANGE: `uploadChangeset` now returns an array of changeset IDs. This is because the function supports chunking uploads into multiple changesets if it exceeds the limit of 10,000 features per changeset.
13+
- 💥 BREAKING CHANGE: The type defintions for `Changeset` have been changed to mark several properties as optional. (see #14)
14+
- 💥 BREAKING CHANGE: `Changeset.created_at`, `Changeset.closed_at`, and `ChangesetComment.date` are now a `string`, not a `Date`. This makes it more consistent with the XML format, and easier to serialise to JSON.
15+
- 💥 BREAKING CHANGE: `ChangesetComment.uid` is now a `number`, not a `string`. This matches the behaviour of OSM's new json API.
16+
- 💥 BREAKING CHANGE: `Changeset.discussion` has been renamed to `Changeset.comments`. This matches the behaviour of OSM's new json API.
17+
1018
- Add new options to the `OsmUserRole` string union.
1119
- Change `createChangesetComment` to return the changeset object instead of returning `undefined`.
1220
- Add 5 new functions that only administrators/moderators can use.

src/__tests__/__snapshots__/e2e.test.ts.snap

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,9 @@ exports[`end to end tests > getCapabilities 1`] = `
109109
exports[`end to end tests > getChangeset (no discussion) 1`] = `
110110
{
111111
"changes_count": 10,
112-
"closed_at": 2021-12-16T09:29:15.000Z,
112+
"closed_at": "2021-12-16T09:29:15Z",
113113
"comments_count": 2,
114-
"created_at": 2021-12-16T09:29:14.000Z,
115-
"discussion": undefined,
114+
"created_at": "2021-12-16T09:29:14Z",
116115
"id": 227200,
117116
"max_lat": -36.8801278,
118117
"max_lon": 174.7400986,
@@ -136,27 +135,27 @@ exports[`end to end tests > getChangeset (no discussion) 1`] = `
136135
exports[`end to end tests > getChangeset (with discussion) 1`] = `
137136
{
138137
"changes_count": 10,
139-
"closed_at": 2021-12-16T09:29:15.000Z,
140-
"comments_count": 2,
141-
"created_at": 2021-12-16T09:29:14.000Z,
142-
"discussion": [
138+
"closed_at": "2021-12-16T09:29:15Z",
139+
"comments": [
143140
{
144-
"date": 2024-06-30T08:59:15.000Z,
141+
"date": "2024-06-30T08:59:15Z",
145142
"id": 736,
146143
"text": "­",
147-
"uid": "12248",
144+
"uid": 12248,
148145
"user": "kylenz_testing",
149146
"visible": true,
150147
},
151148
{
152-
"date": 2024-06-30T08:59:55.000Z,
149+
"date": "2024-06-30T08:59:55Z",
153150
"id": 737,
154151
"text": "sup bro",
155-
"uid": "12248",
152+
"uid": 12248,
156153
"user": "kylenz_testing",
157154
"visible": true,
158155
},
159156
],
157+
"comments_count": 2,
158+
"created_at": "2021-12-16T09:29:14Z",
160159
"id": 227200,
161160
"max_lat": -36.8801278,
162161
"max_lon": 174.7400986,
@@ -533,10 +532,9 @@ exports[`end to end tests > listChangesets 1`] = `
533532
[
534533
{
535534
"changes_count": 2,
536-
"closed_at": 2022-09-10T11:47:14.000Z,
535+
"closed_at": "2022-09-10T11:47:14Z",
537536
"comments_count": 0,
538-
"created_at": 2022-09-10T11:47:13.000Z,
539-
"discussion": undefined,
537+
"created_at": "2022-09-10T11:47:13Z",
540538
"id": 243638,
541539
"max_lat": -36.8804862,
542540
"max_lon": 174.739748,
@@ -553,10 +551,9 @@ exports[`end to end tests > listChangesets 1`] = `
553551
},
554552
{
555553
"changes_count": 10,
556-
"closed_at": 2022-09-10T11:30:13.000Z,
554+
"closed_at": "2022-09-10T11:30:13Z",
557555
"comments_count": 0,
558-
"created_at": 2022-09-10T11:30:12.000Z,
559-
"discussion": undefined,
556+
"created_at": "2022-09-10T11:30:12Z",
560557
"id": 243637,
561558
"max_lat": -36.8804809,
562559
"max_lon": 174.7397571,
@@ -576,10 +573,9 @@ exports[`end to end tests > listChangesets 1`] = `
576573
},
577574
{
578575
"changes_count": 10,
579-
"closed_at": 2021-12-16T09:29:15.000Z,
576+
"closed_at": "2021-12-16T09:29:15Z",
580577
"comments_count": 2,
581-
"created_at": 2021-12-16T09:29:14.000Z,
582-
"discussion": undefined,
578+
"created_at": "2021-12-16T09:29:14Z",
583579
"id": 227200,
584580
"max_lat": -36.8801278,
585581
"max_lon": 174.7400986,
@@ -600,10 +596,9 @@ exports[`end to end tests > listChangesets 1`] = `
600596
},
601597
{
602598
"changes_count": 5,
603-
"closed_at": 2021-12-16T08:43:07.000Z,
599+
"closed_at": "2021-12-16T08:43:07Z",
604600
"comments_count": 0,
605-
"created_at": 2021-12-16T08:43:06.000Z,
606-
"discussion": undefined,
601+
"created_at": "2021-12-16T08:43:06Z",
607602
"id": 227184,
608603
"max_lat": -36.8804809,
609604
"max_lon": 174.7397571,

src/api/_rawResponse.d.ts

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,5 @@
11
import type { Feature, FeatureCollection, Point } from "geojson";
2-
import type {
3-
Changeset,
4-
ChangesetComment,
5-
OsmFeatureType,
6-
OsmNote,
7-
} from "../types";
8-
9-
/** @internal */
10-
export type RawChangeset = Omit<
11-
Changeset,
12-
"discussion" | "created_at" | "closed_at"
13-
> & {
14-
created_at: string;
15-
closed_at?: string;
16-
comments?: (Omit<ChangesetComment, "date" | "uid"> & {
17-
/** ISO Date */
18-
date: string;
19-
uid: number;
20-
})[];
21-
};
2+
import type { OsmFeatureType, OsmNote } from "../types";
223

234
/** @internal */
245
export type RawNotesSearch = FeatureCollection<

src/api/changesets/__tests__/uploadChangeset.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ describe("uploadChangeset", () => {
5353
{ comment: "added a building" },
5454
{ create: [], modify: [], delete: [] }
5555
);
56-
expect(output).toBe(1);
56+
expect(output).toStrictEqual([1]);
5757

5858
expect(osmFetch).toHaveBeenCalledTimes(3);
5959
expect(osmFetch).toHaveBeenNthCalledWith(
@@ -94,7 +94,7 @@ describe("uploadChangeset", () => {
9494
);
9595
}
9696

97-
expect(output).toBe(1);
97+
expect(output).toStrictEqual([1, 4, 7, 10]);
9898
});
9999

100100
it("splits changesets into chunks and suports a custom tag function", async () => {
@@ -128,6 +128,6 @@ describe("uploadChangeset", () => {
128128
);
129129
}
130130

131-
expect(output).toBe(1);
131+
expect(output).toStrictEqual([1, 4, 7, 10]);
132132
});
133133
});

src/api/changesets/createChangesetComment.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import type { Changeset } from "../../types";
22
import { type FetchOptions, osmFetch } from "../_osmFetch";
3-
import type { RawChangeset } from "../_rawResponse";
4-
import { mapRawChangeset } from "./getChangesets";
53

64
/** Add a comment to a changeset. The changeset must be closed. */
75
export async function createChangesetComment(
86
changesetId: number,
97
commentText: string,
108
options?: FetchOptions
119
): Promise<Changeset> {
12-
const result = await osmFetch<{ changeset: RawChangeset }>(
10+
const result = await osmFetch<{ changeset: Changeset }>(
1311
`/0.6/changeset/${changesetId}/comment.json`,
1412
undefined,
1513
{
@@ -22,5 +20,5 @@ export async function createChangesetComment(
2220
},
2321
}
2422
);
25-
return mapRawChangeset(result.changeset);
23+
return result.changeset;
2624
}

src/api/changesets/getChangesets.ts

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,5 @@
11
import type { BBox, Changeset } from "../../types";
22
import { type FetchOptions, osmFetch } from "../_osmFetch";
3-
import type { RawChangeset } from "../_rawResponse";
4-
5-
/** @internal */
6-
export const mapRawChangeset = ({
7-
comments,
8-
...raw
9-
}: RawChangeset): Changeset => ({
10-
...raw,
11-
created_at: new Date(raw.created_at),
12-
closed_at: raw.closed_at ? new Date(raw.closed_at) : undefined!,
13-
14-
discussion: comments?.map((comment) => ({
15-
...comment,
16-
date: new Date(comment.date),
17-
uid: `${comment.uid}`,
18-
})),
19-
});
203

214
// does not extend BasicFilters for historical reasons
225
export type ListChangesetOptions = {
@@ -57,7 +40,7 @@ export async function listChangesets(
5740
): Promise<Changeset[]> {
5841
const { only, ...otherQueries } = query;
5942

60-
const raw = await osmFetch<{ changesets: RawChangeset[] }>(
43+
const raw = await osmFetch<{ changesets: Changeset[] }>(
6144
"/0.6/changesets.json",
6245
{
6346
...(only && { [only]: true }),
@@ -66,7 +49,7 @@ export async function listChangesets(
6649
options
6750
);
6851

69-
return raw.changesets.map(mapRawChangeset);
52+
return raw.changesets;
7053
}
7154

7255
/** get a single changeset */
@@ -76,11 +59,11 @@ export async function getChangeset(
7659
includeDiscussion = true,
7760
options?: FetchOptions
7861
): Promise<Changeset> {
79-
const raw = await osmFetch<{ changeset: RawChangeset }>(
62+
const raw = await osmFetch<{ changeset: Changeset }>(
8063
`/0.6/changeset/${id}.json`,
8164
includeDiscussion ? { include_discussion: 1 } : {},
8265
options
8366
);
8467

85-
return mapRawChangeset(raw.changeset);
68+
return raw.changeset;
8669
}

src/api/changesets/uploadChangeset.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export async function uploadChangeset(
3333
*/
3434
onChunk?(info: UploadChunkInfo): Tags;
3535
}
36-
): Promise<number> {
36+
): Promise<number[]> {
3737
const chunks = chunkOsmChange(diff);
3838
const csIds: number[] = [];
3939

@@ -91,5 +91,5 @@ export async function uploadChangeset(
9191
csIds.push(csId);
9292
}
9393

94-
return csIds[0]; // TODO:(semver breaking) return an array of IDs
94+
return csIds;
9595
}
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
import type { Changeset } from "../../types";
22
import { type FetchOptions, osmFetch } from "../_osmFetch";
3-
import type { RawChangeset } from "../_rawResponse";
4-
import { mapRawChangeset } from "../changesets";
53

64
/** DWG only */
75
export async function hideChangesetComment(
86
changesetCommentId: number,
97
action?: "hide" | "unhide",
108
options?: FetchOptions
119
): Promise<Changeset> {
12-
const result = await osmFetch<{ changeset: RawChangeset }>(
10+
const result = await osmFetch<{ changeset: Changeset }>(
1311
`/0.6/changeset_comments/${changesetCommentId}/visibility.json`,
1412
{},
1513
{ ...options, method: action === "unhide" ? "POST" : "DELETE" }
1614
);
17-
return mapRawChangeset(result.changeset);
15+
return result.changeset;
1816
}

src/types/changesets.ts

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,32 @@ export type ChangesetComment = {
55
id: number;
66
visible: boolean;
77
user: string;
8-
// TODO:(semver breaking) change to number
9-
uid: string;
10-
// TODO:(semver breaking) change to string
11-
date: Date;
8+
uid: number;
9+
date: string;
1210
text: string;
1311
};
1412

1513
export type Changeset = {
1614
id: number;
17-
// TODO:(semver breaking) change to string
18-
created_at: Date;
15+
created_at: string;
1916
open: boolean;
2017
comments_count: number;
2118
changes_count: number;
22-
/** property only exists if `open=false` */
23-
// TODO:(semver breaking) mark as optional
24-
closed_at: Date;
25-
/** property only exists if `open=false` */
26-
// TODO:(semver breaking) mark as optional
27-
min_lat: number;
28-
/** property only exists if `open=false` */
29-
// TODO:(semver breaking) mark as optional
30-
min_lon: number;
31-
/** property only exists if `open=false` */
32-
// TODO:(semver breaking) mark as optional
33-
max_lat: number;
34-
/** property only exists if `open=false` */
35-
// TODO:(semver breaking) mark as optional
36-
max_lon: number;
19+
/** This property is missing if `open=true` */
20+
closed_at?: string;
21+
/** This property is missing if `open=true`, or if none of the edited features have geometry data (see #14) */
22+
min_lat?: number;
23+
/** This property is missing if `open=true`, or if none of the edited features have geometry data (see #14) */
24+
min_lon?: number;
25+
/** This property is missing if `open=true`, or if none of the edited features have geometry data (see #14) */
26+
max_lat?: number;
27+
/** This property is missing if `open=true`, or if none of the edited features have geometry data (see #14) */
28+
max_lon?: number;
3729
uid: number;
3830
user: string;
3931
tags: Tags;
40-
/** the `discussion` attribute is only included in the `getChangeset` API */
41-
discussion?: ChangesetComment[];
32+
/** the `comments` attribute is only included in the `getChangeset` API */
33+
comments?: ChangesetComment[];
4234
};
4335

4436
export type OsmChange = {

0 commit comments

Comments
 (0)