@hotcodepush/node 0.0.0-stage → 0.0.1

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.mjs ADDED
@@ -0,0 +1,2269 @@
1
+ //#region package.json
2
+ var version = "0.0.0";
3
+ //#endregion
4
+ //#region src/errors.ts
5
+ /**
6
+ * Thrown when the API answers with a status outside 2xx.
7
+ * `code`, `message` and `details` come from the API verbatim.
8
+ * A response without the API error shape becomes `unexpected_response` with the status, and its body is dropped.
9
+ */
10
+ var HotCodePushError = class extends Error {
11
+ code;
12
+ details;
13
+ status;
14
+ constructor(errorBody, status) {
15
+ super(errorBody.message);
16
+ this.code = errorBody.code;
17
+ this.details = errorBody.details;
18
+ this.name = "HotCodePushError";
19
+ this.status = status;
20
+ }
21
+ };
22
+ function isErrorBody(value) {
23
+ return typeof value === "object" && value !== null && "code" in value && typeof value.code === "string" && "message" in value && typeof value.message === "string";
24
+ }
25
+ function resolveErrorBody(text) {
26
+ try {
27
+ const body = JSON.parse(text);
28
+ return isErrorBody(body) ? body : void 0;
29
+ } catch {
30
+ return;
31
+ }
32
+ }
33
+ function resolveHotCodePushError(status, text) {
34
+ return new HotCodePushError(resolveErrorBody(text) ?? {
35
+ code: "unexpected_response",
36
+ message: `Request failed with status ${status}.`
37
+ }, status);
38
+ }
39
+ //#endregion
40
+ //#region src/http-client.ts
41
+ const COMMA_LIST_QUERY_NAMES = /* @__PURE__ */ new Set(["ids", "relations"]);
42
+ const DEFAULT_BASE_URL = "https://api.hotcodepush.com";
43
+ const DEFAULT_CLIENT = `node/${version}`;
44
+ const IDEMPOTENT_METHODS = /* @__PURE__ */ new Set([
45
+ "DELETE",
46
+ "GET",
47
+ "PUT"
48
+ ]);
49
+ const INITIAL_RETRY_DELAY_MS = 500;
50
+ const JSON_TIMEOUT_MS = 6e4;
51
+ const MAX_ATTEMPTS = 3;
52
+ const MAX_RETRY_AFTER_MS = 6e4;
53
+ const RETRY_AFTER_STATUSES = /* @__PURE__ */ new Set([429, 503]);
54
+ const TOKEN_ENVIRONMENT_VARIABLE = "HOTCODEPUSH_TOKEN";
55
+ const UPLOAD_TIMEOUT_MS = 6e5;
56
+ var HttpClient = class {
57
+ baseUrl;
58
+ headers;
59
+ timeoutMs;
60
+ constructor(options) {
61
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
62
+ this.headers = resolveHeaders(options);
63
+ this.timeoutMs = options.timeout ?? JSON_TIMEOUT_MS;
64
+ }
65
+ async fetchBlob(options) {
66
+ const response = await this.fetchResponse(options);
67
+ await assertResponseOk(response);
68
+ return response.blob();
69
+ }
70
+ async fetchCreatingPost(options) {
71
+ return this.fetchJson({
72
+ body: options.body,
73
+ headers: { "Idempotency-Key": options.idempotencyKey ?? crypto.randomUUID() },
74
+ isRetryable: true,
75
+ method: "POST",
76
+ path: options.path
77
+ });
78
+ }
79
+ async fetchJson(options) {
80
+ return parseResponseBody(await this.fetchResponse(options));
81
+ }
82
+ async fetchStatus(options) {
83
+ const response = await this.fetchResponse(options);
84
+ await assertResponseOk(response);
85
+ await response.body?.cancel();
86
+ }
87
+ async fetchUpload(options) {
88
+ const fetchWithTimeout = withTimeout(fetch, UPLOAD_TIMEOUT_MS);
89
+ const fetchFunction = isBlobUploadBody(options) ? withRetry(fetchWithTimeout) : fetchWithTimeout;
90
+ const contentLength = isBlobUploadBody(options) ? options.body.size : options.contentLength;
91
+ return parseResponseBody(await fetchFunction(this.resolveRouteUrl(options.path), {
92
+ body: options.body,
93
+ duplex: "half",
94
+ headers: {
95
+ ...this.headers,
96
+ "Content-Length": String(contentLength),
97
+ "Content-Type": options.contentType
98
+ },
99
+ method: "PUT"
100
+ }));
101
+ }
102
+ async fetchResponse(options) {
103
+ const fetchWithTimeout = withTimeout(fetch, this.timeoutMs);
104
+ return (options.isRetryable ?? IDEMPOTENT_METHODS.has(options.method) ? withRetry(fetchWithTimeout) : fetchWithTimeout)(this.resolveUrl(options), this.resolveRequestInit(options));
105
+ }
106
+ resolveRequestInit(options) {
107
+ const headers = {
108
+ ...this.headers,
109
+ ...options.headers
110
+ };
111
+ if (options.body === void 0) return {
112
+ headers,
113
+ method: options.method
114
+ };
115
+ return {
116
+ body: JSON.stringify(options.body),
117
+ headers: {
118
+ ...headers,
119
+ "Content-Type": "application/json"
120
+ },
121
+ method: options.method
122
+ };
123
+ }
124
+ resolveRouteUrl(path) {
125
+ return new URL(this.baseUrl + path);
126
+ }
127
+ resolveUrl(options) {
128
+ const url = this.resolveRouteUrl(options.path);
129
+ for (const [name, value] of Object.entries(options.query ?? {})) for (const queryValue of resolveQueryValues(name, value)) url.searchParams.append(name, queryValue);
130
+ return url;
131
+ }
132
+ };
133
+ async function assertResponseOk(response) {
134
+ if (!response.ok) throw resolveHotCodePushError(response.status, await response.text());
135
+ }
136
+ function isBlobUploadBody(uploadBody) {
137
+ return uploadBody.body instanceof Blob;
138
+ }
139
+ function isRetryableStatus(status) {
140
+ return status === 408 || status === 429 || status >= 500;
141
+ }
142
+ async function parseResponseBody(response) {
143
+ await assertResponseOk(response);
144
+ const text = await response.text();
145
+ return text ? JSON.parse(text) : void 0;
146
+ }
147
+ function resolveHeaders(options) {
148
+ const headers = {
149
+ "Accept": "application/json",
150
+ "X-HotCodePush-Client": options.client ?? DEFAULT_CLIENT
151
+ };
152
+ const token = options.token || process.env[TOKEN_ENVIRONMENT_VARIABLE];
153
+ if (token) headers.Authorization = `Bearer ${token}`;
154
+ if (options.userAgent) headers["User-Agent"] = options.userAgent;
155
+ return headers;
156
+ }
157
+ function resolvePath(template, parameters = {}) {
158
+ return template.replace(/\{(\w+)\}/g, (_placeholder, name) => {
159
+ const parameter = parameters[name];
160
+ if (parameter === void 0) throw new Error(`The path parameter ${name} of ${template} is missing.`);
161
+ return encodeURIComponent(parameter);
162
+ });
163
+ }
164
+ function resolveQueryValues(name, value) {
165
+ if (value === void 0 || value === "") return [];
166
+ if (typeof value !== "object") return [String(value)];
167
+ if (COMMA_LIST_QUERY_NAMES.has(name)) return value.length === 0 ? [] : [value.join(",")];
168
+ return [...value];
169
+ }
170
+ function resolveRetryAfterMs(response) {
171
+ const retryAfter = response.headers.get("Retry-After")?.trim();
172
+ if (!RETRY_AFTER_STATUSES.has(response.status) || !retryAfter) return;
173
+ const retryAfterMs = /^\d+$/.test(retryAfter) ? Number(retryAfter) * 1e3 : Date.parse(retryAfter) - Date.now();
174
+ if (Number.isNaN(retryAfterMs)) return;
175
+ return Math.min(Math.max(retryAfterMs, 0), MAX_RETRY_AFTER_MS);
176
+ }
177
+ function sleep(milliseconds) {
178
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
179
+ }
180
+ function withRetry(fetchFunction) {
181
+ return async (input, init) => {
182
+ for (let attempt = 1;; attempt++) {
183
+ const isLastAttempt = attempt === MAX_ATTEMPTS;
184
+ let retryAfterMs;
185
+ try {
186
+ const response = await fetchFunction(input, init);
187
+ if (isLastAttempt || !isRetryableStatus(response.status)) return response;
188
+ await response.body?.cancel();
189
+ retryAfterMs = resolveRetryAfterMs(response);
190
+ } catch (error) {
191
+ if (isLastAttempt) throw error;
192
+ }
193
+ await sleep(retryAfterMs ?? INITIAL_RETRY_DELAY_MS * 2 ** (attempt - 1));
194
+ }
195
+ };
196
+ }
197
+ function withTimeout(fetchFunction, timeoutMs) {
198
+ return (input, init) => fetchFunction(input, {
199
+ ...init,
200
+ signal: AbortSignal.timeout(timeoutMs)
201
+ });
202
+ }
203
+ //#endregion
204
+ //#region src/resources/binaries.ts
205
+ var BinariesResource = class {
206
+ httpClient;
207
+ constructor(httpClient) {
208
+ this.httpClient = httpClient;
209
+ }
210
+ /**
211
+ * Counts the store builds of the app that match the filters.
212
+ */
213
+ async count(options) {
214
+ const { appId, ...query } = options;
215
+ return this.httpClient.fetchJson({
216
+ method: "GET",
217
+ path: resolvePath("/v1/apps/{appId}/binaries/count", { appId }),
218
+ query
219
+ });
220
+ }
221
+ /**
222
+ * Creates a binary: a store build with a bundle compiled into it. Upload its files first.
223
+ * An identical create answers the existing binary. A different fingerprint or file set is refused unless `force` is set.
224
+ */
225
+ async create(options) {
226
+ const { appId, idempotencyKey, ...body } = options;
227
+ return this.httpClient.fetchCreatingPost({
228
+ body,
229
+ idempotencyKey,
230
+ path: resolvePath("/v1/apps/{appId}/binaries", { appId })
231
+ });
232
+ }
233
+ async get(options) {
234
+ return this.httpClient.fetchJson({
235
+ method: "GET",
236
+ path: resolvePath("/v1/apps/{appId}/binaries/{binaryId}", options)
237
+ });
238
+ }
239
+ /**
240
+ * Lists the store builds of the app, newest first.
241
+ */
242
+ async list(options) {
243
+ const { appId, ...query } = options;
244
+ return this.httpClient.fetchJson({
245
+ method: "GET",
246
+ path: resolvePath("/v1/apps/{appId}/binaries", { appId }),
247
+ query
248
+ });
249
+ }
250
+ };
251
+ //#endregion
252
+ //#region src/resources/bundle-deltas.ts
253
+ var BundleDeltasResource = class {
254
+ httpClient;
255
+ constructor(httpClient) {
256
+ this.httpClient = httpClient;
257
+ }
258
+ /**
259
+ * Counts the deltas of the bundle.
260
+ */
261
+ async count(options) {
262
+ return this.httpClient.fetchJson({
263
+ method: "GET",
264
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}/deltas/count", options)
265
+ });
266
+ }
267
+ /**
268
+ * Lists the deltas of the bundle, newest first, one per base bundle that its devices run.
269
+ * `relations: ['baseBundle']` embeds the base bundle.
270
+ */
271
+ async list(options) {
272
+ const { appId, bundleId, ...query } = options;
273
+ return this.httpClient.fetchJson({
274
+ method: "GET",
275
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}/deltas", {
276
+ appId,
277
+ bundleId
278
+ }),
279
+ query
280
+ });
281
+ }
282
+ };
283
+ //#endregion
284
+ //#region src/resources/bundle-files.ts
285
+ var BundleFilesResource = class {
286
+ httpClient;
287
+ constructor(httpClient) {
288
+ this.httpClient = httpClient;
289
+ }
290
+ /**
291
+ * Counts the files of the bundle that match the filters.
292
+ */
293
+ async count(options) {
294
+ const { appId, bundleId, ...query } = options;
295
+ return this.httpClient.fetchJson({
296
+ method: "GET",
297
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}/files/count", {
298
+ appId,
299
+ bundleId
300
+ }),
301
+ query
302
+ });
303
+ }
304
+ /**
305
+ * Lists the files of the bundle, ordered by path.
306
+ * An embedded bundle answers the files its binary was created with.
307
+ * After creating a bundle, `isStored: false` selects the files still to upload.
308
+ */
309
+ async list(options) {
310
+ const { appId, bundleId, ...query } = options;
311
+ return this.httpClient.fetchJson({
312
+ method: "GET",
313
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}/files", {
314
+ appId,
315
+ bundleId
316
+ }),
317
+ query
318
+ });
319
+ }
320
+ };
321
+ //#endregion
322
+ //#region src/upload-in-parts.ts
323
+ /**
324
+ * The size of every part but the last.
325
+ * The bucket requires at least five mebibytes, and the same size for all of them.
326
+ */
327
+ const PART_SIZE_BYTES = 10485760;
328
+ /**
329
+ * The largest `Blob` sent in one request; a larger one goes up in parts.
330
+ * It stays well under the request body cap of the API hosting plan.
331
+ */
332
+ const SINGLE_UPLOAD_LIMIT_BYTES = 67108864;
333
+ function isBlobAboveSingleUploadLimit(uploadBody) {
334
+ return uploadBody.body instanceof Blob && uploadBody.body.size > 67108864;
335
+ }
336
+ async function uploadInParts(uploads, pathParameters, blob) {
337
+ const { uploadId } = await uploads.create(pathParameters);
338
+ try {
339
+ const parts = [];
340
+ for (let start = 0, partNumber = 1; start < blob.size; start += PART_SIZE_BYTES, partNumber += 1) {
341
+ const uploadedPart = await uploads.parts.upload({
342
+ ...pathParameters,
343
+ body: blob.slice(start, start + PART_SIZE_BYTES),
344
+ partNumber,
345
+ uploadId
346
+ });
347
+ parts.push(uploadedPart);
348
+ }
349
+ return await uploads.complete({
350
+ ...pathParameters,
351
+ parts,
352
+ uploadId
353
+ });
354
+ } catch (error) {
355
+ await uploads.delete({
356
+ ...pathParameters,
357
+ uploadId
358
+ }).catch(() => void 0);
359
+ throw error;
360
+ }
361
+ }
362
+ //#endregion
363
+ //#region src/resources/bundle-pack-upload-parts.ts
364
+ var BundlePackUploadPartsResource = class {
365
+ httpClient;
366
+ constructor(httpClient) {
367
+ this.httpClient = httpClient;
368
+ }
369
+ /**
370
+ * Uploads one part of a multipart pack upload.
371
+ * Pass the answered `etag` and `partNumber` to `complete`.
372
+ */
373
+ async upload(options) {
374
+ const { appId, bundleId, partNumber, uploadId, ...uploadBody } = options;
375
+ return this.httpClient.fetchUpload({
376
+ ...uploadBody,
377
+ contentType: "application/x-tar",
378
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}/pack/uploads/{uploadId}/parts/{partNumber}", {
379
+ appId,
380
+ bundleId,
381
+ partNumber,
382
+ uploadId
383
+ })
384
+ });
385
+ }
386
+ };
387
+ //#endregion
388
+ //#region src/resources/bundle-pack-uploads.ts
389
+ /**
390
+ * Uploads a pack above the request body limit in parts.
391
+ * Create the upload, upload the parts and complete it, or delete it to abort.
392
+ */
393
+ var BundlePackUploadsResource = class {
394
+ httpClient;
395
+ parts;
396
+ constructor(httpClient) {
397
+ this.httpClient = httpClient;
398
+ this.parts = new BundlePackUploadPartsResource(httpClient);
399
+ }
400
+ /**
401
+ * Assembles the parts into the pack and replaces any pack uploaded before.
402
+ * R2 refuses a second completion, so the client never retries the call.
403
+ */
404
+ async complete(options) {
405
+ const { appId, bundleId, uploadId, ...body } = options;
406
+ return this.httpClient.fetchJson({
407
+ body,
408
+ method: "POST",
409
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}/pack/uploads/{uploadId}/complete", {
410
+ appId,
411
+ bundleId,
412
+ uploadId
413
+ })
414
+ });
415
+ }
416
+ /**
417
+ * Starts a multipart upload of the pack.
418
+ * Every part but the last must have the same size of at least five mebibytes.
419
+ * The start holds no state, and an unused upload expires on its own, so the client retries the call.
420
+ */
421
+ async create(options) {
422
+ return this.httpClient.fetchJson({
423
+ isRetryable: true,
424
+ method: "POST",
425
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}/pack/uploads", options)
426
+ });
427
+ }
428
+ /**
429
+ * Aborts a multipart pack upload and discards its parts.
430
+ */
431
+ async delete(options) {
432
+ await this.httpClient.fetchJson({
433
+ method: "DELETE",
434
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}/pack/uploads/{uploadId}", options)
435
+ });
436
+ }
437
+ };
438
+ //#endregion
439
+ //#region src/resources/bundle-pack.ts
440
+ var BundlePackResource = class {
441
+ httpClient;
442
+ uploads;
443
+ constructor(httpClient) {
444
+ this.httpClient = httpClient;
445
+ this.uploads = new BundlePackUploadsResource(httpClient);
446
+ }
447
+ /**
448
+ * Uploads the full pack of the bundle, a tar, before the bundle is completed.
449
+ * A `Blob` above `SINGLE_UPLOAD_LIMIT_BYTES` goes up in parts. A stream goes up in one request, so it must stay within that limit.
450
+ */
451
+ async upload(options) {
452
+ const { appId, bundleId, ...uploadBody } = options;
453
+ if (isBlobAboveSingleUploadLimit(uploadBody)) return uploadInParts(this.uploads, {
454
+ appId,
455
+ bundleId
456
+ }, uploadBody.body);
457
+ return this.httpClient.fetchUpload({
458
+ ...uploadBody,
459
+ contentType: "application/x-tar",
460
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}/pack", {
461
+ appId,
462
+ bundleId
463
+ })
464
+ });
465
+ }
466
+ };
467
+ //#endregion
468
+ //#region src/resources/bundles.ts
469
+ var BundlesResource = class {
470
+ httpClient;
471
+ deltas;
472
+ files;
473
+ pack;
474
+ constructor(httpClient) {
475
+ this.httpClient = httpClient;
476
+ this.deltas = new BundleDeltasResource(httpClient);
477
+ this.files = new BundleFilesResource(httpClient);
478
+ this.pack = new BundlePackResource(httpClient);
479
+ }
480
+ /**
481
+ * Completes a bundle: checks that every listed file and the pack are uploaded, writes the manifest and sets the status to `ready`.
482
+ * A completed bundle answers itself again, so the client retries the call.
483
+ */
484
+ async complete(options) {
485
+ return this.httpClient.fetchJson({
486
+ isRetryable: true,
487
+ method: "POST",
488
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}/complete", options)
489
+ });
490
+ }
491
+ /**
492
+ * Counts the bundles of the app that match the filters.
493
+ */
494
+ async count(options) {
495
+ const { appId, ...query } = options;
496
+ return this.httpClient.fetchJson({
497
+ method: "GET",
498
+ path: resolvePath("/v1/apps/{appId}/bundles/count", { appId }),
499
+ query
500
+ });
501
+ }
502
+ /**
503
+ * Creates a bundle from its manifest. It stays `uploading` until completed.
504
+ * Find the files the app lacks with `apps.bundles.files.list` and `isStored: false`, and upload each through `apps.files.upload`.
505
+ * Upload the pack through `apps.bundles.pack.upload`.
506
+ */
507
+ async create(options) {
508
+ const { appId, idempotencyKey, ...body } = options;
509
+ return this.httpClient.fetchCreatingPost({
510
+ body,
511
+ idempotencyKey,
512
+ path: resolvePath("/v1/apps/{appId}/bundles", { appId })
513
+ });
514
+ }
515
+ /**
516
+ * Deletes a bundle at once.
517
+ * A bundle that a release serves or a store build embeds is refused.
518
+ */
519
+ async delete(options) {
520
+ await this.httpClient.fetchJson({
521
+ method: "DELETE",
522
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}", options)
523
+ });
524
+ }
525
+ async get(options) {
526
+ return this.httpClient.fetchJson({
527
+ method: "GET",
528
+ path: resolvePath("/v1/apps/{appId}/bundles/{bundleId}", options)
529
+ });
530
+ }
531
+ /**
532
+ * Lists the uploaded bundles of the app, newest first.
533
+ */
534
+ async list(options) {
535
+ const { appId, ...query } = options;
536
+ return this.httpClient.fetchJson({
537
+ method: "GET",
538
+ path: resolvePath("/v1/apps/{appId}/bundles", { appId }),
539
+ query
540
+ });
541
+ }
542
+ };
543
+ //#endregion
544
+ //#region src/resources/channel-audience.ts
545
+ var ChannelAudienceResource = class {
546
+ httpClient;
547
+ constructor(httpClient) {
548
+ this.httpClient = httpClient;
549
+ }
550
+ /**
551
+ * Estimates which devices of the channel a release with these conditions would reach, before the release exists.
552
+ * Each condition is repeatable, and repeated conditions combine with AND.
553
+ */
554
+ async get(options) {
555
+ const { appId, channelId, ...query } = options;
556
+ return this.httpClient.fetchJson({
557
+ method: "GET",
558
+ path: resolvePath("/v1/apps/{appId}/channels/{channelId}/audience", {
559
+ appId,
560
+ channelId
561
+ }),
562
+ query
563
+ });
564
+ }
565
+ };
566
+ //#endregion
567
+ //#region src/resources/channel-qr-code.ts
568
+ var ChannelQrCodeResource = class {
569
+ httpClient;
570
+ constructor(httpClient) {
571
+ this.httpClient = httpClient;
572
+ }
573
+ /**
574
+ * Gets the deep link of the channel as a QR image, built from the `channelLinkTemplate` of the app.
575
+ * The image is SVG unless `format` is `png`. Answers `not_found` while the template is unset.
576
+ */
577
+ async get(options) {
578
+ const { appId, channelId, ...query } = options;
579
+ return this.httpClient.fetchBlob({
580
+ method: "GET",
581
+ path: resolvePath("/v1/apps/{appId}/channels/{channelId}/qr-code", {
582
+ appId,
583
+ channelId
584
+ }),
585
+ query
586
+ });
587
+ }
588
+ };
589
+ //#endregion
590
+ //#region src/resources/channel-releases.ts
591
+ var ChannelReleasesResource = class {
592
+ httpClient;
593
+ constructor(httpClient) {
594
+ this.httpClient = httpClient;
595
+ }
596
+ /**
597
+ * Releases a ready bundle, or what another channel serves, in this channel.
598
+ * The release gets the next number of the channel.
599
+ */
600
+ async create(options) {
601
+ const { appId, channelId, idempotencyKey, ...body } = options;
602
+ return this.httpClient.fetchCreatingPost({
603
+ body,
604
+ idempotencyKey,
605
+ path: resolvePath("/v1/apps/{appId}/channels/{channelId}/releases", {
606
+ appId,
607
+ channelId
608
+ })
609
+ });
610
+ }
611
+ /**
612
+ * Revokes several releases of the channel at once: those in `releaseIds`, or every release numbered at or above `fromNumber`.
613
+ * Revoking a revoked release does nothing, so the client retries the call.
614
+ */
615
+ async revoke(options) {
616
+ const { appId, channelId, ...body } = options;
617
+ return this.httpClient.fetchJson({
618
+ body,
619
+ isRetryable: true,
620
+ method: "POST",
621
+ path: resolvePath("/v1/apps/{appId}/channels/{channelId}/releases/revoke", {
622
+ appId,
623
+ channelId
624
+ })
625
+ });
626
+ }
627
+ };
628
+ //#endregion
629
+ //#region src/resources/rollbacks.ts
630
+ var RollbacksResource = class {
631
+ httpClient;
632
+ constructor(httpClient) {
633
+ this.httpClient = httpClient;
634
+ }
635
+ /**
636
+ * Rolls the channel back to its previous bundle, or to the bundle of `toReleaseId`.
637
+ * A rollback is a new release.
638
+ */
639
+ async create(options) {
640
+ const { appId, channelId, idempotencyKey, ...body } = options;
641
+ return this.httpClient.fetchCreatingPost({
642
+ body,
643
+ idempotencyKey,
644
+ path: resolvePath("/v1/apps/{appId}/channels/{channelId}/rollbacks", {
645
+ appId,
646
+ channelId
647
+ })
648
+ });
649
+ }
650
+ };
651
+ //#endregion
652
+ //#region src/resources/channels.ts
653
+ var ChannelsResource = class {
654
+ httpClient;
655
+ audience;
656
+ qrCode;
657
+ releases;
658
+ rollbacks;
659
+ constructor(httpClient) {
660
+ this.httpClient = httpClient;
661
+ this.audience = new ChannelAudienceResource(httpClient);
662
+ this.qrCode = new ChannelQrCodeResource(httpClient);
663
+ this.releases = new ChannelReleasesResource(httpClient);
664
+ this.rollbacks = new RollbacksResource(httpClient);
665
+ }
666
+ /**
667
+ * Counts the channels of the app that match the filters.
668
+ */
669
+ async count(options) {
670
+ const { appId, ...query } = options;
671
+ return this.httpClient.fetchJson({
672
+ method: "GET",
673
+ path: resolvePath("/v1/apps/{appId}/channels/count", { appId }),
674
+ query
675
+ });
676
+ }
677
+ async create(options) {
678
+ const { appId, idempotencyKey, ...body } = options;
679
+ return this.httpClient.fetchCreatingPost({
680
+ body,
681
+ idempotencyKey,
682
+ path: resolvePath("/v1/apps/{appId}/channels", { appId })
683
+ });
684
+ }
685
+ /**
686
+ * Deletes a channel at once. The default channel of the app is refused.
687
+ */
688
+ async delete(options) {
689
+ await this.httpClient.fetchJson({
690
+ method: "DELETE",
691
+ path: resolvePath("/v1/apps/{appId}/channels/{channelId}", options)
692
+ });
693
+ }
694
+ /**
695
+ * Deletes the channels of the app named by `ids`, one to 100. An id of another app is skipped.
696
+ * The default channel, or a protected channel when the caller is a Member, refuses the whole set.
697
+ */
698
+ async deleteMany(options) {
699
+ const { appId, ...query } = options;
700
+ await this.httpClient.fetchJson({
701
+ method: "DELETE",
702
+ path: resolvePath("/v1/apps/{appId}/channels", { appId }),
703
+ query
704
+ });
705
+ }
706
+ /**
707
+ * Gets a channel.
708
+ * To count its devices, call `apps.statistics.fleet.get` with its `channelId`.
709
+ */
710
+ async get(options) {
711
+ return this.httpClient.fetchJson({
712
+ method: "GET",
713
+ path: resolvePath("/v1/apps/{appId}/channels/{channelId}", options)
714
+ });
715
+ }
716
+ /**
717
+ * Lists the channels of the app, newest first.
718
+ */
719
+ async list(options) {
720
+ const { appId, ...query } = options;
721
+ return this.httpClient.fetchJson({
722
+ method: "GET",
723
+ path: resolvePath("/v1/apps/{appId}/channels", { appId }),
724
+ query
725
+ });
726
+ }
727
+ /**
728
+ * Pauses a channel: it serves nothing new, and devices keep what they have.
729
+ * Pausing a paused channel answers it unchanged, so the client retries the call.
730
+ */
731
+ async pause(options) {
732
+ return this.httpClient.fetchJson({
733
+ isRetryable: true,
734
+ method: "POST",
735
+ path: resolvePath("/v1/apps/{appId}/channels/{channelId}/pause", options)
736
+ });
737
+ }
738
+ /**
739
+ * Resumes a paused channel.
740
+ * Resuming a running channel answers it unchanged, so the client retries the call.
741
+ */
742
+ async resume(options) {
743
+ return this.httpClient.fetchJson({
744
+ isRetryable: true,
745
+ method: "POST",
746
+ path: resolvePath("/v1/apps/{appId}/channels/{channelId}/resume", options)
747
+ });
748
+ }
749
+ async update(options) {
750
+ const { appId, channelId, ...body } = options;
751
+ return this.httpClient.fetchJson({
752
+ body,
753
+ method: "PATCH",
754
+ path: resolvePath("/v1/apps/{appId}/channels/{channelId}", {
755
+ appId,
756
+ channelId
757
+ })
758
+ });
759
+ }
760
+ };
761
+ //#endregion
762
+ //#region src/resources/device-events.ts
763
+ var DeviceEventsResource = class {
764
+ httpClient;
765
+ constructor(httpClient) {
766
+ this.httpClient = httpClient;
767
+ }
768
+ /**
769
+ * Counts the events of the device that match the filter.
770
+ */
771
+ async count(options) {
772
+ const { appId, deviceId, ...query } = options;
773
+ return this.httpClient.fetchJson({
774
+ method: "GET",
775
+ path: resolvePath("/v1/apps/{appId}/devices/{deviceId}/events/count", {
776
+ appId,
777
+ deviceId
778
+ }),
779
+ query
780
+ });
781
+ }
782
+ /**
783
+ * Lists the events of the device across all releases of the app, newest first, filtered by `releaseId`.
784
+ */
785
+ async list(options) {
786
+ const { appId, deviceId, ...query } = options;
787
+ return this.httpClient.fetchJson({
788
+ method: "GET",
789
+ path: resolvePath("/v1/apps/{appId}/devices/{deviceId}/events", {
790
+ appId,
791
+ deviceId
792
+ }),
793
+ query
794
+ });
795
+ }
796
+ };
797
+ //#endregion
798
+ //#region src/resources/devices.ts
799
+ var DevicesResource = class {
800
+ httpClient;
801
+ events;
802
+ constructor(httpClient) {
803
+ this.httpClient = httpClient;
804
+ this.events = new DeviceEventsResource(httpClient);
805
+ }
806
+ /**
807
+ * Counts the devices of the app that match the filters.
808
+ */
809
+ async count(options) {
810
+ const { appId, ...query } = options;
811
+ return this.httpClient.fetchJson({
812
+ method: "GET",
813
+ path: resolvePath("/v1/apps/{appId}/devices/count", { appId }),
814
+ query
815
+ });
816
+ }
817
+ /**
818
+ * Deletes a device from the registry, for an erasure request.
819
+ */
820
+ async delete(options) {
821
+ await this.httpClient.fetchJson({
822
+ method: "DELETE",
823
+ path: resolvePath("/v1/apps/{appId}/devices/{deviceId}", options)
824
+ });
825
+ }
826
+ /**
827
+ * Deletes the devices of the app named by `ids`, one to 100. An id of another app is skipped.
828
+ */
829
+ async deleteMany(options) {
830
+ const { appId, ...query } = options;
831
+ await this.httpClient.fetchJson({
832
+ method: "DELETE",
833
+ path: resolvePath("/v1/apps/{appId}/devices", { appId }),
834
+ query
835
+ });
836
+ }
837
+ async get(options) {
838
+ const { appId, deviceId, ...query } = options;
839
+ return this.httpClient.fetchJson({
840
+ method: "GET",
841
+ path: resolvePath("/v1/apps/{appId}/devices/{deviceId}", {
842
+ appId,
843
+ deviceId
844
+ }),
845
+ query
846
+ });
847
+ }
848
+ /**
849
+ * Lists the devices of the app, newest report first.
850
+ * `attribute` takes one `key=value` pair.
851
+ */
852
+ async list(options) {
853
+ const { appId, ...query } = options;
854
+ return this.httpClient.fetchJson({
855
+ method: "GET",
856
+ path: resolvePath("/v1/apps/{appId}/devices", { appId }),
857
+ query
858
+ });
859
+ }
860
+ };
861
+ //#endregion
862
+ //#region src/resources/file-upload-parts.ts
863
+ var FileUploadPartsResource = class {
864
+ httpClient;
865
+ constructor(httpClient) {
866
+ this.httpClient = httpClient;
867
+ }
868
+ /**
869
+ * Uploads one part of a multipart file upload.
870
+ * Pass the answered `etag` and `partNumber` to `complete`.
871
+ */
872
+ async upload(options) {
873
+ const { appId, partNumber, sha256, uploadId, ...uploadBody } = options;
874
+ return this.httpClient.fetchUpload({
875
+ ...uploadBody,
876
+ contentType: "application/gzip",
877
+ path: resolvePath("/v1/apps/{appId}/files/{sha256}/uploads/{uploadId}/parts/{partNumber}", {
878
+ appId,
879
+ partNumber,
880
+ sha256,
881
+ uploadId
882
+ })
883
+ });
884
+ }
885
+ };
886
+ //#endregion
887
+ //#region src/resources/file-uploads.ts
888
+ /**
889
+ * Uploads a larger file in parts.
890
+ * Create the upload, upload the parts and complete it, or delete it to abort.
891
+ */
892
+ var FileUploadsResource = class {
893
+ httpClient;
894
+ parts;
895
+ constructor(httpClient) {
896
+ this.httpClient = httpClient;
897
+ this.parts = new FileUploadPartsResource(httpClient);
898
+ }
899
+ /**
900
+ * Assembles the parts into the file and checks its hash.
901
+ * If the app already holds the hash, the stored file is answered without assembly, so the client retries the call.
902
+ */
903
+ async complete(options) {
904
+ const { appId, sha256, uploadId, ...body } = options;
905
+ return this.httpClient.fetchJson({
906
+ body,
907
+ isRetryable: true,
908
+ method: "POST",
909
+ path: resolvePath("/v1/apps/{appId}/files/{sha256}/uploads/{uploadId}/complete", {
910
+ appId,
911
+ sha256,
912
+ uploadId
913
+ })
914
+ });
915
+ }
916
+ /**
917
+ * Starts a multipart file upload.
918
+ * Every part but the last must have the same size of at least five mebibytes.
919
+ * The start holds no state, and an unused upload expires on its own, so the client retries the call.
920
+ */
921
+ async create(options) {
922
+ return this.httpClient.fetchJson({
923
+ isRetryable: true,
924
+ method: "POST",
925
+ path: resolvePath("/v1/apps/{appId}/files/{sha256}/uploads", options)
926
+ });
927
+ }
928
+ /**
929
+ * Aborts a multipart file upload and discards its parts.
930
+ */
931
+ async delete(options) {
932
+ await this.httpClient.fetchJson({
933
+ method: "DELETE",
934
+ path: resolvePath("/v1/apps/{appId}/files/{sha256}/uploads/{uploadId}", options)
935
+ });
936
+ }
937
+ };
938
+ //#endregion
939
+ //#region src/resources/files.ts
940
+ var FilesResource = class {
941
+ httpClient;
942
+ uploads;
943
+ constructor(httpClient) {
944
+ this.httpClient = httpClient;
945
+ this.uploads = new FileUploadsResource(httpClient);
946
+ }
947
+ /**
948
+ * Uploads one file.
949
+ * The body is the gzip-compressed file, and `sha256` is the hash of the uncompressed content. A hash the app already holds answers the existing file.
950
+ * A `Blob` above `SINGLE_UPLOAD_LIMIT_BYTES` goes up in parts. A stream goes up in one request, so it must stay within that limit.
951
+ */
952
+ async upload(options) {
953
+ const { appId, sha256, ...uploadBody } = options;
954
+ if (isBlobAboveSingleUploadLimit(uploadBody)) return uploadInParts(this.uploads, {
955
+ appId,
956
+ sha256
957
+ }, uploadBody.body);
958
+ return this.httpClient.fetchUpload({
959
+ ...uploadBody,
960
+ contentType: "application/gzip",
961
+ path: resolvePath("/v1/apps/{appId}/files/{sha256}", {
962
+ appId,
963
+ sha256
964
+ })
965
+ });
966
+ }
967
+ };
968
+ //#endregion
969
+ //#region src/resources/release-audience.ts
970
+ var ReleaseAudienceResource = class {
971
+ httpClient;
972
+ constructor(httpClient) {
973
+ this.httpClient = httpClient;
974
+ }
975
+ /**
976
+ * Gets the devices a release reaches.
977
+ * The API evaluates the registry the same way a device evaluates the index.
978
+ */
979
+ async get(options) {
980
+ return this.httpClient.fetchJson({
981
+ method: "GET",
982
+ path: resolvePath("/v1/apps/{appId}/releases/{releaseId}/audience", options)
983
+ });
984
+ }
985
+ };
986
+ //#endregion
987
+ //#region src/resources/releases.ts
988
+ var ReleasesResource = class {
989
+ httpClient;
990
+ audience;
991
+ constructor(httpClient) {
992
+ this.httpClient = httpClient;
993
+ this.audience = new ReleaseAudienceResource(httpClient);
994
+ }
995
+ /**
996
+ * Counts the releases of the app that match the filters.
997
+ * `number` is valid only beside `channelId`, since release numbers count per channel.
998
+ */
999
+ async count(options) {
1000
+ const { appId, ...query } = options;
1001
+ return this.httpClient.fetchJson({
1002
+ method: "GET",
1003
+ path: resolvePath("/v1/apps/{appId}/releases/count", { appId }),
1004
+ query
1005
+ });
1006
+ }
1007
+ /**
1008
+ * Gets a release with its status: when it went live in the index and when the purge completed.
1009
+ */
1010
+ async get(options) {
1011
+ const { appId, releaseId, ...query } = options;
1012
+ return this.httpClient.fetchJson({
1013
+ method: "GET",
1014
+ path: resolvePath("/v1/apps/{appId}/releases/{releaseId}", {
1015
+ appId,
1016
+ releaseId
1017
+ }),
1018
+ query
1019
+ });
1020
+ }
1021
+ /**
1022
+ * Lists every release of the app, newest first.
1023
+ * `channelId` selects the release log of one channel, and `number` beside it one release of that log.
1024
+ */
1025
+ async list(options) {
1026
+ const { appId, ...query } = options;
1027
+ return this.httpClient.fetchJson({
1028
+ method: "GET",
1029
+ path: resolvePath("/v1/apps/{appId}/releases", { appId }),
1030
+ query
1031
+ });
1032
+ }
1033
+ /**
1034
+ * Pauses a release: it is no longer offered, and devices on it keep it.
1035
+ * Pausing a paused release answers it unchanged, so the client retries the call.
1036
+ */
1037
+ async pause(options) {
1038
+ return this.httpClient.fetchJson({
1039
+ isRetryable: true,
1040
+ method: "POST",
1041
+ path: resolvePath("/v1/apps/{appId}/releases/{releaseId}/pause", options)
1042
+ });
1043
+ }
1044
+ /**
1045
+ * Resumes a paused release, so it is offered again.
1046
+ * Resuming an active release answers it unchanged, so the client retries the call.
1047
+ */
1048
+ async resume(options) {
1049
+ return this.httpClient.fetchJson({
1050
+ isRetryable: true,
1051
+ method: "POST",
1052
+ path: resolvePath("/v1/apps/{appId}/releases/{releaseId}/resume", options)
1053
+ });
1054
+ }
1055
+ /**
1056
+ * Revokes a release for good.
1057
+ * Devices on it move to the newest eligible older release or to the embedded bundle.
1058
+ * A repeat answers `release_revoked`, so the client never retries the call.
1059
+ */
1060
+ async revoke(options) {
1061
+ return this.httpClient.fetchJson({
1062
+ method: "POST",
1063
+ path: resolvePath("/v1/apps/{appId}/releases/{releaseId}/revoke", options)
1064
+ });
1065
+ }
1066
+ /**
1067
+ * Changes the rollout percentage (up or down), the progression schedule, the mandatory flag or the notes.
1068
+ * Setting the progression schedule to null stops it.
1069
+ */
1070
+ async update(options) {
1071
+ const { appId, releaseId, ...body } = options;
1072
+ return this.httpClient.fetchJson({
1073
+ body,
1074
+ method: "PATCH",
1075
+ path: resolvePath("/v1/apps/{appId}/releases/{releaseId}", {
1076
+ appId,
1077
+ releaseId
1078
+ })
1079
+ });
1080
+ }
1081
+ };
1082
+ //#endregion
1083
+ //#region src/resources/signing-keys.ts
1084
+ var SigningKeysResource = class {
1085
+ httpClient;
1086
+ constructor(httpClient) {
1087
+ this.httpClient = httpClient;
1088
+ }
1089
+ /**
1090
+ * Counts the signing keys of the app.
1091
+ */
1092
+ async count(options) {
1093
+ return this.httpClient.fetchJson({
1094
+ method: "GET",
1095
+ path: resolvePath("/v1/apps/{appId}/signing-keys/count", options)
1096
+ });
1097
+ }
1098
+ /**
1099
+ * Registers a public key. From then on, the app releases only signed bundles.
1100
+ * The key is `rsa-v1_5-sha256:` followed by the base64 SPKI DER of an RSA key of at least 2048 bits.
1101
+ * A key the app already holds answers its row unchanged, so the client retries the call.
1102
+ */
1103
+ async create(options) {
1104
+ const { appId, ...body } = options;
1105
+ return this.httpClient.fetchJson({
1106
+ body,
1107
+ isRetryable: true,
1108
+ method: "POST",
1109
+ path: resolvePath("/v1/apps/{appId}/signing-keys", { appId })
1110
+ });
1111
+ }
1112
+ async delete(options) {
1113
+ await this.httpClient.fetchJson({
1114
+ method: "DELETE",
1115
+ path: resolvePath("/v1/apps/{appId}/signing-keys/{signingKeyId}", options)
1116
+ });
1117
+ }
1118
+ /**
1119
+ * Lists the signing keys of the app, newest first.
1120
+ */
1121
+ async list(options) {
1122
+ const { appId, ...query } = options;
1123
+ return this.httpClient.fetchJson({
1124
+ method: "GET",
1125
+ path: resolvePath("/v1/apps/{appId}/signing-keys", { appId }),
1126
+ query
1127
+ });
1128
+ }
1129
+ };
1130
+ //#endregion
1131
+ //#region src/resources/statistics-fleet.ts
1132
+ var StatisticsFleetResource = class {
1133
+ httpClient;
1134
+ constructor(httpClient) {
1135
+ this.httpClient = httpClient;
1136
+ }
1137
+ /**
1138
+ * Gets a snapshot of the fleet from the registry, for one channel when `channelId` is set.
1139
+ */
1140
+ async get(options) {
1141
+ const { appId, ...query } = options;
1142
+ return this.httpClient.fetchJson({
1143
+ method: "GET",
1144
+ path: resolvePath("/v1/apps/{appId}/statistics/fleet", { appId }),
1145
+ query
1146
+ });
1147
+ }
1148
+ };
1149
+ //#endregion
1150
+ //#region src/resources/statistics-updates.ts
1151
+ var StatisticsUpdatesResource = class {
1152
+ httpClient;
1153
+ constructor(httpClient) {
1154
+ this.httpClient = httpClient;
1155
+ }
1156
+ /**
1157
+ * Gets the update statistics from `periodSince` to `periodUntil`, both inclusive, for one channel when `channelId` is set.
1158
+ * `releaseId` limits the adoption curves to that one release, whatever its age.
1159
+ */
1160
+ async get(options) {
1161
+ const { appId, ...query } = options;
1162
+ return this.httpClient.fetchJson({
1163
+ method: "GET",
1164
+ path: resolvePath("/v1/apps/{appId}/statistics/updates", { appId }),
1165
+ query
1166
+ });
1167
+ }
1168
+ };
1169
+ //#endregion
1170
+ //#region src/resources/statistics-usage.ts
1171
+ var StatisticsUsageResource = class {
1172
+ httpClient;
1173
+ constructor(httpClient) {
1174
+ this.httpClient = httpClient;
1175
+ }
1176
+ /**
1177
+ * Gets the usage statistics from `periodSince` to `periodUntil`, both inclusive.
1178
+ */
1179
+ async get(options) {
1180
+ const { appId, ...query } = options;
1181
+ return this.httpClient.fetchJson({
1182
+ method: "GET",
1183
+ path: resolvePath("/v1/apps/{appId}/statistics/usage", { appId }),
1184
+ query
1185
+ });
1186
+ }
1187
+ };
1188
+ //#endregion
1189
+ //#region src/resources/statistics.ts
1190
+ var StatisticsResource = class {
1191
+ fleet;
1192
+ updates;
1193
+ usage;
1194
+ constructor(httpClient) {
1195
+ this.fleet = new StatisticsFleetResource(httpClient);
1196
+ this.updates = new StatisticsUpdatesResource(httpClient);
1197
+ this.usage = new StatisticsUsageResource(httpClient);
1198
+ }
1199
+ };
1200
+ //#endregion
1201
+ //#region src/resources/apps.ts
1202
+ var AppsResource = class {
1203
+ httpClient;
1204
+ binaries;
1205
+ bundles;
1206
+ channels;
1207
+ devices;
1208
+ files;
1209
+ releases;
1210
+ signingKeys;
1211
+ statistics;
1212
+ constructor(httpClient) {
1213
+ this.httpClient = httpClient;
1214
+ this.binaries = new BinariesResource(httpClient);
1215
+ this.bundles = new BundlesResource(httpClient);
1216
+ this.channels = new ChannelsResource(httpClient);
1217
+ this.devices = new DevicesResource(httpClient);
1218
+ this.files = new FilesResource(httpClient);
1219
+ this.releases = new ReleasesResource(httpClient);
1220
+ this.signingKeys = new SigningKeysResource(httpClient);
1221
+ this.statistics = new StatisticsResource(httpClient);
1222
+ }
1223
+ /**
1224
+ * Soft-deletes an app. It is gone at once and hard-deleted after seven days.
1225
+ * An API token answers `forbidden`; sign in with a session.
1226
+ */
1227
+ async delete(options) {
1228
+ await this.httpClient.fetchJson({
1229
+ method: "DELETE",
1230
+ path: resolvePath("/v1/apps/{appId}", options)
1231
+ });
1232
+ }
1233
+ async get(options) {
1234
+ return this.httpClient.fetchJson({
1235
+ method: "GET",
1236
+ path: resolvePath("/v1/apps/{appId}", options)
1237
+ });
1238
+ }
1239
+ /**
1240
+ * Moves an app to another organization in which the caller is an Admin.
1241
+ * A repeat answers `validation` because the app is already there, so the client never retries the call.
1242
+ * An API token answers `forbidden`; sign in with a session.
1243
+ */
1244
+ async transfer(options) {
1245
+ const { appId, ...body } = options;
1246
+ return this.httpClient.fetchJson({
1247
+ body,
1248
+ method: "POST",
1249
+ path: resolvePath("/v1/apps/{appId}/transfer", { appId })
1250
+ });
1251
+ }
1252
+ async update(options) {
1253
+ const { appId, ...body } = options;
1254
+ return this.httpClient.fetchJson({
1255
+ body,
1256
+ method: "PATCH",
1257
+ path: resolvePath("/v1/apps/{appId}", { appId })
1258
+ });
1259
+ }
1260
+ };
1261
+ //#endregion
1262
+ //#region src/resources/health.ts
1263
+ var HealthResource = class {
1264
+ httpClient;
1265
+ constructor(httpClient) {
1266
+ this.httpClient = httpClient;
1267
+ }
1268
+ /**
1269
+ * Checks that the API is up: resolves when it answers its plain-text `ok`.
1270
+ * `unavailable` or any other status outside 2xx throws a `HotCodePushError`.
1271
+ */
1272
+ async get() {
1273
+ await this.httpClient.fetchStatus({
1274
+ method: "GET",
1275
+ path: "/health"
1276
+ });
1277
+ }
1278
+ };
1279
+ //#endregion
1280
+ //#region src/resources/invitations.ts
1281
+ var InvitationsResource = class {
1282
+ httpClient;
1283
+ constructor(httpClient) {
1284
+ this.httpClient = httpClient;
1285
+ }
1286
+ /**
1287
+ * Accepts an invitation addressed to the caller, with the token from the invitation mail.
1288
+ * A repeat answers `invitation_invalid`, so the client never retries the call.
1289
+ * An API token answers `forbidden`; sign in with a session.
1290
+ */
1291
+ async accept(options) {
1292
+ const { invitationId, ...body } = options;
1293
+ return this.httpClient.fetchJson({
1294
+ body,
1295
+ method: "POST",
1296
+ path: resolvePath("/v1/invitations/{invitationId}/accept", { invitationId })
1297
+ });
1298
+ }
1299
+ /**
1300
+ * Counts the pending invitations of the caller across all organizations.
1301
+ * An API token answers `forbidden`; sign in with a session.
1302
+ */
1303
+ async count() {
1304
+ return this.httpClient.fetchJson({
1305
+ method: "GET",
1306
+ path: resolvePath("/v1/invitations/count")
1307
+ });
1308
+ }
1309
+ /**
1310
+ * Lists the pending invitations of the caller across all organizations, newest first.
1311
+ * `relations: ['organization']` embeds the id and name of each organization.
1312
+ * An API token answers `forbidden`; sign in with a session.
1313
+ */
1314
+ async list(options = {}) {
1315
+ return this.httpClient.fetchJson({
1316
+ method: "GET",
1317
+ path: resolvePath("/v1/invitations"),
1318
+ query: options
1319
+ });
1320
+ }
1321
+ };
1322
+ //#endregion
1323
+ //#region src/resources/notification-preferences.ts
1324
+ /**
1325
+ * The notification preferences of the caller, one per category and medium.
1326
+ * They apply to the account or, with `organizationId`, to that membership.
1327
+ */
1328
+ var NotificationPreferencesResource = class {
1329
+ httpClient;
1330
+ constructor(httpClient) {
1331
+ this.httpClient = httpClient;
1332
+ }
1333
+ /**
1334
+ * Lists the preferences of the caller, one per category and medium, defaults included.
1335
+ * The order follows the catalog, with email first.
1336
+ * Without `organizationId` it lists the account categories, with it the categories set per membership.
1337
+ * An API token answers `forbidden`; sign in with a session.
1338
+ */
1339
+ async list(options = {}) {
1340
+ return this.httpClient.fetchJson({
1341
+ method: "GET",
1342
+ path: resolvePath("/v1/notification-preferences"),
1343
+ query: options
1344
+ });
1345
+ }
1346
+ /**
1347
+ * Sets one preference, given by category and medium, and answers it.
1348
+ * Email for a mandatory category is always on.
1349
+ * An API token answers `forbidden`; sign in with a session.
1350
+ */
1351
+ async update(options) {
1352
+ return this.httpClient.fetchJson({
1353
+ body: options,
1354
+ method: "PATCH",
1355
+ path: resolvePath("/v1/notification-preferences")
1356
+ });
1357
+ }
1358
+ };
1359
+ //#endregion
1360
+ //#region src/resources/notifications.ts
1361
+ /**
1362
+ * The in-app notifications of the caller across all organizations.
1363
+ */
1364
+ var NotificationsResource = class {
1365
+ httpClient;
1366
+ constructor(httpClient) {
1367
+ this.httpClient = httpClient;
1368
+ }
1369
+ /**
1370
+ * Counts the notifications of the caller that match the filters.
1371
+ * `isRead: false` gives the badge count of the bell.
1372
+ * An API token answers `forbidden`; sign in with a session.
1373
+ */
1374
+ async count(options = {}) {
1375
+ return this.httpClient.fetchJson({
1376
+ method: "GET",
1377
+ path: resolvePath("/v1/notifications/count"),
1378
+ query: options
1379
+ });
1380
+ }
1381
+ /**
1382
+ * Lists the notifications of the caller, newest first.
1383
+ * An API token answers `forbidden`; sign in with a session.
1384
+ */
1385
+ async list(options = {}) {
1386
+ return this.httpClient.fetchJson({
1387
+ method: "GET",
1388
+ path: resolvePath("/v1/notifications"),
1389
+ query: options
1390
+ });
1391
+ }
1392
+ /**
1393
+ * Marks one notification of the caller as read.
1394
+ * An API token answers `forbidden`; sign in with a session.
1395
+ */
1396
+ async update(options) {
1397
+ const { notificationId, ...body } = options;
1398
+ return this.httpClient.fetchJson({
1399
+ body,
1400
+ method: "PATCH",
1401
+ path: resolvePath("/v1/notifications/{notificationId}", { notificationId })
1402
+ });
1403
+ }
1404
+ /**
1405
+ * Marks every unread notification of the caller as read.
1406
+ * An API token answers `forbidden`; sign in with a session.
1407
+ */
1408
+ async updateMany(options) {
1409
+ await this.httpClient.fetchJson({
1410
+ body: options,
1411
+ method: "PATCH",
1412
+ path: resolvePath("/v1/notifications")
1413
+ });
1414
+ }
1415
+ };
1416
+ //#endregion
1417
+ //#region src/resources/audit-logs.ts
1418
+ var AuditLogsResource = class {
1419
+ httpClient;
1420
+ constructor(httpClient) {
1421
+ this.httpClient = httpClient;
1422
+ }
1423
+ /**
1424
+ * Counts the audit log entries that match the filters.
1425
+ * An API token answers `forbidden`; sign in with a session.
1426
+ */
1427
+ async count(options) {
1428
+ const { organizationId, ...query } = options;
1429
+ return this.httpClient.fetchJson({
1430
+ method: "GET",
1431
+ path: resolvePath("/v1/organizations/{organizationId}/audit-logs/count", { organizationId }),
1432
+ query
1433
+ });
1434
+ }
1435
+ /**
1436
+ * Downloads the audit log entries that match the filters as a `text/csv` `Blob`.
1437
+ * An API token answers `forbidden`; sign in with a session.
1438
+ */
1439
+ async downloadCsv(options) {
1440
+ const { organizationId, ...filters } = options;
1441
+ return this.httpClient.fetchBlob({
1442
+ method: "GET",
1443
+ path: resolvePath("/v1/organizations/{organizationId}/audit-logs", { organizationId }),
1444
+ query: {
1445
+ ...filters,
1446
+ format: "csv"
1447
+ }
1448
+ });
1449
+ }
1450
+ /**
1451
+ * Lists the audit log of the organization, newest first.
1452
+ * `type` takes a wildcard such as `channel.*` to match every action on one kind of object.
1453
+ * Needs a plan that includes the audit log; any other plan answers `plan_required`.
1454
+ * An API token answers `forbidden`; sign in with a session.
1455
+ */
1456
+ async list(options) {
1457
+ const { organizationId, ...query } = options;
1458
+ return this.httpClient.fetchJson({
1459
+ method: "GET",
1460
+ path: resolvePath("/v1/organizations/{organizationId}/audit-logs", { organizationId }),
1461
+ query
1462
+ });
1463
+ }
1464
+ };
1465
+ //#endregion
1466
+ //#region src/resources/checkouts.ts
1467
+ var CheckoutsResource = class {
1468
+ httpClient;
1469
+ constructor(httpClient) {
1470
+ this.httpClient = httpClient;
1471
+ }
1472
+ /**
1473
+ * Creates a Polar checkout that enables pay-as-you-go billing on a free organization.
1474
+ * The email of the caller is pre-filled and can be changed on the Polar page.
1475
+ * Once paid, the subscription names the organization and starts at the $5 minimum spending cap, which the customer can raise later.
1476
+ * Each call creates another checkout and the API keeps no `Idempotency-Key` for it, so the client never retries the call.
1477
+ * An API token answers `forbidden`; sign in with a session.
1478
+ */
1479
+ async create(options) {
1480
+ return this.httpClient.fetchJson({
1481
+ method: "POST",
1482
+ path: resolvePath("/v1/organizations/{organizationId}/checkouts", options)
1483
+ });
1484
+ }
1485
+ };
1486
+ //#endregion
1487
+ //#region src/resources/customer-portal-sessions.ts
1488
+ var CustomerPortalSessionsResource = class {
1489
+ httpClient;
1490
+ constructor(httpClient) {
1491
+ this.httpClient = httpClient;
1492
+ }
1493
+ /**
1494
+ * Creates a Polar customer portal session for the invoices and payment method of the organization.
1495
+ * An organization that never subscribed has no portal.
1496
+ * Each call creates another session and the API keeps no `Idempotency-Key` for it, so the client never retries the call.
1497
+ * An API token answers `forbidden`; sign in with a session.
1498
+ */
1499
+ async create(options) {
1500
+ return this.httpClient.fetchJson({
1501
+ method: "POST",
1502
+ path: resolvePath("/v1/organizations/{organizationId}/customer-portal-sessions", options)
1503
+ });
1504
+ }
1505
+ };
1506
+ //#endregion
1507
+ //#region src/resources/limits.ts
1508
+ var LimitsResource = class {
1509
+ httpClient;
1510
+ constructor(httpClient) {
1511
+ this.httpClient = httpClient;
1512
+ }
1513
+ /**
1514
+ * Gets the limits in effect for the organization.
1515
+ * An API token answers `forbidden`; sign in with a session.
1516
+ */
1517
+ async get(options) {
1518
+ return this.httpClient.fetchJson({
1519
+ method: "GET",
1520
+ path: resolvePath("/v1/organizations/{organizationId}/limits", options)
1521
+ });
1522
+ }
1523
+ };
1524
+ //#endregion
1525
+ //#region src/resources/members.ts
1526
+ var MembersResource = class {
1527
+ httpClient;
1528
+ constructor(httpClient) {
1529
+ this.httpClient = httpClient;
1530
+ }
1531
+ /**
1532
+ * Counts the members of the organization that match the filters.
1533
+ */
1534
+ async count(options) {
1535
+ const { organizationId, ...query } = options;
1536
+ return this.httpClient.fetchJson({
1537
+ method: "GET",
1538
+ path: resolvePath("/v1/organizations/{organizationId}/members/count", { organizationId }),
1539
+ query
1540
+ });
1541
+ }
1542
+ /**
1543
+ * Removes a member. Any member may remove themselves to leave the organization.
1544
+ * An API token answers `forbidden`; sign in with a session.
1545
+ */
1546
+ async delete(options) {
1547
+ await this.httpClient.fetchJson({
1548
+ method: "DELETE",
1549
+ path: resolvePath("/v1/organizations/{organizationId}/members/{memberId}", options)
1550
+ });
1551
+ }
1552
+ /**
1553
+ * Removes the members of the organization named by `ids`, one to 100. An id of another organization is skipped.
1554
+ * If the set holds the Owner, the whole set is refused.
1555
+ * An API token answers `forbidden`; sign in with a session.
1556
+ */
1557
+ async deleteMany(options) {
1558
+ const { organizationId, ...query } = options;
1559
+ await this.httpClient.fetchJson({
1560
+ method: "DELETE",
1561
+ path: resolvePath("/v1/organizations/{organizationId}/members", { organizationId }),
1562
+ query
1563
+ });
1564
+ }
1565
+ async get(options) {
1566
+ const { memberId, organizationId, ...query } = options;
1567
+ return this.httpClient.fetchJson({
1568
+ method: "GET",
1569
+ path: resolvePath("/v1/organizations/{organizationId}/members/{memberId}", {
1570
+ memberId,
1571
+ organizationId
1572
+ }),
1573
+ query
1574
+ });
1575
+ }
1576
+ /**
1577
+ * Lists the members of the organization, newest first.
1578
+ */
1579
+ async list(options) {
1580
+ const { organizationId, ...query } = options;
1581
+ return this.httpClient.fetchJson({
1582
+ method: "GET",
1583
+ path: resolvePath("/v1/organizations/{organizationId}/members", { organizationId }),
1584
+ query
1585
+ });
1586
+ }
1587
+ /**
1588
+ * Changes the role of a member. Setting `owner` transfers the ownership.
1589
+ * An API token answers `forbidden`; sign in with a session.
1590
+ */
1591
+ async update(options) {
1592
+ const { memberId, organizationId, ...body } = options;
1593
+ return this.httpClient.fetchJson({
1594
+ body,
1595
+ method: "PATCH",
1596
+ path: resolvePath("/v1/organizations/{organizationId}/members/{memberId}", {
1597
+ memberId,
1598
+ organizationId
1599
+ })
1600
+ });
1601
+ }
1602
+ };
1603
+ //#endregion
1604
+ //#region src/resources/organization-apps.ts
1605
+ var OrganizationAppsResource = class {
1606
+ httpClient;
1607
+ constructor(httpClient) {
1608
+ this.httpClient = httpClient;
1609
+ }
1610
+ /**
1611
+ * Counts the apps of the organization that match the filters.
1612
+ */
1613
+ async count(options) {
1614
+ const { organizationId, ...query } = options;
1615
+ return this.httpClient.fetchJson({
1616
+ method: "GET",
1617
+ path: resolvePath("/v1/organizations/{organizationId}/apps/count", { organizationId }),
1618
+ query
1619
+ });
1620
+ }
1621
+ /**
1622
+ * Creates an app with its default channel `production`.
1623
+ */
1624
+ async create(options) {
1625
+ const { idempotencyKey, organizationId, ...body } = options;
1626
+ return this.httpClient.fetchCreatingPost({
1627
+ body,
1628
+ idempotencyKey,
1629
+ path: resolvePath("/v1/organizations/{organizationId}/apps", { organizationId })
1630
+ });
1631
+ }
1632
+ /**
1633
+ * Lists the apps of the organization, newest first.
1634
+ */
1635
+ async list(options) {
1636
+ const { organizationId, ...query } = options;
1637
+ return this.httpClient.fetchJson({
1638
+ method: "GET",
1639
+ path: resolvePath("/v1/organizations/{organizationId}/apps", { organizationId }),
1640
+ query
1641
+ });
1642
+ }
1643
+ };
1644
+ //#endregion
1645
+ //#region src/resources/organization-invitations.ts
1646
+ var OrganizationInvitationsResource = class {
1647
+ httpClient;
1648
+ constructor(httpClient) {
1649
+ this.httpClient = httpClient;
1650
+ }
1651
+ /**
1652
+ * Counts the invitations of the organization that match the filters.
1653
+ * An API token answers `forbidden`; sign in with a session.
1654
+ */
1655
+ async count(options) {
1656
+ const { organizationId, ...query } = options;
1657
+ return this.httpClient.fetchJson({
1658
+ method: "GET",
1659
+ path: resolvePath("/v1/organizations/{organizationId}/invitations/count", { organizationId }),
1660
+ query
1661
+ });
1662
+ }
1663
+ /**
1664
+ * Invites an email address to the organization. The invitation mail carries the token.
1665
+ * An API token answers `forbidden`; sign in with a session.
1666
+ */
1667
+ async create(options) {
1668
+ const { idempotencyKey, organizationId, ...body } = options;
1669
+ return this.httpClient.fetchCreatingPost({
1670
+ body,
1671
+ idempotencyKey,
1672
+ path: resolvePath("/v1/organizations/{organizationId}/invitations", { organizationId })
1673
+ });
1674
+ }
1675
+ /**
1676
+ * Withdraws an invitation.
1677
+ * An API token answers `forbidden`; sign in with a session.
1678
+ */
1679
+ async delete(options) {
1680
+ await this.httpClient.fetchJson({
1681
+ method: "DELETE",
1682
+ path: resolvePath("/v1/organizations/{organizationId}/invitations/{invitationId}", options)
1683
+ });
1684
+ }
1685
+ /**
1686
+ * Withdraws the invitations of the organization named by `ids`, one to 100. An id of another organization is skipped.
1687
+ * An API token answers `forbidden`; sign in with a session.
1688
+ */
1689
+ async deleteMany(options) {
1690
+ const { organizationId, ...query } = options;
1691
+ await this.httpClient.fetchJson({
1692
+ method: "DELETE",
1693
+ path: resolvePath("/v1/organizations/{organizationId}/invitations", { organizationId }),
1694
+ query
1695
+ });
1696
+ }
1697
+ /**
1698
+ * Lists the invitations of the organization, newest first.
1699
+ * An API token answers `forbidden`; sign in with a session.
1700
+ */
1701
+ async list(options) {
1702
+ const { organizationId, ...query } = options;
1703
+ return this.httpClient.fetchJson({
1704
+ method: "GET",
1705
+ path: resolvePath("/v1/organizations/{organizationId}/invitations", { organizationId }),
1706
+ query
1707
+ });
1708
+ }
1709
+ };
1710
+ //#endregion
1711
+ //#region src/resources/sso-provider-verifications.ts
1712
+ var SsoProviderVerificationsResource = class {
1713
+ httpClient;
1714
+ constructor(httpClient) {
1715
+ this.httpClient = httpClient;
1716
+ }
1717
+ /**
1718
+ * Verifies the SSO domain: looks for `domainVerificationToken` in the TXT record of the domain and sets `domainVerified` when found.
1719
+ * Answers the provider, verified or still waiting for the record. A DNS resolver that cannot be reached answers `dns_lookup_failed`.
1720
+ * A verified provider answers unchanged without a lookup, so the client retries the call.
1721
+ * An API token answers `forbidden`; sign in with a session.
1722
+ */
1723
+ async create(options) {
1724
+ return this.httpClient.fetchJson({
1725
+ isRetryable: true,
1726
+ method: "POST",
1727
+ path: resolvePath("/v1/organizations/{organizationId}/sso-provider/verifications", options)
1728
+ });
1729
+ }
1730
+ };
1731
+ //#endregion
1732
+ //#region src/resources/sso-provider.ts
1733
+ var SsoProviderResource = class {
1734
+ httpClient;
1735
+ verifications;
1736
+ constructor(httpClient) {
1737
+ this.httpClient = httpClient;
1738
+ this.verifications = new SsoProviderVerificationsResource(httpClient);
1739
+ }
1740
+ /**
1741
+ * Removes the SSO provider. Its members can sign in with a password again, and the domain is forgotten.
1742
+ * An API token answers `forbidden`; sign in with a session.
1743
+ */
1744
+ async delete(options) {
1745
+ await this.httpClient.fetchJson({
1746
+ method: "DELETE",
1747
+ path: resolvePath("/v1/organizations/{organizationId}/sso-provider", options)
1748
+ });
1749
+ }
1750
+ /**
1751
+ * Gets the SSO provider of the organization.
1752
+ * An API token answers `forbidden`; sign in with a session.
1753
+ */
1754
+ async get(options) {
1755
+ return this.httpClient.fetchJson({
1756
+ method: "GET",
1757
+ path: resolvePath("/v1/organizations/{organizationId}/sso-provider", options)
1758
+ });
1759
+ }
1760
+ /**
1761
+ * Sets the OIDC or SAML provider and its domain, replacing the one before.
1762
+ * A new or changed domain starts unverified, with a new token for its TXT record.
1763
+ * An API token answers `forbidden`; sign in with a session.
1764
+ */
1765
+ async set(options) {
1766
+ const { organizationId, ...body } = options;
1767
+ return this.httpClient.fetchJson({
1768
+ body,
1769
+ method: "PUT",
1770
+ path: resolvePath("/v1/organizations/{organizationId}/sso-provider", { organizationId })
1771
+ });
1772
+ }
1773
+ };
1774
+ //#endregion
1775
+ //#region src/resources/subscription.ts
1776
+ /**
1777
+ * The organization's one subscription.
1778
+ */
1779
+ var SubscriptionResource = class {
1780
+ httpClient;
1781
+ constructor(httpClient) {
1782
+ this.httpClient = httpClient;
1783
+ }
1784
+ /**
1785
+ * Cancels the subscription at the end of its period, with the reason and comment from the retention dialog.
1786
+ * A cancel already scheduled stays as it is, so the client retries the call.
1787
+ * An API token answers `forbidden`; sign in with a session.
1788
+ */
1789
+ async cancel(options) {
1790
+ const { organizationId, ...body } = options;
1791
+ await this.httpClient.fetchJson({
1792
+ body,
1793
+ isRetryable: true,
1794
+ method: "POST",
1795
+ path: resolvePath("/v1/organizations/{organizationId}/subscription/cancel", { organizationId })
1796
+ });
1797
+ }
1798
+ /**
1799
+ * Undoes a scheduled cancel, so the subscription renews as before.
1800
+ * A subscription with no cancel scheduled stays as it is, so the client retries the call.
1801
+ * An API token answers `forbidden`; sign in with a session.
1802
+ */
1803
+ async uncancel(options) {
1804
+ await this.httpClient.fetchJson({
1805
+ isRetryable: true,
1806
+ method: "POST",
1807
+ path: resolvePath("/v1/organizations/{organizationId}/subscription/uncancel", options)
1808
+ });
1809
+ }
1810
+ };
1811
+ //#endregion
1812
+ //#region src/resources/usage-apps.ts
1813
+ var UsageAppsResource = class {
1814
+ httpClient;
1815
+ constructor(httpClient) {
1816
+ this.httpClient = httpClient;
1817
+ }
1818
+ /**
1819
+ * Counts the apps with usage in `month`, for paging through `list`.
1820
+ */
1821
+ async count(options) {
1822
+ const { organizationId, ...query } = options;
1823
+ return this.httpClient.fetchJson({
1824
+ method: "GET",
1825
+ path: resolvePath("/v1/organizations/{organizationId}/usage/apps/count", { organizationId }),
1826
+ query
1827
+ });
1828
+ }
1829
+ /**
1830
+ * Downloads the usage of every app in `month`, with the app name, as a `text/csv` `Blob`.
1831
+ */
1832
+ async downloadCsv(options) {
1833
+ const { organizationId, ...query } = options;
1834
+ return this.httpClient.fetchBlob({
1835
+ method: "GET",
1836
+ path: resolvePath("/v1/organizations/{organizationId}/usage/apps", { organizationId }),
1837
+ query: {
1838
+ ...query,
1839
+ format: "csv"
1840
+ }
1841
+ });
1842
+ }
1843
+ /**
1844
+ * Lists the usage of each live app in `month`, most monthly active devices first.
1845
+ * `relations: ['app']` embeds the id and name of the app.
1846
+ */
1847
+ async list(options) {
1848
+ const { organizationId, ...query } = options;
1849
+ return this.httpClient.fetchJson({
1850
+ method: "GET",
1851
+ path: resolvePath("/v1/organizations/{organizationId}/usage/apps", { organizationId }),
1852
+ query
1853
+ });
1854
+ }
1855
+ };
1856
+ //#endregion
1857
+ //#region src/resources/usage.ts
1858
+ var UsageResource = class {
1859
+ httpClient;
1860
+ apps;
1861
+ constructor(httpClient) {
1862
+ this.httpClient = httpClient;
1863
+ this.apps = new UsageAppsResource(httpClient);
1864
+ }
1865
+ /**
1866
+ * Gets the usage of the organization in `month`, the current month by default, from the stored months.
1867
+ */
1868
+ async get(options) {
1869
+ const { organizationId, ...query } = options;
1870
+ return this.httpClient.fetchJson({
1871
+ method: "GET",
1872
+ path: resolvePath("/v1/organizations/{organizationId}/usage", { organizationId }),
1873
+ query
1874
+ });
1875
+ }
1876
+ };
1877
+ //#endregion
1878
+ //#region src/resources/webhook-deliveries.ts
1879
+ /**
1880
+ * The delivery log of a webhook. Each delivery is kept for 30 days.
1881
+ */
1882
+ var WebhookDeliveriesResource = class {
1883
+ httpClient;
1884
+ constructor(httpClient) {
1885
+ this.httpClient = httpClient;
1886
+ }
1887
+ /**
1888
+ * Counts the deliveries of the webhook that match the filters.
1889
+ * An API token answers `forbidden`; sign in with a session.
1890
+ */
1891
+ async count(options) {
1892
+ const { organizationId, webhookId, ...query } = options;
1893
+ return this.httpClient.fetchJson({
1894
+ method: "GET",
1895
+ path: resolvePath("/v1/organizations/{organizationId}/webhooks/{webhookId}/deliveries/count", {
1896
+ organizationId,
1897
+ webhookId
1898
+ }),
1899
+ query
1900
+ });
1901
+ }
1902
+ /**
1903
+ * Lists the deliveries of the webhook, newest first.
1904
+ * Filter by `status`, and by `createdSince` and `createdUntil`, both inclusive.
1905
+ * An API token answers `forbidden`; sign in with a session.
1906
+ */
1907
+ async list(options) {
1908
+ const { organizationId, webhookId, ...query } = options;
1909
+ return this.httpClient.fetchJson({
1910
+ method: "GET",
1911
+ path: resolvePath("/v1/organizations/{organizationId}/webhooks/{webhookId}/deliveries", {
1912
+ organizationId,
1913
+ webhookId
1914
+ }),
1915
+ query
1916
+ });
1917
+ }
1918
+ /**
1919
+ * Delivers the event again, once, within the request, and answers the settled delivery with its attempt count carried on.
1920
+ * Each call makes another attempt, so the client never retries the call.
1921
+ * An API token answers `forbidden`; sign in with a session.
1922
+ */
1923
+ async redeliver(options) {
1924
+ return this.httpClient.fetchJson({
1925
+ method: "POST",
1926
+ path: resolvePath("/v1/organizations/{organizationId}/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver", options)
1927
+ });
1928
+ }
1929
+ };
1930
+ //#endregion
1931
+ //#region src/resources/webhooks.ts
1932
+ /**
1933
+ * The webhooks of the organization, for Admins and Owners.
1934
+ * Needs a plan that includes webhooks; any other plan answers `plan_required`.
1935
+ */
1936
+ var WebhooksResource = class {
1937
+ httpClient;
1938
+ deliveries;
1939
+ constructor(httpClient) {
1940
+ this.httpClient = httpClient;
1941
+ this.deliveries = new WebhookDeliveriesResource(httpClient);
1942
+ }
1943
+ /**
1944
+ * Counts the webhooks of the organization.
1945
+ * An API token answers `forbidden`; sign in with a session.
1946
+ */
1947
+ async count(options) {
1948
+ return this.httpClient.fetchJson({
1949
+ method: "GET",
1950
+ path: resolvePath("/v1/organizations/{organizationId}/webhooks/count", options)
1951
+ });
1952
+ }
1953
+ /**
1954
+ * Creates a webhook. Its name must be unique in the organization, or the call answers `webhook_name_taken`.
1955
+ * A `raw` webhook answers its secret only this once.
1956
+ * The API keeps no `Idempotency-Key` for it and a repeat answers `webhook_name_taken`, so the client never retries the call.
1957
+ * An API token answers `forbidden`; sign in with a session.
1958
+ */
1959
+ async create(options) {
1960
+ const { organizationId, ...body } = options;
1961
+ return this.httpClient.fetchJson({
1962
+ body,
1963
+ method: "POST",
1964
+ path: resolvePath("/v1/organizations/{organizationId}/webhooks", { organizationId })
1965
+ });
1966
+ }
1967
+ /**
1968
+ * Deletes the webhook and its delivery log.
1969
+ * An API token answers `forbidden`; sign in with a session.
1970
+ */
1971
+ async delete(options) {
1972
+ await this.httpClient.fetchJson({
1973
+ method: "DELETE",
1974
+ path: resolvePath("/v1/organizations/{organizationId}/webhooks/{webhookId}", options)
1975
+ });
1976
+ }
1977
+ /**
1978
+ * Gets a webhook.
1979
+ * An API token answers `forbidden`; sign in with a session.
1980
+ */
1981
+ async get(options) {
1982
+ return this.httpClient.fetchJson({
1983
+ method: "GET",
1984
+ path: resolvePath("/v1/organizations/{organizationId}/webhooks/{webhookId}", options)
1985
+ });
1986
+ }
1987
+ /**
1988
+ * Lists the webhooks of the organization, newest first.
1989
+ * An API token answers `forbidden`; sign in with a session.
1990
+ */
1991
+ async list(options) {
1992
+ const { organizationId, ...query } = options;
1993
+ return this.httpClient.fetchJson({
1994
+ method: "GET",
1995
+ path: resolvePath("/v1/organizations/{organizationId}/webhooks", { organizationId }),
1996
+ query
1997
+ });
1998
+ }
1999
+ /**
2000
+ * Sends one sample event, `webhook.test`, through the normal delivery path within the request, and answers the settled delivery.
2001
+ * Each call sends another sample event, so the client never retries the call.
2002
+ * An API token answers `forbidden`; sign in with a session.
2003
+ */
2004
+ async test(options) {
2005
+ return this.httpClient.fetchJson({
2006
+ method: "POST",
2007
+ path: resolvePath("/v1/organizations/{organizationId}/webhooks/{webhookId}/test", options)
2008
+ });
2009
+ }
2010
+ /**
2011
+ * Changes the name, the URL, the subscribed `events`, the app filter or `isEnabled`. The format and the secret never change.
2012
+ * Enabling a webhook that was disabled after fifty failed deliveries in a row resets that count.
2013
+ * An API token answers `forbidden`; sign in with a session.
2014
+ */
2015
+ async update(options) {
2016
+ const { organizationId, webhookId, ...body } = options;
2017
+ return this.httpClient.fetchJson({
2018
+ body,
2019
+ method: "PATCH",
2020
+ path: resolvePath("/v1/organizations/{organizationId}/webhooks/{webhookId}", {
2021
+ organizationId,
2022
+ webhookId
2023
+ })
2024
+ });
2025
+ }
2026
+ };
2027
+ //#endregion
2028
+ //#region src/resources/organizations.ts
2029
+ var OrganizationsResource = class {
2030
+ httpClient;
2031
+ apps;
2032
+ auditLogs;
2033
+ checkouts;
2034
+ customerPortalSessions;
2035
+ invitations;
2036
+ limits;
2037
+ members;
2038
+ ssoProvider;
2039
+ subscription;
2040
+ usage;
2041
+ webhooks;
2042
+ constructor(httpClient) {
2043
+ this.httpClient = httpClient;
2044
+ this.apps = new OrganizationAppsResource(httpClient);
2045
+ this.auditLogs = new AuditLogsResource(httpClient);
2046
+ this.checkouts = new CheckoutsResource(httpClient);
2047
+ this.customerPortalSessions = new CustomerPortalSessionsResource(httpClient);
2048
+ this.invitations = new OrganizationInvitationsResource(httpClient);
2049
+ this.limits = new LimitsResource(httpClient);
2050
+ this.members = new MembersResource(httpClient);
2051
+ this.ssoProvider = new SsoProviderResource(httpClient);
2052
+ this.subscription = new SubscriptionResource(httpClient);
2053
+ this.usage = new UsageResource(httpClient);
2054
+ this.webhooks = new WebhooksResource(httpClient);
2055
+ }
2056
+ /**
2057
+ * Counts the organizations of the caller.
2058
+ */
2059
+ async count() {
2060
+ return this.httpClient.fetchJson({
2061
+ method: "GET",
2062
+ path: resolvePath("/v1/organizations/count")
2063
+ });
2064
+ }
2065
+ /**
2066
+ * Creates an organization with the caller as its Owner.
2067
+ * An API token answers `forbidden`; sign in with a session.
2068
+ */
2069
+ async create(options) {
2070
+ const { idempotencyKey, ...body } = options;
2071
+ return this.httpClient.fetchCreatingPost({
2072
+ body,
2073
+ idempotencyKey,
2074
+ path: resolvePath("/v1/organizations")
2075
+ });
2076
+ }
2077
+ /**
2078
+ * Soft-deletes an organization and everything under it.
2079
+ * It is gone at once and hard-deleted after seven days.
2080
+ * An API token answers `forbidden`; sign in with a session.
2081
+ */
2082
+ async delete(options) {
2083
+ await this.httpClient.fetchJson({
2084
+ method: "DELETE",
2085
+ path: resolvePath("/v1/organizations/{organizationId}", options)
2086
+ });
2087
+ }
2088
+ async get(options) {
2089
+ return this.httpClient.fetchJson({
2090
+ method: "GET",
2091
+ path: resolvePath("/v1/organizations/{organizationId}", options)
2092
+ });
2093
+ }
2094
+ /**
2095
+ * Lists the organizations of the caller, newest first.
2096
+ * The role of the caller in each sits on their member rows: `users.get({ relations: ['members'], userId: 'me' })`.
2097
+ */
2098
+ async list(options = {}) {
2099
+ return this.httpClient.fetchJson({
2100
+ method: "GET",
2101
+ path: resolvePath("/v1/organizations"),
2102
+ query: options
2103
+ });
2104
+ }
2105
+ /**
2106
+ * Updates an organization.
2107
+ * An API token answers `forbidden`; sign in with a session.
2108
+ */
2109
+ async update(options) {
2110
+ const { organizationId, ...body } = options;
2111
+ return this.httpClient.fetchJson({
2112
+ body,
2113
+ method: "PATCH",
2114
+ path: resolvePath("/v1/organizations/{organizationId}", { organizationId })
2115
+ });
2116
+ }
2117
+ };
2118
+ //#endregion
2119
+ //#region src/resources/qr-codes.ts
2120
+ var QrCodesResource = class {
2121
+ httpClient;
2122
+ constructor(httpClient) {
2123
+ this.httpClient = httpClient;
2124
+ }
2125
+ /**
2126
+ * Gets a URL on hotcodepush.com, one of its subdomains or the workers.dev subdomain of HotCodePush as a QR image.
2127
+ * The image is SVG unless `format` is `png`. A URL on another host answers `validation`. Needs no token.
2128
+ */
2129
+ async get(options) {
2130
+ return this.httpClient.fetchBlob({
2131
+ method: "GET",
2132
+ path: resolvePath("/v1/qr-codes"),
2133
+ query: options
2134
+ });
2135
+ }
2136
+ };
2137
+ //#endregion
2138
+ //#region src/resources/user-password.ts
2139
+ var UserPasswordResource = class {
2140
+ httpClient;
2141
+ constructor(httpClient) {
2142
+ this.httpClient = httpClient;
2143
+ }
2144
+ /**
2145
+ * Sets the first password of an account that signed up through GitHub, Google or SSO, and ends its other sessions.
2146
+ * An account with a password answers `password_already_set`, as a repeat would, so the client never retries the call.
2147
+ * An API token answers `forbidden`; sign in with a session.
2148
+ */
2149
+ async create(options) {
2150
+ const { userId, ...body } = options;
2151
+ await this.httpClient.fetchJson({
2152
+ body,
2153
+ method: "POST",
2154
+ path: resolvePath("/v1/users/{userId}/password", { userId })
2155
+ });
2156
+ }
2157
+ };
2158
+ //#endregion
2159
+ //#region src/resources/user-sessions.ts
2160
+ var UserSessionsResource = class {
2161
+ httpClient;
2162
+ constructor(httpClient) {
2163
+ this.httpClient = httpClient;
2164
+ }
2165
+ /**
2166
+ * Ends the sessions of the caller named by `ids`, one to 100, the current session included.
2167
+ * An id that is not the caller's is skipped.
2168
+ * An API token answers `forbidden`; sign in with a session.
2169
+ */
2170
+ async deleteMany(options) {
2171
+ const { userId, ...query } = options;
2172
+ await this.httpClient.fetchJson({
2173
+ method: "DELETE",
2174
+ path: resolvePath("/v1/users/{userId}/sessions", { userId }),
2175
+ query
2176
+ });
2177
+ }
2178
+ };
2179
+ //#endregion
2180
+ //#region src/resources/user-tokens.ts
2181
+ var UserTokensResource = class {
2182
+ httpClient;
2183
+ constructor(httpClient) {
2184
+ this.httpClient = httpClient;
2185
+ }
2186
+ /**
2187
+ * Deletes the API tokens of the caller named by `ids`, one to 100.
2188
+ * An id that is not the caller's is skipped.
2189
+ * An API token answers `forbidden`; sign in with a session.
2190
+ */
2191
+ async deleteMany(options) {
2192
+ const { userId, ...query } = options;
2193
+ await this.httpClient.fetchJson({
2194
+ method: "DELETE",
2195
+ path: resolvePath("/v1/users/{userId}/tokens", { userId }),
2196
+ query
2197
+ });
2198
+ }
2199
+ };
2200
+ //#endregion
2201
+ //#region src/resources/users.ts
2202
+ var UsersResource = class {
2203
+ httpClient;
2204
+ password;
2205
+ sessions;
2206
+ tokens;
2207
+ constructor(httpClient) {
2208
+ this.httpClient = httpClient;
2209
+ this.password = new UserPasswordResource(httpClient);
2210
+ this.sessions = new UserSessionsResource(httpClient);
2211
+ this.tokens = new UserTokensResource(httpClient);
2212
+ }
2213
+ /**
2214
+ * Soft-deletes the account of the caller. It is gone at once and hard-deleted after seven days.
2215
+ * `userId` takes `me`. `password` is the account password; a wrong one answers `forbidden`.
2216
+ * An account without a password also answers `forbidden` and must set one first through `users.password.create`.
2217
+ * An API token answers `forbidden`; sign in with a session.
2218
+ */
2219
+ async delete(options) {
2220
+ const { userId, ...body } = options;
2221
+ await this.httpClient.fetchJson({
2222
+ body,
2223
+ method: "DELETE",
2224
+ path: resolvePath("/v1/users/{userId}", { userId })
2225
+ });
2226
+ }
2227
+ /**
2228
+ * Gets the caller behind the token.
2229
+ * `userId` takes `me`; another user answers `forbidden`.
2230
+ * `relations` embeds `accounts` (the sign-in identities) and `members` (the member rows of live organizations). With `members.organization`, each member row embeds its organization.
2231
+ */
2232
+ async get(options) {
2233
+ const { userId, ...query } = options;
2234
+ return this.httpClient.fetchJson({
2235
+ method: "GET",
2236
+ path: resolvePath("/v1/users/{userId}", { userId }),
2237
+ query
2238
+ });
2239
+ }
2240
+ };
2241
+ //#endregion
2242
+ //#region src/client.ts
2243
+ /**
2244
+ * The client for the HotCodePush REST API.
2245
+ * Resources mirror the API paths, so `/v1/apps/{appId}/channels` is `apps.channels`.
2246
+ */
2247
+ var HotCodePush = class {
2248
+ apps;
2249
+ health;
2250
+ invitations;
2251
+ notificationPreferences;
2252
+ notifications;
2253
+ organizations;
2254
+ qrCodes;
2255
+ users;
2256
+ constructor(options = {}) {
2257
+ const httpClient = new HttpClient(options);
2258
+ this.apps = new AppsResource(httpClient);
2259
+ this.health = new HealthResource(httpClient);
2260
+ this.invitations = new InvitationsResource(httpClient);
2261
+ this.notificationPreferences = new NotificationPreferencesResource(httpClient);
2262
+ this.notifications = new NotificationsResource(httpClient);
2263
+ this.organizations = new OrganizationsResource(httpClient);
2264
+ this.qrCodes = new QrCodesResource(httpClient);
2265
+ this.users = new UsersResource(httpClient);
2266
+ }
2267
+ };
2268
+ //#endregion
2269
+ export { HotCodePush, HotCodePushError, PART_SIZE_BYTES, SINGLE_UPLOAD_LIMIT_BYTES };