@oddington/sdk 0.1.27 → 0.1.29
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 +24 -4
- package/dist/browser.js +280 -176
- package/dist/index.js +9 -9
- package/dist/types/packages/sdk/src/data-schema-types.d.ts +186 -0
- package/dist/types/packages/sdk/src/public.d.ts +4 -1
- package/dist/types/packages/sdk/src/routine-definition-types.d.ts +3 -1
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -10,12 +10,12 @@ var FileOperationError = class extends Error {
|
|
|
10
10
|
retryable;
|
|
11
11
|
}, 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;
|
|
12
12
|
function parseFileDescriptor(value) {
|
|
13
|
-
let
|
|
13
|
+
let invalid9 = () => {
|
|
14
14
|
throw new FileOperationError("unavailable", 503, !0);
|
|
15
15
|
};
|
|
16
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
16
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid9();
|
|
17
17
|
let f = value;
|
|
18
|
-
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
|
|
18
|
+
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 invalid9();
|
|
19
19
|
let d = f.details;
|
|
20
20
|
if (d.kind === "other") {
|
|
21
21
|
if (Object.keys(d).length !== 1 || ![
|
|
@@ -25,36 +25,36 @@ function parseFileDescriptor(value) {
|
|
|
25
25
|
"application/json",
|
|
26
26
|
"image/png",
|
|
27
27
|
"image/jpeg"
|
|
28
|
-
].includes(f.mediaType)) return
|
|
28
|
+
].includes(f.mediaType)) return invalid9();
|
|
29
29
|
} else if (d.kind === "csv") {
|
|
30
|
-
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
|
|
30
|
+
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 invalid9();
|
|
31
31
|
} else if (d.kind === "pdf") {
|
|
32
|
-
if (f.mediaType !== "application/pdf" || Object.keys(d).some((key) => !["kind", "pages"].includes(key)) || "pages" in d && (!Number.isSafeInteger(d.pages) || d.pages < 1)) return
|
|
33
|
-
} else return
|
|
34
|
-
for (let [
|
|
35
|
-
if (!safeEnrichmentName(
|
|
32
|
+
if (f.mediaType !== "application/pdf" || Object.keys(d).some((key) => !["kind", "pages"].includes(key)) || "pages" in d && (!Number.isSafeInteger(d.pages) || d.pages < 1)) return invalid9();
|
|
33
|
+
} else return invalid9();
|
|
34
|
+
for (let [name2, descriptor] of Object.entries(f.enrichments)) {
|
|
35
|
+
if (!safeEnrichmentName(name2)) return invalid9();
|
|
36
36
|
parseEnrichmentDescriptor(descriptor);
|
|
37
37
|
}
|
|
38
|
-
return new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024 ?
|
|
38
|
+
return new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024 ? invalid9() : f;
|
|
39
39
|
}
|
|
40
40
|
function parseEnrichmentDescriptor(value) {
|
|
41
|
-
let
|
|
41
|
+
let invalid9 = () => {
|
|
42
42
|
throw new FileOperationError("unavailable", 503, !0);
|
|
43
43
|
};
|
|
44
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
44
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid9();
|
|
45
45
|
let d = value;
|
|
46
|
-
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) ?
|
|
46
|
+
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) ? invalid9() : d;
|
|
47
47
|
}
|
|
48
48
|
function safeEnrichmentName(value) {
|
|
49
49
|
return safeFileName(value) && !/^original(?:\.|$)/i.test(value);
|
|
50
50
|
}
|
|
51
51
|
function parseFileEnrichMetadata(value, maxBytes) {
|
|
52
|
-
let
|
|
52
|
+
let invalid9 = () => {
|
|
53
53
|
throw new FileOperationError("invalid_input", 400);
|
|
54
54
|
};
|
|
55
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
55
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid9();
|
|
56
56
|
let d = value;
|
|
57
|
-
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
|
|
57
|
+
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 invalid9();
|
|
58
58
|
if (d.size > maxBytes) throw new FileOperationError("request_too_large", 413);
|
|
59
59
|
return d;
|
|
60
60
|
}
|
|
@@ -73,23 +73,23 @@ function declaredOriginalMediaType(value) {
|
|
|
73
73
|
return ORIGINAL_MEDIA_TYPES.includes(normalized) ? normalized : void 0;
|
|
74
74
|
}
|
|
75
75
|
function parseFileCreateMetadata(value, maxBytes) {
|
|
76
|
-
let
|
|
76
|
+
let invalid9 = () => {
|
|
77
77
|
throw new FileOperationError("invalid_input", 400);
|
|
78
78
|
};
|
|
79
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
79
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid9();
|
|
80
80
|
let input = value;
|
|
81
|
-
if (Object.keys(input).some((key) => !["name", "path", "storage", "csv", "inputMediaType", "size", "requestKey"].includes(key))) return
|
|
81
|
+
if (Object.keys(input).some((key) => !["name", "path", "storage", "csv", "inputMediaType", "size", "requestKey"].includes(key))) return invalid9();
|
|
82
82
|
let path = input.path === void 0 ? "Files" : input.path;
|
|
83
|
-
if (!safeFileName(input.name) || !safeManagedFilePath(path) || input.storage !== void 0 && input.storage !== "remote" && input.storage !== "local" || input.inputMediaType !== void 0 && (typeof input.inputMediaType != "string" || !ORIGINAL_MEDIA_TYPES.includes(input.inputMediaType)) || !Number.isSafeInteger(input.size) || input.size < 0) return
|
|
83
|
+
if (!safeFileName(input.name) || !safeManagedFilePath(path) || input.storage !== void 0 && input.storage !== "remote" && input.storage !== "local" || input.inputMediaType !== void 0 && (typeof input.inputMediaType != "string" || !ORIGINAL_MEDIA_TYPES.includes(input.inputMediaType)) || !Number.isSafeInteger(input.size) || input.size < 0) return invalid9();
|
|
84
84
|
if (input.size > maxBytes) throw new FileOperationError("request_too_large", 413);
|
|
85
|
-
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
|
|
85
|
+
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 invalid9();
|
|
86
86
|
let csv;
|
|
87
87
|
if (input.csv !== void 0) {
|
|
88
|
-
if (!input.csv || typeof input.csv != "object" || Array.isArray(input.csv)) return
|
|
88
|
+
if (!input.csv || typeof input.csv != "object" || Array.isArray(input.csv)) return invalid9();
|
|
89
89
|
let hints = input.csv;
|
|
90
|
-
if (Object.keys(hints).some((key) => !["encoding", "delimiter", "headerRow"].includes(key))) return
|
|
90
|
+
if (Object.keys(hints).some((key) => !["encoding", "delimiter", "headerRow"].includes(key))) return invalid9();
|
|
91
91
|
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;
|
|
92
|
-
if (encoding !== "utf-8" && encoding !== "windows-1252" || ![",", ";", " "].includes(delimiter) || !Number.isSafeInteger(headerRow) || headerRow < 1 || headerRow > 1e5) return
|
|
92
|
+
if (encoding !== "utf-8" && encoding !== "windows-1252" || ![",", ";", " "].includes(delimiter) || !Number.isSafeInteger(headerRow) || headerRow < 1 || headerRow > 1e5) return invalid9();
|
|
93
93
|
csv = { encoding, delimiter, headerRow };
|
|
94
94
|
}
|
|
95
95
|
return {
|
|
@@ -167,8 +167,8 @@ function natural(value, label, minimum = 0) {
|
|
|
167
167
|
function validateInboxFile(value) {
|
|
168
168
|
let v = object(serializable(value), "Inbox file");
|
|
169
169
|
keys(v, ["id", "name", "mediaType", "size", "sha256", "details"], "Inbox file");
|
|
170
|
-
let fileId = id(v.id, "Inbox file ID"),
|
|
171
|
-
(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(fileId) || /[\x00-\x1f\x7f/\\]/.test(
|
|
170
|
+
let fileId = id(v.id, "Inbox file ID"), name2 = id(v.name, "filename"), mediaType = id(v.mediaType, "media type");
|
|
171
|
+
(!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(fileId) || /[\x00-\x1f\x7f/\\]/.test(name2) || !/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/.test(mediaType) || typeof v.sha256 != "string" || !/^[0-9a-f]{64}$/.test(v.sha256)) && fail("Invalid Inbox file identity or metadata");
|
|
172
172
|
let size = natural(v.size, "file size");
|
|
173
173
|
size > FILE_ORIGINAL_MAX_BYTES && fail("File exceeds supported size");
|
|
174
174
|
let d = object(v.details, "file details"), details;
|
|
@@ -191,7 +191,7 @@ function validateInboxFile(value) {
|
|
|
191
191
|
default:
|
|
192
192
|
return fail("Unknown file details kind");
|
|
193
193
|
}
|
|
194
|
-
return { id: fileId, name, mediaType, size, sha256: v.sha256, details };
|
|
194
|
+
return { id: fileId, name: name2, mediaType, size, sha256: v.sha256, details };
|
|
195
195
|
}
|
|
196
196
|
function fields(value) {
|
|
197
197
|
let result2 = array(value, "selected fields").map((entry) => {
|
|
@@ -258,8 +258,8 @@ function fileBlock(value) {
|
|
|
258
258
|
} catch {
|
|
259
259
|
return fail("Invalid shared File descriptor");
|
|
260
260
|
}
|
|
261
|
-
let { id: id3, name, mediaType, size, sha256, details } = file2;
|
|
262
|
-
return { id: id3, name, mediaType, size, sha256, details };
|
|
261
|
+
let { id: id3, name: name2, mediaType, size, sha256, details } = file2;
|
|
262
|
+
return { id: id3, name: name2, mediaType, size, sha256, details };
|
|
263
263
|
});
|
|
264
264
|
return validateBlock({ ...input, kind: "files", files: files3 });
|
|
265
265
|
}
|
|
@@ -311,26 +311,26 @@ function validateRecordSource(value) {
|
|
|
311
311
|
keys(source, ["type", "collection", "refPrefix", "where", "display", "suggestions"], "Record selection"), source.type !== "records" && fail("Expected Record options");
|
|
312
312
|
let collection = object(source.collection, "collection");
|
|
313
313
|
keys(collection, ["repository", "name"], "collection");
|
|
314
|
-
let repository = validateRecordReference({ repository: collection.repository, ref: "records/example" }).repository,
|
|
315
|
-
/^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$/.test(
|
|
314
|
+
let repository = validateRecordReference({ repository: collection.repository, ref: "records/example" }).repository, name2 = id(collection.name, "collection name");
|
|
315
|
+
/^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$/.test(name2) || fail("Invalid collection name");
|
|
316
316
|
let refPrefix = source.refPrefix === void 0 ? void 0 : id(source.refPrefix, "Record reference prefix");
|
|
317
317
|
refPrefix !== void 0 && (!refPrefix.endsWith("/") || refPrefix.length > 512 || !/^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)*\/$/.test(refPrefix)) && fail("Invalid Record reference prefix");
|
|
318
|
-
let where = object(source.where ?? {}, "Record filter"), fieldName = (
|
|
319
|
-
for (let [
|
|
320
|
-
(!fieldName(
|
|
318
|
+
let where = object(source.where ?? {}, "Record filter"), fieldName = (name3) => /^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name3) && !["constructor", "prototype"].includes(name3);
|
|
319
|
+
for (let [name3, value2] of Object.entries(where))
|
|
320
|
+
(!fieldName(name3) || !(value2 === null || ["string", "number", "boolean"].includes(typeof value2)) || typeof value2 == "number" && !Number.isFinite(value2)) && fail("Record filters require scalar equality");
|
|
321
321
|
let display = object(source.display, "Record display");
|
|
322
322
|
keys(display, ["labelFields"], "Record display");
|
|
323
323
|
let labelFields = distinctIds(display.labelFields, "label fields");
|
|
324
|
-
(labelFields.length > 2 || labelFields.some((
|
|
324
|
+
(labelFields.length > 2 || labelFields.some((name3) => !fieldName(name3))) && fail("Select one or two scalar label fields");
|
|
325
325
|
let suggestions = array(source.suggestions ?? [], "suggestions").map((value2) => {
|
|
326
326
|
let entry = object(value2, "suggestion");
|
|
327
327
|
keys(entry, ["record", "reason"], "suggestion");
|
|
328
|
-
let
|
|
329
|
-
return
|
|
328
|
+
let record4 = validateRecordReference(entry.record);
|
|
329
|
+
return record4.repository !== repository && fail("Suggestion belongs to another repository"), { record: record4, ...entry.reason === void 0 ? {} : { reason: text(entry.reason, "suggestion reason") } };
|
|
330
330
|
});
|
|
331
331
|
return (suggestions.length > 8 || new Set(suggestions.map((entry) => entry.record.ref)).size !== suggestions.length) && fail("Record selection permits at most eight unique suggestions"), {
|
|
332
332
|
type: "records",
|
|
333
|
-
collection: { repository, name },
|
|
333
|
+
collection: { repository, name: name2 },
|
|
334
334
|
...refPrefix ? { refPrefix } : {},
|
|
335
335
|
where: { ...where },
|
|
336
336
|
display: { labelFields },
|
|
@@ -387,7 +387,7 @@ function presentation(source) {
|
|
|
387
387
|
new Set(views.map((view) => view.id)).size !== views.length && fail("Duplicate view ID");
|
|
388
388
|
let body = source.body === void 0 ? [] : array(source.body, "body").map(validateBlock);
|
|
389
389
|
for (let block2 of body) {
|
|
390
|
-
let targets = block2.kind === "record" ? [block2.view] : block2.kind === "records" ? [block2.view, ...block2.records.map((
|
|
390
|
+
let targets = block2.kind === "record" ? [block2.view] : block2.kind === "records" ? [block2.view, ...block2.records.map((record4) => record4.view)] : [];
|
|
391
391
|
for (let target of targets) target !== void 0 && !views.some((view) => view.id === target) && fail(`Unknown Block View target: ${target}`);
|
|
392
392
|
}
|
|
393
393
|
return { title: text(source.title, "title"), description: text(source.description, "description"), views, body };
|
|
@@ -700,7 +700,7 @@ function parseRoutineAccess(value) {
|
|
|
700
700
|
try {
|
|
701
701
|
value !== void 0 && assertRoutineJson(value), assertRoutineFields(value ?? {}, ["repositories", "connections", "ai", "files", "publish"]);
|
|
702
702
|
let access = value, names = access?.connections ?? [];
|
|
703
|
-
if (!Array.isArray(names) || names.length > 64 || new Set(names).size !== names.length || names.some((
|
|
703
|
+
if (!Array.isArray(names) || names.length > 64 || new Set(names).size !== names.length || names.some((name2) => typeof name2 != "string" || name2.split("/").length !== 2 || name2.split("/").some((part) => !isAppRoutineName(part)))) return invalidContract2();
|
|
704
704
|
let parsed = parseRoutineDeclaration({ $schema: ROUTINE_DECLARATION_SCHEMA, access: { ...access, connections: [] } }).access;
|
|
705
705
|
return freezeRoutineMetadata({ ...parsed, connections: [...names] });
|
|
706
706
|
} catch {
|
|
@@ -717,14 +717,14 @@ var RoutineAIError = class extends Error {
|
|
|
717
717
|
}
|
|
718
718
|
code;
|
|
719
719
|
};
|
|
720
|
-
function capture(value,
|
|
720
|
+
function capture(value, invalid9, oversized) {
|
|
721
721
|
try {
|
|
722
722
|
assertRoutineJson(value);
|
|
723
723
|
let encoded = JSON.stringify(value);
|
|
724
724
|
if (new TextEncoder().encode(encoded).byteLength > ROUTINE_AI_VALUE_BYTES) throw new RoutineAIError(oversized);
|
|
725
725
|
return freezeRoutineMetadata(JSON.parse(encoded));
|
|
726
726
|
} catch (error) {
|
|
727
|
-
throw error instanceof RoutineAIError ? error : new RoutineAIError(
|
|
727
|
+
throw error instanceof RoutineAIError ? error : new RoutineAIError(invalid9);
|
|
728
728
|
}
|
|
729
729
|
}
|
|
730
730
|
function parseRoutineAIRequest(value) {
|
|
@@ -909,7 +909,10 @@ async function executeRoutineDefinition(definition, input, runtime) {
|
|
|
909
909
|
get(_target, key) {
|
|
910
910
|
return guarded(Reflect.get(value, key, value), value);
|
|
911
911
|
}
|
|
912
|
-
}) : value,
|
|
912
|
+
}) : value, validateHandlers = (value) => {
|
|
913
|
+
for (let question2 of value.questions ?? []) if (question2.handler && !contract.responses.some((handler) => handler.id === question2.handler.id)) return invalid3();
|
|
914
|
+
return value;
|
|
915
|
+
}, os2 = Object.freeze({
|
|
913
916
|
...guarded({
|
|
914
917
|
...runtime,
|
|
915
918
|
run: freezeRoutineMetadata({ ...runtime.run }),
|
|
@@ -923,7 +926,7 @@ async function executeRoutineDefinition(definition, input, runtime) {
|
|
|
923
926
|
if (!active2 || broken) throw new Error("Run authority ended");
|
|
924
927
|
return value;
|
|
925
928
|
} },
|
|
926
|
-
inbox: { ...runtime.inbox, publishAsk: (value, options) => runtime.inbox.publishAsk(
|
|
929
|
+
inbox: { ...runtime.inbox, publishAsk: (value, options) => runtime.inbox.publishAsk(validateHandlers(value), options) }
|
|
927
930
|
}),
|
|
928
931
|
step(id3, ...input2) {
|
|
929
932
|
let saved;
|
|
@@ -1094,12 +1097,12 @@ function captureValue(value, ancestors = /* @__PURE__ */ new Set(), depth = 0) {
|
|
|
1094
1097
|
ancestors.delete(value);
|
|
1095
1098
|
}
|
|
1096
1099
|
}
|
|
1097
|
-
function captureDataDelete(
|
|
1098
|
-
let identity = mapping(
|
|
1100
|
+
function captureDataDelete(record4) {
|
|
1101
|
+
let identity = mapping(record4);
|
|
1099
1102
|
return !validRecordRef(identity.$ref) || typeof identity.$version != "string" || !identity.$version.length || identity.$version.length > 512 ? invalidChange() : { ref: identity.$ref, expectedVersion: identity.$version };
|
|
1100
1103
|
}
|
|
1101
|
-
function captureDataUpdate(
|
|
1102
|
-
let identity = captureDataDelete(
|
|
1104
|
+
function captureDataUpdate(record4, set) {
|
|
1105
|
+
let identity = captureDataDelete(record4), fields5 = mapping(set);
|
|
1103
1106
|
return !Object.keys(fields5).length || Object.keys(fields5).some((key) => key.startsWith("$") || ["id", "type"].includes(key)) ? invalidChange() : { ...identity, set: captureValue(fields5) };
|
|
1104
1107
|
}
|
|
1105
1108
|
function captureIdentities(value, update, allowEmpty = !0) {
|
|
@@ -1122,7 +1125,7 @@ function captureDataCreate(value) {
|
|
|
1122
1125
|
let { $ref: ref, $filing, ...fields5 } = row, filing;
|
|
1123
1126
|
if ($filing !== void 0) {
|
|
1124
1127
|
let components = mapping($filing);
|
|
1125
|
-
if (Object.entries(components).some(([
|
|
1128
|
+
if (Object.entries(components).some(([name2, value2]) => !/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name2) || ["constructor", "prototype"].includes(name2) || typeof value2 != "string" || !/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value2)))
|
|
1126
1129
|
return invalidChange();
|
|
1127
1130
|
filing = { ...components };
|
|
1128
1131
|
}
|
|
@@ -1254,8 +1257,8 @@ function capture3(value, ancestors = /* @__PURE__ */ new Set(), depth = 0) {
|
|
|
1254
1257
|
function recordPagination(select) {
|
|
1255
1258
|
function pages(query) {
|
|
1256
1259
|
let captured = capture3(query), names = Object.keys(historyProperties(captured));
|
|
1257
|
-
for (let
|
|
1258
|
-
let selection2 = historyProperties(captured[
|
|
1260
|
+
for (let name2 of names) {
|
|
1261
|
+
let selection2 = historyProperties(captured[name2]);
|
|
1259
1262
|
if (Object.hasOwn(selection2, "$")) {
|
|
1260
1263
|
let options = historyProperties(selection2.$.value);
|
|
1261
1264
|
if (Object.hasOwn(options, "after")) return invalid6();
|
|
@@ -1263,16 +1266,16 @@ function recordPagination(select) {
|
|
|
1263
1266
|
}
|
|
1264
1267
|
return iterate();
|
|
1265
1268
|
async function* iterate() {
|
|
1266
|
-
let state = new Map(names.map((
|
|
1269
|
+
let state = new Map(names.map((name2) => [name2, {
|
|
1267
1270
|
seen: /* @__PURE__ */ new Set(),
|
|
1268
1271
|
total: 0,
|
|
1269
1272
|
count: void 0,
|
|
1270
1273
|
next: void 0
|
|
1271
1274
|
}])), active2 = names, version;
|
|
1272
1275
|
do {
|
|
1273
|
-
let request2 = Object.fromEntries(active2.map((
|
|
1274
|
-
let selection2 = captured[
|
|
1275
|
-
return [
|
|
1276
|
+
let request2 = Object.fromEntries(active2.map((name2) => {
|
|
1277
|
+
let selection2 = captured[name2], next = state.get(name2).next;
|
|
1278
|
+
return [name2, next === void 0 ? selection2 : { ...selection2, $: { ...selection2.$, after: next } }];
|
|
1276
1279
|
})), response2 = await select(request2), page;
|
|
1277
1280
|
try {
|
|
1278
1281
|
page = capture3(response2);
|
|
@@ -1280,28 +1283,28 @@ function recordPagination(select) {
|
|
|
1280
1283
|
(keys4.length !== active2.length + 1 || keys4.some((key) => key !== "$meta" && !active2.includes(key))) && unavailable();
|
|
1281
1284
|
let meta = page.$meta;
|
|
1282
1285
|
(Object.keys(historyProperties(meta)).sort().join(",") !== "collections,version" || !text2(meta.version) || version !== void 0 && version !== meta.version) && unavailable(), version = meta.version, Object.keys(historyProperties(meta.collections)).some((key) => !active2.includes(key)) && unavailable();
|
|
1283
|
-
for (let
|
|
1284
|
-
let records = historyArray(page[
|
|
1286
|
+
for (let name2 of active2) {
|
|
1287
|
+
let records = historyArray(page[name2]), metadata = Object.hasOwn(meta.collections, name2) ? meta.collections[name2] : {};
|
|
1285
1288
|
(Object.keys(historyProperties(metadata)).some((key) => key !== "count" && key !== "next") || Object.hasOwn(metadata, "next") && !text2(metadata.next)) && unavailable();
|
|
1286
|
-
for (let
|
|
1287
|
-
historyProperties(
|
|
1288
|
-
let row =
|
|
1289
|
+
for (let record4 of records) {
|
|
1290
|
+
historyProperties(record4);
|
|
1291
|
+
let row = record4;
|
|
1289
1292
|
(!validRecordRef(row.$ref) || !text2(row.$version)) && unavailable();
|
|
1290
1293
|
}
|
|
1291
|
-
let current2 = state.get(
|
|
1292
|
-
captured[
|
|
1294
|
+
let current2 = state.get(name2);
|
|
1295
|
+
captured[name2].$?.count === !0 ? ((!Number.isSafeInteger(metadata.count) || metadata.count < 0 || current2.count !== void 0 && current2.count !== metadata.count) && unavailable(), current2.count = metadata.count) : Object.hasOwn(metadata, "count") && unavailable(), current2.total += records.length, (!Number.isSafeInteger(current2.total) || current2.count !== void 0 && (current2.total > current2.count || metadata.next === void 0 && current2.total !== current2.count)) && unavailable(), metadata.next !== void 0 && (current2.seen.has(metadata.next) && unavailable(), current2.seen.add(metadata.next)), current2.next = metadata.next;
|
|
1293
1296
|
}
|
|
1294
1297
|
} catch {
|
|
1295
1298
|
return unavailable();
|
|
1296
1299
|
}
|
|
1297
|
-
let collections = Object.fromEntries(names.map((
|
|
1298
|
-
let current2 = state.get(
|
|
1299
|
-
return [
|
|
1300
|
+
let collections = Object.fromEntries(names.map((name2) => {
|
|
1301
|
+
let current2 = state.get(name2);
|
|
1302
|
+
return [name2, {
|
|
1300
1303
|
...current2.count === void 0 ? {} : { count: current2.count },
|
|
1301
1304
|
...current2.next === void 0 ? {} : { next: current2.next }
|
|
1302
1305
|
}];
|
|
1303
|
-
})), output = Object.fromEntries(names.map((
|
|
1304
|
-
active2 = active2.filter((
|
|
1306
|
+
})), output = Object.fromEntries(names.map((name2) => [name2, active2.includes(name2) ? page[name2] : []]));
|
|
1307
|
+
active2 = active2.filter((name2) => state.get(name2).next !== void 0), yield { ...output, $meta: { version, collections } };
|
|
1305
1308
|
} while (active2.length);
|
|
1306
1309
|
}
|
|
1307
1310
|
}
|
|
@@ -1310,12 +1313,12 @@ function recordPagination(select) {
|
|
|
1310
1313
|
(Object.keys(properties).join(",") !== "maxRecords" || !Number.isSafeInteger(maxRecords) || maxRecords < 1) && invalid6();
|
|
1311
1314
|
let result2, total = 0;
|
|
1312
1315
|
for await (let page of pages(query)) {
|
|
1313
|
-
let names = Object.keys(page.$meta.collections), size = names.reduce((sum,
|
|
1316
|
+
let names = Object.keys(page.$meta.collections), size = names.reduce((sum, name2) => sum + page[name2].length, 0);
|
|
1314
1317
|
if (size > maxRecords - total) throw new DataOperationError("capacity");
|
|
1315
|
-
total += size, result2 ??= { ...Object.fromEntries(names.map((
|
|
1316
|
-
for (let
|
|
1317
|
-
let target = result2[
|
|
1318
|
-
for (let
|
|
1318
|
+
total += size, result2 ??= { ...Object.fromEntries(names.map((name2) => [name2, []])), $meta: page.$meta };
|
|
1319
|
+
for (let name2 of names) {
|
|
1320
|
+
let target = result2[name2];
|
|
1321
|
+
for (let record4 of page[name2]) target.push(record4);
|
|
1319
1322
|
}
|
|
1320
1323
|
result2.$meta = page.$meta;
|
|
1321
1324
|
}
|
|
@@ -1324,7 +1327,7 @@ function recordPagination(select) {
|
|
|
1324
1327
|
return { pages, all };
|
|
1325
1328
|
}
|
|
1326
1329
|
|
|
1327
|
-
var
|
|
1330
|
+
var genericData = {
|
|
1328
1331
|
repository(repository) {
|
|
1329
1332
|
async function send3(input) {
|
|
1330
1333
|
let context2 = await resolveDataContext(), envelope = { repository, ...input };
|
|
@@ -1352,7 +1355,7 @@ var data = {
|
|
|
1352
1355
|
return {
|
|
1353
1356
|
collections: {
|
|
1354
1357
|
list: () => send3({ operation: "collections.list" }),
|
|
1355
|
-
schema: (
|
|
1358
|
+
schema: (name2) => send3({ operation: "collections.schema", name: name2 })
|
|
1356
1359
|
},
|
|
1357
1360
|
records: {
|
|
1358
1361
|
read: read2,
|
|
@@ -1378,19 +1381,19 @@ var data = {
|
|
|
1378
1381
|
}), input;
|
|
1379
1382
|
};
|
|
1380
1383
|
return {
|
|
1381
|
-
create(
|
|
1384
|
+
create(record4) {
|
|
1382
1385
|
assertMutable();
|
|
1383
|
-
let next = [...creates, captureDataCreate(
|
|
1386
|
+
let next = [...creates, captureDataCreate(record4)];
|
|
1384
1387
|
snapshot(updates, next, deletes), creates = next;
|
|
1385
1388
|
},
|
|
1386
|
-
update(
|
|
1389
|
+
update(record4, set) {
|
|
1387
1390
|
assertMutable();
|
|
1388
|
-
let next = [...updates, captureDataUpdate(
|
|
1391
|
+
let next = [...updates, captureDataUpdate(record4, set)];
|
|
1389
1392
|
snapshot(next, creates, deletes), updates = next;
|
|
1390
1393
|
},
|
|
1391
|
-
delete(
|
|
1394
|
+
delete(record4) {
|
|
1392
1395
|
assertMutable();
|
|
1393
|
-
let next = [...deletes, captureDataDelete(
|
|
1396
|
+
let next = [...deletes, captureDataDelete(record4)];
|
|
1394
1397
|
snapshot(updates, creates, next), deletes = next;
|
|
1395
1398
|
},
|
|
1396
1399
|
async validate() {
|
|
@@ -1422,7 +1425,7 @@ var data = {
|
|
|
1422
1425
|
}
|
|
1423
1426
|
};
|
|
1424
1427
|
}
|
|
1425
|
-
};
|
|
1428
|
+
}, data = genericData;
|
|
1426
1429
|
|
|
1427
1430
|
async function hostedContent(url, init2, parent, upstream = fetch, check = async () => {
|
|
1428
1431
|
}, failure) {
|
|
@@ -1576,9 +1579,9 @@ async function send(suffix, init2, descriptor, initial, parent) {
|
|
|
1576
1579
|
let parsed;
|
|
1577
1580
|
if (descriptor === "enrichment") {
|
|
1578
1581
|
if (!value || typeof value != "object" || Array.isArray(value)) throw unavailable2();
|
|
1579
|
-
let { name, ...metadata } = value;
|
|
1580
|
-
if (!safeEnrichmentName(
|
|
1581
|
-
parsed = { name, ...parseEnrichmentDescriptor(metadata) };
|
|
1582
|
+
let { name: name2, ...metadata } = value;
|
|
1583
|
+
if (!safeEnrichmentName(name2)) throw unavailable2();
|
|
1584
|
+
parsed = { name: name2, ...parseEnrichmentDescriptor(metadata) };
|
|
1582
1585
|
} else parsed = parseFileDescriptor(value);
|
|
1583
1586
|
return checkCurrent(), parsed;
|
|
1584
1587
|
} catch (error) {
|
|
@@ -1655,10 +1658,10 @@ async function multipartCreate(input, metadata, exchange, release = () => {
|
|
|
1655
1658
|
if (!receipt || typeof receipt != "object" || Object.keys(receipt).sort().join(",") !== "etag,partNumber" || receipt.partNumber !== partNumber || typeof receipt.etag != "string" || !receipt.etag || receipt.etag.length > 256 || /[\u0000-\u001f\u007f]/.test(receipt.etag)) throw unavailable2();
|
|
1656
1659
|
receipts.push({ partNumber, etag: receipt.etag }), sent += length, lastProgress = Date.now();
|
|
1657
1660
|
}
|
|
1658
|
-
if (upload) for (let
|
|
1659
|
-
let bytes = await request2(() => upload.enrichment(
|
|
1660
|
-
if (bytes.byteLength !== upload.file.enrichments[
|
|
1661
|
-
await request2((signal) => exchange(`${route}/enrichments/${encodeURIComponent(
|
|
1661
|
+
if (upload) for (let name2 of Object.keys(upload.file.enrichments)) {
|
|
1662
|
+
let bytes = await request2(() => upload.enrichment(name2));
|
|
1663
|
+
if (bytes.byteLength !== upload.file.enrichments[name2].size || bytes.byteLength > MAX_BYTES) throw invalid7();
|
|
1664
|
+
await request2((signal) => exchange(`${route}/enrichments/${encodeURIComponent(name2)}`, {
|
|
1662
1665
|
method: "POST",
|
|
1663
1666
|
headers: { "content-type": "application/octet-stream", "x-os-transfer": ticket },
|
|
1664
1667
|
body: bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength)
|
|
@@ -1694,11 +1697,11 @@ async function operation(work, initial, parent) {
|
|
|
1694
1697
|
throw error instanceof FileOperationError ? error : unavailable2();
|
|
1695
1698
|
});
|
|
1696
1699
|
}
|
|
1697
|
-
function contentPath(id3,
|
|
1700
|
+
function contentPath(id3, name2) {
|
|
1698
1701
|
let path = idPath(id3);
|
|
1699
|
-
if (
|
|
1700
|
-
if (!safeEnrichmentName(
|
|
1701
|
-
return `${path}/enrichments/${encodeURIComponent(
|
|
1702
|
+
if (name2 === void 0) return `${path}/content`;
|
|
1703
|
+
if (!safeEnrichmentName(name2)) throw invalid7();
|
|
1704
|
+
return `${path}/enrichments/${encodeURIComponent(name2)}/content`;
|
|
1702
1705
|
}
|
|
1703
1706
|
async function read(id3, names) {
|
|
1704
1707
|
let context2 = await resolveFilesContext();
|
|
@@ -1708,14 +1711,14 @@ async function read(id3, names) {
|
|
|
1708
1711
|
}
|
|
1709
1712
|
if (!Array.isArray(names)) throw invalid7();
|
|
1710
1713
|
let distinct = [], seen = /* @__PURE__ */ new Set();
|
|
1711
|
-
for (let
|
|
1712
|
-
if (typeof
|
|
1713
|
-
if (!seen.has(
|
|
1714
|
+
for (let name2 of names) {
|
|
1715
|
+
if (typeof name2 != "string" || !safeEnrichmentName(name2)) throw invalid7();
|
|
1716
|
+
if (!seen.has(name2)) {
|
|
1714
1717
|
if (seen.size === 16) throw invalid7();
|
|
1715
|
-
seen.add(
|
|
1718
|
+
seen.add(name2), distinct.push(name2);
|
|
1716
1719
|
}
|
|
1717
1720
|
}
|
|
1718
|
-
let paths = distinct.map((
|
|
1721
|
+
let paths = distinct.map((name2) => contentPath(id3, name2));
|
|
1719
1722
|
return timed(async (parent) => {
|
|
1720
1723
|
let responses = {};
|
|
1721
1724
|
try {
|
|
@@ -1751,10 +1754,10 @@ var files = {
|
|
|
1751
1754
|
if (!blob && !array3 && !stream) throw invalid7();
|
|
1752
1755
|
let intrinsic = blob ? input.file.size : array3 ? input.file.byteLength : void 0;
|
|
1753
1756
|
if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid7();
|
|
1754
|
-
let
|
|
1755
|
-
|
|
1757
|
+
let name2 = input.name;
|
|
1758
|
+
name2 === void 0 && blob && "name" in input.file && typeof input.file.name == "string" && (name2 = typeof globalThis.File < "u" && input.file instanceof globalThis.File ? input.file.name : input.file.name.split(/[\\/]/).at(-1));
|
|
1756
1759
|
let inputMediaType = blob ? declaredOriginalMediaType(input.file.type) : void 0, metadata = parseFileCreateMetadata({
|
|
1757
|
-
name,
|
|
1760
|
+
name: name2,
|
|
1758
1761
|
size: intrinsic ?? input.size,
|
|
1759
1762
|
path: input.path,
|
|
1760
1763
|
storage: input.storage,
|
|
@@ -1854,7 +1857,7 @@ function validDropboxFileScopes(value) {
|
|
|
1854
1857
|
|
|
1855
1858
|
var ROUTINE_CONNECTION_CREDENTIALS_ENV = "OS_ROUTINE_CONNECTION_CREDENTIALS";
|
|
1856
1859
|
function parseRoutineConnectionNames(value) {
|
|
1857
|
-
if (!Array.isArray(value) || value.some((
|
|
1860
|
+
if (!Array.isArray(value) || value.some((name2) => typeof name2 != "string" || !/^(gmail|airtable|dropbox)\/[a-z0-9][a-z0-9-]{0,62}$/.test(name2)) || new Set(value).size !== value.length)
|
|
1858
1861
|
throw new Error("Invalid routine connections");
|
|
1859
1862
|
return value;
|
|
1860
1863
|
}
|
|
@@ -1957,9 +1960,9 @@ function equal(a, b) {
|
|
|
1957
1960
|
function createConnections(transport) {
|
|
1958
1961
|
return { async get() {
|
|
1959
1962
|
throw new Error("Connection unavailable");
|
|
1960
|
-
}, airtable(
|
|
1961
|
-
(typeof
|
|
1962
|
-
let call = (operation2, input) => transport(
|
|
1963
|
+
}, airtable(name2) {
|
|
1964
|
+
(typeof name2 != "string" || !/^[a-z0-9][a-z0-9-]{0,62}$/.test(name2)) && fail2("Invalid Airtable connection name");
|
|
1965
|
+
let call = (operation2, input) => transport(name2, operation2, input);
|
|
1963
1966
|
return {
|
|
1964
1967
|
tables: { list: async () => await call("tables.list", {}) },
|
|
1965
1968
|
records: {
|
|
@@ -1972,9 +1975,9 @@ function createConnections(transport) {
|
|
|
1972
1975
|
};
|
|
1973
1976
|
} };
|
|
1974
1977
|
}
|
|
1975
|
-
async function executeAirtableOperation(
|
|
1976
|
-
let { name, baseId, accessToken } =
|
|
1977
|
-
(!/^[a-z0-9][a-z0-9-]{0,62}$/.test(
|
|
1978
|
+
async function executeAirtableOperation(authority2, operation2, raw, options = {}) {
|
|
1979
|
+
let { name: name2, baseId, accessToken } = authority2;
|
|
1980
|
+
(!/^[a-z0-9][a-z0-9-]{0,62}$/.test(name2) || !/^app[A-Za-z0-9]+$/.test(baseId) || !/^[A-Za-z0-9._~+/-]{1,8192}={0,2}$/.test(accessToken)) && fail2("Airtable connection unavailable");
|
|
1978
1981
|
let input;
|
|
1979
1982
|
try {
|
|
1980
1983
|
input = object3(serializable(raw));
|
|
@@ -1983,7 +1986,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
|
|
|
1983
1986
|
}
|
|
1984
1987
|
let mutation = ["records.create", "records.update", "records.delete"].includes(operation2), receipt = (ids2) => ({
|
|
1985
1988
|
provider: "airtable",
|
|
1986
|
-
connection: `airtable/${
|
|
1989
|
+
connection: `airtable/${name2}`,
|
|
1987
1990
|
baseId,
|
|
1988
1991
|
table: input.table,
|
|
1989
1992
|
operation: operation2.slice(8),
|
|
@@ -2104,7 +2107,7 @@ var MANAGED_CONNECTION_CAPABILITY_ENV = "OS_MANAGED_CONNECTION_CAPABILITY";
|
|
|
2104
2107
|
function managedConnections(capability) {
|
|
2105
2108
|
let endpoint = new URL(capability.endpoint);
|
|
2106
2109
|
if (endpoint.protocol !== "http:" || endpoint.hostname !== "127.0.0.1" || !endpoint.port || endpoint.pathname !== "/" || endpoint.search || endpoint.hash || endpoint.username || endpoint.password || !/^[0-9a-f-]{36}$/.test(capability.token)) throw new AirtableOperationError("Airtable capability unavailable");
|
|
2107
|
-
return createConnections(async (
|
|
2110
|
+
return createConnections(async (name2, operation2, input) => {
|
|
2108
2111
|
let safeInput;
|
|
2109
2112
|
try {
|
|
2110
2113
|
safeInput = serializable(input);
|
|
@@ -2116,7 +2119,7 @@ function managedConnections(capability) {
|
|
|
2116
2119
|
method: "POST",
|
|
2117
2120
|
redirect: "error",
|
|
2118
2121
|
headers: { authorization: `Bearer ${capability.token}`, "content-type": "application/json" },
|
|
2119
|
-
body: JSON.stringify({ name, operation: operation2, input: safeInput }),
|
|
2122
|
+
body: JSON.stringify({ name: name2, operation: operation2, input: safeInput }),
|
|
2120
2123
|
signal: AbortSignal.timeout(125e3)
|
|
2121
2124
|
}), value = await response2.json();
|
|
2122
2125
|
if (!response2.ok) throw new AirtableOperationError(
|
|
@@ -2140,7 +2143,7 @@ async function reportLocalRoutineEffect(value) {
|
|
|
2140
2143
|
}
|
|
2141
2144
|
|
|
2142
2145
|
var local;
|
|
2143
|
-
var airtable = /* @__PURE__ */ createConnections(async (
|
|
2146
|
+
var airtable = /* @__PURE__ */ createConnections(async (name2, operation2, input) => {
|
|
2144
2147
|
throw new AirtableOperationError("Airtable connection unavailable");
|
|
2145
2148
|
});
|
|
2146
2149
|
function runtimeConnections() {
|
|
@@ -2182,28 +2185,28 @@ function validateRecordWrite(value) {
|
|
|
2182
2185
|
}
|
|
2183
2186
|
function validateRecordUpdate(value) {
|
|
2184
2187
|
let input = validateRecordWrite(value);
|
|
2185
|
-
if (input.records.some((
|
|
2188
|
+
if (input.records.some((record4) => !("expectedVersion" in record4)))
|
|
2186
2189
|
throw new InboxContractError("Record creation is unavailable for this operation");
|
|
2187
2190
|
return input;
|
|
2188
2191
|
}
|
|
2189
2192
|
function validateRecordDelete(value) {
|
|
2190
2193
|
let input = serializable(value);
|
|
2191
|
-
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((
|
|
2194
|
+
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((record4) => record4?.ref)).size !== input.records.length)
|
|
2192
2195
|
throw new InboxContractError("Invalid record deletion batch");
|
|
2193
|
-
for (let
|
|
2194
|
-
if (!
|
|
2196
|
+
for (let record4 of input.records)
|
|
2197
|
+
if (!record4 || Array.isArray(record4) || typeof record4 != "object" || Object.keys(record4).sort().join(",") !== "expectedVersion,ref" || !validRecordRef(record4.ref) || typeof record4.expectedVersion != "string" || !/^record-v1:[0-9a-f]{64}$/.test(record4.expectedVersion))
|
|
2195
2198
|
throw new InboxContractError("Invalid record deletion");
|
|
2196
2199
|
return structuredClone(input);
|
|
2197
2200
|
}
|
|
2198
2201
|
function validateRecordChange(value) {
|
|
2199
2202
|
let input = serializable(value);
|
|
2200
|
-
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((
|
|
2203
|
+
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((record4) => record4?.ref)).size !== input.records.length || new TextEncoder().encode(JSON.stringify(input)).byteLength > RECORD_WRITE_INPUT_LIMIT)
|
|
2201
2204
|
throw new InboxContractError("Invalid record change batch");
|
|
2202
2205
|
let writes = [], deletes = [];
|
|
2203
|
-
for (let
|
|
2204
|
-
if (!
|
|
2206
|
+
for (let record4 of input.records) {
|
|
2207
|
+
if (!record4 || typeof record4 != "object" || Array.isArray(record4))
|
|
2205
2208
|
throw new InboxContractError("Invalid record change");
|
|
2206
|
-
"set" in
|
|
2209
|
+
"set" in record4 || "fields" in record4 ? writes.push(record4) : deletes.push(record4);
|
|
2207
2210
|
}
|
|
2208
2211
|
return writes.length && validateRecordWrite({ repository: input.repository, records: writes }), deletes.length && validateRecordDelete({ repository: input.repository, records: deletes }), structuredClone(input);
|
|
2209
2212
|
}
|
|
@@ -2287,8 +2290,8 @@ function json(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
|
2287
2290
|
}
|
|
2288
2291
|
}
|
|
2289
2292
|
function recordReference(value) {
|
|
2290
|
-
let
|
|
2291
|
-
return keys3(
|
|
2293
|
+
let record4 = object4(value);
|
|
2294
|
+
return keys3(record4, ["repository", "ref"]), assert(text4(record4.repository) && record4.repository === record4.repository.trim() && /^[a-z0-9][a-z0-9._/-]{0,127}$/.test(record4.repository) && !/\.\.|\/\//.test(record4.repository) && text4(record4.ref) && record4.ref === record4.ref.trim() && record4.ref.length <= 512 && /^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)+$/.test(record4.ref)), record4;
|
|
2292
2295
|
}
|
|
2293
2296
|
function responseDefinition(value) {
|
|
2294
2297
|
let definition = object4(value);
|
|
@@ -2318,7 +2321,7 @@ function responseDefinition(value) {
|
|
|
2318
2321
|
let collection = object4(source.collection);
|
|
2319
2322
|
keys3(collection, ["repository", "name"]), recordReference({ repository: collection.repository, ref: "records/example" }), assert(text4(collection.name) && /^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$/.test(collection.name)), "refPrefix" in source && assert(text4(source.refPrefix) && source.refPrefix.length <= 512 && /^[_a-zA-Z0-9][a-zA-Z0-9_-]*(\/[_a-zA-Z0-9][a-zA-Z0-9_-]*)*\/$/.test(source.refPrefix));
|
|
2320
2323
|
let where = object4(source.where ?? {});
|
|
2321
|
-
assert(Object.entries(where).every(([
|
|
2324
|
+
assert(Object.entries(where).every(([name2, value2]) => /^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name2) && !["constructor", "prototype"].includes(name2) && (value2 === null || typeof value2 == "string" || typeof value2 == "boolean" || typeof value2 == "number" && Number.isFinite(value2))));
|
|
2322
2325
|
let display = object4(source.display);
|
|
2323
2326
|
keys3(display, ["labelFields"]);
|
|
2324
2327
|
let labels = array2(display.labelFields);
|
|
@@ -2326,8 +2329,8 @@ function responseDefinition(value) {
|
|
|
2326
2329
|
let suggestions = array2(source.suggestions ?? []), refs = suggestions.map((value2) => {
|
|
2327
2330
|
let suggestion = object4(value2);
|
|
2328
2331
|
keys3(suggestion, ["record", "reason"], ["record"]);
|
|
2329
|
-
let
|
|
2330
|
-
return assert(
|
|
2332
|
+
let record4 = recordReference(suggestion.record);
|
|
2333
|
+
return assert(record4.repository === collection.repository), "reason" in suggestion && assert(text4(suggestion.reason)), record4.ref;
|
|
2331
2334
|
});
|
|
2332
2335
|
assert(suggestions.length <= 8 && new Set(refs).size === refs.length);
|
|
2333
2336
|
}
|
|
@@ -2361,14 +2364,14 @@ function block(value) {
|
|
|
2361
2364
|
["kind", "label", "initiallyExpanded", ...entry.kind === "record" ? ["record", "view"] : entry.kind === "records" ? ["records", "view"] : ["files"]],
|
|
2362
2365
|
["kind", "label", entry.kind === "record" ? "record" : entry.kind === "records" ? "records" : "files"]
|
|
2363
2366
|
), assert(text4(entry.label) && (!("initiallyExpanded" in entry) || typeof entry.initiallyExpanded == "boolean") && (!("view" in entry) || text4(entry.view) && entry.view === entry.view.trim())), entry.kind === "record") {
|
|
2364
|
-
let
|
|
2365
|
-
keys3(
|
|
2367
|
+
let record4 = object4(entry.record);
|
|
2368
|
+
keys3(record4, ["ref", "title", "fields"]), assert(text4(record4.ref) && record4.ref === record4.ref.trim() && text4(record4.title)), fields4(record4.fields);
|
|
2366
2369
|
return;
|
|
2367
2370
|
}
|
|
2368
2371
|
if (entry.kind === "records") {
|
|
2369
2372
|
let records = array2(entry.records), refs = records.map((value2) => {
|
|
2370
|
-
let
|
|
2371
|
-
return keys3(
|
|
2373
|
+
let record4 = object4(value2);
|
|
2374
|
+
return keys3(record4, ["ref", "title", "description", "facts", "view"], ["ref", "title"]), assert(text4(record4.ref) && record4.ref === record4.ref.trim() && text4(record4.title)), "description" in record4 && assert(text4(record4.description)), "facts" in record4 && fields4(record4.facts), "view" in record4 && assert(text4(record4.view) && record4.view === record4.view.trim()), record4.ref;
|
|
2372
2375
|
});
|
|
2373
2376
|
assert(records.length > 0 && new Set(refs).size === refs.length);
|
|
2374
2377
|
return;
|
|
@@ -2505,8 +2508,8 @@ function parseInboxResult(operation2, value) {
|
|
|
2505
2508
|
let result2 = object4(value);
|
|
2506
2509
|
assert(text4(result2.recordType) && integer(result2.eligibleCount, 0) && integer(result2.matchCount, 0) && Number(result2.matchCount) <= Number(result2.eligibleCount));
|
|
2507
2510
|
let labeled = (value2) => {
|
|
2508
|
-
let
|
|
2509
|
-
recordReference({ repository:
|
|
2511
|
+
let record4 = object4(value2);
|
|
2512
|
+
recordReference({ repository: record4.repository, ref: record4.ref }), assert(text4(record4.label)), "reason" in record4 && assert(text4(record4.reason));
|
|
2510
2513
|
};
|
|
2511
2514
|
return array2(result2.matches).forEach(labeled), array2(result2.suggestions).forEach(labeled), "selected" in result2 && labeled(result2.selected), result2;
|
|
2512
2515
|
}
|
|
@@ -2673,7 +2676,7 @@ function appContext(origin, active2) {
|
|
|
2673
2676
|
} catch {
|
|
2674
2677
|
return !1;
|
|
2675
2678
|
}
|
|
2676
|
-
}, sameSession = (value) => !binding || ["appId", "memberId", "workspace", "sessionId"].every((key) => value[key] === binding[key]),
|
|
2679
|
+
}, sameSession = (value) => !binding || ["appId", "memberId", "workspace", "sessionId"].every((key) => value[key] === binding[key]), bounded3 = (value) => validBinding(value) && value.expiresAt > Date.now() && value.expiresAt <= Date.now() + 6e5 && sameSession(value), readPair = (candidate) => {
|
|
2677
2680
|
let value = JSON.parse(candidate ?? "null");
|
|
2678
2681
|
if (!validPair(value) || value.context.expiresAt > Date.now() + 6e5 || !sameSession(value.context)) throw new Error();
|
|
2679
2682
|
return value;
|
|
@@ -2710,7 +2713,7 @@ function appContext(origin, active2) {
|
|
|
2710
2713
|
if (response2.status >= 500) throw new AppRenewalUnavailable();
|
|
2711
2714
|
if (!response2.ok) throw new Error();
|
|
2712
2715
|
let value = await appResponse(response2, 4096, signal);
|
|
2713
|
-
if (!alive() || !
|
|
2716
|
+
if (!alive() || !bounded3(value)) throw new Error();
|
|
2714
2717
|
return value;
|
|
2715
2718
|
}
|
|
2716
2719
|
function install(value, candidate, raw) {
|
|
@@ -2782,7 +2785,7 @@ function appContext(origin, active2) {
|
|
|
2782
2785
|
return;
|
|
2783
2786
|
}
|
|
2784
2787
|
if (!response2.ok) throw new Error();
|
|
2785
|
-
if (!alive() || !validPair(value) || !
|
|
2788
|
+
if (!alive() || !validPair(value) || !bounded3(value.context) || (/* @__PURE__ */ new Set([value.credential, value.renewalCredential, pair.credential, pair.renewalCredential])).size !== 4) throw new Error();
|
|
2786
2789
|
if (stored() !== previous) {
|
|
2787
2790
|
await synchronize(requestController.signal);
|
|
2788
2791
|
return;
|
|
@@ -2863,16 +2866,16 @@ function appContext(origin, active2) {
|
|
|
2863
2866
|
return requestChecked(`routines/${encodeURIComponent(key)}/${suffix}`, {}, !1, !0);
|
|
2864
2867
|
}
|
|
2865
2868
|
async function requestFiles(suffix, init2, parent) {
|
|
2866
|
-
let
|
|
2869
|
+
let unavailable5 = () => new FileOperationError("unsupported_context", 400);
|
|
2867
2870
|
if (!current2() || !/^(?:|\/[0-9a-f-]{36}(?:\/(?:content|upload|enrichments(?:\/[^/?#]+\/content)?))?)$/i.test(suffix))
|
|
2868
|
-
throw
|
|
2869
|
-
let admitted = credential, signal = parent ? AbortSignal.any([access.signal, parent]) : access.signal, failure = () => current2() && !signal.aborted ? new FileOperationError("unavailable", 503, !0) :
|
|
2871
|
+
throw unavailable5();
|
|
2872
|
+
let admitted = credential, signal = parent ? AbortSignal.any([access.signal, parent]) : access.signal, failure = () => current2() && !signal.aborted ? new FileOperationError("unavailable", 503, !0) : unavailable5();
|
|
2870
2873
|
try {
|
|
2871
2874
|
return await hostedContent("", init2, signal, (_url, request2) => untilAborted(
|
|
2872
2875
|
send3(`files${suffix}`, admitted, signal, request2).then((value) => {
|
|
2873
2876
|
if (signal.aborted)
|
|
2874
2877
|
throw value.body?.cancel().catch(() => {
|
|
2875
|
-
}),
|
|
2878
|
+
}), unavailable5();
|
|
2876
2879
|
return value;
|
|
2877
2880
|
}),
|
|
2878
2881
|
signal
|
|
@@ -3179,8 +3182,8 @@ function init({ auth: input }) {
|
|
|
3179
3182
|
url.protocol === "https:" && !url.port && !url.username && !url.password && !url.search && !url.hash && url.pathname === "/" && /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(slug) && slug !== "auth" && (endpoint = url.origin, workspace = slug);
|
|
3180
3183
|
} catch {
|
|
3181
3184
|
}
|
|
3182
|
-
let active2 = !0, revision = 0, person, token, binding = {},
|
|
3183
|
-
if (
|
|
3185
|
+
let active2 = !0, revision = 0, person, token, binding = {}, local2 = localOrigin ? appContext(localOrigin, () => active2) : void 0, subscription, stopDisposal, resolve = async () => {
|
|
3186
|
+
if (local2) return local2.resolve();
|
|
3184
3187
|
if (!active2 || !endpoint || !workspace || globalThis.location.origin !== endpoint) throw new Error("Hosted Data context unavailable.");
|
|
3185
3188
|
let started = revision, { data: { session }, error } = await auth2.getSession();
|
|
3186
3189
|
if (!active2 || globalThis.location.origin !== endpoint || started !== revision || error || !session || person !== void 0 && person !== session.user.id)
|
|
@@ -3199,13 +3202,13 @@ function init({ auth: input }) {
|
|
|
3199
3202
|
memberId: session.user.id,
|
|
3200
3203
|
binding
|
|
3201
3204
|
};
|
|
3202
|
-
}, uninstall = installMemberContext(resolve,
|
|
3203
|
-
active2 && (active2 = !1,
|
|
3205
|
+
}, uninstall = installMemberContext(resolve, local2 ? local2.retained : resolve), dispose = () => {
|
|
3206
|
+
active2 && (active2 = !1, local2?.dispose(), revision++, subscription?.unsubscribe(), stopDisposal?.(), uninstall(), installedDispose === dispose && (installedDispose = void 0));
|
|
3204
3207
|
};
|
|
3205
3208
|
installedDispose = dispose, stopDisposal = registered?.onDispose(dispose), active2 && (subscription = auth2.onAuthStateChange((event, session) => {
|
|
3206
3209
|
let next = session?.user.id ?? null;
|
|
3207
|
-
(event === "SIGNED_OUT" || person !== void 0 && next !== person ||
|
|
3208
|
-
}).data.subscription,
|
|
3210
|
+
(event === "SIGNED_OUT" || person !== void 0 && next !== person || person !== void 0 && event === "SIGNED_IN" && token !== session?.access_token) && (revision++, local2?.invalidate()), person = next, token = session?.access_token;
|
|
3211
|
+
}).data.subscription, local2?.start());
|
|
3209
3212
|
}
|
|
3210
3213
|
var os = { init };
|
|
3211
3214
|
|
|
@@ -3279,8 +3282,8 @@ function createBrowserAuth(runtime) {
|
|
|
3279
3282
|
return;
|
|
3280
3283
|
}
|
|
3281
3284
|
c.session = session;
|
|
3282
|
-
let email = typeof session.user.email == "string" ? session.user.email.trim() : "", metadata = session.user.user_metadata,
|
|
3283
|
-
publish(c, { status: "signed_in", account, ...pending ? { pending } : {} })
|
|
3285
|
+
let email = typeof session.user.email == "string" ? session.user.email.trim() : "", metadata = session.user.user_metadata, name2 = ["name", "full_name", "first_name"].map((key) => metadata?.[key]).find((value) => typeof value == "string" && value.trim())?.trim() || email, account = !replaced && c.state.account?.email === email && c.state.account.displayName === name2 ? c.state.account : Object.freeze({ email, displayName: name2 });
|
|
3286
|
+
notify(c, event), publish(c, { status: "signed_in", account, ...pending ? { pending } : {} });
|
|
3284
3287
|
let checkExpiry = () => {
|
|
3285
3288
|
if (!c.active || !c.session) return;
|
|
3286
3289
|
let remaining = c.session.expires_at * 1e3 - Date.now();
|
|
@@ -3634,7 +3637,60 @@ function routineRunHandle(operations2) {
|
|
|
3634
3637
|
});
|
|
3635
3638
|
}
|
|
3636
3639
|
|
|
3637
|
-
var
|
|
3640
|
+
var name = /^[a-z0-9][a-z0-9-]{0,62}$/, uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/, invalid8 = () => {
|
|
3641
|
+
throw new Error("Run state unavailable");
|
|
3642
|
+
}, record3 = (value) => value && typeof value == "object" && !Array.isArray(value) ? value : invalid8();
|
|
3643
|
+
function time(value) {
|
|
3644
|
+
return typeof value != "string" || value.length > 40 || !Number.isFinite(Date.parse(value)) ? invalid8() : value;
|
|
3645
|
+
}
|
|
3646
|
+
function times(value) {
|
|
3647
|
+
return {
|
|
3648
|
+
...value.startedAt === void 0 ? {} : { startedAt: time(value.startedAt) },
|
|
3649
|
+
...value.finishedAt === void 0 ? {} : { finishedAt: time(value.finishedAt) }
|
|
3650
|
+
};
|
|
3651
|
+
}
|
|
3652
|
+
function bounded(value) {
|
|
3653
|
+
return assertRoutineJson(value), new TextEncoder().encode(JSON.stringify(value)).byteLength > 256 * 1024 ? invalid8() : value;
|
|
3654
|
+
}
|
|
3655
|
+
function parseRunStep(value, expected) {
|
|
3656
|
+
let v = record3(value);
|
|
3657
|
+
return typeof v.id != "string" || !name.test(v.id) || expected !== void 0 && v.id !== expected || typeof v.title != "string" || !v.title.trim() || v.title.length > 256 || !["pending", "running", "completed", "failed", "skipped"].includes(v.status) ? invalid8() : {
|
|
3658
|
+
id: v.id,
|
|
3659
|
+
title: v.title,
|
|
3660
|
+
status: v.status,
|
|
3661
|
+
...times(v),
|
|
3662
|
+
...Object.hasOwn(v, "summary") ? { summary: bounded(v.summary) } : {},
|
|
3663
|
+
...Object.hasOwn(v, "data") ? { data: bounded(v.data) } : {}
|
|
3664
|
+
};
|
|
3665
|
+
}
|
|
3666
|
+
function parseRemoteRun(value, expected = {}) {
|
|
3667
|
+
let v = record3(value);
|
|
3668
|
+
if (typeof v.id != "string" || !uuid.test(v.id) || expected.id !== void 0 && v.id !== expected.id || typeof v.routine != "string" || !name.test(v.routine) || expected.routine !== void 0 && v.routine !== expected.routine || v.placement !== "remote" || !["queued", "running", "succeeded", "failed"].includes(v.status) || !Array.isArray(v.steps) || v.steps.length > 64) return invalid8();
|
|
3669
|
+
let steps = v.steps.map((value2) => {
|
|
3670
|
+
let step = record3(value2);
|
|
3671
|
+
return typeof step.detailAvailable != "boolean" || Object.hasOwn(step, "data") ? invalid8() : { ...parseRunStep(step), detailAvailable: step.detailAvailable };
|
|
3672
|
+
});
|
|
3673
|
+
if (new Set(steps.map((step) => step.id)).size !== steps.length) return invalid8();
|
|
3674
|
+
let failure;
|
|
3675
|
+
if (v.failure !== void 0) {
|
|
3676
|
+
let f = record3(v.failure);
|
|
3677
|
+
if (v.status !== "failed" || typeof f.message != "string" || !f.message || f.message.length > 512) return invalid8();
|
|
3678
|
+
failure = { message: f.message };
|
|
3679
|
+
}
|
|
3680
|
+
return Object.hasOwn(v, "result") && v.status !== "succeeded" ? invalid8() : {
|
|
3681
|
+
id: v.id,
|
|
3682
|
+
routine: v.routine,
|
|
3683
|
+
placement: "remote",
|
|
3684
|
+
status: v.status,
|
|
3685
|
+
createdAt: time(v.createdAt),
|
|
3686
|
+
...times(v),
|
|
3687
|
+
steps,
|
|
3688
|
+
...Object.hasOwn(v, "result") ? { result: bounded(v.result) } : {},
|
|
3689
|
+
...failure ? { failure } : {}
|
|
3690
|
+
};
|
|
3691
|
+
}
|
|
3692
|
+
|
|
3693
|
+
var identifier = /^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/, uuid2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}(?![\s\S])/i, SUMMARY_BYTES = 17 * 1024 * 1024, AppRoutineError = class extends Error {
|
|
3638
3694
|
constructor(reason) {
|
|
3639
3695
|
super(reason);
|
|
3640
3696
|
this.reason = reason;
|
|
@@ -3645,44 +3701,72 @@ var identifier = /^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/, uuid = /^[0-9a-f]{8}-[0-
|
|
|
3645
3701
|
throw new AppRoutineError(reason);
|
|
3646
3702
|
};
|
|
3647
3703
|
function current(context2) {
|
|
3648
|
-
(!context2.isCurrent() || context2.signal.aborted) && fail3("authority_unavailable");
|
|
3704
|
+
(!context2.isCurrent() || context2.kind === "local" && context2.signal.aborted) && fail3("authority_unavailable");
|
|
3649
3705
|
}
|
|
3650
3706
|
function appDescriptors() {
|
|
3651
3707
|
return globalThis[/* @__PURE__ */ Symbol.for("oddington.app.descriptor")]?.routines ?? [];
|
|
3652
3708
|
}
|
|
3653
|
-
async function
|
|
3709
|
+
async function authority(retained = !1) {
|
|
3654
3710
|
let context2 = await resolveAppContext(retained).catch(() => fail3("authority_unavailable"));
|
|
3655
|
-
return context2.kind !== "local"
|
|
3711
|
+
return current(context2), context2.kind !== "local" && (!context2.binding || !context2.memberId || !identifier.test(context2.workspace) || context2.workspace.length > 63 || ["auth", "api", "os", "www"].includes(context2.workspace) || context2.endpoint !== `https://${context2.workspace}.oddington.ai`) && fail3("authority_unavailable"), context2;
|
|
3712
|
+
}
|
|
3713
|
+
async function live(context2, read2) {
|
|
3714
|
+
if (current(context2), context2.kind === "local") return context2;
|
|
3715
|
+
let resolved = await authority(read2);
|
|
3716
|
+
return current(context2), (resolved.kind === "local" || resolved.binding !== context2.binding || resolved.memberId !== context2.memberId || resolved.workspace !== context2.workspace || resolved.endpoint !== context2.endpoint) && fail3("authority_unavailable"), resolved;
|
|
3656
3717
|
}
|
|
3657
3718
|
async function request(key, suffix, init2, maximum = SUMMARY_BYTES, retained, read2 = !1) {
|
|
3658
3719
|
(!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable");
|
|
3659
|
-
let context2 = retained
|
|
3720
|
+
let context2 = retained ? await live(retained, read2) : await authority(read2);
|
|
3660
3721
|
current(context2);
|
|
3722
|
+
let deadline = new AbortController(), timeout = context2.kind === "local" ? void 0 : setTimeout(() => deadline.abort(), 2e4);
|
|
3661
3723
|
try {
|
|
3662
|
-
let response2 = await (read2 ? context2.requestRetainedRoutine(key, suffix) : context2.requestRoutine(key, suffix, init2)
|
|
3663
|
-
|
|
3724
|
+
let response2 = await (context2.kind === "local" ? read2 ? context2.requestRetainedRoutine(key, suffix) : context2.requestRoutine(key, suffix, init2) : fetch(`${context2.endpoint}/api/routines/${key}/${suffix}`, {
|
|
3725
|
+
...init2,
|
|
3726
|
+
credentials: "omit",
|
|
3727
|
+
redirect: "error",
|
|
3728
|
+
signal: deadline.signal,
|
|
3729
|
+
headers: { authorization: `Bearer ${context2.accessToken}`, ...init2?.body ? { "content-type": "application/json" } : {} }
|
|
3730
|
+
}));
|
|
3731
|
+
response2.redirected && fail3("execution_unavailable");
|
|
3732
|
+
let value = await appResponse(response2, maximum, context2.kind === "local" ? context2.signal : deadline.signal);
|
|
3733
|
+
if (current(context2), context2.kind !== "local" && await live(context2, read2), !response2.ok) {
|
|
3734
|
+
if (context2.kind !== "local") {
|
|
3735
|
+
let code = value?.code;
|
|
3736
|
+
if ((code === "authentication_required" || code === "access_denied") && fail3("authority_unavailable"), (code === "input_invalid" || code === "file_not_remote") && fail3("invalid_input"), suffix === "describe" && (code === "active_version_unavailable" || code === "capability_unavailable"))
|
|
3737
|
+
return unavailable4(key, code === "active_version_unavailable" ? "not_deployed" : "capability_unavailable");
|
|
3738
|
+
fail3("execution_unavailable");
|
|
3739
|
+
}
|
|
3664
3740
|
let reason = value?.error;
|
|
3665
|
-
reason === "authority_unavailable" && (context2.invalidate(), fail3(reason)), (reason === "invalid_input" || reason === "execution_unavailable") && fail3(reason), fail3("execution_unavailable");
|
|
3741
|
+
reason === "authority_unavailable" && (context2.kind === "local" && context2.invalidate(), fail3(reason)), (reason === "invalid_input" || reason === "execution_unavailable") && fail3(reason), fail3("execution_unavailable");
|
|
3666
3742
|
}
|
|
3667
3743
|
return value;
|
|
3668
3744
|
} catch (error) {
|
|
3669
3745
|
if (current(context2), error instanceof AppRoutineError) throw error;
|
|
3670
3746
|
fail3("execution_unavailable");
|
|
3747
|
+
} finally {
|
|
3748
|
+
clearTimeout(timeout);
|
|
3671
3749
|
}
|
|
3672
3750
|
}
|
|
3673
|
-
function summary(value, key, id3) {
|
|
3751
|
+
function summary(value, key, context2, id3) {
|
|
3752
|
+
if (context2.kind !== "local")
|
|
3753
|
+
try {
|
|
3754
|
+
return (!only(value, "id,routine,placement,status,createdAt,startedAt,finishedAt,steps,result,failure") || !Array.isArray(value.steps) || value.steps.some((step) => !only(step, "id,title,status,startedAt,finishedAt,summary,detailAvailable")) || value.failure !== void 0 && !only(value.failure, "message")) && fail3("execution_unavailable"), parseRemoteRun(value, { routine: key, id: id3 });
|
|
3755
|
+
} catch {
|
|
3756
|
+
return fail3("execution_unavailable");
|
|
3757
|
+
}
|
|
3674
3758
|
let run = value;
|
|
3675
|
-
return (!only(run, "id,routine,placement,status,createdAt,startedAt,finishedAt,steps,result,failure,publication") || typeof run.id != "string" || !
|
|
3759
|
+
return (!only(run, "id,routine,placement,status,createdAt,startedAt,finishedAt,steps,result,failure,publication") || typeof run.id != "string" || !uuid2.test(run.id) || id3 !== void 0 && run.id !== id3 || run.routine !== key || run.placement !== "local" || !["queued", "running", "succeeded", "failed"].includes(run.status) || !timestamp(run.createdAt) || !optionalTimes(run) || !Array.isArray(run.steps) || run.steps.length > 64 || run.steps.some((step) => !only(step, "id,title,status,startedAt,finishedAt,summary,detailAvailable") || typeof step.detailAvailable != "boolean" || !validStep(step)) || new Set(run.steps.map((step) => step.id)).size !== run.steps.length || Object.hasOwn(run, "result") && (run.status !== "succeeded" || !bounded2(run.result)) || run.failure !== void 0 && (run.status !== "failed" || !only(run.failure, "message") || !message(run.failure.message)) || run.publication !== void 0 && (run.status !== "succeeded" || !validPublication(run.publication))) && fail3("execution_unavailable"), run;
|
|
3676
3760
|
}
|
|
3677
3761
|
function only(value, allowed) {
|
|
3678
3762
|
return !!value && typeof value == "object" && !Array.isArray(value) && Object.keys(value).every((key) => allowed.split(",").includes(key));
|
|
3679
3763
|
}
|
|
3680
|
-
var timestamp = (value) => typeof value == "string" && value.length <= 32 && Number.isFinite(Date.parse(value)), message = (value) => typeof value == "string" && value.length > 0 && value.length <= 512,
|
|
3764
|
+
var timestamp = (value) => typeof value == "string" && value.length <= 32 && Number.isFinite(Date.parse(value)), message = (value) => typeof value == "string" && value.length > 0 && value.length <= 512, bounded2 = (value) => new TextEncoder().encode(JSON.stringify(value)).byteLength <= 256 * 1024;
|
|
3681
3765
|
function optionalTimes(value) {
|
|
3682
3766
|
return (value.startedAt === void 0 || timestamp(value.startedAt)) && (value.finishedAt === void 0 || timestamp(value.finishedAt));
|
|
3683
3767
|
}
|
|
3684
3768
|
function validStep(step) {
|
|
3685
|
-
return typeof step.id == "string" && identifier.test(step.id) && typeof step.title == "string" && step.title.length > 0 && step.title.length <= 256 && ["pending", "running", "completed", "failed", "skipped"].includes(step.status) && optionalTimes(step) && (!Object.hasOwn(step, "summary") ||
|
|
3769
|
+
return typeof step.id == "string" && identifier.test(step.id) && typeof step.title == "string" && step.title.length > 0 && step.title.length <= 256 && ["pending", "running", "completed", "failed", "skipped"].includes(step.status) && optionalTimes(step) && (!Object.hasOwn(step, "summary") || bounded2(step.summary)) && (!Object.hasOwn(step, "data") || bounded2(step.data));
|
|
3686
3770
|
}
|
|
3687
3771
|
function validPublication(value) {
|
|
3688
3772
|
return value && only(value, value.state === "failed" ? "state,message" : "state") && (["not_needed", "ready", "published"].includes(value.state) || value.state === "failed" && message(value.message));
|
|
@@ -3705,8 +3789,8 @@ function structure(value) {
|
|
|
3705
3789
|
return JSON.stringify(value, (_key, item) => item && typeof item == "object" && !Array.isArray(item) ? Object.fromEntries(Object.keys(item).sort().map((key) => [key, item[key]])) : item);
|
|
3706
3790
|
}
|
|
3707
3791
|
function handle(key, id3, context2) {
|
|
3708
|
-
(!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable"), (typeof id3 != "string" || !
|
|
3709
|
-
let read2 = async () => summary(await request(key, `runs/${id3}`, void 0, SUMMARY_BYTES, context2, !0), key, id3);
|
|
3792
|
+
(!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable"), (typeof id3 != "string" || !uuid2.test(id3)) && fail3("invalid_input");
|
|
3793
|
+
let read2 = async () => summary(await request(key, `runs/${id3}`, void 0, SUMMARY_BYTES, context2, !0), key, context2, id3);
|
|
3710
3794
|
return routineRunHandle({
|
|
3711
3795
|
async current() {
|
|
3712
3796
|
return current(context2), read2();
|
|
@@ -3714,26 +3798,44 @@ function handle(key, id3, context2) {
|
|
|
3714
3798
|
async step(step) {
|
|
3715
3799
|
(typeof step != "string" || !identifier.test(step)) && fail3("invalid_input");
|
|
3716
3800
|
let value = await request(key, `runs/${id3}/steps/${step}`, void 0, 514 * 1024, context2, !0);
|
|
3801
|
+
if (context2.kind !== "local")
|
|
3802
|
+
try {
|
|
3803
|
+
return only(value, "id,title,status,startedAt,finishedAt,summary,data") || fail3("execution_unavailable"), parseRunStep(value, step);
|
|
3804
|
+
} catch {
|
|
3805
|
+
return fail3("execution_unavailable");
|
|
3806
|
+
}
|
|
3717
3807
|
return (!only(value, "id,title,status,startedAt,finishedAt,summary,data") || value.id !== step || !validStep(value)) && fail3("execution_unavailable"), value;
|
|
3718
3808
|
},
|
|
3719
3809
|
async publish() {
|
|
3720
|
-
return summary(await request(key, `runs/${id3}/publish`, { method: "POST" }, SUMMARY_BYTES, context2), key, id3);
|
|
3810
|
+
return context2.kind !== "local" && fail3("execution_unavailable"), summary(await request(key, `runs/${id3}/publish`, { method: "POST" }, SUMMARY_BYTES, context2), key, context2, id3);
|
|
3721
3811
|
}
|
|
3722
3812
|
});
|
|
3723
3813
|
}
|
|
3724
|
-
|
|
3814
|
+
function unavailable4(key, reason) {
|
|
3725
3815
|
let descriptor = appDescriptors().find((item) => item.id === key);
|
|
3726
|
-
|
|
3727
|
-
let unavailable4 = () => ({
|
|
3816
|
+
return {
|
|
3728
3817
|
...structuredClone(descriptor),
|
|
3729
3818
|
connections: descriptor.connections.map((connection) => ({ ...connection, available: !1 })),
|
|
3730
|
-
readiness: { state: "unavailable", reason: "
|
|
3819
|
+
readiness: { state: "unavailable", reason, message: reason === "not_deployed" ? "Routine is not deployed." : "Routine capability unavailable." }
|
|
3820
|
+
};
|
|
3821
|
+
}
|
|
3822
|
+
function deployedDescription(value, key) {
|
|
3823
|
+
(!only(value, "id,title,input,connections,steps,readiness") || value.id !== key || value.title !== void 0 && (typeof value.title != "string" || !value.title.trim() || value.title.length > 256) || !only(value.input, "type,properties,required,additionalProperties,items,maxItems,maxLength,minimum,maximum,storage,path,default") || !Array.isArray(value.steps) || value.steps.length > 64 || value.steps.some((step) => !only(step, "id,title") || typeof step.title != "string" || !step.title.trim() || step.title.length > 256) || !Array.isArray(value.connections) || value.connections.length > 64 || value.connections.some((item) => !only(item, "id,provider,name,available") || typeof item.available != "boolean" || typeof item.provider != "string" || !identifier.test(item.provider) || typeof item.name != "string" || !identifier.test(item.name) || item.id !== `${item.provider}/${item.name}`) || new Set(value.connections.map((item) => item.id)).size !== value.connections.length) && fail3("execution_unavailable");
|
|
3824
|
+
let { default: inputDefault, ...input } = value.input, contract = parseAppRoutineContract({
|
|
3825
|
+
routine: key,
|
|
3826
|
+
input,
|
|
3827
|
+
steps: value.steps.length ? value.steps.map(({ id: id3 }) => ({ id: id3 })) : [{ id: "inspect" }]
|
|
3731
3828
|
});
|
|
3829
|
+
Object.hasOwn(value.input, "default") && validateRoutineSchemaValue(contract.input, inputDefault);
|
|
3830
|
+
}
|
|
3831
|
+
async function describeAppRoutine(key) {
|
|
3832
|
+
let descriptor = appDescriptors().find((item) => item.id === key);
|
|
3833
|
+
if (!descriptor) return fail3("authority_unavailable");
|
|
3732
3834
|
try {
|
|
3733
|
-
let value = await request(key, "describe", void 0,
|
|
3734
|
-
return (!only(value, "id,title,input,connections,steps,readiness") || !value.readiness || !Array.isArray(value.connections) || structure({ ...value, readiness: void 0, connections: value.connections.map(({ available, ...item }) => item) }) !== structure(descriptor) || value.connections.some((item) => typeof item.available != "boolean") || !(value.readiness.state === "ready" && only(value.readiness, "state,placement") && value.readiness.placement === "local" || value.readiness.state === "unavailable" && only(value.readiness, "state,reason,message") && ["not_deployed", "definition_invalid", "capability_unavailable"].includes(value.readiness.reason) && message(value.readiness.message))) && fail3("execution_unavailable"), value;
|
|
3835
|
+
let context2 = await authority(), value = await request(key, "describe", void 0, 1024 * 1024, context2);
|
|
3836
|
+
return context2.kind !== "local" && deployedDescription(value, key), (!only(value, "id,title,input,connections,steps,readiness") || !value.readiness || !Array.isArray(value.connections) || context2.kind === "local" && structure({ ...value, readiness: void 0, connections: value.connections.map(({ available, ...item }) => item) }) !== structure(descriptor) || value.connections.some((item) => typeof item.available != "boolean") || !(value.readiness.state === "ready" && only(value.readiness, "state,placement") && value.readiness.placement === (context2.kind === "local" ? "local" : "remote") || value.readiness.state === "unavailable" && only(value.readiness, "state,reason,message") && ["not_deployed", "definition_invalid", "capability_unavailable"].includes(value.readiness.reason) && message(value.readiness.message))) && fail3("execution_unavailable"), value;
|
|
3735
3837
|
} catch {
|
|
3736
|
-
return unavailable4();
|
|
3838
|
+
return unavailable4(key, "capability_unavailable");
|
|
3737
3839
|
}
|
|
3738
3840
|
}
|
|
3739
3841
|
function appRoutineBinding(key) {
|
|
@@ -3752,27 +3854,29 @@ function appRoutineBinding(key) {
|
|
|
3752
3854
|
} catch {
|
|
3753
3855
|
return fail3("invalid_input");
|
|
3754
3856
|
}
|
|
3755
|
-
let context2 = await
|
|
3857
|
+
let context2 = await authority();
|
|
3858
|
+
context2.kind !== "local" && (encoded = JSON.stringify({ ...JSON.parse(encoded), startKey: crypto.randomUUID() }));
|
|
3859
|
+
let run = summary(await request(key, "runs", { method: "POST", body: encoded }, SUMMARY_BYTES, context2), key, context2);
|
|
3756
3860
|
return handle(key, run.id, context2);
|
|
3757
3861
|
},
|
|
3758
3862
|
runs: Object.freeze({
|
|
3759
3863
|
async list() {
|
|
3760
|
-
let value = await request(key, "runs", void 0, 20 * SUMMARY_BYTES,
|
|
3864
|
+
let context2 = await authority(!0), value = await request(key, "runs", void 0, 20 * SUMMARY_BYTES, context2, !0);
|
|
3761
3865
|
if (!Array.isArray(value) || value.length > 20) return fail3("execution_unavailable");
|
|
3762
|
-
let runs = value.map((run) => summary(run, key));
|
|
3866
|
+
let runs = value.map((run) => summary(run, key, context2));
|
|
3763
3867
|
return new Set(runs.map((run) => run.id)).size !== runs.length && fail3("execution_unavailable"), runs;
|
|
3764
3868
|
},
|
|
3765
3869
|
async get(id3) {
|
|
3766
|
-
return (typeof id3 != "string" || !
|
|
3870
|
+
return (typeof id3 != "string" || !uuid2.test(id3)) && fail3("invalid_input"), (!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable"), handle(key, id3, await authority(!0));
|
|
3767
3871
|
}
|
|
3768
3872
|
})
|
|
3769
3873
|
});
|
|
3770
3874
|
}
|
|
3771
3875
|
|
|
3772
|
-
var app = Object.freeze({
|
|
3876
|
+
var app = /* @__PURE__ */ Object.freeze({
|
|
3773
3877
|
listRoutines: () => Promise.all(appDescriptors().map(({ id: id3 }) => describeAppRoutine(id3))),
|
|
3774
3878
|
routine: appRoutineBinding,
|
|
3775
|
-
routines: new Proxy(/* @__PURE__ */ Object.create(null), {
|
|
3879
|
+
routines: /* @__PURE__ */ new Proxy(/* @__PURE__ */ Object.create(null), {
|
|
3776
3880
|
get(_target, key) {
|
|
3777
3881
|
if (!(typeof key != "string" || !appDescriptors().some((item) => item.id === key)))
|
|
3778
3882
|
return appRoutineBinding(key);
|
|
@@ -3811,7 +3915,7 @@ function routineDataEnvelope(command) {
|
|
|
3811
3915
|
}
|
|
3812
3916
|
|
|
3813
3917
|
function routinePublicationClient2(options = {}) {
|
|
3814
|
-
let environment = {}, installed2 = routineTransport(),
|
|
3918
|
+
let environment = {}, installed2 = routineTransport(), local2 = installed2?.request ?? void 0, workspace = installed2 ? "installed" : options.workspace ?? environment.OS_ROUTINE_WORKSPACE, capability = options.capability ?? environment.OS_ROUTINE_RUN;
|
|
3815
3919
|
if (!workspace || !/^[a-z0-9][a-z0-9-]*$/.test(workspace) || capability !== void 0 && !/^[0-9a-f]{64}$/.test(capability))
|
|
3816
3920
|
throw new Error("A workspace and valid optional routine capability are required");
|
|
3817
3921
|
let workingRoot = options.workingRoot ?? environment.OS_INBOX_WORKING_ROOT ?? void 0, headers = capability ? { "x-os-run": capability } : {}, request2 = options.request ?? (capability ? async (path, init2) => {
|
|
@@ -3824,7 +3928,7 @@ function routinePublicationClient2(options = {}) {
|
|
|
3824
3928
|
throw new Error("Member publication requires a host-supplied request");
|
|
3825
3929
|
});
|
|
3826
3930
|
async function send3(operation2, body) {
|
|
3827
|
-
if (
|
|
3931
|
+
if (local2) return await local2(operation2, body);
|
|
3828
3932
|
let writing = operation2 === "records/update", reading = operation2 === "records/read", response2 = await request2(writing || reading ? "/api/data" : `/api/inbox/${operation2}`, {
|
|
3829
3933
|
method: "POST",
|
|
3830
3934
|
headers: {
|
|
@@ -3871,7 +3975,7 @@ function routinePublicationClient2(options = {}) {
|
|
|
3871
3975
|
files: {
|
|
3872
3976
|
async add(value) {
|
|
3873
3977
|
let input = validateFileAddOptions(value);
|
|
3874
|
-
if (
|
|
3978
|
+
if (local2) return validateInboxFile(await local2("files/add", input));
|
|
3875
3979
|
throw workingRoot ? new Error("Inbox file reads require a Node working root") : new Error("Inbox file reads require a working root");
|
|
3876
3980
|
}
|
|
3877
3981
|
},
|