@finueva/drive 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +67 -9
- package/THIRD_PARTY_NOTICES.md +26 -0
- package/dist/client.d.ts +2 -2
- package/dist/client.js +1809 -28
- package/dist/contract.d.ts +3046 -443
- package/dist/core.d.ts +3 -1
- package/dist/core.js +4 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1809 -28
- package/dist/server.d.ts +3 -3
- package/dist/server.js +1062 -25
- package/dist/types.d.ts +2 -2
- package/package.json +6 -2
package/dist/server.js
CHANGED
|
@@ -8,8 +8,10 @@ const DRIVE_API_ERROR_CODES = Object.freeze([
|
|
|
8
8
|
"invalid_pagination_cursor",
|
|
9
9
|
"invalid_idempotency_key",
|
|
10
10
|
"precondition_failed",
|
|
11
|
+
"range_not_satisfiable",
|
|
11
12
|
"idempotency_conflict",
|
|
12
13
|
"quota_exceeded",
|
|
14
|
+
"upload_recovery_required",
|
|
13
15
|
"service_unavailable",
|
|
14
16
|
"internal_error"
|
|
15
17
|
]);
|
|
@@ -22,8 +24,10 @@ const DRIVE_API_ERROR_MESSAGES = Object.freeze({
|
|
|
22
24
|
invalid_pagination_cursor: "The pagination cursor is invalid.",
|
|
23
25
|
invalid_idempotency_key: "The idempotency key is invalid.",
|
|
24
26
|
precondition_failed: "The request precondition failed.",
|
|
27
|
+
range_not_satisfiable: "The requested byte range is not satisfiable.",
|
|
25
28
|
idempotency_conflict: "The idempotency key conflicts with an earlier request.",
|
|
26
29
|
quota_exceeded: "The workspace storage quota would be exceeded.",
|
|
30
|
+
upload_recovery_required: "The upload requires recovery before it can continue.",
|
|
27
31
|
service_unavailable: "The service is temporarily unavailable.",
|
|
28
32
|
internal_error: "The request could not be completed."
|
|
29
33
|
});
|
|
@@ -59,6 +63,7 @@ const REQUEST_ID = /^[A-Za-z0-9_-]{16,128}$/;
|
|
|
59
63
|
const COLLECTION_ETAG = /^"drive\.permission-collection\.v1\.(0|[1-9][0-9]*)"$/;
|
|
60
64
|
const GRANT_ETAG$1 = /^"drive\.permission-grant\.v1\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)"$/;
|
|
61
65
|
const LIST_ETAG$1 = /^"drive\.permission-list\.v1\.[0-9a-f]{64}"$/;
|
|
66
|
+
const ITEM_ETAG = /^"drive\.item\.v1\.(0|[1-9][0-9]*)"$/;
|
|
62
67
|
async function parseResponse(response, operationSignal, preconditionStatus, successStatuses, guard, allowsQuotaExceeded, allowedErrorCodes) {
|
|
63
68
|
const requestId = safeRequestId(response.headers.get("x-request-id"));
|
|
64
69
|
if (requestId === null) {
|
|
@@ -66,6 +71,24 @@ async function parseResponse(response, operationSignal, preconditionStatus, succ
|
|
|
66
71
|
throw new DriveError("invalid_response", { status: response.status });
|
|
67
72
|
}
|
|
68
73
|
if (!successStatuses.includes(response.status)) throw await normalizeError(response, requestId, operationSignal, preconditionStatus, allowsQuotaExceeded, allowedErrorCodes);
|
|
74
|
+
if (response.status === 304) {
|
|
75
|
+
const contentLength = response.headers.get("content-length");
|
|
76
|
+
const etag = response.headers.get("etag");
|
|
77
|
+
const status = response.status;
|
|
78
|
+
if (response.body !== null || contentLength !== null && contentLength !== "0" || response.headers.has("content-type") || etag === null || !/^"[\x21\x23-\x7e]{1,1022}"$/.test(etag) || !guard(void 0, status, response.headers)) {
|
|
79
|
+
cancelResponse(response);
|
|
80
|
+
throw new DriveError("invalid_response", {
|
|
81
|
+
status,
|
|
82
|
+
requestId
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return Object.freeze({
|
|
86
|
+
data: void 0,
|
|
87
|
+
status,
|
|
88
|
+
requestId,
|
|
89
|
+
validators: Object.freeze({ etag })
|
|
90
|
+
});
|
|
91
|
+
}
|
|
69
92
|
const { value } = await parseBoundedJson(response, SUCCESS_BODY_LIMIT, response.status, requestId, operationSignal);
|
|
70
93
|
const status = response.status;
|
|
71
94
|
if (!guard(value, status, response.headers)) throw new DriveError("invalid_response", {
|
|
@@ -79,6 +102,28 @@ async function parseResponse(response, operationSignal, preconditionStatus, succ
|
|
|
79
102
|
validators: readValidators(response.headers)
|
|
80
103
|
});
|
|
81
104
|
}
|
|
105
|
+
async function parseNoContentResponse(response, operationSignal, preconditionStatus, successStatuses, allowedErrorCodes) {
|
|
106
|
+
const requestId = safeRequestId(response.headers.get("x-request-id"));
|
|
107
|
+
if (requestId === null) {
|
|
108
|
+
cancelResponse(response);
|
|
109
|
+
throw new DriveError("invalid_response", { status: response.status });
|
|
110
|
+
}
|
|
111
|
+
if (!successStatuses.includes(response.status)) throw await normalizeError(response, requestId, operationSignal, preconditionStatus, false, allowedErrorCodes);
|
|
112
|
+
const contentLength = response.headers.get("content-length");
|
|
113
|
+
if (response.body !== null || contentLength !== null && contentLength !== "0" || response.headers.has("content-type")) {
|
|
114
|
+
cancelResponse(response);
|
|
115
|
+
throw new DriveError("invalid_response", {
|
|
116
|
+
status: response.status,
|
|
117
|
+
requestId
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return Object.freeze({
|
|
121
|
+
data: void 0,
|
|
122
|
+
status: response.status,
|
|
123
|
+
requestId,
|
|
124
|
+
validators: Object.freeze({})
|
|
125
|
+
});
|
|
126
|
+
}
|
|
82
127
|
function parseCollectionEtag(value) {
|
|
83
128
|
const match = COLLECTION_ETAG.exec(value);
|
|
84
129
|
if (!match) return void 0;
|
|
@@ -92,6 +137,12 @@ function parseGrantEtag(value) {
|
|
|
92
137
|
const grantRevision = Number(match[2]);
|
|
93
138
|
return Number.isSafeInteger(collectionRevision) && Number.isSafeInteger(grantRevision) ? [collectionRevision, grantRevision] : void 0;
|
|
94
139
|
}
|
|
140
|
+
function parseItemEtag(value) {
|
|
141
|
+
const match = ITEM_ETAG.exec(value);
|
|
142
|
+
if (!match) return void 0;
|
|
143
|
+
const revision = Number(match[1]);
|
|
144
|
+
return Number.isSafeInteger(revision) ? revision : void 0;
|
|
145
|
+
}
|
|
95
146
|
async function normalizeError(response, headerRequestId, signal, preconditionStatus, allowsQuotaExceeded, allowedErrorCodes) {
|
|
96
147
|
let parsed;
|
|
97
148
|
try {
|
|
@@ -135,8 +186,10 @@ function errorStatusMatches(code, status, preconditionStatus, allowsQuotaExceede
|
|
|
135
186
|
invalid_pagination_cursor: [422],
|
|
136
187
|
invalid_idempotency_key: [422],
|
|
137
188
|
precondition_failed: preconditionStatus === null ? [] : [preconditionStatus],
|
|
189
|
+
range_not_satisfiable: [416],
|
|
138
190
|
idempotency_conflict: [409],
|
|
139
191
|
quota_exceeded: [409],
|
|
192
|
+
upload_recovery_required: [409],
|
|
140
193
|
service_unavailable: [503],
|
|
141
194
|
internal_error: [500]
|
|
142
195
|
}[code].includes(status);
|
|
@@ -231,7 +284,7 @@ function readValidators(headers) {
|
|
|
231
284
|
const permissionCollectionEtag = headers.get("drive-permission-collection-etag");
|
|
232
285
|
const permissionGrantEtag = headers.get("drive-permission-grant-etag");
|
|
233
286
|
return Object.freeze({
|
|
234
|
-
...etag !== null && LIST_ETAG$1.test(etag) ? { etag } : {},
|
|
287
|
+
...etag !== null && (LIST_ETAG$1.test(etag) || parseItemEtag(etag) !== void 0) ? { etag } : {},
|
|
235
288
|
...permissionCollectionEtag !== null && parseCollectionEtag(permissionCollectionEtag) !== void 0 ? { permissionCollectionEtag } : {},
|
|
236
289
|
...permissionGrantEtag !== null && parseGrantEtag(permissionGrantEtag) !== void 0 ? { permissionGrantEtag } : {}
|
|
237
290
|
});
|
|
@@ -247,6 +300,8 @@ const WORKSPACE_ID$1 = /^drive\.workspace\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-
|
|
|
247
300
|
const VOLUME_ID = /^drive\.volume\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
248
301
|
const GRANT_ID$1 = /^drive\.grant\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
249
302
|
const UPLOAD_ID$1 = /^drive\.upload\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
303
|
+
const VERSION_ID$1 = /^drive\.version\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
304
|
+
const RETRIEVAL_ID = /^drive\.retrieval\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
250
305
|
const CURSOR$1 = /^drive\.cursor\.v1\.[A-Za-z0-9_-]+$/;
|
|
251
306
|
const AUTH_ID$1 = /^[A-Za-z0-9_-]{1,128}$/;
|
|
252
307
|
const GRANT_ETAG = /^"drive\.permission-grant\.v1\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)"$/;
|
|
@@ -269,7 +324,9 @@ const EFFECTIVE_ACTIONS = Object.freeze([
|
|
|
269
324
|
"items:update"
|
|
270
325
|
]);
|
|
271
326
|
const MAX_UPLOAD_BYTE_LENGTH$1 = 33554432e4;
|
|
272
|
-
const
|
|
327
|
+
const UPLOAD_PART_BYTE_LENGTH$1 = 32 * 1024 * 1024;
|
|
328
|
+
const CONTENT_DIGEST$1 = /^sha256:[0-9a-f]{64}$/;
|
|
329
|
+
const UTF8 = new TextEncoder();
|
|
273
330
|
function isCurrentWorkspace(value) {
|
|
274
331
|
if (!isExactRecord(value, [
|
|
275
332
|
"workspaceId",
|
|
@@ -280,6 +337,61 @@ function isCurrentWorkspace(value) {
|
|
|
280
337
|
const reference = value.workspaceReference;
|
|
281
338
|
return isExactRecord(reference, ["type", "userId"]) && reference.type === "personal" && typeof reference.userId === "string" && AUTH_ID$1.test(reference.userId) || isExactRecord(reference, ["type", "organizationId"]) && reference.type === "organization" && typeof reference.organizationId === "string" && AUTH_ID$1.test(reference.organizationId);
|
|
282
339
|
}
|
|
340
|
+
function isManagedDownloadDescriptor(value) {
|
|
341
|
+
if (!isExactRecord(value, [
|
|
342
|
+
"mode",
|
|
343
|
+
"method",
|
|
344
|
+
"url",
|
|
345
|
+
"headers",
|
|
346
|
+
"expiresAtEpochMilliseconds",
|
|
347
|
+
"response"
|
|
348
|
+
]) || value.mode !== "presigned-single" || value.method !== "GET" && value.method !== "HEAD" || typeof value.url !== "string" || !isSafeCapabilityUrl(value.url) || !isSafeInteger$1(value.expiresAtEpochMilliseconds) || !isExactRecord(value.headers, ["if-match"]) && !isExactRecord(value.headers, ["if-match", "range"]) || typeof value.headers["if-match"] !== "string" || !isStrongEtag(value.headers["if-match"]) || value.headers.range !== void 0 && (typeof value.headers.range !== "string" || !/^bytes=(?:0|[1-9][0-9]*)-(?:0|[1-9][0-9]*)$/.test(value.headers.range)) || !isExactRecord(value.response, [
|
|
349
|
+
"status",
|
|
350
|
+
"versionId",
|
|
351
|
+
"byteLength",
|
|
352
|
+
"contentLength",
|
|
353
|
+
"contentType",
|
|
354
|
+
"contentDisposition",
|
|
355
|
+
"etag",
|
|
356
|
+
"acceptRanges",
|
|
357
|
+
"contentRange"
|
|
358
|
+
]) || value.response.status !== 200 && value.response.status !== 206 || typeof value.response.versionId !== "string" || !VERSION_ID$1.test(value.response.versionId) || !isSafeInteger$1(value.response.byteLength) || !isSafeInteger$1(value.response.contentLength) || typeof value.response.contentType !== "string" || !/^[a-z0-9](?:[a-z0-9!#$&^_.+-]{0,125}[a-z0-9])?\/[a-z0-9](?:[a-z0-9!#$&^_.+-]{0,125}[a-z0-9])?$/.test(value.response.contentType) || typeof value.response.contentDisposition !== "string" || value.response.contentDisposition.length > 2048 || !/^[\x20-\x7e]+$/.test(value.response.contentDisposition) || value.response.etag !== value.headers["if-match"] || value.response.acceptRanges !== "bytes" || value.response.contentRange !== null && typeof value.response.contentRange !== "string") return false;
|
|
359
|
+
if (!downloadDescriptorIsCoherent(value)) return false;
|
|
360
|
+
Object.freeze(value.headers);
|
|
361
|
+
Object.freeze(value.response);
|
|
362
|
+
Object.freeze(value);
|
|
363
|
+
return true;
|
|
364
|
+
}
|
|
365
|
+
function downloadDescriptorIsCoherent(value) {
|
|
366
|
+
const response = value.response;
|
|
367
|
+
if (response.contentLength > response.byteLength || value.method === "HEAD" && response.status !== 200 || !response.contentDisposition.startsWith("attachment; filename=\"")) return false;
|
|
368
|
+
if (response.status === 200) return value.headers.range === void 0 && response.contentRange === null && response.contentLength === response.byteLength;
|
|
369
|
+
if (value.method !== "GET" || value.headers.range === void 0 || response.contentRange === null) return false;
|
|
370
|
+
const range = /^bytes=(0|[1-9][0-9]*)-(0|[1-9][0-9]*)$/.exec(value.headers.range);
|
|
371
|
+
const contentRange = /^bytes (0|[1-9][0-9]*)-(0|[1-9][0-9]*)\/(0|[1-9][0-9]*)$/.exec(response.contentRange);
|
|
372
|
+
if (!range || !contentRange) return false;
|
|
373
|
+
const start = Number(range[1]);
|
|
374
|
+
const end = Number(range[2]);
|
|
375
|
+
const contentStart = Number(contentRange[1]);
|
|
376
|
+
const contentEnd = Number(contentRange[2]);
|
|
377
|
+
const byteLength = Number(contentRange[3]);
|
|
378
|
+
return [
|
|
379
|
+
start,
|
|
380
|
+
end,
|
|
381
|
+
contentStart,
|
|
382
|
+
contentEnd,
|
|
383
|
+
byteLength
|
|
384
|
+
].every(isSafeInteger$1) && start === contentStart && end === contentEnd && byteLength === response.byteLength && start <= end && end < byteLength && response.contentLength === end - start + 1;
|
|
385
|
+
}
|
|
386
|
+
function isManagedDownloadRestorePending(value) {
|
|
387
|
+
return isExactRecord(value, [
|
|
388
|
+
"mode",
|
|
389
|
+
"operationId",
|
|
390
|
+
"versionId",
|
|
391
|
+
"state",
|
|
392
|
+
"pollAfterSeconds"
|
|
393
|
+
]) && value.mode === "restore-pending" && typeof value.operationId === "string" && RETRIEVAL_ID.test(value.operationId) && typeof value.versionId === "string" && VERSION_ID$1.test(value.versionId) && (value.state === "pending" || value.state === "restoring") && isSafeInteger$1(value.pollAfterSeconds) && value.pollAfterSeconds >= 1 && value.pollAfterSeconds <= 60;
|
|
394
|
+
}
|
|
283
395
|
function isFolderPage(value, workspaceId, parentItemId) {
|
|
284
396
|
if (!(isExactRecord(value, ["items", "nextCursor"]) && Array.isArray(value.items) && value.items.length <= 50 && value.items.every(isFolderItem) && (value.nextCursor === null || typeof value.nextCursor === "string" && value.nextCursor.length <= 699 && CURSOR$1.test(value.nextCursor)))) return false;
|
|
285
397
|
return value.items.every((item) => item.workspaceId === workspaceId && item.parentItemId === parentItemId) && isStrictlyOrdered(value.items, (item) => item.itemId);
|
|
@@ -296,6 +408,101 @@ function isFolderItem(value) {
|
|
|
296
408
|
"revision"
|
|
297
409
|
]) && typeof value.workspaceId === "string" && WORKSPACE_ID$1.test(value.workspaceId) && typeof value.volumeId === "string" && VOLUME_ID.test(value.volumeId) && typeof value.itemId === "string" && ITEM_ID$1.test(value.itemId) && typeof value.parentItemId === "string" && ITEM_ID$1.test(value.parentItemId) && (value.kind === "file" || value.kind === "folder") && isSafeFilename$1(value.name) && (value.visibility === "workspace" || value.visibility === "restricted") && isSafeInteger$1(value.revision);
|
|
298
410
|
}
|
|
411
|
+
function isManagedLifecycleItem(value, workspaceId, itemId, expectedState) {
|
|
412
|
+
if (!isExactRecord(value, [
|
|
413
|
+
"workspaceId",
|
|
414
|
+
"volumeId",
|
|
415
|
+
"itemId",
|
|
416
|
+
"parentItemId",
|
|
417
|
+
"kind",
|
|
418
|
+
"name",
|
|
419
|
+
"state",
|
|
420
|
+
"revision",
|
|
421
|
+
"purgeAfterEpochMilliseconds"
|
|
422
|
+
]) || value.workspaceId !== workspaceId || value.itemId !== itemId || typeof value.volumeId !== "string" || !VOLUME_ID.test(value.volumeId) || typeof value.parentItemId !== "string" || !ITEM_ID$1.test(value.parentItemId) || value.kind !== "file" && value.kind !== "folder" || !isSafeFilename$1(value.name) || value.state !== expectedState || !isSafeInteger$1(value.revision) || (value.state === "active" ? value.purgeAfterEpochMilliseconds !== null : !isSafeInteger$1(value.purgeAfterEpochMilliseconds))) return false;
|
|
423
|
+
Object.freeze(value);
|
|
424
|
+
return true;
|
|
425
|
+
}
|
|
426
|
+
function isManagedItemMetadata(value, workspaceId, itemId) {
|
|
427
|
+
if (!isExactRecord(value, [
|
|
428
|
+
"workspaceId",
|
|
429
|
+
"itemId",
|
|
430
|
+
"parentId",
|
|
431
|
+
"type",
|
|
432
|
+
"name",
|
|
433
|
+
"lifecycleState",
|
|
434
|
+
"revision",
|
|
435
|
+
"currentVersion"
|
|
436
|
+
]) || value.workspaceId !== workspaceId || value.itemId !== itemId || !(value.parentId === null || typeof value.parentId === "string" && ITEM_ID$1.test(value.parentId)) || value.type !== "file" && value.type !== "folder" || !isSafeFilename$1(value.name) || value.lifecycleState !== "active" || !isSafeInteger$1(value.revision) || (value.type === "folder" ? value.currentVersion !== null : !isCurrentVersionMetadata(value.currentVersion))) return false;
|
|
437
|
+
if (value.currentVersion !== null) Object.freeze(value.currentVersion);
|
|
438
|
+
Object.freeze(value);
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
function isWorkspaceItemSearchPage(value, workspaceId, query, limit) {
|
|
442
|
+
if (!isExactRecord(value, ["items", "nextCursor"]) || !Array.isArray(value.items) || value.items.length > limit || !value.items.every((item) => isWorkspaceItemSearchItem(item, workspaceId, query)) || !(value.nextCursor === null || typeof value.nextCursor === "string" && value.nextCursor.length <= 699 && CURSOR$1.test(value.nextCursor)) || value.items.length === 0 && value.nextCursor !== null || new Set(value.items.map((item) => item.itemId)).size !== value.items.length || !isWorkspaceItemSearchOrder(value.items)) return false;
|
|
443
|
+
for (const item of value.items) {
|
|
444
|
+
if (item.currentVersion !== null) Object.freeze(item.currentVersion);
|
|
445
|
+
Object.freeze(item);
|
|
446
|
+
}
|
|
447
|
+
Object.freeze(value.items);
|
|
448
|
+
Object.freeze(value);
|
|
449
|
+
return true;
|
|
450
|
+
}
|
|
451
|
+
function itemEtagMatchesRevision(headers, revision) {
|
|
452
|
+
const etag = headers.get("etag");
|
|
453
|
+
return etag !== null && parseItemEtag(etag) === revision;
|
|
454
|
+
}
|
|
455
|
+
function isCurrentVersionMetadata(value) {
|
|
456
|
+
return isExactRecord(value, [
|
|
457
|
+
"versionId",
|
|
458
|
+
"state",
|
|
459
|
+
"byteLength",
|
|
460
|
+
"mediaType",
|
|
461
|
+
"protectionClassification"
|
|
462
|
+
]) && typeof value.versionId === "string" && VERSION_ID$1.test(value.versionId) && value.state === "current" && isSafeInteger$1(value.byteLength) && isMediaType$1(value.mediaType) && (value.protectionClassification === "ordinary" || value.protectionClassification === "opaque-encrypted");
|
|
463
|
+
}
|
|
464
|
+
function isWorkspaceItemSearchItem(value, workspaceId, query) {
|
|
465
|
+
return isExactRecord(value, [
|
|
466
|
+
"workspaceId",
|
|
467
|
+
"volumeId",
|
|
468
|
+
"provider",
|
|
469
|
+
"itemId",
|
|
470
|
+
"parentId",
|
|
471
|
+
"type",
|
|
472
|
+
"name",
|
|
473
|
+
"lifecycleState",
|
|
474
|
+
"revision",
|
|
475
|
+
"currentVersion"
|
|
476
|
+
]) && value.workspaceId === workspaceId && typeof value.volumeId === "string" && VOLUME_ID.test(value.volumeId) && value.provider === "managed" && typeof value.itemId === "string" && ITEM_ID$1.test(value.itemId) && (value.parentId === null || typeof value.parentId === "string" && ITEM_ID$1.test(value.parentId)) && (value.type === "file" || value.type === "folder") && isSafeFilename$1(value.name) && value.name.startsWith(query) && value.lifecycleState === "active" && isSafeInteger$1(value.revision) && (value.type === "folder" ? value.currentVersion === null : isCurrentVersionMetadata(value.currentVersion));
|
|
477
|
+
}
|
|
478
|
+
function isWorkspaceItemSearchOrder(items) {
|
|
479
|
+
for (let index = 1; index < items.length; index += 1) {
|
|
480
|
+
const previous = items[index - 1];
|
|
481
|
+
const current = items[index];
|
|
482
|
+
const nameOrder = compareBinary(previous.name, current.name);
|
|
483
|
+
if (nameOrder > 0 || nameOrder === 0 && previous.itemId >= current.itemId) return false;
|
|
484
|
+
}
|
|
485
|
+
return true;
|
|
486
|
+
}
|
|
487
|
+
function compareBinary(left, right) {
|
|
488
|
+
const leftBytes = UTF8.encode(left);
|
|
489
|
+
const rightBytes = UTF8.encode(right);
|
|
490
|
+
const length = Math.min(leftBytes.length, rightBytes.length);
|
|
491
|
+
for (let index = 0; index < length; index += 1) if (leftBytes[index] !== rightBytes[index]) return leftBytes[index] - rightBytes[index];
|
|
492
|
+
return leftBytes.length - rightBytes.length;
|
|
493
|
+
}
|
|
494
|
+
function isManagedItemVersionPage(value, limit) {
|
|
495
|
+
if (!isExactRecord(value, ["items", "nextCursor"]) || !Array.isArray(value.items) || value.items.length > limit || !value.items.every(isManagedItemVersion) || !(value.nextCursor === null || typeof value.nextCursor === "string" && value.nextCursor.length <= 699 && CURSOR$1.test(value.nextCursor)) || value.nextCursor !== null && value.items.length === 0 || !isStrictlyOrdered(value.items, (version) => version.versionId)) return false;
|
|
496
|
+
for (const version of value.items) Object.freeze(version);
|
|
497
|
+
Object.freeze(value.items);
|
|
498
|
+
Object.freeze(value);
|
|
499
|
+
return true;
|
|
500
|
+
}
|
|
501
|
+
function isManagedItemVersionRestoreResult(value, versionId) {
|
|
502
|
+
if (!isExactRecord(value, ["itemRevision", "currentVersionId"]) || !isSafeInteger$1(value.itemRevision) || value.currentVersionId !== versionId) return false;
|
|
503
|
+
Object.freeze(value);
|
|
504
|
+
return true;
|
|
505
|
+
}
|
|
299
506
|
function isPermissionPage(value, headers, targetItemId) {
|
|
300
507
|
if (!(isExactRecord(value, [
|
|
301
508
|
"items",
|
|
@@ -350,18 +557,127 @@ function isEffectivePermissionResponse(value, targetItemId) {
|
|
|
350
557
|
}
|
|
351
558
|
return true;
|
|
352
559
|
}
|
|
353
|
-
function
|
|
354
|
-
|
|
355
|
-
"
|
|
560
|
+
function isUploadSession(value, expectedByteLength) {
|
|
561
|
+
if (!isExactRecord(value, [
|
|
562
|
+
"itemId",
|
|
563
|
+
"versionId",
|
|
356
564
|
"uploadId",
|
|
357
|
-
"
|
|
358
|
-
"
|
|
359
|
-
"
|
|
360
|
-
"
|
|
361
|
-
"
|
|
565
|
+
"mode",
|
|
566
|
+
"partByteLength",
|
|
567
|
+
"partCount",
|
|
568
|
+
"revision",
|
|
569
|
+
"expiresAtEpochMilliseconds"
|
|
570
|
+
]) || typeof value.itemId !== "string" || !ITEM_ID$1.test(value.itemId) || typeof value.versionId !== "string" || !VERSION_ID$1.test(value.versionId) || typeof value.uploadId !== "string" || !UPLOAD_ID$1.test(value.uploadId) || value.mode !== "presigned-multipart" && value.mode !== "server-mediated-zero-byte" || value.partByteLength !== UPLOAD_PART_BYTE_LENGTH$1 || !isSafeInteger$1(value.partCount) || value.partCount > 1e4 || value.partCount !== Math.ceil(expectedByteLength / UPLOAD_PART_BYTE_LENGTH$1) || (expectedByteLength === 0 ? value.mode !== "server-mediated-zero-byte" : value.mode !== "presigned-multipart") || !isSafeInteger$1(value.revision) || !isSafeInteger$1(value.expiresAtEpochMilliseconds) || value.expiresAtEpochMilliseconds <= Date.now()) return false;
|
|
571
|
+
Object.freeze(value);
|
|
572
|
+
return true;
|
|
573
|
+
}
|
|
574
|
+
function isUploadStatus(value, afterPartNumber, limit) {
|
|
575
|
+
if (!isExactRecord(value, [
|
|
576
|
+
"itemId",
|
|
577
|
+
"versionId",
|
|
578
|
+
"uploadId",
|
|
579
|
+
"mode",
|
|
580
|
+
"lifecycle",
|
|
581
|
+
"revision",
|
|
582
|
+
"partPolicy",
|
|
583
|
+
"confirmedParts",
|
|
584
|
+
"nextAfterPartNumber",
|
|
362
585
|
"expiresAtEpochMilliseconds",
|
|
363
|
-
"
|
|
364
|
-
])
|
|
586
|
+
"ready"
|
|
587
|
+
]) || typeof value.itemId !== "string" || !ITEM_ID$1.test(value.itemId) || typeof value.versionId !== "string" || !VERSION_ID$1.test(value.versionId) || typeof value.uploadId !== "string" || !UPLOAD_ID$1.test(value.uploadId) || value.mode !== "presigned-multipart" && value.mode !== "server-mediated-zero-byte" || ![
|
|
588
|
+
"initiating",
|
|
589
|
+
"recovery-required",
|
|
590
|
+
"uploading",
|
|
591
|
+
"completing",
|
|
592
|
+
"provider-completed",
|
|
593
|
+
"ready",
|
|
594
|
+
"aborting",
|
|
595
|
+
"aborted"
|
|
596
|
+
].includes(String(value.lifecycle)) || !isSafeInteger$1(value.revision) || !isExactRecord(value.partPolicy, [
|
|
597
|
+
"partByteLength",
|
|
598
|
+
"partCount",
|
|
599
|
+
"maxParts"
|
|
600
|
+
]) || value.partPolicy.partByteLength !== UPLOAD_PART_BYTE_LENGTH$1 || !isSafeInteger$1(value.partPolicy.partCount) || value.partPolicy.partCount > 1e4 || value.partPolicy.maxParts !== 1e4 || (value.mode === "server-mediated-zero-byte" ? value.partPolicy.partCount !== 0 : value.partPolicy.partCount < 1) || !Array.isArray(value.confirmedParts) || value.confirmedParts.length > limit || !isSafeInteger$1(value.expiresAtEpochMilliseconds)) return false;
|
|
601
|
+
let previousPartNumber = afterPartNumber;
|
|
602
|
+
for (const part of value.confirmedParts) {
|
|
603
|
+
if (!isExactRecord(part, ["partNumber", "checksumSha256"]) || !isSafeInteger$1(part.partNumber) || part.partNumber <= previousPartNumber || part.partNumber > value.partPolicy.partCount || !isPartChecksum$1(part.checksumSha256)) return false;
|
|
604
|
+
previousPartNumber = part.partNumber;
|
|
605
|
+
}
|
|
606
|
+
if (!(value.nextAfterPartNumber === null || isSafeInteger$1(value.nextAfterPartNumber) && value.confirmedParts.length === limit && value.nextAfterPartNumber === previousPartNumber) || value.mode === "server-mediated-zero-byte" && (value.confirmedParts.length !== 0 || value.nextAfterPartNumber !== null) || value.lifecycle === "ready" !== (value.ready !== null) || value.ready !== null && (!isReadyUpload(value.ready, { uploadId: value.uploadId }) || value.ready.itemId !== value.itemId || value.ready.versionId !== value.versionId)) return false;
|
|
607
|
+
Object.freeze(value.partPolicy);
|
|
608
|
+
for (const part of value.confirmedParts) Object.freeze(part);
|
|
609
|
+
Object.freeze(value.confirmedParts);
|
|
610
|
+
Object.freeze(value);
|
|
611
|
+
return true;
|
|
612
|
+
}
|
|
613
|
+
function isUploadPartDescriptor(value, expectedPartNumber, checksumSha256, allowInsecureHttp) {
|
|
614
|
+
if (!isExactRecord(value, [
|
|
615
|
+
"url",
|
|
616
|
+
"method",
|
|
617
|
+
"headers",
|
|
618
|
+
"partNumber",
|
|
619
|
+
"expectedByteLength",
|
|
620
|
+
"expiresAtEpochMilliseconds"
|
|
621
|
+
]) || !isSignedTransferUrl(value.url, allowInsecureHttp) || value.method !== "PUT" || !isExactRecord(value.headers, ["x-amz-checksum-sha256"]) || value.headers["x-amz-checksum-sha256"] !== checksumSha256 || value.partNumber !== expectedPartNumber || !isSafeInteger$1(value.expectedByteLength) || value.expectedByteLength < 1 || value.expectedByteLength > UPLOAD_PART_BYTE_LENGTH$1 || !isSafeInteger$1(value.expiresAtEpochMilliseconds) || value.expiresAtEpochMilliseconds <= Date.now()) return false;
|
|
622
|
+
Object.freeze(value.headers);
|
|
623
|
+
Object.freeze(value);
|
|
624
|
+
return true;
|
|
625
|
+
}
|
|
626
|
+
function isUploadPartResult(value, expectedPartNumber, expectedUploadRevision) {
|
|
627
|
+
if (!isExactRecord(value, ["partNumber", "revision"]) || value.partNumber !== expectedPartNumber || value.revision !== expectedUploadRevision + 1 || !isSafeInteger$1(value.revision)) return false;
|
|
628
|
+
Object.freeze(value);
|
|
629
|
+
return true;
|
|
630
|
+
}
|
|
631
|
+
function isReadyUpload(value, expected) {
|
|
632
|
+
if (!isExactRecord(value, [
|
|
633
|
+
"itemId",
|
|
634
|
+
"versionId",
|
|
635
|
+
"uploadId",
|
|
636
|
+
"byteLength",
|
|
637
|
+
"callerDeclaredContentDigest",
|
|
638
|
+
"displayFilename",
|
|
639
|
+
"mediaType",
|
|
640
|
+
"state"
|
|
641
|
+
]) || typeof value.itemId !== "string" || !ITEM_ID$1.test(value.itemId) || typeof value.versionId !== "string" || !VERSION_ID$1.test(value.versionId) || value.uploadId !== expected.uploadId || !isSafeInteger$1(value.byteLength) || value.byteLength < 0 || value.byteLength > MAX_UPLOAD_BYTE_LENGTH$1 || typeof value.callerDeclaredContentDigest !== "string" || !CONTENT_DIGEST$1.test(value.callerDeclaredContentDigest) || !isSafeFilename$1(value.displayFilename) || !isMediaType$1(value.mediaType) || value.state !== "ready" || expected.byteLength !== void 0 && value.byteLength !== expected.byteLength || expected.callerDeclaredContentDigest !== void 0 && value.callerDeclaredContentDigest !== expected.callerDeclaredContentDigest || expected.displayFilename !== void 0 && value.displayFilename !== expected.displayFilename || expected.mediaType !== void 0 && value.mediaType !== expected.mediaType) return false;
|
|
642
|
+
Object.freeze(value);
|
|
643
|
+
return true;
|
|
644
|
+
}
|
|
645
|
+
function isPartChecksum$1(value) {
|
|
646
|
+
return typeof value === "string" && /^[A-Za-z0-9+/]{42}[AEIMQUYcgkosw048]=$/.test(value);
|
|
647
|
+
}
|
|
648
|
+
function isManagedItemVersion(value) {
|
|
649
|
+
const valid = isExactRecord(value, managedItemVersionKeys) && managedItemVersionFieldsAreValid(value);
|
|
650
|
+
if (valid) Object.freeze(value);
|
|
651
|
+
return valid;
|
|
652
|
+
}
|
|
653
|
+
function isManagedItemVersionResource(value, workspaceId, itemId, versionId) {
|
|
654
|
+
const valid = isExactRecord(value, [
|
|
655
|
+
...managedItemVersionKeys,
|
|
656
|
+
"workspaceId",
|
|
657
|
+
"itemId"
|
|
658
|
+
]) && value.workspaceId === workspaceId && value.itemId === itemId && value.versionId === versionId && managedItemVersionFieldsAreValid(value);
|
|
659
|
+
if (valid) Object.freeze(value);
|
|
660
|
+
return valid;
|
|
661
|
+
}
|
|
662
|
+
const managedItemVersionKeys = Object.freeze([
|
|
663
|
+
"versionId",
|
|
664
|
+
"state",
|
|
665
|
+
"revision",
|
|
666
|
+
"byteLength",
|
|
667
|
+
"contentDigest",
|
|
668
|
+
"mediaType",
|
|
669
|
+
"displayFilename",
|
|
670
|
+
"protectionClassification",
|
|
671
|
+
"archiveState"
|
|
672
|
+
]);
|
|
673
|
+
function managedItemVersionFieldsAreValid(value) {
|
|
674
|
+
return typeof value.versionId === "string" && VERSION_ID$1.test(value.versionId) && (value.state === "current" || value.state === "superseded") && isSafeInteger$1(value.revision) && isSafeInteger$1(value.byteLength) && typeof value.contentDigest === "string" && CONTENT_DIGEST$1.test(value.contentDigest) && isMediaType$1(value.mediaType) && isSafeFilename$1(value.displayFilename) && (value.protectionClassification === "ordinary" || value.protectionClassification === "opaque-encrypted") && [
|
|
675
|
+
"available",
|
|
676
|
+
"cold",
|
|
677
|
+
"restoring",
|
|
678
|
+
"unavailable",
|
|
679
|
+
"corrupt"
|
|
680
|
+
].includes(String(value.archiveState));
|
|
365
681
|
}
|
|
366
682
|
function mutationValidatorsAreCoherent(headers) {
|
|
367
683
|
const collection = headers.get("drive-permission-collection-etag");
|
|
@@ -418,6 +734,19 @@ function isSafeFilename$1(value) {
|
|
|
418
734
|
}
|
|
419
735
|
return true;
|
|
420
736
|
}
|
|
737
|
+
function isMediaType$1(value) {
|
|
738
|
+
return typeof value === "string" && value.length <= 255 && /^[a-z0-9](?:[a-z0-9!#$&^_.+-]{0,125}[a-z0-9])?\/[a-z0-9](?:[a-z0-9!#$&^_.+-]{0,125}[a-z0-9])?$/.test(value);
|
|
739
|
+
}
|
|
740
|
+
function isSignedTransferUrl(value, allowInsecureHttp) {
|
|
741
|
+
if (typeof value !== "string" || value.length < 1 || value.length > 8192 || value !== value.trim()) return false;
|
|
742
|
+
try {
|
|
743
|
+
const url = new URL(value);
|
|
744
|
+
const loopbackHost = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
|
|
745
|
+
return (url.protocol === "https:" || url.protocol === "http:" && allowInsecureHttp && loopbackHost) && url.username === "" && url.password === "" && url.hash === "" && url.host !== "";
|
|
746
|
+
} catch {
|
|
747
|
+
return false;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
421
750
|
function filenameIsReserved$1(value) {
|
|
422
751
|
const base = value.split(".", 1)[0].toUpperCase();
|
|
423
752
|
return value === "." || value === ".." || [
|
|
@@ -436,6 +765,22 @@ function isStrictlyOrdered(values, key) {
|
|
|
436
765
|
function isSafeInteger$1(value) {
|
|
437
766
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
438
767
|
}
|
|
768
|
+
function isStrongEtag(value) {
|
|
769
|
+
return /^"[\x21\x23-\x7e]{1,1022}"$/.test(value);
|
|
770
|
+
}
|
|
771
|
+
function isSafeCapabilityUrl(value) {
|
|
772
|
+
try {
|
|
773
|
+
const url = new URL(value);
|
|
774
|
+
const localHttp = url.protocol === "http:" && [
|
|
775
|
+
"localhost",
|
|
776
|
+
"127.0.0.1",
|
|
777
|
+
"[::1]"
|
|
778
|
+
].includes(url.hostname);
|
|
779
|
+
return (url.protocol === "https:" || localHttp) && !url.username && !url.password && !url.hash;
|
|
780
|
+
} catch {
|
|
781
|
+
return false;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
439
784
|
function isExactRecord(value, keys) {
|
|
440
785
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
441
786
|
return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
@@ -446,6 +791,7 @@ const ITEM_ID = /^drive\.item\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-
|
|
|
446
791
|
const WORKSPACE_ID = /^drive\.workspace\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
447
792
|
const GRANT_ID = /^drive\.grant\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
448
793
|
const UPLOAD_ID = /^drive\.upload\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
794
|
+
const VERSION_ID = /^drive\.version\.[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
449
795
|
const CURSOR = /^drive\.cursor\.v1\.[A-Za-z0-9_-]+$/;
|
|
450
796
|
const AUTH_ID = /^[A-Za-z0-9_-]{1,128}$/;
|
|
451
797
|
const PERMISSION_ACTIONS = Object.freeze([
|
|
@@ -457,7 +803,10 @@ const PERMISSION_ACTIONS = Object.freeze([
|
|
|
457
803
|
"items:update"
|
|
458
804
|
]);
|
|
459
805
|
const IDEMPOTENCY_KEY = /^[A-Za-z0-9_-]{16,128}$/;
|
|
806
|
+
const CONTENT_DIGEST = /^sha256:[0-9a-f]{64}$/;
|
|
807
|
+
const PART_CHECKSUM = /^[A-Za-z0-9+/]{42}[AEIMQUYcgkosw048]=$/;
|
|
460
808
|
const MAX_UPLOAD_BYTE_LENGTH = 33554432e4;
|
|
809
|
+
const UPLOAD_PART_BYTE_LENGTH = 32 * 1024 * 1024;
|
|
461
810
|
function validateCurrentWorkspaceInput(value) {
|
|
462
811
|
const signal = validateSignal(captureRecord(value === void 0 ? {} : value, [], ["signal"]).signal);
|
|
463
812
|
return signal === void 0 ? {} : { signal };
|
|
@@ -474,6 +823,71 @@ function validateResourceInput(value) {
|
|
|
474
823
|
...signal === void 0 ? {} : { signal }
|
|
475
824
|
};
|
|
476
825
|
}
|
|
826
|
+
function validateItemVersionInput(value) {
|
|
827
|
+
const input = captureRecord(value, [
|
|
828
|
+
"workspaceId",
|
|
829
|
+
"itemId",
|
|
830
|
+
"versionId"
|
|
831
|
+
], ["signal"]);
|
|
832
|
+
const resource = validateResourceInput({
|
|
833
|
+
workspaceId: input.workspaceId,
|
|
834
|
+
itemId: input.itemId,
|
|
835
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
836
|
+
});
|
|
837
|
+
if (typeof input.versionId !== "string" || !VERSION_ID.test(input.versionId)) throw new DriveError("invalid_input");
|
|
838
|
+
return {
|
|
839
|
+
...resource,
|
|
840
|
+
versionId: input.versionId
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
function validateCreateDownloadInput(value) {
|
|
844
|
+
const input = captureRecord(value, [
|
|
845
|
+
"workspaceId",
|
|
846
|
+
"itemId",
|
|
847
|
+
"idempotencyKey"
|
|
848
|
+
], [
|
|
849
|
+
"versionId",
|
|
850
|
+
"method",
|
|
851
|
+
"range",
|
|
852
|
+
"ifMatch",
|
|
853
|
+
"ifNoneMatch",
|
|
854
|
+
"ifRange",
|
|
855
|
+
"signal"
|
|
856
|
+
]);
|
|
857
|
+
const resource = validateResourceInput({
|
|
858
|
+
workspaceId: input.workspaceId,
|
|
859
|
+
itemId: input.itemId,
|
|
860
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
861
|
+
});
|
|
862
|
+
const method = input.method ?? "GET";
|
|
863
|
+
if (!isIdempotencyKey(input.idempotencyKey) || input.versionId !== void 0 && (typeof input.versionId !== "string" || !VERSION_ID.test(input.versionId)) || method !== "GET" && method !== "HEAD" || input.range !== void 0 && (typeof input.range !== "string" || input.range.length > 128 || !/^bytes=(?:[0-9]+-[0-9]*|-[0-9]+)$/.test(input.range)) || !isOptionalHeaderValue(input.ifMatch) || !isOptionalHeaderValue(input.ifNoneMatch) || !isOptionalHeaderValue(input.ifRange)) throw new DriveError("invalid_input");
|
|
864
|
+
return {
|
|
865
|
+
...resource,
|
|
866
|
+
idempotencyKey: input.idempotencyKey,
|
|
867
|
+
method,
|
|
868
|
+
...input.versionId === void 0 ? {} : { versionId: input.versionId },
|
|
869
|
+
...input.range === void 0 ? {} : { range: input.range },
|
|
870
|
+
...input.ifMatch === void 0 ? {} : { ifMatch: input.ifMatch },
|
|
871
|
+
...input.ifNoneMatch === void 0 ? {} : { ifNoneMatch: input.ifNoneMatch },
|
|
872
|
+
...input.ifRange === void 0 ? {} : { ifRange: input.ifRange }
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
function validateSearchWorkspaceItemsInput(value) {
|
|
876
|
+
const input = captureRecord(value, ["workspaceId", "query"], [
|
|
877
|
+
"limit",
|
|
878
|
+
"cursor",
|
|
879
|
+
"signal"
|
|
880
|
+
]);
|
|
881
|
+
const signal = validateSignal(input.signal);
|
|
882
|
+
if (typeof input.workspaceId !== "string" || !WORKSPACE_ID.test(input.workspaceId) || !isSearchQuery(input.query) || input.limit !== void 0 && (!isSafeInteger(input.limit) || input.limit < 1 || input.limit > 50) || input.cursor !== void 0 && (typeof input.cursor !== "string" || input.cursor.length > 699 || !CURSOR.test(input.cursor))) throw new DriveError("invalid_input");
|
|
883
|
+
return {
|
|
884
|
+
workspaceId: input.workspaceId,
|
|
885
|
+
query: input.query,
|
|
886
|
+
...input.limit === void 0 ? {} : { limit: input.limit },
|
|
887
|
+
...input.cursor === void 0 ? {} : { cursor: input.cursor },
|
|
888
|
+
...signal === void 0 ? {} : { signal }
|
|
889
|
+
};
|
|
890
|
+
}
|
|
477
891
|
function validatePageInput(value) {
|
|
478
892
|
const input = captureRecord(value, ["workspaceId", "itemId"], [
|
|
479
893
|
"signal",
|
|
@@ -513,6 +927,69 @@ function validateCreateFolderInput(value) {
|
|
|
513
927
|
idempotencyKey: input.idempotencyKey
|
|
514
928
|
};
|
|
515
929
|
}
|
|
930
|
+
function validateUpdateItemInput(value) {
|
|
931
|
+
const input = captureRecord(value, [
|
|
932
|
+
"workspaceId",
|
|
933
|
+
"itemId",
|
|
934
|
+
"name",
|
|
935
|
+
"parentItemId",
|
|
936
|
+
"idempotencyKey",
|
|
937
|
+
"ifMatch"
|
|
938
|
+
], ["signal"]);
|
|
939
|
+
const mutation = validateLifecycleMutationInput({
|
|
940
|
+
workspaceId: input.workspaceId,
|
|
941
|
+
itemId: input.itemId,
|
|
942
|
+
idempotencyKey: input.idempotencyKey,
|
|
943
|
+
ifMatch: input.ifMatch,
|
|
944
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
945
|
+
});
|
|
946
|
+
if (!isSafeFilename(input.name) || typeof input.parentItemId !== "string" || !ITEM_ID.test(input.parentItemId)) throw new DriveError("invalid_input");
|
|
947
|
+
return {
|
|
948
|
+
...mutation,
|
|
949
|
+
name: input.name,
|
|
950
|
+
parentItemId: input.parentItemId
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
function validateLifecycleMutationInput(value) {
|
|
954
|
+
const input = captureRecord(value, [
|
|
955
|
+
"workspaceId",
|
|
956
|
+
"itemId",
|
|
957
|
+
"idempotencyKey",
|
|
958
|
+
"ifMatch"
|
|
959
|
+
], ["signal"]);
|
|
960
|
+
const resource = validateResourceInput({
|
|
961
|
+
workspaceId: input.workspaceId,
|
|
962
|
+
itemId: input.itemId,
|
|
963
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
964
|
+
});
|
|
965
|
+
if (!isIdempotencyKey(input.idempotencyKey) || typeof input.ifMatch !== "string" || parseItemEtag(input.ifMatch) === void 0) throw new DriveError("invalid_input");
|
|
966
|
+
return {
|
|
967
|
+
...resource,
|
|
968
|
+
idempotencyKey: input.idempotencyKey,
|
|
969
|
+
ifMatch: input.ifMatch
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
function validateRestoreItemVersionInput(value) {
|
|
973
|
+
const input = captureRecord(value, [
|
|
974
|
+
"workspaceId",
|
|
975
|
+
"itemId",
|
|
976
|
+
"versionId",
|
|
977
|
+
"idempotencyKey",
|
|
978
|
+
"ifMatch"
|
|
979
|
+
], ["signal"]);
|
|
980
|
+
const mutation = validateLifecycleMutationInput({
|
|
981
|
+
workspaceId: input.workspaceId,
|
|
982
|
+
itemId: input.itemId,
|
|
983
|
+
idempotencyKey: input.idempotencyKey,
|
|
984
|
+
ifMatch: input.ifMatch,
|
|
985
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
986
|
+
});
|
|
987
|
+
if (typeof input.versionId !== "string" || !VERSION_ID.test(input.versionId)) throw new DriveError("invalid_input");
|
|
988
|
+
return {
|
|
989
|
+
...mutation,
|
|
990
|
+
versionId: input.versionId
|
|
991
|
+
};
|
|
992
|
+
}
|
|
516
993
|
function validateCreatePermissionInput(value) {
|
|
517
994
|
const input = captureRecord(value, [
|
|
518
995
|
"workspaceId",
|
|
@@ -596,28 +1073,93 @@ function validateCreateUploadInput(value) {
|
|
|
596
1073
|
"workspaceId",
|
|
597
1074
|
"parentItemId",
|
|
598
1075
|
"expectedByteLength",
|
|
1076
|
+
"displayFilename",
|
|
1077
|
+
"mediaType",
|
|
1078
|
+
"callerDeclaredContentDigest",
|
|
1079
|
+
"protectionClassification",
|
|
599
1080
|
"idempotencyKey"
|
|
600
1081
|
], ["signal"]);
|
|
601
1082
|
const signal = validateSignal(input.signal);
|
|
602
|
-
if (typeof input.workspaceId !== "string" || !WORKSPACE_ID.test(input.workspaceId) || typeof input.parentItemId !== "string" || !ITEM_ID.test(input.parentItemId) || typeof input.expectedByteLength !== "number" || !Number.isSafeInteger(input.expectedByteLength) || input.expectedByteLength < 0 || input.expectedByteLength > MAX_UPLOAD_BYTE_LENGTH || !isIdempotencyKey(input.idempotencyKey)) throw new DriveError("invalid_input");
|
|
1083
|
+
if (typeof input.workspaceId !== "string" || !WORKSPACE_ID.test(input.workspaceId) || typeof input.parentItemId !== "string" || !ITEM_ID.test(input.parentItemId) || typeof input.expectedByteLength !== "number" || !Number.isSafeInteger(input.expectedByteLength) || input.expectedByteLength < 0 || input.expectedByteLength > MAX_UPLOAD_BYTE_LENGTH || !isSafeFilename(input.displayFilename) || !isMediaType(input.mediaType) || typeof input.callerDeclaredContentDigest !== "string" || !CONTENT_DIGEST.test(input.callerDeclaredContentDigest) || input.protectionClassification !== "ordinary" && input.protectionClassification !== "opaque-encrypted" || !isIdempotencyKey(input.idempotencyKey)) throw new DriveError("invalid_input");
|
|
603
1084
|
return {
|
|
604
1085
|
workspaceId: input.workspaceId,
|
|
605
1086
|
parentItemId: input.parentItemId,
|
|
606
1087
|
expectedByteLength: input.expectedByteLength,
|
|
1088
|
+
displayFilename: input.displayFilename,
|
|
1089
|
+
mediaType: input.mediaType,
|
|
1090
|
+
callerDeclaredContentDigest: input.callerDeclaredContentDigest,
|
|
1091
|
+
protectionClassification: input.protectionClassification,
|
|
607
1092
|
idempotencyKey: input.idempotencyKey,
|
|
608
1093
|
...signal === void 0 ? {} : { signal }
|
|
609
1094
|
};
|
|
610
1095
|
}
|
|
611
|
-
function
|
|
612
|
-
const input = captureRecord(value, ["workspaceId", "uploadId"], [
|
|
613
|
-
|
|
614
|
-
|
|
1096
|
+
function validateGetUploadStatusInput(value) {
|
|
1097
|
+
const input = captureRecord(value, ["workspaceId", "uploadId"], [
|
|
1098
|
+
"afterPartNumber",
|
|
1099
|
+
"limit",
|
|
1100
|
+
"signal"
|
|
1101
|
+
]);
|
|
1102
|
+
const upload = validateUploadPath(input.workspaceId, input.uploadId, input.signal);
|
|
1103
|
+
if (input.afterPartNumber !== void 0 && (!isSafeInteger(input.afterPartNumber) || input.afterPartNumber > 1e4) || input.limit !== void 0 && (!isSafeInteger(input.limit) || input.limit < 1 || input.limit > 100)) throw new DriveError("invalid_input");
|
|
615
1104
|
return {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
...
|
|
1105
|
+
...upload,
|
|
1106
|
+
...input.afterPartNumber === void 0 ? {} : { afterPartNumber: input.afterPartNumber },
|
|
1107
|
+
...input.limit === void 0 ? {} : { limit: input.limit }
|
|
619
1108
|
};
|
|
620
1109
|
}
|
|
1110
|
+
function validateCreateUploadPartDescriptorInput(value) {
|
|
1111
|
+
const input = captureRecord(value, [
|
|
1112
|
+
"workspaceId",
|
|
1113
|
+
"uploadId",
|
|
1114
|
+
"partNumber",
|
|
1115
|
+
"checksumSha256"
|
|
1116
|
+
], ["signal"]);
|
|
1117
|
+
const upload = validateUploadPath(input.workspaceId, input.uploadId, input.signal);
|
|
1118
|
+
if (!isPartNumber(input.partNumber) || !isPartChecksum(input.checksumSha256)) throw new DriveError("invalid_input");
|
|
1119
|
+
return {
|
|
1120
|
+
...upload,
|
|
1121
|
+
partNumber: input.partNumber,
|
|
1122
|
+
checksumSha256: input.checksumSha256
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
function validateRecordUploadPartInput(value) {
|
|
1126
|
+
const input = captureRecord(value, [
|
|
1127
|
+
"workspaceId",
|
|
1128
|
+
"uploadId",
|
|
1129
|
+
"partNumber",
|
|
1130
|
+
"expectedUploadRevision",
|
|
1131
|
+
"byteLength",
|
|
1132
|
+
"etag",
|
|
1133
|
+
"checksumSha256"
|
|
1134
|
+
], ["signal"]);
|
|
1135
|
+
const upload = validateUploadPath(input.workspaceId, input.uploadId, input.signal);
|
|
1136
|
+
if (!isPartNumber(input.partNumber) || !isSafeInteger(input.expectedUploadRevision) || input.expectedUploadRevision >= Number.MAX_SAFE_INTEGER || !isSafeInteger(input.byteLength) || input.byteLength < 1 || input.byteLength > UPLOAD_PART_BYTE_LENGTH || !isEtag(input.etag) || !isPartChecksum(input.checksumSha256)) throw new DriveError("invalid_input");
|
|
1137
|
+
return {
|
|
1138
|
+
...upload,
|
|
1139
|
+
partNumber: input.partNumber,
|
|
1140
|
+
expectedUploadRevision: input.expectedUploadRevision,
|
|
1141
|
+
byteLength: input.byteLength,
|
|
1142
|
+
etag: input.etag,
|
|
1143
|
+
checksumSha256: input.checksumSha256
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
function validateCompleteUploadInput(value) {
|
|
1147
|
+
const input = captureRecord(value, [
|
|
1148
|
+
"workspaceId",
|
|
1149
|
+
"uploadId",
|
|
1150
|
+
"idempotencyKey"
|
|
1151
|
+
], ["signal"]);
|
|
1152
|
+
const upload = validateUploadPath(input.workspaceId, input.uploadId, input.signal);
|
|
1153
|
+
if (!isIdempotencyKey(input.idempotencyKey)) throw new DriveError("invalid_input");
|
|
1154
|
+
return {
|
|
1155
|
+
...upload,
|
|
1156
|
+
idempotencyKey: input.idempotencyKey
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
function validateAbortUploadInput(value) {
|
|
1160
|
+
const input = captureRecord(value, ["workspaceId", "uploadId"], ["signal"]);
|
|
1161
|
+
return validateUploadPath(input.workspaceId, input.uploadId, input.signal);
|
|
1162
|
+
}
|
|
621
1163
|
function resourcePath(input) {
|
|
622
1164
|
return {
|
|
623
1165
|
workspaceId: input.workspaceId,
|
|
@@ -702,6 +1244,45 @@ function captureArray(value) {
|
|
|
702
1244
|
function isIdempotencyKey(value) {
|
|
703
1245
|
return typeof value === "string" && IDEMPOTENCY_KEY.test(value);
|
|
704
1246
|
}
|
|
1247
|
+
function validateUploadPath(workspaceId, uploadId, signalValue) {
|
|
1248
|
+
const signal = validateSignal(signalValue);
|
|
1249
|
+
if (typeof workspaceId !== "string" || !WORKSPACE_ID.test(workspaceId) || typeof uploadId !== "string" || !UPLOAD_ID.test(uploadId)) throw new DriveError("invalid_input");
|
|
1250
|
+
return {
|
|
1251
|
+
workspaceId,
|
|
1252
|
+
uploadId,
|
|
1253
|
+
...signal === void 0 ? {} : { signal }
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
function isPartNumber(value) {
|
|
1257
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 1 && value <= 1e4;
|
|
1258
|
+
}
|
|
1259
|
+
function isPartChecksum(value) {
|
|
1260
|
+
return typeof value === "string" && PART_CHECKSUM.test(value);
|
|
1261
|
+
}
|
|
1262
|
+
function isEtag(value) {
|
|
1263
|
+
return typeof value === "string" && value.length >= 1 && value.length <= 1024 && /^[\x20-\x7e]+$/.test(value);
|
|
1264
|
+
}
|
|
1265
|
+
function isMediaType(value) {
|
|
1266
|
+
return typeof value === "string" && value.length <= 255 && /^[a-z0-9](?:[a-z0-9!#$&^_.+-]{0,125}[a-z0-9])?\/[a-z0-9](?:[a-z0-9!#$&^_.+-]{0,125}[a-z0-9])?$/.test(value);
|
|
1267
|
+
}
|
|
1268
|
+
function isSearchQuery(value) {
|
|
1269
|
+
if (typeof value !== "string" || value.length === 0) return false;
|
|
1270
|
+
try {
|
|
1271
|
+
if (value.normalize("NFC") !== value) return false;
|
|
1272
|
+
let codePoints = 0;
|
|
1273
|
+
let bytes = 0;
|
|
1274
|
+
for (const character of value) {
|
|
1275
|
+
const point = character.codePointAt(0);
|
|
1276
|
+
if (point === void 0 || point <= 31 || point >= 127 && point <= 159 || point === 8232 || point === 8233 || point >= 55296 && point <= 57343) return false;
|
|
1277
|
+
codePoints += 1;
|
|
1278
|
+
bytes += point <= 127 ? 1 : point <= 2047 ? 2 : point <= 65535 ? 3 : 4;
|
|
1279
|
+
if (codePoints > 64 || bytes > 255) return false;
|
|
1280
|
+
}
|
|
1281
|
+
return true;
|
|
1282
|
+
} catch {
|
|
1283
|
+
return false;
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
705
1286
|
function isExpiry(value) {
|
|
706
1287
|
return value === null || isSafeInteger(value);
|
|
707
1288
|
}
|
|
@@ -733,6 +1314,12 @@ function filenameIsReserved(value) {
|
|
|
733
1314
|
function isSafeInteger(value) {
|
|
734
1315
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
735
1316
|
}
|
|
1317
|
+
function isOptionalHeaderValue(value) {
|
|
1318
|
+
return value === void 0 || typeof value === "string" && value.length <= 8192 && !value.split("").some((character) => {
|
|
1319
|
+
const code = character.charCodeAt(0);
|
|
1320
|
+
return code <= 31 || code === 127;
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
736
1323
|
//#endregion
|
|
737
1324
|
//#region ../../node_modules/.pnpm/openapi-fetch@0.17.0/node_modules/openapi-fetch/dist/index.mjs
|
|
738
1325
|
const PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
@@ -1188,7 +1775,7 @@ async function execute(runtime, signal, preconditionStatus, send, successStatuse
|
|
|
1188
1775
|
signal: operationSignal
|
|
1189
1776
|
});
|
|
1190
1777
|
if (!capturedResponse) throw new DriveError("network_error");
|
|
1191
|
-
return await parseResponse(capturedResponse, operationSignal, preconditionStatus, successStatuses, guard, allowsQuotaExceeded, allowedErrorCodes);
|
|
1778
|
+
return guard === null ? await parseNoContentResponse(capturedResponse, operationSignal, preconditionStatus, successStatuses, allowedErrorCodes) : await parseResponse(capturedResponse, operationSignal, preconditionStatus, successStatuses, guard, allowsQuotaExceeded, allowedErrorCodes);
|
|
1192
1779
|
} catch (error) {
|
|
1193
1780
|
if (operation.didTimeout()) throw new DriveError("timeout");
|
|
1194
1781
|
if (error instanceof DriveError) throw error;
|
|
@@ -1276,27 +1863,313 @@ const CURRENT_WORKSPACE_ERROR_CODES = Object.freeze([
|
|
|
1276
1863
|
"invalid_request",
|
|
1277
1864
|
"service_unavailable"
|
|
1278
1865
|
]);
|
|
1866
|
+
const GET_ITEM_ERROR_CODES = Object.freeze([
|
|
1867
|
+
"authentication_required",
|
|
1868
|
+
"identity_authority_unavailable",
|
|
1869
|
+
"permission_denied",
|
|
1870
|
+
"resource_not_found",
|
|
1871
|
+
"invalid_request",
|
|
1872
|
+
"precondition_failed",
|
|
1873
|
+
"service_unavailable"
|
|
1874
|
+
]);
|
|
1875
|
+
const SEARCH_WORKSPACE_ITEMS_ERROR_CODES = Object.freeze([
|
|
1876
|
+
"authentication_required",
|
|
1877
|
+
"identity_authority_unavailable",
|
|
1878
|
+
"permission_denied",
|
|
1879
|
+
"resource_not_found",
|
|
1880
|
+
"invalid_request",
|
|
1881
|
+
"invalid_pagination_cursor",
|
|
1882
|
+
"precondition_failed",
|
|
1883
|
+
"service_unavailable"
|
|
1884
|
+
]);
|
|
1885
|
+
const TRANSFER_ERROR_CODES = Object.freeze([
|
|
1886
|
+
"authentication_required",
|
|
1887
|
+
"identity_authority_unavailable",
|
|
1888
|
+
"permission_denied",
|
|
1889
|
+
"resource_not_found",
|
|
1890
|
+
"invalid_request",
|
|
1891
|
+
"precondition_failed",
|
|
1892
|
+
"upload_recovery_required",
|
|
1893
|
+
"service_unavailable"
|
|
1894
|
+
]);
|
|
1895
|
+
const STATUS_ERROR_CODES = Object.freeze([
|
|
1896
|
+
"authentication_required",
|
|
1897
|
+
"identity_authority_unavailable",
|
|
1898
|
+
"permission_denied",
|
|
1899
|
+
"resource_not_found",
|
|
1900
|
+
"invalid_request",
|
|
1901
|
+
"service_unavailable"
|
|
1902
|
+
]);
|
|
1903
|
+
const CREATE_UPLOAD_ERROR_CODES = Object.freeze([
|
|
1904
|
+
...TRANSFER_ERROR_CODES,
|
|
1905
|
+
"invalid_idempotency_key",
|
|
1906
|
+
"idempotency_conflict",
|
|
1907
|
+
"quota_exceeded"
|
|
1908
|
+
]);
|
|
1909
|
+
const COMPLETE_UPLOAD_ERROR_CODES = Object.freeze([...TRANSFER_ERROR_CODES, "invalid_idempotency_key"]);
|
|
1910
|
+
const LIFECYCLE_MUTATION_ERROR_CODES = Object.freeze([
|
|
1911
|
+
"authentication_required",
|
|
1912
|
+
"identity_authority_unavailable",
|
|
1913
|
+
"permission_denied",
|
|
1914
|
+
"resource_not_found",
|
|
1915
|
+
"invalid_request",
|
|
1916
|
+
"invalid_idempotency_key",
|
|
1917
|
+
"idempotency_conflict",
|
|
1918
|
+
"precondition_failed",
|
|
1919
|
+
"service_unavailable"
|
|
1920
|
+
]);
|
|
1921
|
+
const LIST_ITEM_VERSIONS_ERROR_CODES = Object.freeze([
|
|
1922
|
+
"authentication_required",
|
|
1923
|
+
"identity_authority_unavailable",
|
|
1924
|
+
"permission_denied",
|
|
1925
|
+
"resource_not_found",
|
|
1926
|
+
"invalid_request",
|
|
1927
|
+
"precondition_failed",
|
|
1928
|
+
"service_unavailable"
|
|
1929
|
+
]);
|
|
1930
|
+
const DOWNLOAD_ERROR_CODES = Object.freeze([
|
|
1931
|
+
"authentication_required",
|
|
1932
|
+
"identity_authority_unavailable",
|
|
1933
|
+
"permission_denied",
|
|
1934
|
+
"resource_not_found",
|
|
1935
|
+
"invalid_request",
|
|
1936
|
+
"invalid_idempotency_key",
|
|
1937
|
+
"idempotency_conflict",
|
|
1938
|
+
"precondition_failed",
|
|
1939
|
+
"range_not_satisfiable",
|
|
1940
|
+
"service_unavailable"
|
|
1941
|
+
]);
|
|
1279
1942
|
function createDriveClientInternal(config) {
|
|
1280
|
-
|
|
1943
|
+
return createDriveOperations(createClientRuntime(config));
|
|
1944
|
+
}
|
|
1945
|
+
function createDriveOperations(runtime) {
|
|
1281
1946
|
return Object.freeze({
|
|
1282
1947
|
getCurrentWorkspace: (input) => getCurrentWorkspace(runtime, input),
|
|
1948
|
+
getItem: (input) => getItem(runtime, input),
|
|
1949
|
+
searchWorkspaceItems: (input) => searchWorkspaceItems(runtime, input),
|
|
1283
1950
|
listFolderChildren: (input) => listFolderChildren(runtime, input),
|
|
1284
1951
|
createFolder: (input) => createFolder(runtime, input),
|
|
1952
|
+
updateItem: (input) => updateItem(runtime, input),
|
|
1953
|
+
trashItem: (input) => trashItem(runtime, input),
|
|
1954
|
+
restoreItem: (input) => restoreItem(runtime, input),
|
|
1955
|
+
deleteItem: (input) => deleteItem(runtime, input),
|
|
1956
|
+
listItemVersions: (input) => listItemVersions(runtime, input),
|
|
1957
|
+
getItemVersion: (input) => getItemVersion(runtime, input),
|
|
1958
|
+
restoreItemVersion: (input) => restoreItemVersion(runtime, input),
|
|
1959
|
+
createDownload: (input) => createDownload(runtime, input),
|
|
1960
|
+
downloadItem: (input) => downloadItem(runtime, input),
|
|
1285
1961
|
listItemPermissions: (input) => listItemPermissions(runtime, input),
|
|
1286
1962
|
readEffectiveItemPermissions: (input) => readEffectiveItemPermissions(runtime, input),
|
|
1287
1963
|
createItemPermission: (input) => createItemPermission(runtime, input),
|
|
1288
1964
|
updateItemPermission: (input) => updateItemPermission(runtime, input),
|
|
1289
1965
|
revokeItemPermission: (input) => revokeItemPermission(runtime, input),
|
|
1290
1966
|
createUpload: (input) => createUpload(runtime, input),
|
|
1967
|
+
getUploadStatus: (input) => getUploadStatus(runtime, input),
|
|
1968
|
+
createUploadPartDescriptor: (input) => createUploadPartDescriptor(runtime, input),
|
|
1969
|
+
recordUploadPart: (input) => recordUploadPart(runtime, input),
|
|
1970
|
+
completeUpload: (input) => completeUpload(runtime, input),
|
|
1291
1971
|
abortUpload: (input) => abortUpload(runtime, input)
|
|
1292
1972
|
});
|
|
1293
1973
|
}
|
|
1974
|
+
async function createDownload(runtime, input) {
|
|
1975
|
+
const validated = validateCreateDownloadInput(input);
|
|
1976
|
+
return execute(runtime, validated.signal, 412, (api, requestOptions) => api.POST("/api/v1/workspaces/{workspaceId}/items/{itemId}/downloads", {
|
|
1977
|
+
...operationOptions("createDownload", { params: {
|
|
1978
|
+
path: {
|
|
1979
|
+
workspaceId: validated.workspaceId,
|
|
1980
|
+
itemId: validated.itemId
|
|
1981
|
+
},
|
|
1982
|
+
query: validated.versionId === void 0 ? {} : { versionId: validated.versionId },
|
|
1983
|
+
header: {
|
|
1984
|
+
"Idempotency-Key": validated.idempotencyKey,
|
|
1985
|
+
"Download-Method": validated.method,
|
|
1986
|
+
...validated.range === void 0 ? {} : { Range: validated.range },
|
|
1987
|
+
...validated.ifMatch === void 0 ? {} : { "If-Match": validated.ifMatch },
|
|
1988
|
+
...validated.ifNoneMatch === void 0 ? {} : { "If-None-Match": validated.ifNoneMatch },
|
|
1989
|
+
...validated.ifRange === void 0 ? {} : { "If-Range": validated.ifRange }
|
|
1990
|
+
}
|
|
1991
|
+
} }),
|
|
1992
|
+
...requestOptions
|
|
1993
|
+
}), [
|
|
1994
|
+
200,
|
|
1995
|
+
202,
|
|
1996
|
+
304
|
|
1997
|
+
], (value, status) => status === 200 ? isManagedDownloadDescriptor(value) : status === 202 ? isManagedDownloadRestorePending(value) : value === void 0, false, DOWNLOAD_ERROR_CODES);
|
|
1998
|
+
}
|
|
1999
|
+
async function downloadItem(runtime, input) {
|
|
2000
|
+
const validated = validateCreateDownloadInput(input);
|
|
2001
|
+
const created = await createDownload(runtime, input);
|
|
2002
|
+
if (created.status === 202 || created.status === 304) return created;
|
|
2003
|
+
const descriptor = created.data;
|
|
2004
|
+
if (descriptor.expiresAtEpochMilliseconds <= Date.now()) throw new DriveError("invalid_response");
|
|
2005
|
+
const operation = createOperationSignal(validated.signal, runtime.timeoutMilliseconds);
|
|
2006
|
+
try {
|
|
2007
|
+
const response = await raceWithAbort(runtime.fetchImplementation(directDownloadRequest(descriptor, operation.signal)), operation.signal);
|
|
2008
|
+
if (!responseMatchesDownloadDescriptor(response, descriptor)) {
|
|
2009
|
+
await response.body?.cancel().catch(() => void 0);
|
|
2010
|
+
throw new DriveError("invalid_response");
|
|
2011
|
+
}
|
|
2012
|
+
const responseHeaders = downloadResponseHeaders(descriptor);
|
|
2013
|
+
if (descriptor.method === "HEAD") {
|
|
2014
|
+
await response.body?.cancel().catch(() => void 0);
|
|
2015
|
+
operation.dispose();
|
|
2016
|
+
return new Response(null, {
|
|
2017
|
+
status: response.status,
|
|
2018
|
+
headers: responseHeaders
|
|
2019
|
+
});
|
|
2020
|
+
}
|
|
2021
|
+
if (!response.body) {
|
|
2022
|
+
operation.dispose();
|
|
2023
|
+
if (descriptor.response.contentLength !== 0) throw new DriveError("invalid_response");
|
|
2024
|
+
return new Response(null, {
|
|
2025
|
+
status: response.status,
|
|
2026
|
+
headers: responseHeaders
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
operation.dispose();
|
|
2030
|
+
return new Response(streamWithOperationLifetime(response.body, descriptor.response.contentLength, validated.signal), {
|
|
2031
|
+
status: response.status,
|
|
2032
|
+
headers: responseHeaders
|
|
2033
|
+
});
|
|
2034
|
+
} catch (error) {
|
|
2035
|
+
operation.dispose();
|
|
2036
|
+
if (operation.didTimeout()) throw new DriveError("timeout");
|
|
2037
|
+
if (error instanceof DriveError) throw error;
|
|
2038
|
+
throw operation.signal.aborted ? new DriveError(operation.didTimeout() ? "timeout" : "aborted") : new DriveError("network_error");
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
function downloadResponseHeaders(descriptor) {
|
|
2042
|
+
const expected = descriptor.response;
|
|
2043
|
+
const headers = new Headers();
|
|
2044
|
+
headers.set("accept-ranges", expected.acceptRanges);
|
|
2045
|
+
headers.set("content-disposition", expected.contentDisposition);
|
|
2046
|
+
headers.set("content-length", String(expected.contentLength));
|
|
2047
|
+
headers.set("content-type", expected.contentType);
|
|
2048
|
+
headers.set("etag", expected.etag);
|
|
2049
|
+
if (expected.contentRange === null) headers.delete("content-range");
|
|
2050
|
+
else headers.set("content-range", expected.contentRange);
|
|
2051
|
+
return headers;
|
|
2052
|
+
}
|
|
2053
|
+
function directDownloadRequest(descriptor, signal) {
|
|
2054
|
+
const base = {
|
|
2055
|
+
method: descriptor.method,
|
|
2056
|
+
headers: descriptor.headers,
|
|
2057
|
+
redirect: "manual",
|
|
2058
|
+
signal
|
|
2059
|
+
};
|
|
2060
|
+
try {
|
|
2061
|
+
return new Request(descriptor.url, {
|
|
2062
|
+
...base,
|
|
2063
|
+
cache: "no-store",
|
|
2064
|
+
credentials: "omit",
|
|
2065
|
+
referrerPolicy: "no-referrer"
|
|
2066
|
+
});
|
|
2067
|
+
} catch {
|
|
2068
|
+
try {
|
|
2069
|
+
return new Request(descriptor.url, {
|
|
2070
|
+
...base,
|
|
2071
|
+
credentials: "omit",
|
|
2072
|
+
referrerPolicy: "no-referrer"
|
|
2073
|
+
});
|
|
2074
|
+
} catch {
|
|
2075
|
+
return new Request(descriptor.url, {
|
|
2076
|
+
...base,
|
|
2077
|
+
credentials: "omit"
|
|
2078
|
+
});
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
function responseMatchesDownloadDescriptor(response, descriptor) {
|
|
2083
|
+
const expected = descriptor.response;
|
|
2084
|
+
const encoding = response.headers.get("content-encoding");
|
|
2085
|
+
return response.status === expected.status && response.headers.get("etag") === expected.etag && response.headers.get("content-length") === String(expected.contentLength) && (encoding === null || encoding === "identity") && (expected.contentRange === null ? response.headers.get("content-range") === null : response.headers.get("content-range") === expected.contentRange);
|
|
2086
|
+
}
|
|
2087
|
+
function streamWithOperationLifetime(source, expectedLength, signal) {
|
|
2088
|
+
const reader = source.getReader();
|
|
2089
|
+
let receivedLength = 0;
|
|
2090
|
+
let finished = false;
|
|
2091
|
+
let removeAbort = () => {};
|
|
2092
|
+
return new ReadableStream({
|
|
2093
|
+
start(controller) {
|
|
2094
|
+
if (!signal) return;
|
|
2095
|
+
const onAbort = () => {
|
|
2096
|
+
if (finished) return;
|
|
2097
|
+
finished = true;
|
|
2098
|
+
removeAbort();
|
|
2099
|
+
reader.cancel().catch(() => void 0);
|
|
2100
|
+
controller.error(new DriveError("aborted"));
|
|
2101
|
+
};
|
|
2102
|
+
if (signal.aborted) onAbort();
|
|
2103
|
+
else {
|
|
2104
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
2105
|
+
removeAbort = () => signal.removeEventListener("abort", onAbort);
|
|
2106
|
+
}
|
|
2107
|
+
},
|
|
2108
|
+
async pull(controller) {
|
|
2109
|
+
if (finished) return;
|
|
2110
|
+
try {
|
|
2111
|
+
const chunk = await reader.read();
|
|
2112
|
+
if (finished) return;
|
|
2113
|
+
if (chunk.done) {
|
|
2114
|
+
finished = true;
|
|
2115
|
+
removeAbort();
|
|
2116
|
+
reader.releaseLock();
|
|
2117
|
+
if (receivedLength === expectedLength) controller.close();
|
|
2118
|
+
else controller.error(new DriveError("invalid_response"));
|
|
2119
|
+
} else {
|
|
2120
|
+
receivedLength += chunk.value.byteLength;
|
|
2121
|
+
if (!Number.isSafeInteger(receivedLength) || receivedLength > expectedLength) {
|
|
2122
|
+
finished = true;
|
|
2123
|
+
removeAbort();
|
|
2124
|
+
await reader.cancel().catch(() => void 0);
|
|
2125
|
+
controller.error(new DriveError("invalid_response"));
|
|
2126
|
+
return;
|
|
2127
|
+
}
|
|
2128
|
+
controller.enqueue(chunk.value);
|
|
2129
|
+
}
|
|
2130
|
+
} catch (error) {
|
|
2131
|
+
if (finished) return;
|
|
2132
|
+
finished = true;
|
|
2133
|
+
removeAbort();
|
|
2134
|
+
await reader.cancel().catch(() => void 0);
|
|
2135
|
+
controller.error(error instanceof DriveError ? error : signal?.aborted ? new DriveError("aborted") : new DriveError("network_error"));
|
|
2136
|
+
}
|
|
2137
|
+
},
|
|
2138
|
+
async cancel(reason) {
|
|
2139
|
+
if (finished) return;
|
|
2140
|
+
finished = true;
|
|
2141
|
+
removeAbort();
|
|
2142
|
+
await reader.cancel(reason).catch(() => void 0);
|
|
2143
|
+
}
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
1294
2146
|
async function getCurrentWorkspace(runtime, input) {
|
|
1295
2147
|
return execute(runtime, validateCurrentWorkspaceInput(input).signal, null, (api, requestOptions) => api.GET("/api/v1/workspaces/current", {
|
|
1296
2148
|
...operationOptions("getCurrentWorkspace", { params: {} }),
|
|
1297
2149
|
...requestOptions
|
|
1298
2150
|
}), [200], isCurrentWorkspace, false, CURRENT_WORKSPACE_ERROR_CODES);
|
|
1299
2151
|
}
|
|
2152
|
+
async function getItem(runtime, input) {
|
|
2153
|
+
const validated = validateResourceInput(input);
|
|
2154
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.GET("/api/v1/workspaces/{workspaceId}/items/{itemId}", {
|
|
2155
|
+
...operationOptions("getItem", { params: { path: resourcePath(validated) } }),
|
|
2156
|
+
...requestOptions
|
|
2157
|
+
}), [200], (value, _status, headers) => isManagedItemMetadata(value, validated.workspaceId, validated.itemId) && itemEtagMatchesRevision(headers, value.revision), false, GET_ITEM_ERROR_CODES);
|
|
2158
|
+
}
|
|
2159
|
+
async function searchWorkspaceItems(runtime, input) {
|
|
2160
|
+
const validated = validateSearchWorkspaceItemsInput(input);
|
|
2161
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.GET("/api/v1/workspaces/{workspaceId}/search", {
|
|
2162
|
+
...operationOptions("searchWorkspaceItems", { params: {
|
|
2163
|
+
path: { workspaceId: validated.workspaceId },
|
|
2164
|
+
query: {
|
|
2165
|
+
query: validated.query,
|
|
2166
|
+
...validated.limit === void 0 ? {} : { limit: validated.limit },
|
|
2167
|
+
...validated.cursor === void 0 ? {} : { cursor: validated.cursor }
|
|
2168
|
+
}
|
|
2169
|
+
} }),
|
|
2170
|
+
...requestOptions
|
|
2171
|
+
}), [200], (value) => isWorkspaceItemSearchPage(value, validated.workspaceId, validated.query, validated.limit ?? 50), false, SEARCH_WORKSPACE_ITEMS_ERROR_CODES);
|
|
2172
|
+
}
|
|
1300
2173
|
async function listFolderChildren(runtime, input) {
|
|
1301
2174
|
const validated = validatePageInput(input);
|
|
1302
2175
|
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.GET("/api/v1/workspaces/{workspaceId}/items/{itemId}/children", {
|
|
@@ -1320,6 +2193,100 @@ async function createFolder(runtime, input) {
|
|
|
1320
2193
|
...requestOptions
|
|
1321
2194
|
}), [200, 201], (value) => isFolderItem(value) && value.workspaceId === validated.workspaceId && value.parentItemId === validated.itemId && value.kind === "folder" && value.name === validated.name);
|
|
1322
2195
|
}
|
|
2196
|
+
async function updateItem(runtime, input) {
|
|
2197
|
+
const validated = validateUpdateItemInput(input);
|
|
2198
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.PATCH("/api/v1/workspaces/{workspaceId}/items/{itemId}", {
|
|
2199
|
+
...operationOptions("updateItem", {
|
|
2200
|
+
params: {
|
|
2201
|
+
path: resourcePath(validated),
|
|
2202
|
+
header: {
|
|
2203
|
+
"Idempotency-Key": validated.idempotencyKey,
|
|
2204
|
+
"If-Match": validated.ifMatch
|
|
2205
|
+
}
|
|
2206
|
+
},
|
|
2207
|
+
body: {
|
|
2208
|
+
name: validated.name,
|
|
2209
|
+
parentItemId: validated.parentItemId
|
|
2210
|
+
}
|
|
2211
|
+
}),
|
|
2212
|
+
...requestOptions
|
|
2213
|
+
}), [200], (value, _status, headers) => isManagedLifecycleItem(value, validated.workspaceId, validated.itemId, "active") && value.name === validated.name && value.parentItemId === validated.parentItemId && itemEtagMatchesRevision(headers, value.revision), false, LIFECYCLE_MUTATION_ERROR_CODES);
|
|
2214
|
+
}
|
|
2215
|
+
async function trashItem(runtime, input) {
|
|
2216
|
+
const validated = validateLifecycleMutationInput(input);
|
|
2217
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.POST("/api/v1/workspaces/{workspaceId}/items/{itemId}/trash", {
|
|
2218
|
+
...operationOptions("trashItem", { params: {
|
|
2219
|
+
path: resourcePath(validated),
|
|
2220
|
+
header: {
|
|
2221
|
+
"Idempotency-Key": validated.idempotencyKey,
|
|
2222
|
+
"If-Match": validated.ifMatch
|
|
2223
|
+
}
|
|
2224
|
+
} }),
|
|
2225
|
+
...requestOptions
|
|
2226
|
+
}), [200], (value, _status, headers) => isManagedLifecycleItem(value, validated.workspaceId, validated.itemId, "trashed") && itemEtagMatchesRevision(headers, value.revision), false, LIFECYCLE_MUTATION_ERROR_CODES);
|
|
2227
|
+
}
|
|
2228
|
+
async function restoreItem(runtime, input) {
|
|
2229
|
+
const validated = validateLifecycleMutationInput(input);
|
|
2230
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.POST("/api/v1/workspaces/{workspaceId}/items/{itemId}/restore", {
|
|
2231
|
+
...operationOptions("restoreItem", { params: {
|
|
2232
|
+
path: resourcePath(validated),
|
|
2233
|
+
header: {
|
|
2234
|
+
"Idempotency-Key": validated.idempotencyKey,
|
|
2235
|
+
"If-Match": validated.ifMatch
|
|
2236
|
+
}
|
|
2237
|
+
} }),
|
|
2238
|
+
...requestOptions
|
|
2239
|
+
}), [200], (value, _status, headers) => isManagedLifecycleItem(value, validated.workspaceId, validated.itemId, "active") && itemEtagMatchesRevision(headers, value.revision), false, LIFECYCLE_MUTATION_ERROR_CODES);
|
|
2240
|
+
}
|
|
2241
|
+
async function deleteItem(runtime, input) {
|
|
2242
|
+
const validated = validateLifecycleMutationInput(input);
|
|
2243
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.DELETE("/api/v1/workspaces/{workspaceId}/items/{itemId}", {
|
|
2244
|
+
...operationOptions("deleteItem", { params: {
|
|
2245
|
+
path: resourcePath(validated),
|
|
2246
|
+
header: {
|
|
2247
|
+
"Idempotency-Key": validated.idempotencyKey,
|
|
2248
|
+
"If-Match": validated.ifMatch
|
|
2249
|
+
}
|
|
2250
|
+
} }),
|
|
2251
|
+
...requestOptions
|
|
2252
|
+
}), [200, 202], (value, _status, headers) => isManagedLifecycleItem(value, validated.workspaceId, validated.itemId, "deleting") && itemEtagMatchesRevision(headers, value.revision), false, LIFECYCLE_MUTATION_ERROR_CODES);
|
|
2253
|
+
}
|
|
2254
|
+
async function listItemVersions(runtime, input) {
|
|
2255
|
+
const validated = validatePageInput(input);
|
|
2256
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.GET("/api/v1/workspaces/{workspaceId}/items/{itemId}/versions", {
|
|
2257
|
+
...operationOptions("listItemVersions", { params: {
|
|
2258
|
+
path: resourcePath(validated),
|
|
2259
|
+
query: pageQuery(validated)
|
|
2260
|
+
} }),
|
|
2261
|
+
...requestOptions
|
|
2262
|
+
}), [200], (value) => isManagedItemVersionPage(value, validated.limit ?? 50), false, LIST_ITEM_VERSIONS_ERROR_CODES);
|
|
2263
|
+
}
|
|
2264
|
+
async function getItemVersion(runtime, input) {
|
|
2265
|
+
const validated = validateItemVersionInput(input);
|
|
2266
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.GET("/api/v1/workspaces/{workspaceId}/items/{itemId}/versions/{versionId}", {
|
|
2267
|
+
...operationOptions("getItemVersion", { params: { path: {
|
|
2268
|
+
...resourcePath(validated),
|
|
2269
|
+
versionId: validated.versionId
|
|
2270
|
+
} } }),
|
|
2271
|
+
...requestOptions
|
|
2272
|
+
}), [200], (value) => isManagedItemVersionResource(value, validated.workspaceId, validated.itemId, validated.versionId), false, LIST_ITEM_VERSIONS_ERROR_CODES);
|
|
2273
|
+
}
|
|
2274
|
+
async function restoreItemVersion(runtime, input) {
|
|
2275
|
+
const validated = validateRestoreItemVersionInput(input);
|
|
2276
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.POST("/api/v1/workspaces/{workspaceId}/items/{itemId}/versions/{versionId}/restore", {
|
|
2277
|
+
...operationOptions("restoreItemVersion", { params: {
|
|
2278
|
+
path: {
|
|
2279
|
+
...resourcePath(validated),
|
|
2280
|
+
versionId: validated.versionId
|
|
2281
|
+
},
|
|
2282
|
+
header: {
|
|
2283
|
+
"Idempotency-Key": validated.idempotencyKey,
|
|
2284
|
+
"If-Match": validated.ifMatch
|
|
2285
|
+
}
|
|
2286
|
+
} }),
|
|
2287
|
+
...requestOptions
|
|
2288
|
+
}), [200], (value, _status, headers) => isManagedItemVersionRestoreResult(value, validated.versionId) && itemEtagMatchesRevision(headers, value.itemRevision), false, LIFECYCLE_MUTATION_ERROR_CODES);
|
|
2289
|
+
}
|
|
1323
2290
|
async function listItemPermissions(runtime, input) {
|
|
1324
2291
|
const validated = validatePageInput(input);
|
|
1325
2292
|
return execute(runtime, validated.signal, 412, (api, requestOptions) => api.GET("/api/v1/workspaces/{workspaceId}/items/{itemId}/permissions", {
|
|
@@ -1405,11 +2372,81 @@ async function createUpload(runtime, input) {
|
|
|
1405
2372
|
},
|
|
1406
2373
|
body: {
|
|
1407
2374
|
parentItemId: validated.parentItemId,
|
|
1408
|
-
expectedByteLength: validated.expectedByteLength
|
|
2375
|
+
expectedByteLength: validated.expectedByteLength,
|
|
2376
|
+
displayFilename: validated.displayFilename,
|
|
2377
|
+
mediaType: validated.mediaType,
|
|
2378
|
+
callerDeclaredContentDigest: validated.callerDeclaredContentDigest,
|
|
2379
|
+
protectionClassification: validated.protectionClassification
|
|
1409
2380
|
}
|
|
1410
2381
|
}),
|
|
1411
2382
|
...requestOptions
|
|
1412
|
-
}), [200, 201], (value) =>
|
|
2383
|
+
}), [200, 201], (value) => isUploadSession(value, validated.expectedByteLength), true, CREATE_UPLOAD_ERROR_CODES);
|
|
2384
|
+
}
|
|
2385
|
+
async function getUploadStatus(runtime, input) {
|
|
2386
|
+
const validated = validateGetUploadStatusInput(input);
|
|
2387
|
+
const afterPartNumber = validated.afterPartNumber ?? 0;
|
|
2388
|
+
const limit = validated.limit ?? 100;
|
|
2389
|
+
return execute(runtime, validated.signal, null, (api, requestOptions) => api.GET("/api/v1/workspaces/{workspaceId}/uploads/{uploadId}", {
|
|
2390
|
+
...operationOptions("getUploadStatus", { params: {
|
|
2391
|
+
path: {
|
|
2392
|
+
workspaceId: validated.workspaceId,
|
|
2393
|
+
uploadId: validated.uploadId
|
|
2394
|
+
},
|
|
2395
|
+
query: {
|
|
2396
|
+
...validated.afterPartNumber === void 0 ? {} : { afterPartNumber: String(validated.afterPartNumber) },
|
|
2397
|
+
...validated.limit === void 0 ? {} : { limit: String(validated.limit) }
|
|
2398
|
+
}
|
|
2399
|
+
} }),
|
|
2400
|
+
...requestOptions
|
|
2401
|
+
}), [200], (value) => isUploadStatus(value, afterPartNumber, limit), false, STATUS_ERROR_CODES);
|
|
2402
|
+
}
|
|
2403
|
+
async function createUploadPartDescriptor(runtime, input) {
|
|
2404
|
+
const validated = validateCreateUploadPartDescriptorInput(input);
|
|
2405
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.POST("/api/v1/workspaces/{workspaceId}/uploads/{uploadId}/parts", {
|
|
2406
|
+
...operationOptions("createUploadPartDescriptor", {
|
|
2407
|
+
params: { path: {
|
|
2408
|
+
workspaceId: validated.workspaceId,
|
|
2409
|
+
uploadId: validated.uploadId
|
|
2410
|
+
} },
|
|
2411
|
+
body: {
|
|
2412
|
+
partNumber: validated.partNumber,
|
|
2413
|
+
checksumSha256: validated.checksumSha256
|
|
2414
|
+
}
|
|
2415
|
+
}),
|
|
2416
|
+
...requestOptions
|
|
2417
|
+
}), [200], (value) => isUploadPartDescriptor(value, validated.partNumber, validated.checksumSha256, new URL(runtime.baseUrl).protocol === "http:"), false, TRANSFER_ERROR_CODES);
|
|
2418
|
+
}
|
|
2419
|
+
async function recordUploadPart(runtime, input) {
|
|
2420
|
+
const validated = validateRecordUploadPartInput(input);
|
|
2421
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.POST("/api/v1/workspaces/{workspaceId}/uploads/{uploadId}/parts/{partNumber}", {
|
|
2422
|
+
...operationOptions("recordUploadPart", {
|
|
2423
|
+
params: { path: {
|
|
2424
|
+
workspaceId: validated.workspaceId,
|
|
2425
|
+
uploadId: validated.uploadId,
|
|
2426
|
+
partNumber: String(validated.partNumber)
|
|
2427
|
+
} },
|
|
2428
|
+
body: {
|
|
2429
|
+
expectedUploadRevision: validated.expectedUploadRevision,
|
|
2430
|
+
byteLength: validated.byteLength,
|
|
2431
|
+
etag: validated.etag,
|
|
2432
|
+
checksumSha256: validated.checksumSha256
|
|
2433
|
+
}
|
|
2434
|
+
}),
|
|
2435
|
+
...requestOptions
|
|
2436
|
+
}), [200], (value) => isUploadPartResult(value, validated.partNumber, validated.expectedUploadRevision), false, TRANSFER_ERROR_CODES);
|
|
2437
|
+
}
|
|
2438
|
+
async function completeUpload(runtime, input) {
|
|
2439
|
+
const validated = validateCompleteUploadInput(input);
|
|
2440
|
+
return execute(runtime, validated.signal, 409, (api, requestOptions) => api.POST("/api/v1/workspaces/{workspaceId}/uploads/{uploadId}/complete", {
|
|
2441
|
+
...operationOptions("completeUpload", { params: {
|
|
2442
|
+
path: {
|
|
2443
|
+
workspaceId: validated.workspaceId,
|
|
2444
|
+
uploadId: validated.uploadId
|
|
2445
|
+
},
|
|
2446
|
+
header: { "Idempotency-Key": validated.idempotencyKey }
|
|
2447
|
+
} }),
|
|
2448
|
+
...requestOptions
|
|
2449
|
+
}), [200], (value) => isReadyUpload(value, { uploadId: validated.uploadId }), false, COMPLETE_UPLOAD_ERROR_CODES);
|
|
1413
2450
|
}
|
|
1414
2451
|
async function abortUpload(runtime, input) {
|
|
1415
2452
|
const validated = validateAbortUploadInput(input);
|
|
@@ -1419,7 +2456,7 @@ async function abortUpload(runtime, input) {
|
|
|
1419
2456
|
uploadId: validated.uploadId
|
|
1420
2457
|
} } }),
|
|
1421
2458
|
...requestOptions
|
|
1422
|
-
}), [
|
|
2459
|
+
}), [204], null, false, TRANSFER_ERROR_CODES);
|
|
1423
2460
|
}
|
|
1424
2461
|
//#endregion
|
|
1425
2462
|
//#region src/server.ts
|