@oddington/sdk 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -5985,9 +5985,9 @@ var init_errors = __esm(() => {
|
|
|
5985
5985
|
}(Error);
|
|
5986
5986
|
CorruptPageTreeError = function(_super) {
|
|
5987
5987
|
__extends(CorruptPageTreeError2, _super);
|
|
5988
|
-
function CorruptPageTreeError2(targetIndex,
|
|
5988
|
+
function CorruptPageTreeError2(targetIndex, operation2) {
|
|
5989
5989
|
var _this = this;
|
|
5990
|
-
var msg = "Failed to " +
|
|
5990
|
+
var msg = "Failed to " + operation2 + " at targetIndex=" + targetIndex + " due to corrupt page tree: It is likely that one or more 'Count' entries are invalid";
|
|
5991
5991
|
_this = _super.call(this, msg) || this;
|
|
5992
5992
|
return _this;
|
|
5993
5993
|
}
|
|
@@ -21329,9 +21329,22 @@ function validateRecordDelete(value) {
|
|
|
21329
21329
|
}
|
|
21330
21330
|
function validateRecordChange(value) {
|
|
21331
21331
|
const input = serializable(value);
|
|
21332
|
-
if (Array.isArray(input
|
|
21333
|
-
|
|
21334
|
-
|
|
21332
|
+
if (!input || Array.isArray(input) || typeof input !== "object" || Object.keys(input).sort().join(",") !== "records,repository" || !validRepositoryAlias(input.repository) || !Array.isArray(input.records) || !input.records.length || input.records.length > 1e4 || new Set(input.records.map((record) => record?.ref)).size !== input.records.length || new TextEncoder().encode(JSON.stringify(input)).byteLength > RECORD_WRITE_INPUT_LIMIT)
|
|
21333
|
+
throw new InboxContractError("Invalid record change batch");
|
|
21334
|
+
const writes = [], deletes = [];
|
|
21335
|
+
for (const record of input.records) {
|
|
21336
|
+
if (!record || typeof record !== "object" || Array.isArray(record))
|
|
21337
|
+
throw new InboxContractError("Invalid record change");
|
|
21338
|
+
if ("set" in record || "fields" in record)
|
|
21339
|
+
writes.push(record);
|
|
21340
|
+
else
|
|
21341
|
+
deletes.push(record);
|
|
21342
|
+
}
|
|
21343
|
+
if (writes.length)
|
|
21344
|
+
validateRecordWrite({ repository: input.repository, records: writes });
|
|
21345
|
+
if (deletes.length)
|
|
21346
|
+
validateRecordDelete({ repository: input.repository, records: deletes });
|
|
21347
|
+
return structuredClone(input);
|
|
21335
21348
|
}
|
|
21336
21349
|
function validateRoutineRecordWrite(value) {
|
|
21337
21350
|
const body = serializable(value);
|
|
@@ -21685,15 +21698,60 @@ class DataOperationError extends Error {
|
|
|
21685
21698
|
code;
|
|
21686
21699
|
retryable;
|
|
21687
21700
|
effect;
|
|
21688
|
-
|
|
21701
|
+
component;
|
|
21702
|
+
constructor(code, retryable = false, effect, component) {
|
|
21689
21703
|
super(`Data operation failed: ${code}`);
|
|
21690
21704
|
this.code = code;
|
|
21691
21705
|
this.retryable = retryable;
|
|
21692
21706
|
this.effect = effect;
|
|
21707
|
+
this.component = component;
|
|
21693
21708
|
this.name = "DataOperationError";
|
|
21694
21709
|
}
|
|
21695
21710
|
}
|
|
21696
21711
|
|
|
21712
|
+
// ../../shared/data-search-input.ts
|
|
21713
|
+
var invalid = () => {
|
|
21714
|
+
throw new DataOperationError("invalid_query");
|
|
21715
|
+
};
|
|
21716
|
+
var scalarText = (value) => typeof value === "string" && !/[\u0000\uD800-\uDFFF]/u.test(value);
|
|
21717
|
+
function captureRecordsSearchInput(query, options) {
|
|
21718
|
+
if (!scalarText(query))
|
|
21719
|
+
return invalid();
|
|
21720
|
+
const length = [...query.trim()].length;
|
|
21721
|
+
if (length < 1 || length > 256)
|
|
21722
|
+
return invalid();
|
|
21723
|
+
if (options === undefined)
|
|
21724
|
+
return { query };
|
|
21725
|
+
if (!options || typeof options !== "object" || Array.isArray(options) || ![Object.prototype, null].includes(Object.getPrototypeOf(options)))
|
|
21726
|
+
return invalid();
|
|
21727
|
+
const descriptors = Object.getOwnPropertyDescriptors(options);
|
|
21728
|
+
if (Reflect.ownKeys(options).some((key) => typeof key !== "string" || !["collections", "limit"].includes(key) || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value")))
|
|
21729
|
+
return invalid();
|
|
21730
|
+
const captured = {};
|
|
21731
|
+
if (Object.hasOwn(descriptors, "collections")) {
|
|
21732
|
+
const supplied = descriptors.collections.value;
|
|
21733
|
+
if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1)
|
|
21734
|
+
return invalid();
|
|
21735
|
+
const collections = [];
|
|
21736
|
+
for (let index = 0;index < supplied.length; index++) {
|
|
21737
|
+
const descriptor = Object.getOwnPropertyDescriptor(supplied, String(index));
|
|
21738
|
+
if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value") || !scalarText(descriptor.value))
|
|
21739
|
+
return invalid();
|
|
21740
|
+
collections.push(descriptor.value);
|
|
21741
|
+
}
|
|
21742
|
+
if (new Set(collections).size !== collections.length)
|
|
21743
|
+
return invalid();
|
|
21744
|
+
captured.collections = collections;
|
|
21745
|
+
}
|
|
21746
|
+
if (Object.hasOwn(descriptors, "limit")) {
|
|
21747
|
+
const supplied = descriptors.limit.value;
|
|
21748
|
+
if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100)
|
|
21749
|
+
return invalid();
|
|
21750
|
+
captured.limit = supplied;
|
|
21751
|
+
}
|
|
21752
|
+
return { query, options: captured };
|
|
21753
|
+
}
|
|
21754
|
+
|
|
21697
21755
|
// ../../shared/data-envelope.ts
|
|
21698
21756
|
var DATA_REQUEST_LIMIT = 256 * 1024;
|
|
21699
21757
|
var invalidChange = () => {
|
|
@@ -21727,14 +21785,20 @@ function captureValue(value, ancestors = new Set, depth = 0) {
|
|
|
21727
21785
|
ancestors.delete(value);
|
|
21728
21786
|
}
|
|
21729
21787
|
}
|
|
21788
|
+
function captureDataDelete(record2) {
|
|
21789
|
+
const identity = mapping(record2);
|
|
21790
|
+
if (!validRecordRef(identity.$ref) || typeof identity.$version !== "string" || !identity.$version.length || identity.$version.length > 512)
|
|
21791
|
+
return invalidChange();
|
|
21792
|
+
return { ref: identity.$ref, expectedVersion: identity.$version };
|
|
21793
|
+
}
|
|
21730
21794
|
function captureDataUpdate(record2, set) {
|
|
21731
|
-
const identity =
|
|
21732
|
-
if (!
|
|
21795
|
+
const identity = captureDataDelete(record2), fields3 = mapping(set);
|
|
21796
|
+
if (!Object.keys(fields3).length || Object.keys(fields3).some((key) => key.startsWith("$") || ["id", "type"].includes(key)))
|
|
21733
21797
|
return invalidChange();
|
|
21734
|
-
return {
|
|
21798
|
+
return { ...identity, set: captureValue(fields3) };
|
|
21735
21799
|
}
|
|
21736
|
-
function captureDataUpdates(value) {
|
|
21737
|
-
if (!Array.isArray(value) || !value.length || value.length > 1e4)
|
|
21800
|
+
function captureDataUpdates(value, allowEmpty = false) {
|
|
21801
|
+
if (!Array.isArray(value) || !allowEmpty && !value.length || value.length > 1e4)
|
|
21738
21802
|
return invalidChange();
|
|
21739
21803
|
const updates = value.map((item) => {
|
|
21740
21804
|
const row = mapping(item);
|
|
@@ -21746,6 +21810,46 @@ function captureDataUpdates(value) {
|
|
|
21746
21810
|
return invalidChange();
|
|
21747
21811
|
return updates;
|
|
21748
21812
|
}
|
|
21813
|
+
function captureDataCreate(value) {
|
|
21814
|
+
const row = mapping(value);
|
|
21815
|
+
if (!validRecordRef(row.$ref) || Object.keys(row).some((key) => key.startsWith("$") && !["$ref", "$filing"].includes(key)))
|
|
21816
|
+
return invalidChange();
|
|
21817
|
+
const { $ref: ref, $filing, ...fields3 } = row;
|
|
21818
|
+
let filing;
|
|
21819
|
+
if ($filing !== undefined) {
|
|
21820
|
+
const components = mapping($filing);
|
|
21821
|
+
if (Object.entries(components).some(([name, value2]) => !/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name) || ["constructor", "prototype"].includes(name) || typeof value2 !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value2)))
|
|
21822
|
+
return invalidChange();
|
|
21823
|
+
filing = { ...components };
|
|
21824
|
+
}
|
|
21825
|
+
return { ref, fields: captureValue(fields3), ...filing ? { filing } : {} };
|
|
21826
|
+
}
|
|
21827
|
+
function captureDataChanges(updatesValue, createsValue = [], deletesValue = []) {
|
|
21828
|
+
const updates = captureDataUpdates(updatesValue, true);
|
|
21829
|
+
if (!Array.isArray(createsValue) || createsValue.length > 1e4)
|
|
21830
|
+
return invalidChange();
|
|
21831
|
+
const creates = createsValue.map((item) => {
|
|
21832
|
+
const row = mapping(item);
|
|
21833
|
+
if (Object.keys(row).some((key) => !["ref", "fields", "filing"].includes(key)) || !Object.hasOwn(row, "ref") || !Object.hasOwn(row, "fields"))
|
|
21834
|
+
return invalidChange();
|
|
21835
|
+
const fields3 = mapping(row.fields);
|
|
21836
|
+
if (Object.keys(fields3).some((key) => key.startsWith("$")))
|
|
21837
|
+
return invalidChange();
|
|
21838
|
+
return captureDataCreate({ ...fields3, $ref: row.ref, ...Object.hasOwn(row, "filing") ? { $filing: row.filing } : {} });
|
|
21839
|
+
});
|
|
21840
|
+
if (!Array.isArray(deletesValue) || deletesValue.length > 1e4)
|
|
21841
|
+
return invalidChange();
|
|
21842
|
+
const deletes = deletesValue.map((item) => {
|
|
21843
|
+
const row = mapping(item);
|
|
21844
|
+
if (Object.keys(row).sort().join(",") !== "expectedVersion,ref")
|
|
21845
|
+
return invalidChange();
|
|
21846
|
+
return captureDataDelete({ $ref: row.ref, $version: row.expectedVersion });
|
|
21847
|
+
});
|
|
21848
|
+
const refs = [...updates, ...creates, ...deletes].map((item) => item.ref);
|
|
21849
|
+
if (!refs.length || refs.length > 1e4 || new Set(refs).size !== refs.length)
|
|
21850
|
+
return invalidChange();
|
|
21851
|
+
return { updates, creates, deletes };
|
|
21852
|
+
}
|
|
21749
21853
|
function checkDataRequestSize(input) {
|
|
21750
21854
|
if (new TextEncoder().encode(JSON.stringify(input)).byteLength > DATA_REQUEST_LIMIT)
|
|
21751
21855
|
throw new DataOperationError("request_too_large", false, "unapplied");
|
|
@@ -21764,7 +21868,7 @@ function dataTransportError(status, value) {
|
|
|
21764
21868
|
const row = error && typeof error === "object" ? error : undefined;
|
|
21765
21869
|
const code = failures[status]?.find((allowed) => allowed === row?.code) ?? "unavailable";
|
|
21766
21870
|
const effect = ["unapplied", "uncertain", "applied"].includes(String(row?.effect)) ? row.effect : undefined;
|
|
21767
|
-
return new DataOperationError(code, ["capacity", "unavailable", "publication_pending"].includes(code), code === "conflict" ? "unapplied" : effect);
|
|
21871
|
+
return new DataOperationError(code, ["capacity", "unavailable", "publication_pending"].includes(code), code === "conflict" ? "unapplied" : effect, code === "invalid_change" && typeof row?.component === "string" && /^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(row.component) ? row.component : undefined);
|
|
21768
21872
|
}
|
|
21769
21873
|
|
|
21770
21874
|
// ../../shared/files-contract.ts
|
|
@@ -21781,25 +21885,59 @@ class FileOperationError extends Error {
|
|
|
21781
21885
|
}
|
|
21782
21886
|
var 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}$/;
|
|
21783
21887
|
function parseFileDescriptor(value) {
|
|
21784
|
-
const
|
|
21888
|
+
const invalid2 = () => {
|
|
21785
21889
|
throw new FileOperationError("unavailable", 503, true);
|
|
21786
21890
|
};
|
|
21787
21891
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
21788
|
-
return
|
|
21892
|
+
return invalid2();
|
|
21789
21893
|
const f = value;
|
|
21790
|
-
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 || typeof f.sha256 !== "string" || !/^[0-9a-f]{64}$/.test(f.sha256) || !f.enrichments || typeof f.enrichments !== "object" || Array.isArray(f.enrichments) ||
|
|
21791
|
-
return
|
|
21894
|
+
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 > 16 * 1024 * 1024 || 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))
|
|
21895
|
+
return invalid2();
|
|
21792
21896
|
const d = f.details;
|
|
21793
21897
|
if (d.kind === "other") {
|
|
21794
21898
|
if (Object.keys(d).length !== 1 || f.mediaType !== "application/octet-stream")
|
|
21795
|
-
return
|
|
21899
|
+
return invalid2();
|
|
21796
21900
|
} else if (d.kind === "csv") {
|
|
21797
21901
|
if (Object.keys(d).sort().join(",") !== "dataRows,delimiter,encoding,headerRow,kind" || f.mediaType !== "text/csv" || !["utf-8", "windows-1252"].includes(d.encoding) || ![",", ";", "\t"].includes(d.delimiter) || !Number.isSafeInteger(d.headerRow) || d.headerRow < 1 || !Number.isSafeInteger(d.dataRows) || d.dataRows < 0)
|
|
21798
|
-
return
|
|
21902
|
+
return invalid2();
|
|
21799
21903
|
} else
|
|
21800
|
-
return
|
|
21904
|
+
return invalid2();
|
|
21905
|
+
for (const [name, descriptor] of Object.entries(f.enrichments)) {
|
|
21906
|
+
if (!safeEnrichmentName(name))
|
|
21907
|
+
return invalid2();
|
|
21908
|
+
parseEnrichmentDescriptor(descriptor);
|
|
21909
|
+
}
|
|
21910
|
+
if (new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024)
|
|
21911
|
+
return invalid2();
|
|
21801
21912
|
return f;
|
|
21802
21913
|
}
|
|
21914
|
+
function parseEnrichmentDescriptor(value) {
|
|
21915
|
+
const invalid2 = () => {
|
|
21916
|
+
throw new FileOperationError("unavailable", 503, true);
|
|
21917
|
+
};
|
|
21918
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
21919
|
+
return invalid2();
|
|
21920
|
+
const d = value;
|
|
21921
|
+
if (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))
|
|
21922
|
+
return invalid2();
|
|
21923
|
+
return d;
|
|
21924
|
+
}
|
|
21925
|
+
function safeEnrichmentName(value) {
|
|
21926
|
+
return safeFileName(value) && !/^original(?:\.|$)/i.test(value);
|
|
21927
|
+
}
|
|
21928
|
+
function parseFileEnrichMetadata(value, maxBytes) {
|
|
21929
|
+
const invalid2 = () => {
|
|
21930
|
+
throw new FileOperationError("invalid_input", 400);
|
|
21931
|
+
};
|
|
21932
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
21933
|
+
return invalid2();
|
|
21934
|
+
const d = value;
|
|
21935
|
+
if (Object.keys(d).some((key) => !["name", "size", "mediaType", "replace"].includes(key)) || !safeEnrichmentName(d.name) || !Number.isSafeInteger(d.size) || d.size < 0 || d.mediaType !== undefined && (typeof d.mediaType !== "string" || d.mediaType.length > 255 || /[\u0000-\u001f\u007f]/.test(d.mediaType)) || d.replace !== undefined && (typeof d.replace !== "string" || !/^[0-9a-f]{64}$/.test(d.replace)))
|
|
21936
|
+
return invalid2();
|
|
21937
|
+
if (d.size > maxBytes)
|
|
21938
|
+
throw new FileOperationError("request_too_large", 413);
|
|
21939
|
+
return d;
|
|
21940
|
+
}
|
|
21803
21941
|
function safeFileName(value) {
|
|
21804
21942
|
return typeof value === "string" && value.length > 0 && value.length <= 255 && value === value.trim() && value !== "." && value !== ".." && !/[\u0000-\u001f\u007f-\u009f/\\:*?"<>|]/u.test(value) && !/[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/.test(value) && !/[. ]$/.test(value) && !/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(value);
|
|
21805
21943
|
}
|
|
@@ -21807,42 +21945,47 @@ function safeFilePath(value) {
|
|
|
21807
21945
|
return typeof value === "string" && value.length <= 1024 && value.split("/").every(safeFileName);
|
|
21808
21946
|
}
|
|
21809
21947
|
function parseFileCreateMetadata(value, maxBytes) {
|
|
21810
|
-
const
|
|
21948
|
+
const invalid2 = () => {
|
|
21811
21949
|
throw new FileOperationError("invalid_input", 400);
|
|
21812
21950
|
};
|
|
21813
21951
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
21814
|
-
return
|
|
21952
|
+
return invalid2();
|
|
21815
21953
|
const input = value;
|
|
21816
21954
|
if (Object.keys(input).some((key) => !["name", "path", "storage", "csv", "size", "requestKey"].includes(key)))
|
|
21817
|
-
return
|
|
21955
|
+
return invalid2();
|
|
21818
21956
|
const path = input.path === undefined ? "Files" : input.path;
|
|
21819
21957
|
if (!safeFileName(input.name) || !safeFilePath(path))
|
|
21820
|
-
return
|
|
21821
|
-
if (input.storage
|
|
21822
|
-
|
|
21823
|
-
if (input.storage !== undefined && input.storage !== "remote")
|
|
21824
|
-
return invalid();
|
|
21958
|
+
return invalid2();
|
|
21959
|
+
if (input.storage !== undefined && input.storage !== "remote" && input.storage !== "local")
|
|
21960
|
+
return invalid2();
|
|
21825
21961
|
if (!Number.isSafeInteger(input.size) || input.size < 0)
|
|
21826
|
-
return
|
|
21962
|
+
return invalid2();
|
|
21827
21963
|
if (input.size > maxBytes)
|
|
21828
21964
|
throw new FileOperationError("request_too_large", 413);
|
|
21829
21965
|
if (typeof input.requestKey !== "string" || input.requestKey.length < 1 || input.requestKey.length > 256 || input.requestKey !== input.requestKey.trim() || /[\u0000-\u001f\u007f]/.test(input.requestKey))
|
|
21830
|
-
return
|
|
21966
|
+
return invalid2();
|
|
21831
21967
|
let csv;
|
|
21832
21968
|
if (input.csv !== undefined) {
|
|
21833
21969
|
if (!input.csv || typeof input.csv !== "object" || Array.isArray(input.csv))
|
|
21834
|
-
return
|
|
21970
|
+
return invalid2();
|
|
21835
21971
|
const hints = input.csv;
|
|
21836
21972
|
if (Object.keys(hints).some((key) => !["encoding", "delimiter", "headerRow"].includes(key)))
|
|
21837
|
-
return
|
|
21973
|
+
return invalid2();
|
|
21838
21974
|
const encoding = hints.encoding === undefined ? "utf-8" : hints.encoding;
|
|
21839
21975
|
const delimiter = hints.delimiter === undefined ? "," : hints.delimiter;
|
|
21840
21976
|
const headerRow = hints.headerRow === undefined ? 1 : hints.headerRow;
|
|
21841
21977
|
if (encoding !== "utf-8" && encoding !== "windows-1252" || ![",", ";", "\t"].includes(delimiter) || !Number.isSafeInteger(headerRow) || headerRow < 1 || headerRow > 1e5)
|
|
21842
|
-
return
|
|
21978
|
+
return invalid2();
|
|
21843
21979
|
csv = { encoding, delimiter, headerRow };
|
|
21844
21980
|
}
|
|
21845
|
-
return {
|
|
21981
|
+
return {
|
|
21982
|
+
name: input.name,
|
|
21983
|
+
path,
|
|
21984
|
+
...input.storage ? { storage: input.storage } : {},
|
|
21985
|
+
...csv ? { csv } : {},
|
|
21986
|
+
size: input.size,
|
|
21987
|
+
requestKey: input.requestKey
|
|
21988
|
+
};
|
|
21846
21989
|
}
|
|
21847
21990
|
|
|
21848
21991
|
// ../../shared/os-origin.ts
|
|
@@ -21856,6 +21999,21 @@ function oddingtonOrigin(environment = process.env) {
|
|
|
21856
21999
|
}
|
|
21857
22000
|
|
|
21858
22001
|
// src/routine-local-transport.ts
|
|
22002
|
+
function privateRoutineRequest(environment = typeof process === "undefined" ? {} : process.env) {
|
|
22003
|
+
const prepared = ["ODDINGTON_ROUTINE_LOCAL", "ODDINGTON_ROUTINE_LOCAL_SOCKET", "ODDINGTON_ROUTINE_LOCAL_TOKEN"].some((key) => environment[key] !== undefined);
|
|
22004
|
+
const managed = ["ODDINGTON_FILES_SOCKET", "ODDINGTON_FILES_TOKEN"].some((key) => environment[key] !== undefined);
|
|
22005
|
+
if (!prepared && !managed)
|
|
22006
|
+
return;
|
|
22007
|
+
const socket = prepared ? environment.ODDINGTON_ROUTINE_LOCAL_SOCKET : environment.ODDINGTON_FILES_SOCKET;
|
|
22008
|
+
const token = prepared ? environment.ODDINGTON_ROUTINE_LOCAL_TOKEN : environment.ODDINGTON_FILES_TOKEN;
|
|
22009
|
+
const request = localRoutineRequest(prepared ? environment : {
|
|
22010
|
+
ODDINGTON_ROUTINE_LOCAL: "1",
|
|
22011
|
+
ODDINGTON_ROUTINE_LOCAL_SOCKET: socket,
|
|
22012
|
+
ODDINGTON_ROUTINE_LOCAL_TOKEN: token
|
|
22013
|
+
});
|
|
22014
|
+
const isCurrent = () => prepared ? environment.ODDINGTON_ROUTINE_LOCAL === "1" && environment.ODDINGTON_ROUTINE_LOCAL_SOCKET === socket && environment.ODDINGTON_ROUTINE_LOCAL_TOKEN === token : environment.ODDINGTON_FILES_SOCKET === socket && environment.ODDINGTON_FILES_TOKEN === token;
|
|
22015
|
+
return { request, isCurrent, identity: `private:${socket}` };
|
|
22016
|
+
}
|
|
21859
22017
|
function localRoutineRequest(environment = typeof process === "undefined" ? {} : process.env) {
|
|
21860
22018
|
const {
|
|
21861
22019
|
ODDINGTON_ROUTINE_LOCAL: mode,
|
|
@@ -21865,11 +22023,11 @@ function localRoutineRequest(environment = typeof process === "undefined" ? {} :
|
|
|
21865
22023
|
if (mode === undefined && socket === undefined && token === undefined)
|
|
21866
22024
|
return;
|
|
21867
22025
|
if (mode !== "1" || !socket || !token || !/^[0-9a-f]{64}$/.test(token))
|
|
21868
|
-
throw new Error("
|
|
22026
|
+
throw new Error("Preparation transport unavailable; nothing can publish");
|
|
21869
22027
|
const tcp = /^tcp:\/\/127\.0\.0\.1:([1-9][0-9]{0,4})$/.exec(socket);
|
|
21870
22028
|
const endpoint = tcp && tcp[0] === socket && Number(tcp[1]) <= 65535 ? { hostname: "127.0.0.1", port: Number(tcp[1]) } : socket.startsWith("/") && !socket.startsWith("//") && !socket.includes("\x00") ? { socketPath: socket } : undefined;
|
|
21871
22029
|
if (!endpoint)
|
|
21872
|
-
throw new Error("
|
|
22030
|
+
throw new Error("Preparation transport unavailable; nothing can publish");
|
|
21873
22031
|
return async (operation, input) => {
|
|
21874
22032
|
const { request } = await import("node:http");
|
|
21875
22033
|
return await new Promise((resolve, reject) => {
|
|
@@ -21880,7 +22038,7 @@ function localRoutineRequest(environment = typeof process === "undefined" ? {} :
|
|
|
21880
22038
|
headers: { "content-type": "application/json", authorization: `Bearer ${token}` },
|
|
21881
22039
|
timeout: 120000
|
|
21882
22040
|
}, (response) => {
|
|
21883
|
-
const
|
|
22041
|
+
const bytes = Buffer.alloc(33554432);
|
|
21884
22042
|
let size = 0;
|
|
21885
22043
|
response.on("data", (chunk) => {
|
|
21886
22044
|
size += chunk.length;
|
|
@@ -21888,17 +22046,37 @@ function localRoutineRequest(environment = typeof process === "undefined" ? {} :
|
|
|
21888
22046
|
response.destroy();
|
|
21889
22047
|
reject(new Error("Local result exceeds supported size"));
|
|
21890
22048
|
} else
|
|
21891
|
-
|
|
22049
|
+
bytes.set(chunk, size - chunk.length);
|
|
21892
22050
|
});
|
|
21893
22051
|
response.on("error", reject);
|
|
21894
22052
|
response.on("end", () => {
|
|
21895
22053
|
try {
|
|
21896
|
-
const result = JSON.parse(
|
|
22054
|
+
const result = JSON.parse(bytes.subarray(0, size).toString());
|
|
21897
22055
|
if (response.statusCode !== 200) {
|
|
22056
|
+
if (operation === "files/request") {
|
|
22057
|
+
const error = result.error;
|
|
22058
|
+
const status = response.statusCode ?? 503;
|
|
22059
|
+
const codes = [
|
|
22060
|
+
"invalid_input",
|
|
22061
|
+
"unsupported_context",
|
|
22062
|
+
"unauthenticated",
|
|
22063
|
+
"access_denied",
|
|
22064
|
+
"request_too_large",
|
|
22065
|
+
"conflict",
|
|
22066
|
+
"local_only",
|
|
22067
|
+
"integrity",
|
|
22068
|
+
"unavailable",
|
|
22069
|
+
"capacity",
|
|
22070
|
+
"method_not_allowed"
|
|
22071
|
+
];
|
|
22072
|
+
if (error?.code && codes.includes(error.code))
|
|
22073
|
+
throw new FileOperationError(error.code, status, error.code === "capacity" || error.code === "unavailable");
|
|
22074
|
+
throw new FileOperationError("unavailable", 503, true);
|
|
22075
|
+
}
|
|
21898
22076
|
if (operation === "data/query") {
|
|
21899
22077
|
throw dataTransportError(response.statusCode ?? 0, result);
|
|
21900
22078
|
}
|
|
21901
|
-
throw new Error(typeof result.error === "string" ? result.error : "
|
|
22079
|
+
throw new Error(typeof result.error === "string" ? result.error : "Preparation failed");
|
|
21902
22080
|
}
|
|
21903
22081
|
resolve(result);
|
|
21904
22082
|
} catch (error) {
|
|
@@ -21906,8 +22084,8 @@ function localRoutineRequest(environment = typeof process === "undefined" ? {} :
|
|
|
21906
22084
|
}
|
|
21907
22085
|
});
|
|
21908
22086
|
});
|
|
21909
|
-
call.on("error", () => reject(new Error("
|
|
21910
|
-
call.on("timeout", () => call.destroy(new Error("
|
|
22087
|
+
call.on("error", () => reject(new Error("Preparation transport unavailable; nothing was published")));
|
|
22088
|
+
call.on("timeout", () => call.destroy(new Error("Preparation timed out")));
|
|
21911
22089
|
call.end(JSON.stringify(input));
|
|
21912
22090
|
});
|
|
21913
22091
|
};
|
|
@@ -21927,6 +22105,9 @@ async function resolveDataContext() {
|
|
|
21927
22105
|
const local = localRoutineRequest();
|
|
21928
22106
|
if (local)
|
|
21929
22107
|
return { local };
|
|
22108
|
+
const managed = privateRoutineRequest();
|
|
22109
|
+
if (managed)
|
|
22110
|
+
return { local: managed.request };
|
|
21930
22111
|
const host = memberContext;
|
|
21931
22112
|
if (host !== undefined) {
|
|
21932
22113
|
const context = await host();
|
|
@@ -21945,8 +22126,14 @@ async function resolveDataContext() {
|
|
|
21945
22126
|
async function resolveFilesContext() {
|
|
21946
22127
|
try {
|
|
21947
22128
|
const environment = typeof process === "undefined" ? {} : process.env;
|
|
21948
|
-
|
|
21949
|
-
|
|
22129
|
+
const local = privateRoutineRequest(environment);
|
|
22130
|
+
if (local)
|
|
22131
|
+
return {
|
|
22132
|
+
url: local.identity,
|
|
22133
|
+
headers: {},
|
|
22134
|
+
isCurrent: local.isCurrent,
|
|
22135
|
+
local: local.request
|
|
22136
|
+
};
|
|
21950
22137
|
const host = memberContext;
|
|
21951
22138
|
if (host) {
|
|
21952
22139
|
const context = await host();
|
|
@@ -21954,13 +22141,14 @@ async function resolveFilesContext() {
|
|
|
21954
22141
|
throw new Error;
|
|
21955
22142
|
return {
|
|
21956
22143
|
...filesContext(context.workspace, context.endpoint, { authorization: `Bearer ${context.accessToken}` }),
|
|
21957
|
-
isCurrent: context.isCurrent
|
|
22144
|
+
isCurrent: context.isCurrent,
|
|
22145
|
+
local: undefined
|
|
21958
22146
|
};
|
|
21959
22147
|
}
|
|
21960
22148
|
if (!/^[0-9a-f]{64}$/.test(environment.ODDINGTON_ROUTINE_RUN ?? ""))
|
|
21961
22149
|
throw new Error;
|
|
21962
22150
|
const workspace = environment.ODDINGTON_ROUTINE_WORKSPACE;
|
|
21963
|
-
return filesContext(workspace, `https://${workspace}.oddington.ai`, { "x-oddington-run": environment.ODDINGTON_ROUTINE_RUN });
|
|
22151
|
+
return { ...filesContext(workspace, `https://${workspace}.oddington.ai`, { "x-oddington-run": environment.ODDINGTON_ROUTINE_RUN }), local: undefined };
|
|
21964
22152
|
} catch {
|
|
21965
22153
|
throw new FileOperationError("unsupported_context", 400);
|
|
21966
22154
|
}
|
|
@@ -22011,36 +22199,82 @@ var data = {
|
|
|
22011
22199
|
list: () => send({ operation: "collections.list" }),
|
|
22012
22200
|
schema: (name) => send({ operation: "collections.schema", name })
|
|
22013
22201
|
},
|
|
22014
|
-
records: {
|
|
22202
|
+
records: {
|
|
22203
|
+
select: (query) => send({ operation: "records.select", query }),
|
|
22204
|
+
search: (query, options) => {
|
|
22205
|
+
try {
|
|
22206
|
+
return send({ operation: "records.search", ...captureRecordsSearchInput(query, options) });
|
|
22207
|
+
} catch (error) {
|
|
22208
|
+
return Promise.reject(error);
|
|
22209
|
+
}
|
|
22210
|
+
}
|
|
22211
|
+
},
|
|
22015
22212
|
changes() {
|
|
22016
|
-
let updates = [], publicationId;
|
|
22213
|
+
let updates = [], creates = [], deletes = [], publicationId;
|
|
22017
22214
|
let pending, confirmed;
|
|
22018
22215
|
const snapshot = () => {
|
|
22019
|
-
const captured =
|
|
22216
|
+
const captured = captureDataChanges(updates, creates, deletes);
|
|
22217
|
+
const input = {
|
|
22218
|
+
updates: captured.updates,
|
|
22219
|
+
...captured.creates.length ? { creates: captured.creates } : {},
|
|
22220
|
+
...captured.deletes.length ? { deletes: captured.deletes } : {}
|
|
22221
|
+
};
|
|
22020
22222
|
checkDataRequestSize({
|
|
22021
22223
|
repository,
|
|
22022
22224
|
operation: "changes.publish",
|
|
22023
|
-
|
|
22225
|
+
...input,
|
|
22024
22226
|
publicationId: publicationId ?? "00000000-0000-4000-8000-000000000000"
|
|
22025
22227
|
});
|
|
22026
|
-
return
|
|
22228
|
+
return input;
|
|
22027
22229
|
};
|
|
22028
22230
|
return {
|
|
22231
|
+
create(record2) {
|
|
22232
|
+
if (publicationId)
|
|
22233
|
+
throw new DataOperationError("invalid_change", false, "unapplied");
|
|
22234
|
+
const next = [...creates, captureDataCreate(record2)];
|
|
22235
|
+
captureDataChanges(updates, next, deletes);
|
|
22236
|
+
checkDataRequestSize({
|
|
22237
|
+
repository,
|
|
22238
|
+
operation: "changes.publish",
|
|
22239
|
+
updates,
|
|
22240
|
+
creates: next,
|
|
22241
|
+
...deletes.length ? { deletes } : {},
|
|
22242
|
+
publicationId: "00000000-0000-4000-8000-000000000000"
|
|
22243
|
+
});
|
|
22244
|
+
creates = next;
|
|
22245
|
+
},
|
|
22029
22246
|
update(record2, set) {
|
|
22030
22247
|
if (publicationId)
|
|
22031
22248
|
throw new DataOperationError("invalid_change", false, "unapplied");
|
|
22032
22249
|
const next = [...updates, captureDataUpdate(record2, set)];
|
|
22033
|
-
|
|
22250
|
+
captureDataChanges(next, creates, deletes);
|
|
22034
22251
|
checkDataRequestSize({
|
|
22035
22252
|
repository,
|
|
22036
22253
|
operation: "changes.publish",
|
|
22037
22254
|
updates: next,
|
|
22255
|
+
...creates.length ? { creates } : {},
|
|
22256
|
+
...deletes.length ? { deletes } : {},
|
|
22038
22257
|
publicationId: "00000000-0000-4000-8000-000000000000"
|
|
22039
22258
|
});
|
|
22040
22259
|
updates = next;
|
|
22041
22260
|
},
|
|
22261
|
+
delete(record2) {
|
|
22262
|
+
if (publicationId)
|
|
22263
|
+
throw new DataOperationError("invalid_change", false, "unapplied");
|
|
22264
|
+
const next = [...deletes, captureDataDelete(record2)];
|
|
22265
|
+
captureDataChanges(updates, creates, next);
|
|
22266
|
+
checkDataRequestSize({
|
|
22267
|
+
repository,
|
|
22268
|
+
operation: "changes.publish",
|
|
22269
|
+
updates,
|
|
22270
|
+
deletes: next,
|
|
22271
|
+
...creates.length ? { creates } : {},
|
|
22272
|
+
publicationId: "00000000-0000-4000-8000-000000000000"
|
|
22273
|
+
});
|
|
22274
|
+
deletes = next;
|
|
22275
|
+
},
|
|
22042
22276
|
async validate() {
|
|
22043
|
-
await send({ operation: "changes.validate",
|
|
22277
|
+
await send({ operation: "changes.validate", ...snapshot() });
|
|
22044
22278
|
},
|
|
22045
22279
|
publish() {
|
|
22046
22280
|
if (confirmed)
|
|
@@ -22053,12 +22287,12 @@ var data = {
|
|
|
22053
22287
|
return Promise.reject(error);
|
|
22054
22288
|
}
|
|
22055
22289
|
publicationId ??= crypto.randomUUID();
|
|
22056
|
-
pending = send({ operation: "changes.publish",
|
|
22290
|
+
pending = send({ operation: "changes.publish", ...captured, publicationId }).then((result) => {
|
|
22057
22291
|
confirmed = structuredClone(result);
|
|
22058
22292
|
return result;
|
|
22059
22293
|
}).catch((error) => {
|
|
22060
22294
|
if (error instanceof DataOperationError)
|
|
22061
|
-
throw new DataOperationError(error.code, error.retryable, error.effect ?? (["unavailable", "publication_pending"].includes(error.code) ? "uncertain" : "unapplied"));
|
|
22295
|
+
throw new DataOperationError(error.code, error.retryable, error.effect ?? (["unavailable", "publication_pending"].includes(error.code) ? "uncertain" : "unapplied"), error.component);
|
|
22062
22296
|
throw new DataOperationError("unavailable", true, "uncertain");
|
|
22063
22297
|
}).finally(() => {
|
|
22064
22298
|
pending = undefined;
|
|
@@ -22079,14 +22313,14 @@ var TIMEOUT_MS = 30000;
|
|
|
22079
22313
|
var MAX_ACTIVE = 4;
|
|
22080
22314
|
var ATTEMPTS = 2;
|
|
22081
22315
|
var active = 0;
|
|
22082
|
-
var
|
|
22316
|
+
var invalid2 = () => new FileOperationError("invalid_input", 400);
|
|
22083
22317
|
var unavailable = () => new FileOperationError("unavailable", 503, true);
|
|
22084
22318
|
var failures = {
|
|
22085
22319
|
400: ["invalid_input", "unsupported_context"],
|
|
22086
22320
|
401: ["unauthenticated"],
|
|
22087
22321
|
403: ["access_denied"],
|
|
22088
22322
|
405: ["method_not_allowed"],
|
|
22089
|
-
409: ["conflict"],
|
|
22323
|
+
409: ["conflict", "local_only"],
|
|
22090
22324
|
413: ["request_too_large"],
|
|
22091
22325
|
429: ["capacity"],
|
|
22092
22326
|
503: ["integrity", "unavailable"]
|
|
@@ -22103,7 +22337,7 @@ async function boundedBytes(stream, limit) {
|
|
|
22103
22337
|
if (done)
|
|
22104
22338
|
break;
|
|
22105
22339
|
if (!(value instanceof Uint8Array))
|
|
22106
|
-
throw
|
|
22340
|
+
throw invalid2();
|
|
22107
22341
|
size += value.byteLength;
|
|
22108
22342
|
if (size > limit)
|
|
22109
22343
|
throw new FileOperationError("request_too_large", 413);
|
|
@@ -22143,8 +22377,76 @@ async function result(response) {
|
|
|
22143
22377
|
throw unavailable();
|
|
22144
22378
|
}
|
|
22145
22379
|
}
|
|
22380
|
+
async function hostedContent(url, init, parent) {
|
|
22381
|
+
const delivery = new AbortController;
|
|
22382
|
+
const abort = () => delivery.abort(parent.reason);
|
|
22383
|
+
parent.addEventListener("abort", abort, { once: true });
|
|
22384
|
+
if (parent.aborted)
|
|
22385
|
+
abort();
|
|
22386
|
+
const detach = () => parent.removeEventListener("abort", abort);
|
|
22387
|
+
try {
|
|
22388
|
+
const response = await fetch(url, { ...init, signal: delivery.signal });
|
|
22389
|
+
if (delivery.signal.aborted) {
|
|
22390
|
+
response.body?.cancel().catch(() => {});
|
|
22391
|
+
throw unavailable();
|
|
22392
|
+
}
|
|
22393
|
+
if (!response.body) {
|
|
22394
|
+
detach();
|
|
22395
|
+
return response;
|
|
22396
|
+
}
|
|
22397
|
+
const source = response.body;
|
|
22398
|
+
let reader;
|
|
22399
|
+
let settled = false;
|
|
22400
|
+
const cancel = async (reason) => {
|
|
22401
|
+
if (settled)
|
|
22402
|
+
return;
|
|
22403
|
+
settled = true;
|
|
22404
|
+
detach();
|
|
22405
|
+
delivery.abort(reason);
|
|
22406
|
+
try {
|
|
22407
|
+
await (reader ? reader.cancel(reason) : source.cancel(reason));
|
|
22408
|
+
} catch (error) {
|
|
22409
|
+
if (error !== delivery.signal.reason && !(error instanceof Error && error.name === "AbortError"))
|
|
22410
|
+
throw error;
|
|
22411
|
+
} finally {
|
|
22412
|
+
reader?.releaseLock();
|
|
22413
|
+
}
|
|
22414
|
+
};
|
|
22415
|
+
const body = new ReadableStream({
|
|
22416
|
+
async pull(controller) {
|
|
22417
|
+
try {
|
|
22418
|
+
reader ??= source.getReader();
|
|
22419
|
+
const { done, value } = await reader.read();
|
|
22420
|
+
if (settled)
|
|
22421
|
+
return;
|
|
22422
|
+
if (done) {
|
|
22423
|
+
settled = true;
|
|
22424
|
+
detach();
|
|
22425
|
+
reader.releaseLock();
|
|
22426
|
+
controller.close();
|
|
22427
|
+
} else
|
|
22428
|
+
controller.enqueue(value);
|
|
22429
|
+
} catch (error) {
|
|
22430
|
+
if (settled)
|
|
22431
|
+
return;
|
|
22432
|
+
controller.error(error);
|
|
22433
|
+
await cancel(error).catch(() => {});
|
|
22434
|
+
}
|
|
22435
|
+
},
|
|
22436
|
+
cancel
|
|
22437
|
+
}, { highWaterMark: 0 });
|
|
22438
|
+
const wrapped = new Response(body, { status: response.status, statusText: response.statusText, headers: response.headers });
|
|
22439
|
+
for (const key of ["url", "redirected", "type"])
|
|
22440
|
+
Object.defineProperty(wrapped, key, { value: response[key] });
|
|
22441
|
+
return wrapped;
|
|
22442
|
+
} catch (error) {
|
|
22443
|
+
detach();
|
|
22444
|
+
delivery.abort(error);
|
|
22445
|
+
throw error;
|
|
22446
|
+
}
|
|
22447
|
+
}
|
|
22146
22448
|
async function send(suffix, init, descriptor, initial, parent) {
|
|
22147
|
-
const original = initial
|
|
22449
|
+
const original = initial;
|
|
22148
22450
|
const checkCurrent = () => {
|
|
22149
22451
|
if (parent?.aborted)
|
|
22150
22452
|
throw unavailable();
|
|
@@ -22153,37 +22455,75 @@ async function send(suffix, init, descriptor, initial, parent) {
|
|
|
22153
22455
|
};
|
|
22154
22456
|
for (let attempt = 0;attempt < ATTEMPTS; attempt++) {
|
|
22155
22457
|
checkCurrent();
|
|
22156
|
-
const context =
|
|
22458
|
+
const context = await resolveFilesContext();
|
|
22157
22459
|
checkCurrent();
|
|
22158
22460
|
if (context.url !== original.url)
|
|
22159
22461
|
throw new FileOperationError("unsupported_context", 400);
|
|
22160
22462
|
try {
|
|
22161
|
-
return await
|
|
22162
|
-
const response = await
|
|
22163
|
-
|
|
22164
|
-
|
|
22165
|
-
|
|
22166
|
-
|
|
22167
|
-
|
|
22168
|
-
|
|
22463
|
+
return await (async () => {
|
|
22464
|
+
const response = context.local ? await (async () => {
|
|
22465
|
+
const body = init.body instanceof ArrayBuffer ? new Uint8Array(init.body) : undefined;
|
|
22466
|
+
let binary = "";
|
|
22467
|
+
if (body)
|
|
22468
|
+
for (let offset = 0;offset < body.length; offset += 8192)
|
|
22469
|
+
binary += String.fromCharCode(...body.subarray(offset, offset + 8192));
|
|
22470
|
+
const value2 = await context.local("files/request", {
|
|
22471
|
+
suffix,
|
|
22472
|
+
method: init.method,
|
|
22473
|
+
headers: Object.fromEntries(new Headers(init.headers)),
|
|
22474
|
+
...body ? { bytes: btoa(binary) } : {}
|
|
22475
|
+
});
|
|
22476
|
+
if (value2.bytes !== undefined) {
|
|
22477
|
+
if (value2.bytes.length > Math.ceil(MAX_BYTES / 3) * 4)
|
|
22478
|
+
throw unavailable();
|
|
22479
|
+
const data2 = atob(value2.bytes);
|
|
22480
|
+
return new Response(Uint8Array.from(data2, (c) => c.charCodeAt(0)), { status: value2.status, headers: value2.headers });
|
|
22481
|
+
}
|
|
22482
|
+
return Response.json(value2.json, { status: value2.status, headers: value2.headers });
|
|
22483
|
+
})() : await (async () => {
|
|
22484
|
+
const url = `${context.url}${suffix}`;
|
|
22485
|
+
const request = {
|
|
22486
|
+
...init,
|
|
22487
|
+
signal: parent,
|
|
22488
|
+
headers: { ...context.headers, ...init.headers },
|
|
22489
|
+
redirect: "error",
|
|
22490
|
+
cache: "no-store"
|
|
22491
|
+
};
|
|
22492
|
+
return descriptor ? fetch(url, request) : hostedContent(url, request, parent);
|
|
22493
|
+
})();
|
|
22169
22494
|
if (!response.ok) {
|
|
22170
|
-
const
|
|
22171
|
-
const error =
|
|
22495
|
+
const value2 = await result(response);
|
|
22496
|
+
const error = value2 && typeof value2 === "object" && "error" in value2 ? value2.error : undefined;
|
|
22172
22497
|
const received = error && typeof error === "object" && "code" in error ? error.code : undefined;
|
|
22173
22498
|
const code = failures[response.status]?.find((code2) => code2 === received);
|
|
22174
22499
|
throw code ? new FileOperationError(code, response.status, code === "capacity" || code === "unavailable") : unavailable();
|
|
22175
22500
|
}
|
|
22176
|
-
if (response.status !== 200)
|
|
22501
|
+
if (response.status !== 200) {
|
|
22502
|
+
response.body?.cancel().catch(() => {});
|
|
22177
22503
|
throw unavailable();
|
|
22178
|
-
|
|
22504
|
+
}
|
|
22505
|
+
try {
|
|
22506
|
+
checkCurrent();
|
|
22507
|
+
} catch (error) {
|
|
22508
|
+
response.body?.cancel().catch(() => {});
|
|
22509
|
+
throw error;
|
|
22510
|
+
}
|
|
22179
22511
|
if (!descriptor)
|
|
22180
22512
|
return response;
|
|
22181
|
-
const
|
|
22182
|
-
|
|
22183
|
-
|
|
22513
|
+
const value = await result(response);
|
|
22514
|
+
let parsed;
|
|
22515
|
+
if (descriptor === "enrichment") {
|
|
22516
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
22517
|
+
throw unavailable();
|
|
22518
|
+
const { name, ...metadata } = value;
|
|
22519
|
+
if (!safeEnrichmentName(name))
|
|
22520
|
+
throw unavailable();
|
|
22521
|
+
parsed = { name, ...parseEnrichmentDescriptor(metadata) };
|
|
22522
|
+
} else
|
|
22523
|
+
parsed = parseFileDescriptor(value);
|
|
22184
22524
|
checkCurrent();
|
|
22185
|
-
return
|
|
22186
|
-
}
|
|
22525
|
+
return parsed;
|
|
22526
|
+
})();
|
|
22187
22527
|
} catch (error) {
|
|
22188
22528
|
const failure = error instanceof FileOperationError ? error : unavailable();
|
|
22189
22529
|
if (!failure.retryable || attempt + 1 === ATTEMPTS)
|
|
@@ -22194,22 +22534,92 @@ async function send(suffix, init, descriptor, initial, parent) {
|
|
|
22194
22534
|
}
|
|
22195
22535
|
function idPath(id2) {
|
|
22196
22536
|
if (typeof id2 !== "string" || !FILE_ID_PATTERN.test(id2))
|
|
22197
|
-
throw
|
|
22537
|
+
throw invalid2();
|
|
22198
22538
|
return `/${id2}`;
|
|
22199
22539
|
}
|
|
22540
|
+
async function operation(work, initial, parent) {
|
|
22541
|
+
const context = initial ?? await resolveFilesContext();
|
|
22542
|
+
if (active >= MAX_ACTIVE)
|
|
22543
|
+
throw new FileOperationError("capacity", 429, true);
|
|
22544
|
+
active++;
|
|
22545
|
+
return timed(async (signal) => {
|
|
22546
|
+
try {
|
|
22547
|
+
return await work(context, signal);
|
|
22548
|
+
} finally {
|
|
22549
|
+
active--;
|
|
22550
|
+
}
|
|
22551
|
+
}, parent).catch((error) => {
|
|
22552
|
+
throw error instanceof FileOperationError ? error : unavailable();
|
|
22553
|
+
});
|
|
22554
|
+
}
|
|
22555
|
+
function contentPath(id2, name) {
|
|
22556
|
+
const path = idPath(id2);
|
|
22557
|
+
if (name === undefined)
|
|
22558
|
+
return `${path}/content`;
|
|
22559
|
+
if (!safeEnrichmentName(name))
|
|
22560
|
+
throw invalid2();
|
|
22561
|
+
return `${path}/enrichments/${encodeURIComponent(name)}/content`;
|
|
22562
|
+
}
|
|
22563
|
+
async function read(id2, names) {
|
|
22564
|
+
const context = await resolveFilesContext();
|
|
22565
|
+
idPath(id2);
|
|
22566
|
+
if (names === undefined || typeof names === "string") {
|
|
22567
|
+
const path = contentPath(id2, names);
|
|
22568
|
+
return operation((context2, signal) => send(path, { method: "GET" }, false, context2, signal), context);
|
|
22569
|
+
}
|
|
22570
|
+
if (!Array.isArray(names))
|
|
22571
|
+
throw invalid2();
|
|
22572
|
+
const distinct = [];
|
|
22573
|
+
const seen = new Set;
|
|
22574
|
+
for (const name of names) {
|
|
22575
|
+
if (typeof name !== "string" || !safeEnrichmentName(name))
|
|
22576
|
+
throw invalid2();
|
|
22577
|
+
if (seen.has(name))
|
|
22578
|
+
continue;
|
|
22579
|
+
if (seen.size === 16)
|
|
22580
|
+
throw invalid2();
|
|
22581
|
+
seen.add(name);
|
|
22582
|
+
distinct.push(name);
|
|
22583
|
+
}
|
|
22584
|
+
const paths = distinct.map((name) => contentPath(id2, name));
|
|
22585
|
+
return timed(async (parent) => {
|
|
22586
|
+
const responses = {};
|
|
22587
|
+
try {
|
|
22588
|
+
for (let i = 0;i < paths.length; i++) {
|
|
22589
|
+
const response = await operation((context2, signal) => send(paths[i], { method: "GET" }, false, context2, signal), context, parent);
|
|
22590
|
+
Object.defineProperty(responses, distinct[i], { value: response, enumerable: true });
|
|
22591
|
+
}
|
|
22592
|
+
if (!context.isCurrent())
|
|
22593
|
+
throw new FileOperationError("unsupported_context", 400);
|
|
22594
|
+
return responses;
|
|
22595
|
+
} catch (error) {
|
|
22596
|
+
for (const response of Object.values(responses))
|
|
22597
|
+
response.body?.cancel().catch(() => {});
|
|
22598
|
+
throw error;
|
|
22599
|
+
}
|
|
22600
|
+
});
|
|
22601
|
+
}
|
|
22200
22602
|
var files = {
|
|
22603
|
+
async upload(id2) {
|
|
22604
|
+
return operation(async (context, signal) => {
|
|
22605
|
+
const file = await send(`${idPath(id2)}/upload`, { method: "POST" }, true, context, signal);
|
|
22606
|
+
if (file.id !== id2)
|
|
22607
|
+
throw unavailable();
|
|
22608
|
+
return file;
|
|
22609
|
+
});
|
|
22610
|
+
},
|
|
22201
22611
|
async create(input, options) {
|
|
22202
22612
|
const context = await resolveFilesContext();
|
|
22203
22613
|
if (!input || typeof input !== "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "size", "path", "name", "storage", "csv"].includes(key)) || options !== undefined && (!options || typeof options !== "object" || Array.isArray(options) || Object.keys(options).some((key) => key !== "requestKey")))
|
|
22204
|
-
throw
|
|
22614
|
+
throw invalid2();
|
|
22205
22615
|
const blob = input.file instanceof Blob;
|
|
22206
22616
|
const array2 = input.file instanceof Uint8Array;
|
|
22207
22617
|
const stream = input.file instanceof ReadableStream;
|
|
22208
22618
|
if (!blob && !array2 && !stream)
|
|
22209
|
-
throw
|
|
22619
|
+
throw invalid2();
|
|
22210
22620
|
const intrinsic = blob ? input.file.size : array2 ? input.file.byteLength : undefined;
|
|
22211
22621
|
if (intrinsic !== undefined && input.size !== undefined && input.size !== intrinsic)
|
|
22212
|
-
throw
|
|
22622
|
+
throw invalid2();
|
|
22213
22623
|
let name = input.name;
|
|
22214
22624
|
if (name === undefined && blob && "name" in input.file && typeof input.file.name === "string") {
|
|
22215
22625
|
name = typeof globalThis.File !== "undefined" && input.file instanceof globalThis.File ? input.file.name : input.file.name.split(/[\\/]/).at(-1);
|
|
@@ -22222,9 +22632,11 @@ var files = {
|
|
|
22222
22632
|
csv: input.csv,
|
|
22223
22633
|
requestKey: options?.requestKey === undefined ? crypto.randomUUID() : options.requestKey
|
|
22224
22634
|
}, MAX_BYTES);
|
|
22635
|
+
if (!context.local && metadata.storage === "local")
|
|
22636
|
+
throw new FileOperationError("unsupported_context", 400);
|
|
22225
22637
|
const header = encodeURIComponent(JSON.stringify(metadata));
|
|
22226
22638
|
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES)
|
|
22227
|
-
throw
|
|
22639
|
+
throw invalid2();
|
|
22228
22640
|
if (active >= MAX_ACTIVE)
|
|
22229
22641
|
throw new FileOperationError("capacity", 429, true);
|
|
22230
22642
|
active++;
|
|
@@ -22232,7 +22644,7 @@ var files = {
|
|
|
22232
22644
|
try {
|
|
22233
22645
|
const bytes = array2 ? input.file.slice() : await boundedBytes(blob ? input.file.stream() : input.file, metadata.size);
|
|
22234
22646
|
if (bytes.byteLength !== metadata.size)
|
|
22235
|
-
throw
|
|
22647
|
+
throw invalid2();
|
|
22236
22648
|
if (signal.aborted)
|
|
22237
22649
|
throw unavailable();
|
|
22238
22650
|
return await send("", {
|
|
@@ -22247,12 +22659,45 @@ var files = {
|
|
|
22247
22659
|
throw error instanceof FileOperationError ? error : unavailable();
|
|
22248
22660
|
});
|
|
22249
22661
|
},
|
|
22662
|
+
async enrich(input) {
|
|
22663
|
+
const context = await resolveFilesContext();
|
|
22664
|
+
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))
|
|
22665
|
+
throw invalid2();
|
|
22666
|
+
const path = `${idPath(input.file)}/enrichments`;
|
|
22667
|
+
if (typeof input.content === "string" ? input.content.length > MAX_BYTES : input.content.byteLength > MAX_BYTES)
|
|
22668
|
+
throw new FileOperationError("request_too_large", 413);
|
|
22669
|
+
return operation(async (context2, signal) => {
|
|
22670
|
+
let bytes;
|
|
22671
|
+
if (typeof input.content === "string") {
|
|
22672
|
+
const buffer = new Uint8Array(Math.min(MAX_BYTES, input.content.length * 3));
|
|
22673
|
+
const encoded = new TextEncoder().encodeInto(input.content, buffer);
|
|
22674
|
+
if (encoded.read !== input.content.length)
|
|
22675
|
+
throw new FileOperationError("request_too_large", 413);
|
|
22676
|
+
bytes = buffer.slice(0, encoded.written);
|
|
22677
|
+
} else
|
|
22678
|
+
bytes = input.content.slice();
|
|
22679
|
+
const metadata = parseFileEnrichMetadata({
|
|
22680
|
+
name: input.name,
|
|
22681
|
+
size: bytes.byteLength,
|
|
22682
|
+
...input.mediaType === undefined ? {} : { mediaType: input.mediaType },
|
|
22683
|
+
...input.replace === undefined ? {} : { replace: input.replace }
|
|
22684
|
+
}, MAX_BYTES);
|
|
22685
|
+
const header = encodeURIComponent(JSON.stringify(metadata));
|
|
22686
|
+
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES)
|
|
22687
|
+
throw invalid2();
|
|
22688
|
+
const result2 = await send(path, { method: "POST", headers: {
|
|
22689
|
+
"content-type": "application/octet-stream",
|
|
22690
|
+
"x-oddington-enrichment": header
|
|
22691
|
+
}, body: bytes.buffer }, "enrichment", context2, signal);
|
|
22692
|
+
if (result2.name !== metadata.name)
|
|
22693
|
+
throw unavailable();
|
|
22694
|
+
return result2;
|
|
22695
|
+
}, context);
|
|
22696
|
+
},
|
|
22250
22697
|
async get(id2) {
|
|
22251
|
-
return send(idPath(id2), { method: "GET" }, true);
|
|
22698
|
+
return operation((context, signal) => send(idPath(id2), { method: "GET" }, true, context, signal));
|
|
22252
22699
|
},
|
|
22253
|
-
|
|
22254
|
-
return send(`${idPath(id2)}/content`, { method: "GET" }, false);
|
|
22255
|
-
}
|
|
22700
|
+
read
|
|
22256
22701
|
};
|
|
22257
22702
|
// src/os.ts
|
|
22258
22703
|
var installedDispose;
|
|
@@ -22336,16 +22781,16 @@ function routinePublicationClient(options = {}) {
|
|
|
22336
22781
|
} : async () => {
|
|
22337
22782
|
throw new Error("Member publication requires a host-supplied request");
|
|
22338
22783
|
});
|
|
22339
|
-
async function send2(
|
|
22784
|
+
async function send2(operation2, body) {
|
|
22340
22785
|
if (local)
|
|
22341
|
-
return await local(
|
|
22342
|
-
const response = await request(`/api/cli/workspaces/${workspace}/inbox/${
|
|
22786
|
+
return await local(operation2, body);
|
|
22787
|
+
const response = await request(`/api/cli/workspaces/${workspace}/inbox/${operation2}`, {
|
|
22343
22788
|
method: "POST",
|
|
22344
22789
|
headers: { "content-type": "application/json", ...headers },
|
|
22345
22790
|
body: JSON.stringify(body)
|
|
22346
22791
|
});
|
|
22347
22792
|
const result2 = await response.json();
|
|
22348
|
-
if (!response.ok &&
|
|
22793
|
+
if (!response.ok && operation2 === "records/update")
|
|
22349
22794
|
throw new RoutineRecordWriteError(result2.error ?? "Could not confirm routine preparation", result2.effect ?? "uncertain");
|
|
22350
22795
|
if (!response.ok)
|
|
22351
22796
|
throw new Error(result2.error ?? "Could not confirm routine publication");
|