@andesine/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/LICENSE +21 -0
- package/README.md +728 -0
- package/dist/answer-stream-7N_gLhVS.js +193 -0
- package/dist/answer-stream-7N_gLhVS.js.map +1 -0
- package/dist/index-DFEcYmbh.d.ts +23370 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1167 -0
- package/dist/index.js.map +1 -0
- package/dist/streaming.d.ts +41 -0
- package/dist/streaming.js +93 -0
- package/dist/streaming.js.map +1 -0
- package/openapi.json +27190 -0
- package/package.json +69 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1167 @@
|
|
|
1
|
+
import { i as AndesineStreamProtocolError, n as AndesineAPIError, r as AndesineStreamError, t as createAnswerStream } from "./answer-stream-7N_gLhVS.js";
|
|
2
|
+
import createFetchClient from "openapi-fetch";
|
|
3
|
+
//#region src/paginate.ts
|
|
4
|
+
/**
|
|
5
|
+
* Iterate cursor-paginated pages, retaining their metadata.
|
|
6
|
+
*
|
|
7
|
+
* @param getPage - Fetch one page for the supplied cursor. The first cursor is undefined unless supplied.
|
|
8
|
+
* Keep filters stable. This generic helper does not bind snapshots; use content.paginateEntryPages()
|
|
9
|
+
* or content.paginateCollectionPages() for automatic published snapshot handling.
|
|
10
|
+
* @param options - Optional cursor from an earlier page to resume processing.
|
|
11
|
+
* @returns A lazy iterator that requests the next page only after the previous page is consumed.
|
|
12
|
+
* Save pagination.nextCursor after processing a page. Break the loop to stop further requests.
|
|
13
|
+
* @throws Error for a missing or repeated next cursor. Callback failures pass through unchanged.
|
|
14
|
+
*/
|
|
15
|
+
const paginatePages = async function* (getPage, options = {}) {
|
|
16
|
+
const seen = new Set(options.cursor ? [options.cursor] : []);
|
|
17
|
+
let cursor = options.cursor;
|
|
18
|
+
do {
|
|
19
|
+
const page = await getPage(cursor);
|
|
20
|
+
const next = page.pagination.nextCursor;
|
|
21
|
+
if (page.pagination.hasMore && (!next || seen.has(next))) throw new Error("Pagination returned a missing or repeated cursor");
|
|
22
|
+
yield page;
|
|
23
|
+
if (!page.pagination.hasMore) return;
|
|
24
|
+
seen.add(next);
|
|
25
|
+
cursor = next;
|
|
26
|
+
} while (cursor);
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Iterate items across cursor-paginated pages without collecting them in memory.
|
|
30
|
+
*
|
|
31
|
+
* @param getPage - Fetch one page using the cursor. Keep scope and filters stable in this callback.
|
|
32
|
+
* This generic helper does not bind snapshots; content.paginateEntries() and
|
|
33
|
+
* content.paginateCollections() do that automatically for published content.
|
|
34
|
+
* @param options - Optional starting cursor; retain its matching scope and snapshot yourself.
|
|
35
|
+
* @returns Items in API order. Break the loop to prevent further page requests.
|
|
36
|
+
* @throws Pagination errors from paginatePages(), or the original callback error.
|
|
37
|
+
*/
|
|
38
|
+
const paginate = async function* (getPage, options = {}) {
|
|
39
|
+
for await (const page of paginatePages(getPage, options)) yield* page.data;
|
|
40
|
+
};
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/content-client.ts
|
|
43
|
+
const paginateSnapshotPages = async function* (list, input, options = {}) {
|
|
44
|
+
let query = { ...input };
|
|
45
|
+
yield* paginatePages(async (cursor) => {
|
|
46
|
+
const page = await list({
|
|
47
|
+
...query,
|
|
48
|
+
cursor
|
|
49
|
+
}, {
|
|
50
|
+
...options,
|
|
51
|
+
response: "data"
|
|
52
|
+
});
|
|
53
|
+
if (query.snapshotID !== void 0 && page.snapshotID !== query.snapshotID) throw new Error("Pagination returned a different snapshot");
|
|
54
|
+
query = {
|
|
55
|
+
...query,
|
|
56
|
+
channel: void 0,
|
|
57
|
+
snapshotID: page.snapshotID
|
|
58
|
+
};
|
|
59
|
+
return page;
|
|
60
|
+
}, { cursor: input.cursor });
|
|
61
|
+
};
|
|
62
|
+
const createContentClient = (content) => {
|
|
63
|
+
const paginateEntryPages = (input = {}, options) => paginateSnapshotPages((query, requestOptions) => content.listEntries(query, requestOptions), input, options);
|
|
64
|
+
const paginateCollectionPages = (input = {}, options) => paginateSnapshotPages((query, requestOptions) => content.listCollections(query, requestOptions), input, options);
|
|
65
|
+
return {
|
|
66
|
+
...content,
|
|
67
|
+
paginateEntryPages,
|
|
68
|
+
async *paginateEntries(input, options) {
|
|
69
|
+
for await (const page of paginateEntryPages(input, options)) yield* page.data;
|
|
70
|
+
},
|
|
71
|
+
paginateCollectionPages,
|
|
72
|
+
async *paginateCollections(input, options) {
|
|
73
|
+
for await (const page of paginateCollectionPages(input, options)) yield* page.data;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/query.ts
|
|
79
|
+
const serializeQuery = (query) => {
|
|
80
|
+
const parameters = new URLSearchParams();
|
|
81
|
+
const escapeKey = (key) => key.replace(/[\\[\]]/g, (character) => `\\${character}`);
|
|
82
|
+
const append = (path, value) => {
|
|
83
|
+
if (value === void 0 || value === null) return;
|
|
84
|
+
if (Array.isArray(value)) value.forEach((item, index) => append(`${path}[${index}]`, item));
|
|
85
|
+
else if (typeof value === "object") for (const [key, item] of Object.entries(value)) append(`${path}[${escapeKey(key)}]`, item);
|
|
86
|
+
else parameters.append(path, String(value));
|
|
87
|
+
};
|
|
88
|
+
for (const [key, value] of Object.entries(query)) append(escapeKey(key), value);
|
|
89
|
+
return parameters.toString();
|
|
90
|
+
};
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/operation.ts
|
|
93
|
+
const operation = (request, definition) => {
|
|
94
|
+
return ((input, options) => {
|
|
95
|
+
return request(definition, input || {}, options);
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region src/generated/resources.ts
|
|
100
|
+
const createResources = (request) => ({
|
|
101
|
+
assets: {
|
|
102
|
+
search: operation(request, {
|
|
103
|
+
method: "get",
|
|
104
|
+
path: "/assets/search",
|
|
105
|
+
pathParams: [],
|
|
106
|
+
queryParams: [
|
|
107
|
+
"query",
|
|
108
|
+
"checksum",
|
|
109
|
+
"semantic",
|
|
110
|
+
"limit"
|
|
111
|
+
],
|
|
112
|
+
body: false,
|
|
113
|
+
multipart: false,
|
|
114
|
+
binary: false,
|
|
115
|
+
anonymous: false
|
|
116
|
+
}),
|
|
117
|
+
importURL: operation(request, {
|
|
118
|
+
method: "post",
|
|
119
|
+
path: "/assets/imports",
|
|
120
|
+
pathParams: [],
|
|
121
|
+
queryParams: [],
|
|
122
|
+
body: true,
|
|
123
|
+
multipart: false,
|
|
124
|
+
binary: false,
|
|
125
|
+
anonymous: false
|
|
126
|
+
}),
|
|
127
|
+
attach: operation(request, {
|
|
128
|
+
method: "post",
|
|
129
|
+
path: "/assets/{assetID}/attachments",
|
|
130
|
+
pathParams: ["assetID"],
|
|
131
|
+
queryParams: [],
|
|
132
|
+
body: true,
|
|
133
|
+
multipart: false,
|
|
134
|
+
binary: false,
|
|
135
|
+
anonymous: false
|
|
136
|
+
}),
|
|
137
|
+
register: operation(request, {
|
|
138
|
+
method: "post",
|
|
139
|
+
path: "/assets/uploads",
|
|
140
|
+
pathParams: [],
|
|
141
|
+
queryParams: [],
|
|
142
|
+
body: true,
|
|
143
|
+
multipart: false,
|
|
144
|
+
binary: false,
|
|
145
|
+
anonymous: false
|
|
146
|
+
}),
|
|
147
|
+
upload: operation(request, {
|
|
148
|
+
method: "put",
|
|
149
|
+
path: "/assets/{assetID}/upload",
|
|
150
|
+
pathParams: ["assetID"],
|
|
151
|
+
queryParams: [],
|
|
152
|
+
body: true,
|
|
153
|
+
multipart: true,
|
|
154
|
+
binary: false,
|
|
155
|
+
anonymous: false
|
|
156
|
+
}),
|
|
157
|
+
get: operation(request, {
|
|
158
|
+
method: "get",
|
|
159
|
+
path: "/assets/{assetID}",
|
|
160
|
+
pathParams: ["assetID"],
|
|
161
|
+
queryParams: ["entryID"],
|
|
162
|
+
body: false,
|
|
163
|
+
multipart: false,
|
|
164
|
+
binary: false,
|
|
165
|
+
anonymous: false
|
|
166
|
+
})
|
|
167
|
+
},
|
|
168
|
+
instance: { get: operation(request, {
|
|
169
|
+
method: "get",
|
|
170
|
+
path: "/instance",
|
|
171
|
+
pathParams: [],
|
|
172
|
+
queryParams: [],
|
|
173
|
+
body: false,
|
|
174
|
+
multipart: false,
|
|
175
|
+
binary: false,
|
|
176
|
+
anonymous: false
|
|
177
|
+
}) },
|
|
178
|
+
entries: {
|
|
179
|
+
create: operation(request, {
|
|
180
|
+
method: "post",
|
|
181
|
+
path: "/entries",
|
|
182
|
+
pathParams: [],
|
|
183
|
+
queryParams: [],
|
|
184
|
+
body: true,
|
|
185
|
+
multipart: false,
|
|
186
|
+
binary: false,
|
|
187
|
+
anonymous: false
|
|
188
|
+
}),
|
|
189
|
+
bulkDelete: operation(request, {
|
|
190
|
+
method: "post",
|
|
191
|
+
path: "/entries/bulk/delete",
|
|
192
|
+
pathParams: [],
|
|
193
|
+
queryParams: [],
|
|
194
|
+
body: true,
|
|
195
|
+
multipart: false,
|
|
196
|
+
binary: false,
|
|
197
|
+
anonymous: false
|
|
198
|
+
}),
|
|
199
|
+
delete: operation(request, {
|
|
200
|
+
method: "delete",
|
|
201
|
+
path: "/entries/{id}",
|
|
202
|
+
pathParams: ["id"],
|
|
203
|
+
queryParams: [],
|
|
204
|
+
body: false,
|
|
205
|
+
multipart: false,
|
|
206
|
+
binary: false,
|
|
207
|
+
anonymous: false
|
|
208
|
+
}),
|
|
209
|
+
update: operation(request, {
|
|
210
|
+
method: "put",
|
|
211
|
+
path: "/entries/{id}",
|
|
212
|
+
pathParams: ["id"],
|
|
213
|
+
queryParams: [],
|
|
214
|
+
body: true,
|
|
215
|
+
multipart: false,
|
|
216
|
+
binary: false,
|
|
217
|
+
anonymous: false
|
|
218
|
+
}),
|
|
219
|
+
get: operation(request, {
|
|
220
|
+
method: "get",
|
|
221
|
+
path: "/entries/get",
|
|
222
|
+
pathParams: [],
|
|
223
|
+
queryParams: [
|
|
224
|
+
"id",
|
|
225
|
+
"path",
|
|
226
|
+
"expectedSchemaHash"
|
|
227
|
+
],
|
|
228
|
+
body: false,
|
|
229
|
+
multipart: false,
|
|
230
|
+
binary: false,
|
|
231
|
+
anonymous: false
|
|
232
|
+
}),
|
|
233
|
+
list: operation(request, {
|
|
234
|
+
method: "get",
|
|
235
|
+
path: "/entries/list",
|
|
236
|
+
pathParams: [],
|
|
237
|
+
queryParams: [
|
|
238
|
+
"collectionID",
|
|
239
|
+
"collectionPath",
|
|
240
|
+
"cursor",
|
|
241
|
+
"limit"
|
|
242
|
+
],
|
|
243
|
+
body: false,
|
|
244
|
+
multipart: false,
|
|
245
|
+
binary: false,
|
|
246
|
+
anonymous: false
|
|
247
|
+
})
|
|
248
|
+
},
|
|
249
|
+
collections: {
|
|
250
|
+
create: operation(request, {
|
|
251
|
+
method: "post",
|
|
252
|
+
path: "/collections",
|
|
253
|
+
pathParams: [],
|
|
254
|
+
queryParams: [],
|
|
255
|
+
body: true,
|
|
256
|
+
multipart: false,
|
|
257
|
+
binary: false,
|
|
258
|
+
anonymous: false
|
|
259
|
+
}),
|
|
260
|
+
bulkDelete: operation(request, {
|
|
261
|
+
method: "post",
|
|
262
|
+
path: "/collections/bulk/delete",
|
|
263
|
+
pathParams: [],
|
|
264
|
+
queryParams: [],
|
|
265
|
+
body: true,
|
|
266
|
+
multipart: false,
|
|
267
|
+
binary: false,
|
|
268
|
+
anonymous: false
|
|
269
|
+
}),
|
|
270
|
+
delete: operation(request, {
|
|
271
|
+
method: "delete",
|
|
272
|
+
path: "/collections/{id}",
|
|
273
|
+
pathParams: ["id"],
|
|
274
|
+
queryParams: [],
|
|
275
|
+
body: false,
|
|
276
|
+
multipart: false,
|
|
277
|
+
binary: false,
|
|
278
|
+
anonymous: false
|
|
279
|
+
}),
|
|
280
|
+
update: operation(request, {
|
|
281
|
+
method: "put",
|
|
282
|
+
path: "/collections/{id}",
|
|
283
|
+
pathParams: ["id"],
|
|
284
|
+
queryParams: [],
|
|
285
|
+
body: true,
|
|
286
|
+
multipart: false,
|
|
287
|
+
binary: false,
|
|
288
|
+
anonymous: false
|
|
289
|
+
}),
|
|
290
|
+
list: operation(request, {
|
|
291
|
+
method: "get",
|
|
292
|
+
path: "/collections/list",
|
|
293
|
+
pathParams: [],
|
|
294
|
+
queryParams: [
|
|
295
|
+
"collectionID",
|
|
296
|
+
"collectionPath",
|
|
297
|
+
"cursor",
|
|
298
|
+
"limit"
|
|
299
|
+
],
|
|
300
|
+
body: false,
|
|
301
|
+
multipart: false,
|
|
302
|
+
binary: false,
|
|
303
|
+
anonymous: false
|
|
304
|
+
})
|
|
305
|
+
},
|
|
306
|
+
content: {
|
|
307
|
+
listCollections: operation(request, {
|
|
308
|
+
method: "get",
|
|
309
|
+
path: "/content/collections",
|
|
310
|
+
pathParams: [],
|
|
311
|
+
queryParams: [
|
|
312
|
+
"cursor",
|
|
313
|
+
"limit",
|
|
314
|
+
"collectionID",
|
|
315
|
+
"collectionPath",
|
|
316
|
+
"channel",
|
|
317
|
+
"snapshotID"
|
|
318
|
+
],
|
|
319
|
+
body: false,
|
|
320
|
+
multipart: false,
|
|
321
|
+
binary: false,
|
|
322
|
+
anonymous: false
|
|
323
|
+
}),
|
|
324
|
+
listEntries: operation(request, {
|
|
325
|
+
method: "get",
|
|
326
|
+
path: "/content/entries",
|
|
327
|
+
pathParams: [],
|
|
328
|
+
queryParams: [
|
|
329
|
+
"cursor",
|
|
330
|
+
"limit",
|
|
331
|
+
"collectionID",
|
|
332
|
+
"collectionPath",
|
|
333
|
+
"channel",
|
|
334
|
+
"snapshotID",
|
|
335
|
+
"descendants",
|
|
336
|
+
"includeContent",
|
|
337
|
+
"filters"
|
|
338
|
+
],
|
|
339
|
+
body: false,
|
|
340
|
+
multipart: false,
|
|
341
|
+
binary: false,
|
|
342
|
+
anonymous: false
|
|
343
|
+
}),
|
|
344
|
+
getSchema: operation(request, {
|
|
345
|
+
method: "get",
|
|
346
|
+
path: "/content/entries/schema",
|
|
347
|
+
pathParams: [],
|
|
348
|
+
queryParams: [
|
|
349
|
+
"entryID",
|
|
350
|
+
"path",
|
|
351
|
+
"channel",
|
|
352
|
+
"snapshotID"
|
|
353
|
+
],
|
|
354
|
+
body: false,
|
|
355
|
+
multipart: false,
|
|
356
|
+
binary: false,
|
|
357
|
+
anonymous: false
|
|
358
|
+
}),
|
|
359
|
+
getAsset: operation(request, {
|
|
360
|
+
method: "get",
|
|
361
|
+
path: "/content/assets/{workspaceID}/{snapshotID}/{entryID}/{assetID}/{variant}",
|
|
362
|
+
pathParams: [
|
|
363
|
+
"workspaceID",
|
|
364
|
+
"snapshotID",
|
|
365
|
+
"entryID",
|
|
366
|
+
"assetID",
|
|
367
|
+
"variant"
|
|
368
|
+
],
|
|
369
|
+
queryParams: [],
|
|
370
|
+
body: false,
|
|
371
|
+
multipart: false,
|
|
372
|
+
binary: true,
|
|
373
|
+
anonymous: true
|
|
374
|
+
}),
|
|
375
|
+
get: operation(request, {
|
|
376
|
+
method: "get",
|
|
377
|
+
path: "/content/entries/get",
|
|
378
|
+
pathParams: [],
|
|
379
|
+
queryParams: [
|
|
380
|
+
"entryID",
|
|
381
|
+
"path",
|
|
382
|
+
"expectedSchemaHash",
|
|
383
|
+
"channel",
|
|
384
|
+
"snapshotID"
|
|
385
|
+
],
|
|
386
|
+
body: false,
|
|
387
|
+
multipart: false,
|
|
388
|
+
binary: false,
|
|
389
|
+
anonymous: false
|
|
390
|
+
}),
|
|
391
|
+
getTree: operation(request, {
|
|
392
|
+
method: "get",
|
|
393
|
+
path: "/content/tree",
|
|
394
|
+
pathParams: [],
|
|
395
|
+
queryParams: [
|
|
396
|
+
"collectionID",
|
|
397
|
+
"collectionPath",
|
|
398
|
+
"channel",
|
|
399
|
+
"snapshotID"
|
|
400
|
+
],
|
|
401
|
+
body: false,
|
|
402
|
+
multipart: false,
|
|
403
|
+
binary: false,
|
|
404
|
+
anonymous: false
|
|
405
|
+
})
|
|
406
|
+
},
|
|
407
|
+
roles: {
|
|
408
|
+
list: operation(request, {
|
|
409
|
+
method: "get",
|
|
410
|
+
path: "/roles",
|
|
411
|
+
pathParams: [],
|
|
412
|
+
queryParams: [],
|
|
413
|
+
body: false,
|
|
414
|
+
multipart: false,
|
|
415
|
+
binary: false,
|
|
416
|
+
anonymous: false
|
|
417
|
+
}),
|
|
418
|
+
create: operation(request, {
|
|
419
|
+
method: "post",
|
|
420
|
+
path: "/roles",
|
|
421
|
+
pathParams: [],
|
|
422
|
+
queryParams: [],
|
|
423
|
+
body: true,
|
|
424
|
+
multipart: false,
|
|
425
|
+
binary: false,
|
|
426
|
+
anonymous: false
|
|
427
|
+
}),
|
|
428
|
+
update: operation(request, {
|
|
429
|
+
method: "put",
|
|
430
|
+
path: "/roles/{id}",
|
|
431
|
+
pathParams: ["id"],
|
|
432
|
+
queryParams: [],
|
|
433
|
+
body: true,
|
|
434
|
+
multipart: false,
|
|
435
|
+
binary: false,
|
|
436
|
+
anonymous: false
|
|
437
|
+
}),
|
|
438
|
+
delete: operation(request, {
|
|
439
|
+
method: "delete",
|
|
440
|
+
path: "/roles/{id}",
|
|
441
|
+
pathParams: ["id"],
|
|
442
|
+
queryParams: [],
|
|
443
|
+
body: false,
|
|
444
|
+
multipart: false,
|
|
445
|
+
binary: false,
|
|
446
|
+
anonymous: false
|
|
447
|
+
})
|
|
448
|
+
},
|
|
449
|
+
search: {
|
|
450
|
+
current: operation(request, {
|
|
451
|
+
method: "post",
|
|
452
|
+
path: "/search/current",
|
|
453
|
+
pathParams: [],
|
|
454
|
+
queryParams: [],
|
|
455
|
+
body: true,
|
|
456
|
+
multipart: false,
|
|
457
|
+
binary: false,
|
|
458
|
+
anonymous: false
|
|
459
|
+
}),
|
|
460
|
+
published: operation(request, {
|
|
461
|
+
method: "post",
|
|
462
|
+
path: "/search/published",
|
|
463
|
+
pathParams: [],
|
|
464
|
+
queryParams: [],
|
|
465
|
+
body: true,
|
|
466
|
+
multipart: false,
|
|
467
|
+
binary: false,
|
|
468
|
+
anonymous: false
|
|
469
|
+
}),
|
|
470
|
+
askCurrent: operation(request, {
|
|
471
|
+
method: "post",
|
|
472
|
+
path: "/search/current/ask",
|
|
473
|
+
pathParams: [],
|
|
474
|
+
queryParams: [],
|
|
475
|
+
body: true,
|
|
476
|
+
multipart: false,
|
|
477
|
+
binary: false,
|
|
478
|
+
anonymous: false
|
|
479
|
+
}),
|
|
480
|
+
askPublished: operation(request, {
|
|
481
|
+
method: "post",
|
|
482
|
+
path: "/search/published/ask",
|
|
483
|
+
pathParams: [],
|
|
484
|
+
queryParams: [],
|
|
485
|
+
body: true,
|
|
486
|
+
multipart: false,
|
|
487
|
+
binary: false,
|
|
488
|
+
anonymous: false
|
|
489
|
+
}),
|
|
490
|
+
askCurrentStream: operation(request, {
|
|
491
|
+
streaming: true,
|
|
492
|
+
method: "post",
|
|
493
|
+
path: "/search/current/ask/stream",
|
|
494
|
+
pathParams: [],
|
|
495
|
+
queryParams: [],
|
|
496
|
+
body: true,
|
|
497
|
+
multipart: false,
|
|
498
|
+
binary: false,
|
|
499
|
+
anonymous: false
|
|
500
|
+
}),
|
|
501
|
+
askPublishedStream: operation(request, {
|
|
502
|
+
streaming: true,
|
|
503
|
+
method: "post",
|
|
504
|
+
path: "/search/published/ask/stream",
|
|
505
|
+
pathParams: [],
|
|
506
|
+
queryParams: [],
|
|
507
|
+
body: true,
|
|
508
|
+
multipart: false,
|
|
509
|
+
binary: false,
|
|
510
|
+
anonymous: false
|
|
511
|
+
})
|
|
512
|
+
},
|
|
513
|
+
schemas: {
|
|
514
|
+
create: operation(request, {
|
|
515
|
+
method: "post",
|
|
516
|
+
path: "/collections/{collectionID}/schema",
|
|
517
|
+
pathParams: ["collectionID"],
|
|
518
|
+
queryParams: [],
|
|
519
|
+
body: false,
|
|
520
|
+
multipart: false,
|
|
521
|
+
binary: false,
|
|
522
|
+
anonymous: false
|
|
523
|
+
}),
|
|
524
|
+
delete: operation(request, {
|
|
525
|
+
method: "delete",
|
|
526
|
+
path: "/schemas/{schemaID}",
|
|
527
|
+
pathParams: ["schemaID"],
|
|
528
|
+
queryParams: [],
|
|
529
|
+
body: true,
|
|
530
|
+
multipart: false,
|
|
531
|
+
binary: false,
|
|
532
|
+
anonymous: false
|
|
533
|
+
}),
|
|
534
|
+
getRevision: operation(request, {
|
|
535
|
+
method: "get",
|
|
536
|
+
path: "/schema-revisions/{revisionID}",
|
|
537
|
+
pathParams: ["revisionID"],
|
|
538
|
+
queryParams: [],
|
|
539
|
+
body: false,
|
|
540
|
+
multipart: false,
|
|
541
|
+
binary: false,
|
|
542
|
+
anonymous: false
|
|
543
|
+
}),
|
|
544
|
+
get: operation(request, {
|
|
545
|
+
method: "get",
|
|
546
|
+
path: "/schemas/collection",
|
|
547
|
+
pathParams: [],
|
|
548
|
+
queryParams: ["collectionID", "collectionPath"],
|
|
549
|
+
body: false,
|
|
550
|
+
multipart: false,
|
|
551
|
+
binary: false,
|
|
552
|
+
anonymous: false
|
|
553
|
+
}),
|
|
554
|
+
apply: operation(request, {
|
|
555
|
+
method: "post",
|
|
556
|
+
path: "/schemas/{schemaID}/apply",
|
|
557
|
+
pathParams: ["schemaID"],
|
|
558
|
+
queryParams: [],
|
|
559
|
+
body: true,
|
|
560
|
+
multipart: false,
|
|
561
|
+
binary: false,
|
|
562
|
+
anonymous: false
|
|
563
|
+
})
|
|
564
|
+
},
|
|
565
|
+
schemaMigrations: {
|
|
566
|
+
listContentLossEntries: operation(request, {
|
|
567
|
+
method: "get",
|
|
568
|
+
path: "/schema-migrations/{id}/content-loss-entries",
|
|
569
|
+
pathParams: ["id"],
|
|
570
|
+
queryParams: ["cursor", "limit"],
|
|
571
|
+
body: false,
|
|
572
|
+
multipart: false,
|
|
573
|
+
binary: false,
|
|
574
|
+
anonymous: false
|
|
575
|
+
}),
|
|
576
|
+
getActive: operation(request, {
|
|
577
|
+
method: "get",
|
|
578
|
+
path: "/collections/{collectionID}/schema-migration",
|
|
579
|
+
pathParams: ["collectionID"],
|
|
580
|
+
queryParams: [],
|
|
581
|
+
body: false,
|
|
582
|
+
multipart: false,
|
|
583
|
+
binary: false,
|
|
584
|
+
anonymous: false
|
|
585
|
+
}),
|
|
586
|
+
get: operation(request, {
|
|
587
|
+
method: "get",
|
|
588
|
+
path: "/schema-migrations/{id}",
|
|
589
|
+
pathParams: ["id"],
|
|
590
|
+
queryParams: [],
|
|
591
|
+
body: false,
|
|
592
|
+
multipart: false,
|
|
593
|
+
binary: false,
|
|
594
|
+
anonymous: false
|
|
595
|
+
})
|
|
596
|
+
},
|
|
597
|
+
schemaVersions: {
|
|
598
|
+
list: operation(request, {
|
|
599
|
+
method: "get",
|
|
600
|
+
path: "/schemas/{schemaID}/versions",
|
|
601
|
+
pathParams: ["schemaID"],
|
|
602
|
+
queryParams: ["cursor", "limit"],
|
|
603
|
+
body: false,
|
|
604
|
+
multipart: false,
|
|
605
|
+
binary: false,
|
|
606
|
+
anonymous: false
|
|
607
|
+
}),
|
|
608
|
+
get: operation(request, {
|
|
609
|
+
method: "get",
|
|
610
|
+
path: "/schema-versions/{id}",
|
|
611
|
+
pathParams: ["id"],
|
|
612
|
+
queryParams: [],
|
|
613
|
+
body: false,
|
|
614
|
+
multipart: false,
|
|
615
|
+
binary: false,
|
|
616
|
+
anonymous: false
|
|
617
|
+
}),
|
|
618
|
+
update: operation(request, {
|
|
619
|
+
method: "patch",
|
|
620
|
+
path: "/schema-versions/{id}",
|
|
621
|
+
pathParams: ["id"],
|
|
622
|
+
queryParams: [],
|
|
623
|
+
body: true,
|
|
624
|
+
multipart: false,
|
|
625
|
+
binary: false,
|
|
626
|
+
anonymous: false
|
|
627
|
+
}),
|
|
628
|
+
revert: operation(request, {
|
|
629
|
+
method: "post",
|
|
630
|
+
path: "/schema-versions/{id}/revert",
|
|
631
|
+
pathParams: ["id"],
|
|
632
|
+
queryParams: [],
|
|
633
|
+
body: true,
|
|
634
|
+
multipart: false,
|
|
635
|
+
binary: false,
|
|
636
|
+
anonymous: false
|
|
637
|
+
})
|
|
638
|
+
},
|
|
639
|
+
memberships: {
|
|
640
|
+
list: operation(request, {
|
|
641
|
+
method: "get",
|
|
642
|
+
path: "/memberships",
|
|
643
|
+
pathParams: [],
|
|
644
|
+
queryParams: ["cursor", "limit"],
|
|
645
|
+
body: false,
|
|
646
|
+
multipart: false,
|
|
647
|
+
binary: false,
|
|
648
|
+
anonymous: false
|
|
649
|
+
}),
|
|
650
|
+
invite: operation(request, {
|
|
651
|
+
method: "post",
|
|
652
|
+
path: "/memberships",
|
|
653
|
+
pathParams: [],
|
|
654
|
+
queryParams: [],
|
|
655
|
+
body: true,
|
|
656
|
+
multipart: false,
|
|
657
|
+
binary: false,
|
|
658
|
+
anonymous: false
|
|
659
|
+
}),
|
|
660
|
+
update: operation(request, {
|
|
661
|
+
method: "patch",
|
|
662
|
+
path: "/memberships/{id}",
|
|
663
|
+
pathParams: ["id"],
|
|
664
|
+
queryParams: [],
|
|
665
|
+
body: true,
|
|
666
|
+
multipart: false,
|
|
667
|
+
binary: false,
|
|
668
|
+
anonymous: false
|
|
669
|
+
}),
|
|
670
|
+
remove: operation(request, {
|
|
671
|
+
method: "delete",
|
|
672
|
+
path: "/memberships/{id}",
|
|
673
|
+
pathParams: ["id"],
|
|
674
|
+
queryParams: [],
|
|
675
|
+
body: false,
|
|
676
|
+
multipart: false,
|
|
677
|
+
binary: false,
|
|
678
|
+
anonymous: false
|
|
679
|
+
}),
|
|
680
|
+
listInvites: operation(request, {
|
|
681
|
+
method: "get",
|
|
682
|
+
path: "/memberships/invites",
|
|
683
|
+
pathParams: [],
|
|
684
|
+
queryParams: ["cursor", "limit"],
|
|
685
|
+
body: false,
|
|
686
|
+
multipart: false,
|
|
687
|
+
binary: false,
|
|
688
|
+
anonymous: false
|
|
689
|
+
}),
|
|
690
|
+
resendInvite: operation(request, {
|
|
691
|
+
method: "post",
|
|
692
|
+
path: "/memberships/invites/{id}/resend",
|
|
693
|
+
pathParams: ["id"],
|
|
694
|
+
queryParams: [],
|
|
695
|
+
body: false,
|
|
696
|
+
multipart: false,
|
|
697
|
+
binary: false,
|
|
698
|
+
anonymous: false
|
|
699
|
+
}),
|
|
700
|
+
revokeInvite: operation(request, {
|
|
701
|
+
method: "delete",
|
|
702
|
+
path: "/memberships/invites/{id}",
|
|
703
|
+
pathParams: ["id"],
|
|
704
|
+
queryParams: [],
|
|
705
|
+
body: false,
|
|
706
|
+
multipart: false,
|
|
707
|
+
binary: false,
|
|
708
|
+
anonymous: false
|
|
709
|
+
})
|
|
710
|
+
},
|
|
711
|
+
publishing: {
|
|
712
|
+
setCollection: operation(request, {
|
|
713
|
+
method: "put",
|
|
714
|
+
path: "/publishing/collections/{collectionID}",
|
|
715
|
+
pathParams: ["collectionID"],
|
|
716
|
+
queryParams: [],
|
|
717
|
+
body: true,
|
|
718
|
+
multipart: false,
|
|
719
|
+
binary: false,
|
|
720
|
+
anonymous: false
|
|
721
|
+
}),
|
|
722
|
+
publishCollection: operation(request, {
|
|
723
|
+
method: "post",
|
|
724
|
+
path: "/publishing/collections/{collectionID}",
|
|
725
|
+
pathParams: ["collectionID"],
|
|
726
|
+
queryParams: [],
|
|
727
|
+
body: true,
|
|
728
|
+
multipart: false,
|
|
729
|
+
binary: false,
|
|
730
|
+
anonymous: false
|
|
731
|
+
}),
|
|
732
|
+
unpublishCollection: operation(request, {
|
|
733
|
+
method: "delete",
|
|
734
|
+
path: "/publishing/collections/{collectionID}",
|
|
735
|
+
pathParams: ["collectionID"],
|
|
736
|
+
queryParams: [],
|
|
737
|
+
body: true,
|
|
738
|
+
multipart: false,
|
|
739
|
+
binary: false,
|
|
740
|
+
anonymous: false
|
|
741
|
+
}),
|
|
742
|
+
bulkSetCollections: operation(request, {
|
|
743
|
+
method: "post",
|
|
744
|
+
path: "/publishing/collections/bulk/set",
|
|
745
|
+
pathParams: [],
|
|
746
|
+
queryParams: [],
|
|
747
|
+
body: true,
|
|
748
|
+
multipart: false,
|
|
749
|
+
binary: false,
|
|
750
|
+
anonymous: false
|
|
751
|
+
}),
|
|
752
|
+
bulkPublishCollections: operation(request, {
|
|
753
|
+
method: "post",
|
|
754
|
+
path: "/publishing/collections/bulk/publish",
|
|
755
|
+
pathParams: [],
|
|
756
|
+
queryParams: [],
|
|
757
|
+
body: true,
|
|
758
|
+
multipart: false,
|
|
759
|
+
binary: false,
|
|
760
|
+
anonymous: false
|
|
761
|
+
}),
|
|
762
|
+
bulkUnpublishCollections: operation(request, {
|
|
763
|
+
method: "post",
|
|
764
|
+
path: "/publishing/collections/bulk/unpublish",
|
|
765
|
+
pathParams: [],
|
|
766
|
+
queryParams: [],
|
|
767
|
+
body: true,
|
|
768
|
+
multipart: false,
|
|
769
|
+
binary: false,
|
|
770
|
+
anonymous: false
|
|
771
|
+
}),
|
|
772
|
+
publishEntry: operation(request, {
|
|
773
|
+
method: "post",
|
|
774
|
+
path: "/publishing/entries/{entryID}",
|
|
775
|
+
pathParams: ["entryID"],
|
|
776
|
+
queryParams: [],
|
|
777
|
+
body: true,
|
|
778
|
+
multipart: false,
|
|
779
|
+
binary: false,
|
|
780
|
+
anonymous: false
|
|
781
|
+
}),
|
|
782
|
+
unpublishEntry: operation(request, {
|
|
783
|
+
method: "delete",
|
|
784
|
+
path: "/publishing/entries/{entryID}",
|
|
785
|
+
pathParams: ["entryID"],
|
|
786
|
+
queryParams: [],
|
|
787
|
+
body: true,
|
|
788
|
+
multipart: false,
|
|
789
|
+
binary: false,
|
|
790
|
+
anonymous: false
|
|
791
|
+
}),
|
|
792
|
+
bulkPublishEntries: operation(request, {
|
|
793
|
+
method: "post",
|
|
794
|
+
path: "/publishing/entries/bulk/publish",
|
|
795
|
+
pathParams: [],
|
|
796
|
+
queryParams: [],
|
|
797
|
+
body: true,
|
|
798
|
+
multipart: false,
|
|
799
|
+
binary: false,
|
|
800
|
+
anonymous: false
|
|
801
|
+
}),
|
|
802
|
+
bulkUnpublishEntries: operation(request, {
|
|
803
|
+
method: "post",
|
|
804
|
+
path: "/publishing/entries/bulk/unpublish",
|
|
805
|
+
pathParams: [],
|
|
806
|
+
queryParams: [],
|
|
807
|
+
body: true,
|
|
808
|
+
multipart: false,
|
|
809
|
+
binary: false,
|
|
810
|
+
anonymous: false
|
|
811
|
+
}),
|
|
812
|
+
revertChanges: operation(request, {
|
|
813
|
+
method: "post",
|
|
814
|
+
path: "/publishing/changes/revert",
|
|
815
|
+
pathParams: [],
|
|
816
|
+
queryParams: [],
|
|
817
|
+
body: true,
|
|
818
|
+
multipart: false,
|
|
819
|
+
binary: false,
|
|
820
|
+
anonymous: false
|
|
821
|
+
}),
|
|
822
|
+
getEntryVersion: operation(request, {
|
|
823
|
+
method: "get",
|
|
824
|
+
path: "/publishing/entries/{entryID}/version",
|
|
825
|
+
pathParams: ["entryID"],
|
|
826
|
+
queryParams: [
|
|
827
|
+
"channel",
|
|
828
|
+
"expectedSchemaHash",
|
|
829
|
+
"snapshotID"
|
|
830
|
+
],
|
|
831
|
+
body: false,
|
|
832
|
+
multipart: false,
|
|
833
|
+
binary: false,
|
|
834
|
+
anonymous: false
|
|
835
|
+
}),
|
|
836
|
+
listEntryPublications: operation(request, {
|
|
837
|
+
method: "get",
|
|
838
|
+
path: "/publishing/entries/{entryID}/publications",
|
|
839
|
+
pathParams: ["entryID"],
|
|
840
|
+
queryParams: [],
|
|
841
|
+
body: false,
|
|
842
|
+
multipart: false,
|
|
843
|
+
binary: false,
|
|
844
|
+
anonymous: false
|
|
845
|
+
}),
|
|
846
|
+
listChannels: operation(request, {
|
|
847
|
+
method: "get",
|
|
848
|
+
path: "/publishing/channels",
|
|
849
|
+
pathParams: [],
|
|
850
|
+
queryParams: ["includeAssignmentCount"],
|
|
851
|
+
body: false,
|
|
852
|
+
multipart: false,
|
|
853
|
+
binary: false,
|
|
854
|
+
anonymous: false
|
|
855
|
+
}),
|
|
856
|
+
createChannel: operation(request, {
|
|
857
|
+
method: "post",
|
|
858
|
+
path: "/publishing/channels",
|
|
859
|
+
pathParams: [],
|
|
860
|
+
queryParams: [],
|
|
861
|
+
body: true,
|
|
862
|
+
multipart: false,
|
|
863
|
+
binary: false,
|
|
864
|
+
anonymous: false
|
|
865
|
+
}),
|
|
866
|
+
getChannelContent: operation(request, {
|
|
867
|
+
method: "get",
|
|
868
|
+
path: "/publishing/channels/{channel}/content",
|
|
869
|
+
pathParams: ["channel"],
|
|
870
|
+
queryParams: ["collectionID"],
|
|
871
|
+
body: false,
|
|
872
|
+
multipart: false,
|
|
873
|
+
binary: false,
|
|
874
|
+
anonymous: false
|
|
875
|
+
}),
|
|
876
|
+
deleteChannel: operation(request, {
|
|
877
|
+
method: "delete",
|
|
878
|
+
path: "/publishing/channels/{code}",
|
|
879
|
+
pathParams: ["code"],
|
|
880
|
+
queryParams: [],
|
|
881
|
+
body: true,
|
|
882
|
+
multipart: false,
|
|
883
|
+
binary: false,
|
|
884
|
+
anonymous: false
|
|
885
|
+
})
|
|
886
|
+
},
|
|
887
|
+
versions: {
|
|
888
|
+
create: operation(request, {
|
|
889
|
+
method: "post",
|
|
890
|
+
path: "/entries/{entryID}/versions",
|
|
891
|
+
pathParams: ["entryID"],
|
|
892
|
+
queryParams: [],
|
|
893
|
+
body: true,
|
|
894
|
+
multipart: false,
|
|
895
|
+
binary: false,
|
|
896
|
+
anonymous: false
|
|
897
|
+
}),
|
|
898
|
+
list: operation(request, {
|
|
899
|
+
method: "get",
|
|
900
|
+
path: "/entries/{entryID}/versions",
|
|
901
|
+
pathParams: ["entryID"],
|
|
902
|
+
queryParams: ["cursor", "limit"],
|
|
903
|
+
body: false,
|
|
904
|
+
multipart: false,
|
|
905
|
+
binary: false,
|
|
906
|
+
anonymous: false
|
|
907
|
+
}),
|
|
908
|
+
get: operation(request, {
|
|
909
|
+
method: "get",
|
|
910
|
+
path: "/versions/{id}",
|
|
911
|
+
pathParams: ["id"],
|
|
912
|
+
queryParams: ["expectedSchemaHash"],
|
|
913
|
+
body: false,
|
|
914
|
+
multipart: false,
|
|
915
|
+
binary: false,
|
|
916
|
+
anonymous: false
|
|
917
|
+
}),
|
|
918
|
+
update: operation(request, {
|
|
919
|
+
method: "patch",
|
|
920
|
+
path: "/versions/{id}",
|
|
921
|
+
pathParams: ["id"],
|
|
922
|
+
queryParams: [],
|
|
923
|
+
body: true,
|
|
924
|
+
multipart: false,
|
|
925
|
+
binary: false,
|
|
926
|
+
anonymous: false
|
|
927
|
+
}),
|
|
928
|
+
revert: operation(request, {
|
|
929
|
+
method: "post",
|
|
930
|
+
path: "/versions/{id}/revert",
|
|
931
|
+
pathParams: ["id"],
|
|
932
|
+
queryParams: [],
|
|
933
|
+
body: false,
|
|
934
|
+
multipart: false,
|
|
935
|
+
binary: false,
|
|
936
|
+
anonymous: false
|
|
937
|
+
})
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
//#endregion
|
|
941
|
+
//#region src/retry.ts
|
|
942
|
+
const wait = (delay, signal) => {
|
|
943
|
+
signal.throwIfAborted();
|
|
944
|
+
return new Promise((resolve, reject) => {
|
|
945
|
+
const abort = () => {
|
|
946
|
+
clearTimeout(timer);
|
|
947
|
+
reject(signal.reason);
|
|
948
|
+
};
|
|
949
|
+
const timer = setTimeout(() => {
|
|
950
|
+
signal.removeEventListener("abort", abort);
|
|
951
|
+
resolve();
|
|
952
|
+
}, delay);
|
|
953
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
954
|
+
});
|
|
955
|
+
};
|
|
956
|
+
const retryDelay = (attempt, response) => {
|
|
957
|
+
const value = response?.headers.get("Retry-After");
|
|
958
|
+
const seconds = value === null || value === void 0 ? NaN : Number(value);
|
|
959
|
+
const date = value ? Date.parse(value) : NaN;
|
|
960
|
+
if (Number.isFinite(seconds)) return Math.max(0, seconds * 1e3);
|
|
961
|
+
if (Number.isFinite(date)) return Math.max(0, date - Date.now());
|
|
962
|
+
return Math.min(1e3 * 2 ** attempt, 3e4) + Math.random() * 250;
|
|
963
|
+
};
|
|
964
|
+
const fetchWithRetries = async (fetcher, request, retries) => {
|
|
965
|
+
const signal = request.signal;
|
|
966
|
+
for (let attempt = 0;; attempt += 1) {
|
|
967
|
+
let response;
|
|
968
|
+
signal.throwIfAborted();
|
|
969
|
+
try {
|
|
970
|
+
response = await fetcher(request.clone());
|
|
971
|
+
} catch (error) {
|
|
972
|
+
if (signal.aborted || attempt >= retries || !(error instanceof TypeError)) throw error;
|
|
973
|
+
await wait(retryDelay(attempt), signal);
|
|
974
|
+
continue;
|
|
975
|
+
}
|
|
976
|
+
if (attempt >= retries || ![
|
|
977
|
+
429,
|
|
978
|
+
500,
|
|
979
|
+
502,
|
|
980
|
+
503,
|
|
981
|
+
504
|
|
982
|
+
].includes(response.status)) return response;
|
|
983
|
+
const delay = retryDelay(attempt, response);
|
|
984
|
+
await response.body?.cancel();
|
|
985
|
+
await wait(delay, signal);
|
|
986
|
+
}
|
|
987
|
+
};
|
|
988
|
+
//#endregion
|
|
989
|
+
//#region src/client.ts
|
|
990
|
+
/**
|
|
991
|
+
* Create a typed API client for a hosted or self-hosted Andesine instance.
|
|
992
|
+
*
|
|
993
|
+
* Methods return response data by default. Use response: "full" for status and headers,
|
|
994
|
+
* including conditional reads that can return 304. Creation does not make a request.
|
|
995
|
+
* @param config - Optional API root, credentials, transport, and request defaults.
|
|
996
|
+
* Defaults to https://api.andesine.app and process.env.ANDESINE_API_KEY when available.
|
|
997
|
+
* Runtimes without process.env use no default key. No environment files are loaded.
|
|
998
|
+
* @returns API resources and helpers for published-content snapshots and pagination.
|
|
999
|
+
* @throws TypeError if baseURL is not HTTP(S) or includes credentials, a query, or a fragment.
|
|
1000
|
+
* Request failures throw AndesineAPIError; abort and timeout reasons are preserved.
|
|
1001
|
+
* @example
|
|
1002
|
+
* const client = createClient();
|
|
1003
|
+
* const page = await client.content.get({ path: "/Docs/Welcome" });
|
|
1004
|
+
*/
|
|
1005
|
+
const createClient = (config = {}) => {
|
|
1006
|
+
const baseURL = (config.baseURL ?? "https://api.andesine.app").replace(/\/+$/, "");
|
|
1007
|
+
const apiKey = config.apiKey ?? globalThis.process?.env?.ANDESINE_API_KEY;
|
|
1008
|
+
const url = new URL(baseURL);
|
|
1009
|
+
const fetcher = config.fetch ?? globalThis.fetch;
|
|
1010
|
+
if (!["http:", "https:"].includes(url.protocol) || url.search || url.hash || url.username || url.password) throw new TypeError("baseURL must be an HTTP(S) URL without credentials, query, or fragment");
|
|
1011
|
+
const request = async (definition, input, options = {}) => {
|
|
1012
|
+
const controller = new AbortController();
|
|
1013
|
+
const signal = options.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;
|
|
1014
|
+
const timeout = options.timeout ?? config.timeout ?? 3e4;
|
|
1015
|
+
const retries = options.retries ?? config.retries ?? 0;
|
|
1016
|
+
const headers = new Headers(config.headers);
|
|
1017
|
+
const path = Object.fromEntries(definition.pathParams.map((key) => [key, input[key]]));
|
|
1018
|
+
const query = Object.fromEntries(definition.queryParams.map((key) => [key, input[key]]));
|
|
1019
|
+
const body = Object.fromEntries(Object.entries(input).filter(([key]) => !definition.pathParams.includes(key) && !definition.queryParams.includes(key)));
|
|
1020
|
+
const client = createFetchClient({
|
|
1021
|
+
baseUrl: baseURL,
|
|
1022
|
+
querySerializer: serializeQuery
|
|
1023
|
+
});
|
|
1024
|
+
if (!Number.isFinite(timeout) || timeout < 0 || !Number.isInteger(retries) || retries < 0) throw new TypeError("timeout and retries must be nonnegative; retries must be an integer");
|
|
1025
|
+
if (query.channel !== void 0 && query.snapshotID !== void 0) throw new TypeError("Use either channel or snapshotID, not both");
|
|
1026
|
+
for (const key of definition.pathParams) if (input[key] === void 0 || input[key] === null) throw new TypeError(`Missing path parameter: ${key}`);
|
|
1027
|
+
new Headers(options.headers).forEach((value, key) => headers.set(key, value));
|
|
1028
|
+
if (definition.streaming && !headers.has("Accept")) headers.set("Accept", "text/event-stream");
|
|
1029
|
+
if (apiKey && !definition.anonymous) headers.set("Authorization", `Bearer ${apiKey}`);
|
|
1030
|
+
const timer = timeout > 0 ? setTimeout(() => controller.abort(new DOMException("Request timed out", "TimeoutError")), timeout) : void 0;
|
|
1031
|
+
let streamOwnsRequest = false;
|
|
1032
|
+
try {
|
|
1033
|
+
const result = await client.request(definition.method, definition.path, {
|
|
1034
|
+
params: {
|
|
1035
|
+
path,
|
|
1036
|
+
query
|
|
1037
|
+
},
|
|
1038
|
+
headers,
|
|
1039
|
+
signal,
|
|
1040
|
+
body: definition.body ? body : void 0,
|
|
1041
|
+
parseAs: "stream",
|
|
1042
|
+
bodySerializer: definition.multipart ? (value) => {
|
|
1043
|
+
const form = new FormData();
|
|
1044
|
+
for (const [key, item] of Object.entries(value)) if (item instanceof Blob) form.append(key, item);
|
|
1045
|
+
else if (item !== void 0) form.append(key, typeof item === "string" ? item : JSON.stringify(item));
|
|
1046
|
+
return form;
|
|
1047
|
+
} : void 0,
|
|
1048
|
+
fetch: (request) => fetchWithRetries(fetcher, request, definition.method === "get" ? retries : 0)
|
|
1049
|
+
});
|
|
1050
|
+
const response = result.response;
|
|
1051
|
+
if (response.status === 304) {
|
|
1052
|
+
if (options.response !== "full") throw new TypeError("Use response: 'full' for conditional requests that can return 304");
|
|
1053
|
+
return {
|
|
1054
|
+
status: 304,
|
|
1055
|
+
headers: response.headers,
|
|
1056
|
+
data: void 0,
|
|
1057
|
+
notModified: true
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
if (!response.ok) throw new AndesineAPIError(response, result.error);
|
|
1061
|
+
if (definition.streaming) {
|
|
1062
|
+
const data = createAnswerStream(response, {
|
|
1063
|
+
signal,
|
|
1064
|
+
cancel: () => controller.abort(),
|
|
1065
|
+
cleanup: () => {
|
|
1066
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
streamOwnsRequest = true;
|
|
1070
|
+
return options.response === "full" ? {
|
|
1071
|
+
status: response.status,
|
|
1072
|
+
headers: response.headers,
|
|
1073
|
+
data,
|
|
1074
|
+
notModified: false
|
|
1075
|
+
} : data;
|
|
1076
|
+
}
|
|
1077
|
+
const text = definition.binary || response.status === 204 ? void 0 : await response.text();
|
|
1078
|
+
const data = definition.binary ? await response.blob() : text ? JSON.parse(text) : void 0;
|
|
1079
|
+
return options.response === "full" ? {
|
|
1080
|
+
status: response.status,
|
|
1081
|
+
headers: response.headers,
|
|
1082
|
+
data,
|
|
1083
|
+
notModified: false
|
|
1084
|
+
} : data;
|
|
1085
|
+
} finally {
|
|
1086
|
+
if (!streamOwnsRequest && timer !== void 0) clearTimeout(timer);
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
const resources = createResources(request);
|
|
1090
|
+
return {
|
|
1091
|
+
...resources,
|
|
1092
|
+
content: createContentClient(resources.content),
|
|
1093
|
+
atSnapshot(snapshotID) {
|
|
1094
|
+
return createContentClient(createResources((definition, input, options) => {
|
|
1095
|
+
const pinned = definition.path.startsWith("/content/") && definition.queryParams.includes("snapshotID");
|
|
1096
|
+
if (pinned && (input.channel !== void 0 || input.snapshotID !== void 0 && input.snapshotID !== snapshotID)) throw new TypeError("Cannot override a pinned snapshot");
|
|
1097
|
+
return request(definition, pinned ? {
|
|
1098
|
+
...input,
|
|
1099
|
+
snapshotID
|
|
1100
|
+
} : input, options);
|
|
1101
|
+
}).content);
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
};
|
|
1105
|
+
//#endregion
|
|
1106
|
+
//#region src/content-url.ts
|
|
1107
|
+
/**
|
|
1108
|
+
* Convert a canonical Andesine path or search/citation location to a website URL.
|
|
1109
|
+
*
|
|
1110
|
+
* Encodes each decoded path segment and anchor without changing case or deriving slugs.
|
|
1111
|
+
* This is a pure function: it does not resolve IDs, fetch content, or pin a snapshot.
|
|
1112
|
+
* @param source - An absolute decoded path (starting with /), or an object with path and anchor.
|
|
1113
|
+
* Collection-ID-relative selectors must first be resolved through the API to a canonical path.
|
|
1114
|
+
* @param options - Source collection root and destination URL prefix.
|
|
1115
|
+
* @returns A root-relative URL by default, or an absolute URL when baseURL is absolute.
|
|
1116
|
+
* The source root itself maps to the destination root without adding a trailing slash.
|
|
1117
|
+
* @throws TypeError for invalid paths, a source outside rootPath, or an invalid baseURL.
|
|
1118
|
+
* @example
|
|
1119
|
+
* toContentURL({ path: "/Docs/Getting started", anchor: "install" }, {
|
|
1120
|
+
* rootPath: "/Docs", baseURL: "/docs"
|
|
1121
|
+
* }); // "/docs/Getting%20started#install"
|
|
1122
|
+
*/
|
|
1123
|
+
const toContentURL = (source, options = {}) => {
|
|
1124
|
+
const location = typeof source === "string" ? { path: source } : source;
|
|
1125
|
+
const segments = contentPathSegments(location.path);
|
|
1126
|
+
const root = contentPathSegments(options.rootPath ?? "/");
|
|
1127
|
+
const outsideRoot = root.some((segment, index) => segments[index] !== segment);
|
|
1128
|
+
const baseURL = options.baseURL ?? "/";
|
|
1129
|
+
const relative = baseURL.startsWith("/") && !baseURL.startsWith("//");
|
|
1130
|
+
const url = new URL(baseURL, relative ? "https://andesine.invalid" : void 0);
|
|
1131
|
+
const invalidBase = !["http:", "https:"].includes(url.protocol) || Boolean(url.search || url.hash || url.username || url.password) || baseURL.includes("\\");
|
|
1132
|
+
if (outsideRoot) throw new TypeError("Content path is outside rootPath");
|
|
1133
|
+
if (invalidBase) throw new TypeError("baseURL must be a root-relative or HTTP(S) URL without credentials, query, or fragment");
|
|
1134
|
+
const suffix = segments.slice(root.length).map(encodeURIComponent).join("/");
|
|
1135
|
+
const prefix = url.pathname.replace(/\/+$/, "");
|
|
1136
|
+
url.pathname = (suffix ? `${prefix}/${suffix}` : prefix) || "/";
|
|
1137
|
+
url.hash = location.anchor ? encodeURIComponent(location.anchor) : "";
|
|
1138
|
+
return relative ? `${url.pathname}${url.hash}` : url.href;
|
|
1139
|
+
};
|
|
1140
|
+
const contentPathSegments = (path) => {
|
|
1141
|
+
const segments = path === "/" ? [] : path.slice(1).split("/");
|
|
1142
|
+
if (!path.startsWith("/") || segments.some((segment) => !segment || segment === "." || segment === "..")) throw new TypeError("Use an absolute decoded content path without empty or dot segments");
|
|
1143
|
+
return segments;
|
|
1144
|
+
};
|
|
1145
|
+
//#endregion
|
|
1146
|
+
//#region src/structured-content.ts
|
|
1147
|
+
/**
|
|
1148
|
+
* Unwrap property values and fragment documents for use in application code.
|
|
1149
|
+
*
|
|
1150
|
+
* @param page - Full entry content with properties and fragments, including published list items.
|
|
1151
|
+
* @returns A new object with property.value and fragment.content exposed by key. Other fields,
|
|
1152
|
+
* including schema metadata and assets, are preserved. Nested content is shared, not cloned.
|
|
1153
|
+
* This helper does not validate content, convert formats, or infer collection-specific types.
|
|
1154
|
+
* @example
|
|
1155
|
+
* const tutorial = toStructuredContent(page);
|
|
1156
|
+
* const body = tutorial.fragments.body;
|
|
1157
|
+
* const enabled = tutorial.properties.enabled;
|
|
1158
|
+
*/
|
|
1159
|
+
const toStructuredContent = (page) => ({
|
|
1160
|
+
...page,
|
|
1161
|
+
properties: Object.fromEntries(Object.entries(page.properties).map(([key, property]) => [key, property.value])),
|
|
1162
|
+
fragments: Object.fromEntries(Object.entries(page.fragments).map(([key, fragment]) => [key, fragment.content]))
|
|
1163
|
+
});
|
|
1164
|
+
//#endregion
|
|
1165
|
+
export { AndesineAPIError, AndesineStreamError, AndesineStreamProtocolError, createClient, paginate, paginatePages, toContentURL, toStructuredContent };
|
|
1166
|
+
|
|
1167
|
+
//# sourceMappingURL=index.js.map
|