@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/LICENSE +21 -0
- package/README.md +69 -2
- package/dist/index.d.mts +19172 -0
- package/dist/index.mjs +2410 -0
- package/package.json +65 -4
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 };
|