@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/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