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