@oddington/sdk 0.1.8 → 0.1.10
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/README.md +50 -9
- package/dist/browser.js +319 -101
- package/dist/index.js +428 -114
- package/dist/types/packages/sdk/src/public.d.ts +1 -1
- package/dist/types/shared/data-contract.d.ts +26 -0
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -717,31 +717,65 @@ var DataOperationError = class extends Error {
|
|
|
717
717
|
|
|
718
718
|
var invalid = () => {
|
|
719
719
|
throw new DataOperationError("invalid_query");
|
|
720
|
-
},
|
|
720
|
+
}, historyText = (value) => typeof value == "string" && !/[\u0000\uD800-\uDFFF]/u.test(value);
|
|
721
|
+
function historyVersion(value) {
|
|
722
|
+
return historyText(value) && value.length > 0 && new TextEncoder().encode(value).length <= 1024 && !/[\u0000-\u001f\u007f-\u009f]/.test(value) && !/^[0-9a-f]{40}$/i.test(value);
|
|
723
|
+
}
|
|
724
|
+
function historyProperties(value) {
|
|
725
|
+
if (!value || typeof value != "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return invalid();
|
|
726
|
+
let descriptors = Object.getOwnPropertyDescriptors(value);
|
|
727
|
+
return Reflect.ownKeys(value).some((key) => typeof key != "string" || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value")) ? invalid() : descriptors;
|
|
728
|
+
}
|
|
729
|
+
function captureHistoryListOptions(value) {
|
|
730
|
+
if (value === void 0) return {};
|
|
731
|
+
let descriptors = historyProperties(value), result2 = {};
|
|
732
|
+
if (Object.keys(descriptors).some((key) => !["limit", "before"].includes(key))) return invalid();
|
|
733
|
+
if (Object.hasOwn(descriptors, "limit")) {
|
|
734
|
+
let limit = descriptors.limit.value;
|
|
735
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 100) return invalid();
|
|
736
|
+
result2.limit = limit;
|
|
737
|
+
}
|
|
738
|
+
if (Object.hasOwn(descriptors, "before")) {
|
|
739
|
+
let before = descriptors.before.value;
|
|
740
|
+
if (!historyVersion(before)) return invalid();
|
|
741
|
+
result2.before = before;
|
|
742
|
+
}
|
|
743
|
+
return result2;
|
|
744
|
+
}
|
|
745
|
+
function captureHistoryInstant(value) {
|
|
746
|
+
if (!historyText(value) || value.length > 1024) return invalid();
|
|
747
|
+
let match = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.\d+)?([Zz]|([+-])(\d{2}):(\d{2}))$/.exec(value);
|
|
748
|
+
if (!match) return invalid();
|
|
749
|
+
let [year, month, day, hour, minute, second] = match.slice(1, 7).map(Number), days = new Date(Date.UTC(year, month, 0));
|
|
750
|
+
return days.setUTCFullYear(year), year < 1 || month < 1 || month > 12 || day < 1 || day > days.getUTCDate() || hour > 23 || minute > 59 || second > 59 || Number(match[9] ?? 0) > 23 || Number(match[10] ?? 0) > 59 ? invalid() : value;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
var invalid2 = () => {
|
|
754
|
+
throw new DataOperationError("invalid_query");
|
|
755
|
+
};
|
|
721
756
|
function captureRecordsSearchInput(query, options) {
|
|
722
|
-
if (!
|
|
757
|
+
if (!historyText(query)) return invalid2();
|
|
723
758
|
let length = [...query.trim()].length;
|
|
724
|
-
if (length < 1 || length > 256) return
|
|
759
|
+
if (length < 1 || length > 256) return invalid2();
|
|
725
760
|
if (options === void 0) return { query };
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
if (Reflect.ownKeys(options).some((key) => typeof key != "string" || !["collections", "limit"].includes(key) || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value"))) return invalid();
|
|
761
|
+
let descriptors = historyProperties(options);
|
|
762
|
+
if (Object.keys(descriptors).some((key) => !["collections", "limit"].includes(key))) return invalid2();
|
|
729
763
|
let captured = {};
|
|
730
764
|
if (Object.hasOwn(descriptors, "collections")) {
|
|
731
765
|
let supplied = descriptors.collections.value;
|
|
732
|
-
if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1) return
|
|
766
|
+
if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1) return invalid2();
|
|
733
767
|
let collections = [];
|
|
734
768
|
for (let index = 0; index < supplied.length; index++) {
|
|
735
769
|
let descriptor2 = Object.getOwnPropertyDescriptor(supplied, String(index));
|
|
736
|
-
if (!descriptor2?.enumerable || !Object.hasOwn(descriptor2, "value") || !
|
|
770
|
+
if (!descriptor2?.enumerable || !Object.hasOwn(descriptor2, "value") || !historyText(descriptor2.value)) return invalid2();
|
|
737
771
|
collections.push(descriptor2.value);
|
|
738
772
|
}
|
|
739
|
-
if (new Set(collections).size !== collections.length) return
|
|
773
|
+
if (new Set(collections).size !== collections.length) return invalid2();
|
|
740
774
|
captured.collections = collections;
|
|
741
775
|
}
|
|
742
776
|
if (Object.hasOwn(descriptors, "limit")) {
|
|
743
777
|
let supplied = descriptors.limit.value;
|
|
744
|
-
if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100) return
|
|
778
|
+
if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100) return invalid2();
|
|
745
779
|
captured.limit = supplied;
|
|
746
780
|
}
|
|
747
781
|
return { query, options: captured };
|
|
@@ -842,42 +876,42 @@ var FileOperationError = class extends Error {
|
|
|
842
876
|
retryable;
|
|
843
877
|
}, FILE_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/, FILE_ORIGINAL_MAX_BYTES = 5 * 1024 ** 3;
|
|
844
878
|
function parseFileDescriptor(value) {
|
|
845
|
-
let
|
|
879
|
+
let invalid4 = () => {
|
|
846
880
|
throw new FileOperationError("unavailable", 503, !0);
|
|
847
881
|
};
|
|
848
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
882
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid4();
|
|
849
883
|
let f = value;
|
|
850
|
-
if (Object.keys(f).sort().join(",") !== "details,enrichments,id,mediaType,name,path,sha256,size" || typeof f.id != "string" || !FILE_ID_PATTERN.test(f.id) || !safeFileName(f.name) || !safeFilePath(f.path) || !Number.isSafeInteger(f.size) || f.size < 0 || f.size > FILE_ORIGINAL_MAX_BYTES || typeof f.sha256 != "string" || !/^[0-9a-f]{64}$/.test(f.sha256) || !f.enrichments || typeof f.enrichments != "object" || Array.isArray(f.enrichments) || !f.details || typeof f.details != "object" || Array.isArray(f.details)) return
|
|
884
|
+
if (Object.keys(f).sort().join(",") !== "details,enrichments,id,mediaType,name,path,sha256,size" || typeof f.id != "string" || !FILE_ID_PATTERN.test(f.id) || !safeFileName(f.name) || !safeFilePath(f.path) || !Number.isSafeInteger(f.size) || f.size < 0 || f.size > FILE_ORIGINAL_MAX_BYTES || typeof f.sha256 != "string" || !/^[0-9a-f]{64}$/.test(f.sha256) || !f.enrichments || typeof f.enrichments != "object" || Array.isArray(f.enrichments) || !f.details || typeof f.details != "object" || Array.isArray(f.details)) return invalid4();
|
|
851
885
|
let d = f.details;
|
|
852
886
|
if (d.kind === "other") {
|
|
853
|
-
if (Object.keys(d).length !== 1 || f.mediaType !== "application/octet-stream") return
|
|
887
|
+
if (Object.keys(d).length !== 1 || f.mediaType !== "application/octet-stream") return invalid4();
|
|
854
888
|
} else if (d.kind === "csv") {
|
|
855
|
-
if (Object.keys(d).sort().join(",") !== "dataRows,delimiter,encoding,headerRow,kind" || f.mediaType !== "text/csv" || !["utf-8", "windows-1252"].includes(d.encoding) || ![",", ";", " "].includes(d.delimiter) || !Number.isSafeInteger(d.headerRow) || d.headerRow < 1 || !Number.isSafeInteger(d.dataRows) || d.dataRows < 0) return
|
|
856
|
-
} else return
|
|
889
|
+
if (Object.keys(d).sort().join(",") !== "dataRows,delimiter,encoding,headerRow,kind" || f.mediaType !== "text/csv" || !["utf-8", "windows-1252"].includes(d.encoding) || ![",", ";", " "].includes(d.delimiter) || !Number.isSafeInteger(d.headerRow) || d.headerRow < 1 || !Number.isSafeInteger(d.dataRows) || d.dataRows < 0) return invalid4();
|
|
890
|
+
} else return invalid4();
|
|
857
891
|
for (let [name, descriptor2] of Object.entries(f.enrichments)) {
|
|
858
|
-
if (!safeEnrichmentName(name)) return
|
|
892
|
+
if (!safeEnrichmentName(name)) return invalid4();
|
|
859
893
|
parseEnrichmentDescriptor(descriptor2);
|
|
860
894
|
}
|
|
861
|
-
return new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024 ?
|
|
895
|
+
return new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024 ? invalid4() : f;
|
|
862
896
|
}
|
|
863
897
|
function parseEnrichmentDescriptor(value) {
|
|
864
|
-
let
|
|
898
|
+
let invalid4 = () => {
|
|
865
899
|
throw new FileOperationError("unavailable", 503, !0);
|
|
866
900
|
};
|
|
867
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
901
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid4();
|
|
868
902
|
let d = value;
|
|
869
|
-
return Object.keys(d).sort().join(",") !== "mediaType,sha256,size" || !["application/octet-stream", "text/plain", "text/markdown", "application/json"].includes(d.mediaType) || !Number.isSafeInteger(d.size) || d.size < 0 || d.size > 16 * 1024 * 1024 || typeof d.sha256 != "string" || !/^[0-9a-f]{64}$/.test(d.sha256) ?
|
|
903
|
+
return Object.keys(d).sort().join(",") !== "mediaType,sha256,size" || !["application/octet-stream", "text/plain", "text/markdown", "application/json"].includes(d.mediaType) || !Number.isSafeInteger(d.size) || d.size < 0 || d.size > 16 * 1024 * 1024 || typeof d.sha256 != "string" || !/^[0-9a-f]{64}$/.test(d.sha256) ? invalid4() : d;
|
|
870
904
|
}
|
|
871
905
|
function safeEnrichmentName(value) {
|
|
872
906
|
return safeFileName(value) && !/^original(?:\.|$)/i.test(value);
|
|
873
907
|
}
|
|
874
908
|
function parseFileEnrichMetadata(value, maxBytes) {
|
|
875
|
-
let
|
|
909
|
+
let invalid4 = () => {
|
|
876
910
|
throw new FileOperationError("invalid_input", 400);
|
|
877
911
|
};
|
|
878
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
912
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid4();
|
|
879
913
|
let d = value;
|
|
880
|
-
if (Object.keys(d).some((key) => !["name", "size", "mediaType", "replace"].includes(key)) || !safeEnrichmentName(d.name) || !Number.isSafeInteger(d.size) || d.size < 0 || d.mediaType !== void 0 && (typeof d.mediaType != "string" || d.mediaType.length > 255 || /[\u0000-\u001f\u007f]/.test(d.mediaType)) || d.replace !== void 0 && (typeof d.replace != "string" || !/^[0-9a-f]{64}$/.test(d.replace))) return
|
|
914
|
+
if (Object.keys(d).some((key) => !["name", "size", "mediaType", "replace"].includes(key)) || !safeEnrichmentName(d.name) || !Number.isSafeInteger(d.size) || d.size < 0 || d.mediaType !== void 0 && (typeof d.mediaType != "string" || d.mediaType.length > 255 || /[\u0000-\u001f\u007f]/.test(d.mediaType)) || d.replace !== void 0 && (typeof d.replace != "string" || !/^[0-9a-f]{64}$/.test(d.replace))) return invalid4();
|
|
881
915
|
if (d.size > maxBytes) throw new FileOperationError("request_too_large", 413);
|
|
882
916
|
return d;
|
|
883
917
|
}
|
|
@@ -888,23 +922,23 @@ function safeFilePath(value) {
|
|
|
888
922
|
return typeof value == "string" && value.length <= 1024 && value.split("/").every(safeFileName);
|
|
889
923
|
}
|
|
890
924
|
function parseFileCreateMetadata(value, maxBytes) {
|
|
891
|
-
let
|
|
925
|
+
let invalid4 = () => {
|
|
892
926
|
throw new FileOperationError("invalid_input", 400);
|
|
893
927
|
};
|
|
894
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
928
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid4();
|
|
895
929
|
let input = value;
|
|
896
|
-
if (Object.keys(input).some((key) => !["name", "path", "storage", "csv", "size", "requestKey"].includes(key))) return
|
|
930
|
+
if (Object.keys(input).some((key) => !["name", "path", "storage", "csv", "size", "requestKey"].includes(key))) return invalid4();
|
|
897
931
|
let path = input.path === void 0 ? "Files" : input.path;
|
|
898
|
-
if (!safeFileName(input.name) || !safeFilePath(path) || input.storage !== void 0 && input.storage !== "remote" && input.storage !== "local" || !Number.isSafeInteger(input.size) || input.size < 0) return
|
|
932
|
+
if (!safeFileName(input.name) || !safeFilePath(path) || input.storage !== void 0 && input.storage !== "remote" && input.storage !== "local" || !Number.isSafeInteger(input.size) || input.size < 0) return invalid4();
|
|
899
933
|
if (input.size > maxBytes) throw new FileOperationError("request_too_large", 413);
|
|
900
|
-
if (typeof input.requestKey != "string" || input.requestKey.length < 1 || input.requestKey.length > 256 || input.requestKey !== input.requestKey.trim() || /[\u0000-\u001f\u007f]/.test(input.requestKey)) return
|
|
934
|
+
if (typeof input.requestKey != "string" || input.requestKey.length < 1 || input.requestKey.length > 256 || input.requestKey !== input.requestKey.trim() || /[\u0000-\u001f\u007f]/.test(input.requestKey)) return invalid4();
|
|
901
935
|
let csv;
|
|
902
936
|
if (input.csv !== void 0) {
|
|
903
|
-
if (!input.csv || typeof input.csv != "object" || Array.isArray(input.csv)) return
|
|
937
|
+
if (!input.csv || typeof input.csv != "object" || Array.isArray(input.csv)) return invalid4();
|
|
904
938
|
let hints = input.csv;
|
|
905
|
-
if (Object.keys(hints).some((key) => !["encoding", "delimiter", "headerRow"].includes(key))) return
|
|
939
|
+
if (Object.keys(hints).some((key) => !["encoding", "delimiter", "headerRow"].includes(key))) return invalid4();
|
|
906
940
|
let encoding = hints.encoding === void 0 ? "utf-8" : hints.encoding, delimiter = hints.delimiter === void 0 ? "," : hints.delimiter, headerRow = hints.headerRow === void 0 ? 1 : hints.headerRow;
|
|
907
|
-
if (encoding !== "utf-8" && encoding !== "windows-1252" || ![",", ";", " "].includes(delimiter) || !Number.isSafeInteger(headerRow) || headerRow < 1 || headerRow > 1e5) return
|
|
941
|
+
if (encoding !== "utf-8" && encoding !== "windows-1252" || ![",", ";", " "].includes(delimiter) || !Number.isSafeInteger(headerRow) || headerRow < 1 || headerRow > 1e5) return invalid4();
|
|
908
942
|
csv = { encoding, delimiter, headerRow };
|
|
909
943
|
}
|
|
910
944
|
return {
|
|
@@ -992,13 +1026,14 @@ var data = {
|
|
|
992
1026
|
async function send2(input) {
|
|
993
1027
|
let context2 = await resolveDataContext();
|
|
994
1028
|
try {
|
|
995
|
-
|
|
1029
|
+
let envelope = { repository, ...input };
|
|
1030
|
+
if (checkDataRequestSize(envelope), "local" in context2) return await context2.local("data/query", envelope);
|
|
996
1031
|
let response = await fetch(context2.url, {
|
|
997
1032
|
method: "POST",
|
|
998
1033
|
redirect: "error",
|
|
999
1034
|
cache: "no-store",
|
|
1000
1035
|
headers: { "content-type": "application/json", ...context2.headers },
|
|
1001
|
-
body: JSON.stringify(
|
|
1036
|
+
body: JSON.stringify(envelope)
|
|
1002
1037
|
}), result2 = await response.json();
|
|
1003
1038
|
if (!response.ok)
|
|
1004
1039
|
throw dataTransportError(response.status, result2);
|
|
@@ -1014,13 +1049,11 @@ var data = {
|
|
|
1014
1049
|
},
|
|
1015
1050
|
records: {
|
|
1016
1051
|
select: (query) => send2({ operation: "records.select", query }),
|
|
1017
|
-
search: (query, options) => {
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1052
|
+
search: async (query, options) => send2({ operation: "records.search", ...captureRecordsSearchInput(query, options) })
|
|
1053
|
+
},
|
|
1054
|
+
history: {
|
|
1055
|
+
list: async (options) => send2({ operation: "history.list", options: captureHistoryListOptions(options) }),
|
|
1056
|
+
at: async (instant) => send2({ operation: "history.at", instant: captureHistoryInstant(instant) })
|
|
1024
1057
|
},
|
|
1025
1058
|
changes() {
|
|
1026
1059
|
let updates = [], creates = [], deletes = [], publicationId, pending, confirmed, snapshot = () => {
|
|
@@ -1104,7 +1137,7 @@ var data = {
|
|
|
1104
1137
|
}
|
|
1105
1138
|
};
|
|
1106
1139
|
|
|
1107
|
-
var MAX_BYTES = 16 * 1024 * 1024, PART_BYTES = 8 * 1024 * 1024, METADATA_BYTES = 4096, RESULT_BYTES = 16 * 1024, CONTROL_RESULT_BYTES = 128 * 1024, TIMEOUT_MS = 3e4, MAX_ACTIVE = 4, ATTEMPTS = 2, active = 0,
|
|
1140
|
+
var MAX_BYTES = 16 * 1024 * 1024, PART_BYTES = 8 * 1024 * 1024, METADATA_BYTES = 4096, RESULT_BYTES = 16 * 1024, CONTROL_RESULT_BYTES = 128 * 1024, TIMEOUT_MS = 3e4, MAX_ACTIVE = 4, ATTEMPTS = 2, active = 0, invalid3 = () => new FileOperationError("invalid_input", 400), unavailable = () => new FileOperationError("unavailable", 503, !0), failures = {
|
|
1108
1141
|
400: ["invalid_input", "unsupported_context"],
|
|
1109
1142
|
401: ["unauthenticated"],
|
|
1110
1143
|
403: ["access_denied"],
|
|
@@ -1121,7 +1154,7 @@ async function boundedBytes(stream, limit) {
|
|
|
1121
1154
|
for (; ; ) {
|
|
1122
1155
|
let { done, value } = await reader.read();
|
|
1123
1156
|
if (done) break;
|
|
1124
|
-
if (!(value instanceof Uint8Array)) throw
|
|
1157
|
+
if (!(value instanceof Uint8Array)) throw invalid3();
|
|
1125
1158
|
if (size += value.byteLength, size > limit) throw new FileOperationError("request_too_large", 413);
|
|
1126
1159
|
bytes.set(value, size - value.byteLength);
|
|
1127
1160
|
}
|
|
@@ -1249,7 +1282,7 @@ async function send(suffix, init2, descriptor2, initial, parent) {
|
|
|
1249
1282
|
throw unavailable();
|
|
1250
1283
|
}
|
|
1251
1284
|
function idPath(id2) {
|
|
1252
|
-
if (typeof id2 != "string" || !FILE_ID_PATTERN.test(id2)) throw
|
|
1285
|
+
if (typeof id2 != "string" || !FILE_ID_PATTERN.test(id2)) throw invalid3();
|
|
1253
1286
|
return `/${id2}`;
|
|
1254
1287
|
}
|
|
1255
1288
|
async function multipartCreate(input, metadata, exchange, release = () => {
|
|
@@ -1292,18 +1325,18 @@ async function multipartCreate(input, metadata, exchange, release = () => {
|
|
|
1292
1325
|
if (!chunk || offset === chunk.byteLength) {
|
|
1293
1326
|
chunk = void 0, offset = 0;
|
|
1294
1327
|
let value2 = await next();
|
|
1295
|
-
if (value2.done || !(value2.value instanceof Uint8Array) || (chunk = value2.value, chunk.byteLength > metadata.size - sent - filled)) throw
|
|
1328
|
+
if (value2.done || !(value2.value instanceof Uint8Array) || (chunk = value2.value, chunk.byteLength > metadata.size - sent - filled)) throw invalid3();
|
|
1296
1329
|
}
|
|
1297
1330
|
let take = Math.min(length - filled, chunk.byteLength - offset);
|
|
1298
1331
|
part.set(chunk.subarray(offset, offset + take), filled), filled += take, offset += take, offset === chunk.byteLength && (chunk = void 0, offset = 0);
|
|
1299
1332
|
}
|
|
1300
1333
|
}
|
|
1301
|
-
if (part.byteLength !== length) throw
|
|
1334
|
+
if (part.byteLength !== length) throw invalid3();
|
|
1302
1335
|
if (reader && sent + length === metadata.size)
|
|
1303
1336
|
for (lastProgress = Date.now(); ; ) {
|
|
1304
1337
|
let value2 = await next();
|
|
1305
1338
|
if (value2.done) break;
|
|
1306
|
-
if (!(value2.value instanceof Uint8Array) || value2.value.byteLength) throw
|
|
1339
|
+
if (!(value2.value instanceof Uint8Array) || value2.value.byteLength) throw invalid3();
|
|
1307
1340
|
}
|
|
1308
1341
|
let value = await request((signal) => exchange(`${route}/part`, {
|
|
1309
1342
|
method: "POST",
|
|
@@ -1317,7 +1350,7 @@ async function multipartCreate(input, metadata, exchange, release = () => {
|
|
|
1317
1350
|
}
|
|
1318
1351
|
if (upload) for (let name of Object.keys(upload.file.enrichments)) {
|
|
1319
1352
|
let bytes = await request(() => upload.enrichment(name));
|
|
1320
|
-
if (bytes.byteLength !== upload.file.enrichments[name].size || bytes.byteLength > MAX_BYTES) throw
|
|
1353
|
+
if (bytes.byteLength !== upload.file.enrichments[name].size || bytes.byteLength > MAX_BYTES) throw invalid3();
|
|
1321
1354
|
await request((signal) => exchange(`${route}/enrichments/${encodeURIComponent(name)}`, {
|
|
1322
1355
|
method: "POST",
|
|
1323
1356
|
headers: { "content-type": "application/octet-stream", "x-oddington-transfer": ticket },
|
|
@@ -1361,7 +1394,7 @@ async function operation(work, initial, parent) {
|
|
|
1361
1394
|
function contentPath(id2, name) {
|
|
1362
1395
|
let path = idPath(id2);
|
|
1363
1396
|
if (name === void 0) return `${path}/content`;
|
|
1364
|
-
if (!safeEnrichmentName(name)) throw
|
|
1397
|
+
if (!safeEnrichmentName(name)) throw invalid3();
|
|
1365
1398
|
return `${path}/enrichments/${encodeURIComponent(name)}/content`;
|
|
1366
1399
|
}
|
|
1367
1400
|
async function read(id2, names) {
|
|
@@ -1370,12 +1403,12 @@ async function read(id2, names) {
|
|
|
1370
1403
|
let path = contentPath(id2, names);
|
|
1371
1404
|
return operation((context3, signal) => send(path, { method: "GET" }, !1, context3, signal), context2);
|
|
1372
1405
|
}
|
|
1373
|
-
if (!Array.isArray(names)) throw
|
|
1406
|
+
if (!Array.isArray(names)) throw invalid3();
|
|
1374
1407
|
let distinct = [], seen = /* @__PURE__ */ new Set();
|
|
1375
1408
|
for (let name of names) {
|
|
1376
|
-
if (typeof name != "string" || !safeEnrichmentName(name)) throw
|
|
1409
|
+
if (typeof name != "string" || !safeEnrichmentName(name)) throw invalid3();
|
|
1377
1410
|
if (!seen.has(name)) {
|
|
1378
|
-
if (seen.size === 16) throw
|
|
1411
|
+
if (seen.size === 16) throw invalid3();
|
|
1379
1412
|
seen.add(name), distinct.push(name);
|
|
1380
1413
|
}
|
|
1381
1414
|
}
|
|
@@ -1407,11 +1440,11 @@ var files = {
|
|
|
1407
1440
|
async create(input, options) {
|
|
1408
1441
|
let context2 = await resolveFilesContext();
|
|
1409
1442
|
if (!input || typeof input != "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "size", "path", "name", "storage", "csv"].includes(key)) || options !== void 0 && (!options || typeof options != "object" || Array.isArray(options) || Object.keys(options).some((key) => key !== "requestKey")))
|
|
1410
|
-
throw
|
|
1443
|
+
throw invalid3();
|
|
1411
1444
|
let blob = input.file instanceof Blob, array2 = input.file instanceof Uint8Array, stream = input.file instanceof ReadableStream;
|
|
1412
|
-
if (!blob && !array2 && !stream) throw
|
|
1445
|
+
if (!blob && !array2 && !stream) throw invalid3();
|
|
1413
1446
|
let intrinsic = blob ? input.file.size : array2 ? input.file.byteLength : void 0;
|
|
1414
|
-
if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw
|
|
1447
|
+
if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid3();
|
|
1415
1448
|
let name = input.name;
|
|
1416
1449
|
name === void 0 && blob && "name" in input.file && typeof input.file.name == "string" && (name = typeof globalThis.File < "u" && input.file instanceof globalThis.File ? input.file.name : input.file.name.split(/[\\/]/).at(-1));
|
|
1417
1450
|
let metadata = parseFileCreateMetadata({
|
|
@@ -1424,7 +1457,7 @@ var files = {
|
|
|
1424
1457
|
}, FILE_ORIGINAL_MAX_BYTES);
|
|
1425
1458
|
if (!context2.local && metadata.storage === "local") throw new FileOperationError("unsupported_context", 400);
|
|
1426
1459
|
let header = encodeURIComponent(JSON.stringify(metadata));
|
|
1427
|
-
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw
|
|
1460
|
+
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid3();
|
|
1428
1461
|
if (active >= MAX_ACTIVE) throw new FileOperationError("capacity", 429, !0);
|
|
1429
1462
|
if (active++, context2.localFiles && metadata.size > MAX_BYTES) {
|
|
1430
1463
|
let controller = new AbortController(), file = input.file, offset = 0, body2 = file instanceof ReadableStream ? file : file instanceof Blob ? file.stream() : new ReadableStream({
|
|
@@ -1452,7 +1485,7 @@ var files = {
|
|
|
1452
1485
|
blob ? input.file.stream() : input.file,
|
|
1453
1486
|
metadata.size
|
|
1454
1487
|
);
|
|
1455
|
-
if (bytes.byteLength !== metadata.size) throw
|
|
1488
|
+
if (bytes.byteLength !== metadata.size) throw invalid3();
|
|
1456
1489
|
if (signal.aborted) throw unavailable();
|
|
1457
1490
|
return await send("", {
|
|
1458
1491
|
method: "POST",
|
|
@@ -1468,7 +1501,7 @@ var files = {
|
|
|
1468
1501
|
},
|
|
1469
1502
|
async enrich(input) {
|
|
1470
1503
|
let context2 = await resolveFilesContext();
|
|
1471
|
-
if (!input || typeof input != "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "name", "content", "mediaType", "replace"].includes(key)) || typeof input.content != "string" && !(input.content instanceof Uint8Array)) throw
|
|
1504
|
+
if (!input || typeof input != "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "name", "content", "mediaType", "replace"].includes(key)) || typeof input.content != "string" && !(input.content instanceof Uint8Array)) throw invalid3();
|
|
1472
1505
|
let path = `${idPath(input.file)}/enrichments`;
|
|
1473
1506
|
if (typeof input.content == "string" ? input.content.length > MAX_BYTES : input.content.byteLength > MAX_BYTES)
|
|
1474
1507
|
throw new FileOperationError("request_too_large", 413);
|
|
@@ -1485,7 +1518,7 @@ var files = {
|
|
|
1485
1518
|
...input.mediaType === void 0 ? {} : { mediaType: input.mediaType },
|
|
1486
1519
|
...input.replace === void 0 ? {} : { replace: input.replace }
|
|
1487
1520
|
}, MAX_BYTES), header = encodeURIComponent(JSON.stringify(metadata));
|
|
1488
|
-
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw
|
|
1521
|
+
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid3();
|
|
1489
1522
|
let result2 = await send(path, { method: "POST", headers: {
|
|
1490
1523
|
"content-type": "application/octet-stream",
|
|
1491
1524
|
"x-oddington-enrichment": header
|
|
@@ -1500,7 +1533,9 @@ var files = {
|
|
|
1500
1533
|
read
|
|
1501
1534
|
};
|
|
1502
1535
|
|
|
1503
|
-
var sessionKey = "_os.app.session", AppResponseReadError = class extends Error {
|
|
1536
|
+
var sessionKey = "_os.app.session", responseChecks = /* @__PURE__ */ new WeakMap(), AppResponseReadError = class extends Error {
|
|
1537
|
+
}, AppContextDenied = class extends Error {
|
|
1538
|
+
}, AppRenewalUnavailable = class extends Error {
|
|
1504
1539
|
};
|
|
1505
1540
|
async function appResponse(response, maximum, signal) {
|
|
1506
1541
|
if (signal.aborted || !response.body || response.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase() !== "application/json") throw new Error();
|
|
@@ -1519,7 +1554,11 @@ async function appResponse(response, maximum, signal) {
|
|
|
1519
1554
|
throw new AppResponseReadError();
|
|
1520
1555
|
}
|
|
1521
1556
|
if (signal.aborted) throw new Error();
|
|
1522
|
-
if (chunk.done)
|
|
1557
|
+
if (chunk.done) {
|
|
1558
|
+
let value = JSON.parse(text3 + decoder.decode());
|
|
1559
|
+
if (await responseChecks.get(response)?.(value), signal.aborted) throw new Error();
|
|
1560
|
+
return value;
|
|
1561
|
+
}
|
|
1523
1562
|
if (bytes += chunk.value.byteLength, bytes > maximum)
|
|
1524
1563
|
throw abort(), new Error();
|
|
1525
1564
|
text3 += decoder.decode(chunk.value, { stream: !0 });
|
|
@@ -1537,27 +1576,180 @@ function isAppOrigin(value) {
|
|
|
1537
1576
|
}
|
|
1538
1577
|
}
|
|
1539
1578
|
function appContext(origin, active2) {
|
|
1540
|
-
let binding, credential, denied = !1, controller = new AbortController(), expiry,
|
|
1541
|
-
|
|
1579
|
+
let binding, credential, denied = !1, controller = new AbortController(), expiry, startup, renewalTimer, renewal, observation, resolution2, disposed = !1, stored = () => globalThis.localStorage.getItem(sessionKey), alive = () => {
|
|
1580
|
+
try {
|
|
1581
|
+
return !denied && !disposed && active2() && globalThis.location.origin === origin && (!binding || binding.expiresAt > Date.now());
|
|
1582
|
+
} catch {
|
|
1583
|
+
return !1;
|
|
1584
|
+
}
|
|
1585
|
+
}, cancel = () => {
|
|
1586
|
+
controller.abort(), clearTimeout(expiry), clearTimeout(startup), clearTimeout(renewalTimer), clearInterval(monitor), globalThis.removeEventListener?.("storage", storageChanged);
|
|
1587
|
+
}, invalidate = () => {
|
|
1588
|
+
denied = !0, cancel();
|
|
1542
1589
|
try {
|
|
1543
|
-
active2() && globalThis.location.origin === origin && (!credential || globalThis.localStorage.getItem(sessionKey) === credential) && globalThis.localStorage.removeItem(sessionKey);
|
|
1590
|
+
!disposed && active2() && globalThis.location.origin === origin && (!credential || globalThis.localStorage.getItem(sessionKey) === credential) && globalThis.localStorage.removeItem(sessionKey);
|
|
1544
1591
|
} catch {
|
|
1545
1592
|
}
|
|
1546
1593
|
}, current2 = () => {
|
|
1547
1594
|
try {
|
|
1548
|
-
return
|
|
1595
|
+
return alive() && stored() === credential;
|
|
1549
1596
|
} catch {
|
|
1550
1597
|
return !1;
|
|
1551
1598
|
}
|
|
1599
|
+
}, sameSession = (value) => !binding || value.appId === binding.appId && value.memberId === binding.memberId && value.workspace === binding.workspace && value.sessionId === binding.sessionId, bounded = (value) => validBinding(value) && value.expiresAt > Date.now() && value.expiresAt <= Date.now() + 6e5 && sameSession(value);
|
|
1600
|
+
async function proof(candidate, signal = controller.signal) {
|
|
1601
|
+
if (!alive() || !/^[A-Za-z0-9_-]{43}$/.test(candidate)) throw new Error();
|
|
1602
|
+
let url = `${origin}/_os/app/context`, response = await fetch(url, {
|
|
1603
|
+
credentials: "omit",
|
|
1604
|
+
redirect: "error",
|
|
1605
|
+
cache: "no-store",
|
|
1606
|
+
referrerPolicy: "no-referrer",
|
|
1607
|
+
headers: { authorization: `Bearer ${candidate}` },
|
|
1608
|
+
signal
|
|
1609
|
+
});
|
|
1610
|
+
if (response.redirected || response.url && response.url !== url) throw new Error();
|
|
1611
|
+
if (response.status === 401 || response.status === 403) throw new AppContextDenied();
|
|
1612
|
+
if (!response.ok) throw new Error();
|
|
1613
|
+
let value = await appResponse(response, 4096, signal);
|
|
1614
|
+
if (!alive() || !bounded(value)) throw new Error();
|
|
1615
|
+
return value;
|
|
1616
|
+
}
|
|
1617
|
+
function install(value, candidate) {
|
|
1618
|
+
binding = { ...value }, credential = candidate, clearTimeout(expiry), clearTimeout(renewalTimer);
|
|
1619
|
+
let remaining = binding.expiresAt - Date.now();
|
|
1620
|
+
expiry = setTimeout(invalidate, remaining), renewalTimer = setTimeout(() => {
|
|
1621
|
+
renew();
|
|
1622
|
+
}, remaining - Math.min(6e4, remaining / 5));
|
|
1623
|
+
}
|
|
1624
|
+
async function synchronize() {
|
|
1625
|
+
if (!alive()) throw new Error();
|
|
1626
|
+
if (credential && stored() !== credential) {
|
|
1627
|
+
if (!binding) throw new Error();
|
|
1628
|
+
if (observation) return observation;
|
|
1629
|
+
observation = (async () => {
|
|
1630
|
+
for (; alive(); ) {
|
|
1631
|
+
let candidate = stored();
|
|
1632
|
+
if (!candidate) throw new Error();
|
|
1633
|
+
let value;
|
|
1634
|
+
try {
|
|
1635
|
+
value = await proof(candidate);
|
|
1636
|
+
} catch {
|
|
1637
|
+
if (stored() !== candidate) continue;
|
|
1638
|
+
throw new Error();
|
|
1639
|
+
}
|
|
1640
|
+
if (stored() === candidate) {
|
|
1641
|
+
install(value, candidate);
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
throw new Error();
|
|
1646
|
+
})();
|
|
1647
|
+
try {
|
|
1648
|
+
await observation;
|
|
1649
|
+
} catch {
|
|
1650
|
+
throw invalidate(), new Error("Local app context unavailable.");
|
|
1651
|
+
} finally {
|
|
1652
|
+
observation = void 0;
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
async function renew() {
|
|
1657
|
+
if (!(renewal || !binding || !alive())) {
|
|
1658
|
+
renewal = (async () => {
|
|
1659
|
+
let deadline = binding.expiresAt, requestController = new AbortController(), abort = () => requestController.abort();
|
|
1660
|
+
controller.signal.addEventListener("abort", abort, { once: !0 });
|
|
1661
|
+
let timeout = setTimeout(abort, Math.min(2e4, deadline - Date.now())), previous = credential;
|
|
1662
|
+
try {
|
|
1663
|
+
if (await synchronize(), credential !== previous) return;
|
|
1664
|
+
let url = `${origin}/_os/app/renew`, response;
|
|
1665
|
+
try {
|
|
1666
|
+
response = await fetch(url, {
|
|
1667
|
+
method: "POST",
|
|
1668
|
+
credentials: "omit",
|
|
1669
|
+
redirect: "error",
|
|
1670
|
+
cache: "no-store",
|
|
1671
|
+
referrerPolicy: "no-referrer",
|
|
1672
|
+
signal: requestController.signal,
|
|
1673
|
+
headers: { authorization: `Bearer ${previous}` }
|
|
1674
|
+
});
|
|
1675
|
+
} catch {
|
|
1676
|
+
throw new AppRenewalUnavailable();
|
|
1677
|
+
}
|
|
1678
|
+
if (response.redirected || response.url && response.url !== url) throw new Error();
|
|
1679
|
+
let value = await appResponse(response, 4096, requestController.signal);
|
|
1680
|
+
if (response.status === 503 && value && typeof value == "object" && !Array.isArray(value) && Object.keys(value).join(",") === "error" && "error" in value && value.error === "renewal_unavailable")
|
|
1681
|
+
throw new AppRenewalUnavailable();
|
|
1682
|
+
if (response.status === 403 && value && typeof value == "object" && !Array.isArray(value) && Object.keys(value).join(",") === "error" && "error" in value && value.error === "renewal_conflict") {
|
|
1683
|
+
for (; alive() && stored() === previous && !requestController.signal.aborted; )
|
|
1684
|
+
await new Promise((resolve2, reject) => {
|
|
1685
|
+
let abortWait = () => {
|
|
1686
|
+
clearTimeout(timer), reject(new Error());
|
|
1687
|
+
}, timer = setTimeout(() => {
|
|
1688
|
+
requestController.signal.removeEventListener("abort", abortWait), resolve2();
|
|
1689
|
+
}, 100);
|
|
1690
|
+
requestController.signal.addEventListener("abort", abortWait, { once: !0 });
|
|
1691
|
+
});
|
|
1692
|
+
if (requestController.signal.aborted) throw new Error();
|
|
1693
|
+
await synchronize();
|
|
1694
|
+
return;
|
|
1695
|
+
}
|
|
1696
|
+
if (!response.ok) throw new Error();
|
|
1697
|
+
if (!alive() || Date.now() >= deadline || !value || typeof value != "object" || Array.isArray(value) || Object.keys(value).sort().join(",") !== "context,credential") throw new Error();
|
|
1698
|
+
let result2 = value;
|
|
1699
|
+
if (!bounded(result2.context) || typeof result2.credential != "string" || !/^[A-Za-z0-9_-]{43}$/.test(result2.credential) || result2.credential === previous) throw new Error();
|
|
1700
|
+
if (stored() !== previous) {
|
|
1701
|
+
await synchronize();
|
|
1702
|
+
return;
|
|
1703
|
+
}
|
|
1704
|
+
globalThis.localStorage.setItem(sessionKey, result2.credential), install(result2.context, result2.credential);
|
|
1705
|
+
} catch (error) {
|
|
1706
|
+
try {
|
|
1707
|
+
if (alive() && stored() && stored() !== previous) {
|
|
1708
|
+
await synchronize();
|
|
1709
|
+
return;
|
|
1710
|
+
}
|
|
1711
|
+
} catch {
|
|
1712
|
+
}
|
|
1713
|
+
try {
|
|
1714
|
+
if (alive() && stored() && stored() !== previous) {
|
|
1715
|
+
await synchronize();
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1718
|
+
} catch {
|
|
1719
|
+
}
|
|
1720
|
+
(error instanceof AppRenewalUnavailable || error instanceof AppResponseReadError || requestController.signal.aborted) && current2() && Date.now() < deadline ? renewalTimer = setTimeout(() => {
|
|
1721
|
+
renew();
|
|
1722
|
+
}, Math.min(5e3, (deadline - Date.now()) / 5)) : invalidate();
|
|
1723
|
+
} finally {
|
|
1724
|
+
clearTimeout(timeout), controller.signal.removeEventListener("abort", abort);
|
|
1725
|
+
}
|
|
1726
|
+
})();
|
|
1727
|
+
try {
|
|
1728
|
+
await renewal;
|
|
1729
|
+
} finally {
|
|
1730
|
+
renewal = void 0;
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
let storageChanged = () => {
|
|
1735
|
+
if (credential) {
|
|
1736
|
+
if (!alive()) {
|
|
1737
|
+
invalidate();
|
|
1738
|
+
return;
|
|
1739
|
+
}
|
|
1740
|
+
synchronize().catch(invalidate);
|
|
1741
|
+
}
|
|
1552
1742
|
}, monitor = setInterval(() => {
|
|
1553
|
-
|
|
1554
|
-
}, 100)
|
|
1555
|
-
|
|
1743
|
+
storageChanged();
|
|
1744
|
+
}, 100);
|
|
1745
|
+
globalThis.addEventListener?.("storage", storageChanged);
|
|
1746
|
+
let dispose = () => {
|
|
1747
|
+
disposed = !0, cancel();
|
|
1556
1748
|
};
|
|
1557
1749
|
async function requestData(operation2, input) {
|
|
1558
1750
|
try {
|
|
1559
1751
|
if (operation2 !== "data/query" || !current2()) throw new Error();
|
|
1560
|
-
let url = `${origin}/_os/app/data`, response = await fetch(url, {
|
|
1752
|
+
let url = `${origin}/_os/app/data`, admitted = credential, response = await fetch(url, {
|
|
1561
1753
|
method: "POST",
|
|
1562
1754
|
credentials: "omit",
|
|
1563
1755
|
redirect: "error",
|
|
@@ -1567,10 +1759,12 @@ function appContext(origin, active2) {
|
|
|
1567
1759
|
headers: { "content-type": "application/json", authorization: `Bearer ${credential}` },
|
|
1568
1760
|
body: JSON.stringify(input)
|
|
1569
1761
|
});
|
|
1762
|
+
for (await synchronize(); alive() && stored() !== credential; ) await synchronize();
|
|
1570
1763
|
if (!current2() || response.redirected || response.url && response.url !== url) throw new Error();
|
|
1571
1764
|
if (response.status === 401 || response.status === 403)
|
|
1572
|
-
throw invalidate(), new DataOperationError("access_denied");
|
|
1765
|
+
throw admitted === credential && invalidate(), new DataOperationError("access_denied");
|
|
1573
1766
|
let result2 = await appResponse(response, Number.MAX_SAFE_INTEGER, controller.signal);
|
|
1767
|
+
for (await synchronize(); alive() && stored() !== credential; ) await synchronize();
|
|
1574
1768
|
if (!current2()) throw new Error();
|
|
1575
1769
|
if (!response.ok) throw dataTransportError(response.status, result2);
|
|
1576
1770
|
return result2;
|
|
@@ -1581,7 +1775,7 @@ function appContext(origin, active2) {
|
|
|
1581
1775
|
async function requestRoutine(key, suffix, init2 = {}) {
|
|
1582
1776
|
if (!current2())
|
|
1583
1777
|
throw invalidate(), new Error("Local app context unavailable.");
|
|
1584
|
-
let url = `${origin}/_os/app/routines/${encodeURIComponent(key)}/${suffix}`, response = await fetch(url, {
|
|
1778
|
+
let url = `${origin}/_os/app/routines/${encodeURIComponent(key)}/${suffix}`, admitted = credential, response = await fetch(url, {
|
|
1585
1779
|
...init2,
|
|
1586
1780
|
credentials: "omit",
|
|
1587
1781
|
redirect: "error",
|
|
@@ -1590,45 +1784,69 @@ function appContext(origin, active2) {
|
|
|
1590
1784
|
signal: controller.signal,
|
|
1591
1785
|
headers: { ...init2.body === void 0 ? {} : { "content-type": "application/json" }, authorization: `Bearer ${credential}` }
|
|
1592
1786
|
});
|
|
1787
|
+
for (await synchronize(); alive() && stored() !== credential; ) await synchronize();
|
|
1593
1788
|
if (!current2() || response.redirected || response.url && response.url !== url)
|
|
1594
1789
|
throw invalidate(), new Error("Local app context unavailable.");
|
|
1595
|
-
return (response.status === 401 || response.status === 403) && invalidate(), response
|
|
1790
|
+
return (response.status === 401 || response.status === 403) && admitted === credential && invalidate(), responseChecks.set(response, async (value) => {
|
|
1791
|
+
for (await synchronize(); alive() && stored() !== credential; ) await synchronize();
|
|
1792
|
+
admitted === credential && value && typeof value == "object" && "error" in value && value.error === "authority_unavailable" && invalidate();
|
|
1793
|
+
}), response;
|
|
1596
1794
|
}
|
|
1597
|
-
|
|
1795
|
+
function context2() {
|
|
1796
|
+
let issued = credential;
|
|
1797
|
+
return {
|
|
1798
|
+
kind: "local",
|
|
1799
|
+
...binding,
|
|
1800
|
+
get expiresAt() {
|
|
1801
|
+
return binding.expiresAt;
|
|
1802
|
+
},
|
|
1803
|
+
isCurrent: current2,
|
|
1804
|
+
signal: controller.signal,
|
|
1805
|
+
invalidate: () => {
|
|
1806
|
+
issued === credential && invalidate();
|
|
1807
|
+
},
|
|
1808
|
+
requestRoutine,
|
|
1809
|
+
requestData,
|
|
1810
|
+
requestAvailability: (key) => requestRoutine(key, "availability", { method: "GET" })
|
|
1811
|
+
};
|
|
1812
|
+
}
|
|
1813
|
+
let resolveOnce = async () => {
|
|
1814
|
+
let attempted;
|
|
1598
1815
|
try {
|
|
1599
1816
|
if (denied || !active2() || globalThis.location.origin !== origin) throw new Error();
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
if (
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
invalidate,
|
|
1619
|
-
requestRoutine,
|
|
1620
|
-
requestData,
|
|
1621
|
-
requestAvailability: (key) => requestRoutine(key, "availability", { method: "GET" })
|
|
1622
|
-
};
|
|
1623
|
-
} catch {
|
|
1624
|
-
throw invalidate(), new Error("Local app context unavailable.");
|
|
1817
|
+
credential && await synchronize();
|
|
1818
|
+
let candidate = stored();
|
|
1819
|
+
if (!candidate || !/^[A-Za-z0-9_-]{43}$/.test(candidate)) throw new Error();
|
|
1820
|
+
if (credential = candidate, attempted = candidate, !current2()) throw new Error();
|
|
1821
|
+
let value = await proof(candidate);
|
|
1822
|
+
if (stored() !== candidate || credential !== candidate)
|
|
1823
|
+
return binding || (binding = { ...value }), await synchronize(), context2();
|
|
1824
|
+
if (!current2()) throw new Error();
|
|
1825
|
+
if (binding && value.expiresAt > binding.expiresAt) throw new Error();
|
|
1826
|
+
return (!binding || value.expiresAt !== binding.expiresAt) && install(value, candidate), context2();
|
|
1827
|
+
} catch (error) {
|
|
1828
|
+
try {
|
|
1829
|
+
if (binding && current2() && attempted && attempted !== credential) return context2();
|
|
1830
|
+
if (binding && alive() && stored() && stored() !== credential)
|
|
1831
|
+
return await synchronize(), context2();
|
|
1832
|
+
} catch {
|
|
1833
|
+
}
|
|
1834
|
+
throw error instanceof AppContextDenied && binding && alive() && renewal ? new Error("Local app context unavailable.") : (invalidate(), new Error("Local app context unavailable."));
|
|
1625
1835
|
}
|
|
1836
|
+
}, resolve = () => resolution2 || (resolution2 = resolveOnce().finally(() => {
|
|
1837
|
+
resolution2 = void 0;
|
|
1838
|
+
}), resolution2);
|
|
1839
|
+
return { resolve, start: () => {
|
|
1840
|
+
startup = setTimeout(() => {
|
|
1841
|
+
alive() && !resolution2 && !binding && resolve().catch(() => {
|
|
1842
|
+
});
|
|
1843
|
+
}, 0);
|
|
1626
1844
|
}, invalidate, dispose };
|
|
1627
1845
|
}
|
|
1628
1846
|
function validBinding(value) {
|
|
1629
|
-
if (!value || typeof value != "object" || Array.isArray(value) || Object.keys(value).sort().join(",") !== "appId,expiresAt,memberId,workspace") return !1;
|
|
1847
|
+
if (!value || typeof value != "object" || Array.isArray(value) || Object.keys(value).sort().join(",") !== "appId,expiresAt,memberId,sessionId,workspace") return !1;
|
|
1630
1848
|
let binding = value;
|
|
1631
|
-
return typeof binding.appId == "string" && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(binding.appId) && typeof binding.workspace == "string" && /^[a-z0-9][a-z0-9-]{0,62}$/.test(binding.workspace) && typeof binding.memberId == "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(binding.memberId) && typeof binding.expiresAt == "number" && Number.isFinite(binding.expiresAt);
|
|
1849
|
+
return typeof binding.appId == "string" && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(binding.appId) && typeof binding.workspace == "string" && /^[a-z0-9][a-z0-9-]{0,62}$/.test(binding.workspace) && typeof binding.memberId == "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(binding.memberId) && typeof binding.sessionId == "string" && /^[A-Za-z0-9_-]{43}$/.test(binding.sessionId) && typeof binding.expiresAt == "number" && Number.isFinite(binding.expiresAt);
|
|
1632
1850
|
}
|
|
1633
1851
|
|
|
1634
1852
|
var installedDispose;
|
|
@@ -1664,7 +1882,7 @@ function init({ auth }) {
|
|
|
1664
1882
|
}), dispose = () => {
|
|
1665
1883
|
active2 && (active2 = !1, local?.dispose(), revision++, subscription.unsubscribe(), uninstall(), installedDispose === dispose && (installedDispose = void 0));
|
|
1666
1884
|
};
|
|
1667
|
-
installedDispose = dispose;
|
|
1885
|
+
installedDispose = dispose, local?.start();
|
|
1668
1886
|
}
|
|
1669
1887
|
var os = { init };
|
|
1670
1888
|
|