@oddington/sdk 0.1.28 → 0.1.30
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 +28 -2
- package/dist/browser.js +274 -173
- 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 +11 -1
- package/dist/types/packages/sdk/src/routine-definition-types.d.ts +3 -1
- package/dist/types/shared/routine-deployment-contract.d.ts +1 -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) {
|
|
@@ -1097,12 +1097,12 @@ function captureValue(value, ancestors = /* @__PURE__ */ new Set(), depth = 0) {
|
|
|
1097
1097
|
ancestors.delete(value);
|
|
1098
1098
|
}
|
|
1099
1099
|
}
|
|
1100
|
-
function captureDataDelete(
|
|
1101
|
-
let identity = mapping(
|
|
1100
|
+
function captureDataDelete(record4) {
|
|
1101
|
+
let identity = mapping(record4);
|
|
1102
1102
|
return !validRecordRef(identity.$ref) || typeof identity.$version != "string" || !identity.$version.length || identity.$version.length > 512 ? invalidChange() : { ref: identity.$ref, expectedVersion: identity.$version };
|
|
1103
1103
|
}
|
|
1104
|
-
function captureDataUpdate(
|
|
1105
|
-
let identity = captureDataDelete(
|
|
1104
|
+
function captureDataUpdate(record4, set) {
|
|
1105
|
+
let identity = captureDataDelete(record4), fields5 = mapping(set);
|
|
1106
1106
|
return !Object.keys(fields5).length || Object.keys(fields5).some((key) => key.startsWith("$") || ["id", "type"].includes(key)) ? invalidChange() : { ...identity, set: captureValue(fields5) };
|
|
1107
1107
|
}
|
|
1108
1108
|
function captureIdentities(value, update, allowEmpty = !0) {
|
|
@@ -1125,7 +1125,7 @@ function captureDataCreate(value) {
|
|
|
1125
1125
|
let { $ref: ref, $filing, ...fields5 } = row, filing;
|
|
1126
1126
|
if ($filing !== void 0) {
|
|
1127
1127
|
let components = mapping($filing);
|
|
1128
|
-
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)))
|
|
1129
1129
|
return invalidChange();
|
|
1130
1130
|
filing = { ...components };
|
|
1131
1131
|
}
|
|
@@ -1257,8 +1257,8 @@ function capture3(value, ancestors = /* @__PURE__ */ new Set(), depth = 0) {
|
|
|
1257
1257
|
function recordPagination(select) {
|
|
1258
1258
|
function pages(query) {
|
|
1259
1259
|
let captured = capture3(query), names = Object.keys(historyProperties(captured));
|
|
1260
|
-
for (let
|
|
1261
|
-
let selection2 = historyProperties(captured[
|
|
1260
|
+
for (let name2 of names) {
|
|
1261
|
+
let selection2 = historyProperties(captured[name2]);
|
|
1262
1262
|
if (Object.hasOwn(selection2, "$")) {
|
|
1263
1263
|
let options = historyProperties(selection2.$.value);
|
|
1264
1264
|
if (Object.hasOwn(options, "after")) return invalid6();
|
|
@@ -1266,16 +1266,16 @@ function recordPagination(select) {
|
|
|
1266
1266
|
}
|
|
1267
1267
|
return iterate();
|
|
1268
1268
|
async function* iterate() {
|
|
1269
|
-
let state = new Map(names.map((
|
|
1269
|
+
let state = new Map(names.map((name2) => [name2, {
|
|
1270
1270
|
seen: /* @__PURE__ */ new Set(),
|
|
1271
1271
|
total: 0,
|
|
1272
1272
|
count: void 0,
|
|
1273
1273
|
next: void 0
|
|
1274
1274
|
}])), active2 = names, version;
|
|
1275
1275
|
do {
|
|
1276
|
-
let request2 = Object.fromEntries(active2.map((
|
|
1277
|
-
let selection2 = captured[
|
|
1278
|
-
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 } }];
|
|
1279
1279
|
})), response2 = await select(request2), page;
|
|
1280
1280
|
try {
|
|
1281
1281
|
page = capture3(response2);
|
|
@@ -1283,28 +1283,28 @@ function recordPagination(select) {
|
|
|
1283
1283
|
(keys4.length !== active2.length + 1 || keys4.some((key) => key !== "$meta" && !active2.includes(key))) && unavailable();
|
|
1284
1284
|
let meta = page.$meta;
|
|
1285
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();
|
|
1286
|
-
for (let
|
|
1287
|
-
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] : {};
|
|
1288
1288
|
(Object.keys(historyProperties(metadata)).some((key) => key !== "count" && key !== "next") || Object.hasOwn(metadata, "next") && !text2(metadata.next)) && unavailable();
|
|
1289
|
-
for (let
|
|
1290
|
-
historyProperties(
|
|
1291
|
-
let row =
|
|
1289
|
+
for (let record4 of records) {
|
|
1290
|
+
historyProperties(record4);
|
|
1291
|
+
let row = record4;
|
|
1292
1292
|
(!validRecordRef(row.$ref) || !text2(row.$version)) && unavailable();
|
|
1293
1293
|
}
|
|
1294
|
-
let current2 = state.get(
|
|
1295
|
-
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;
|
|
1296
1296
|
}
|
|
1297
1297
|
} catch {
|
|
1298
1298
|
return unavailable();
|
|
1299
1299
|
}
|
|
1300
|
-
let collections = Object.fromEntries(names.map((
|
|
1301
|
-
let current2 = state.get(
|
|
1302
|
-
return [
|
|
1300
|
+
let collections = Object.fromEntries(names.map((name2) => {
|
|
1301
|
+
let current2 = state.get(name2);
|
|
1302
|
+
return [name2, {
|
|
1303
1303
|
...current2.count === void 0 ? {} : { count: current2.count },
|
|
1304
1304
|
...current2.next === void 0 ? {} : { next: current2.next }
|
|
1305
1305
|
}];
|
|
1306
|
-
})), output = Object.fromEntries(names.map((
|
|
1307
|
-
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 } };
|
|
1308
1308
|
} while (active2.length);
|
|
1309
1309
|
}
|
|
1310
1310
|
}
|
|
@@ -1313,12 +1313,12 @@ function recordPagination(select) {
|
|
|
1313
1313
|
(Object.keys(properties).join(",") !== "maxRecords" || !Number.isSafeInteger(maxRecords) || maxRecords < 1) && invalid6();
|
|
1314
1314
|
let result2, total = 0;
|
|
1315
1315
|
for await (let page of pages(query)) {
|
|
1316
|
-
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);
|
|
1317
1317
|
if (size > maxRecords - total) throw new DataOperationError("capacity");
|
|
1318
|
-
total += size, result2 ??= { ...Object.fromEntries(names.map((
|
|
1319
|
-
for (let
|
|
1320
|
-
let target = result2[
|
|
1321
|
-
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);
|
|
1322
1322
|
}
|
|
1323
1323
|
result2.$meta = page.$meta;
|
|
1324
1324
|
}
|
|
@@ -1327,7 +1327,7 @@ function recordPagination(select) {
|
|
|
1327
1327
|
return { pages, all };
|
|
1328
1328
|
}
|
|
1329
1329
|
|
|
1330
|
-
var
|
|
1330
|
+
var genericData = {
|
|
1331
1331
|
repository(repository) {
|
|
1332
1332
|
async function send3(input) {
|
|
1333
1333
|
let context2 = await resolveDataContext(), envelope = { repository, ...input };
|
|
@@ -1355,7 +1355,7 @@ var data = {
|
|
|
1355
1355
|
return {
|
|
1356
1356
|
collections: {
|
|
1357
1357
|
list: () => send3({ operation: "collections.list" }),
|
|
1358
|
-
schema: (
|
|
1358
|
+
schema: (name2) => send3({ operation: "collections.schema", name: name2 })
|
|
1359
1359
|
},
|
|
1360
1360
|
records: {
|
|
1361
1361
|
read: read2,
|
|
@@ -1381,19 +1381,19 @@ var data = {
|
|
|
1381
1381
|
}), input;
|
|
1382
1382
|
};
|
|
1383
1383
|
return {
|
|
1384
|
-
create(
|
|
1384
|
+
create(record4) {
|
|
1385
1385
|
assertMutable();
|
|
1386
|
-
let next = [...creates, captureDataCreate(
|
|
1386
|
+
let next = [...creates, captureDataCreate(record4)];
|
|
1387
1387
|
snapshot(updates, next, deletes), creates = next;
|
|
1388
1388
|
},
|
|
1389
|
-
update(
|
|
1389
|
+
update(record4, set) {
|
|
1390
1390
|
assertMutable();
|
|
1391
|
-
let next = [...updates, captureDataUpdate(
|
|
1391
|
+
let next = [...updates, captureDataUpdate(record4, set)];
|
|
1392
1392
|
snapshot(next, creates, deletes), updates = next;
|
|
1393
1393
|
},
|
|
1394
|
-
delete(
|
|
1394
|
+
delete(record4) {
|
|
1395
1395
|
assertMutable();
|
|
1396
|
-
let next = [...deletes, captureDataDelete(
|
|
1396
|
+
let next = [...deletes, captureDataDelete(record4)];
|
|
1397
1397
|
snapshot(updates, creates, next), deletes = next;
|
|
1398
1398
|
},
|
|
1399
1399
|
async validate() {
|
|
@@ -1425,7 +1425,7 @@ var data = {
|
|
|
1425
1425
|
}
|
|
1426
1426
|
};
|
|
1427
1427
|
}
|
|
1428
|
-
};
|
|
1428
|
+
}, data = genericData;
|
|
1429
1429
|
|
|
1430
1430
|
async function hostedContent(url, init2, parent, upstream = fetch, check = async () => {
|
|
1431
1431
|
}, failure) {
|
|
@@ -1579,9 +1579,9 @@ async function send(suffix, init2, descriptor, initial, parent) {
|
|
|
1579
1579
|
let parsed;
|
|
1580
1580
|
if (descriptor === "enrichment") {
|
|
1581
1581
|
if (!value || typeof value != "object" || Array.isArray(value)) throw unavailable2();
|
|
1582
|
-
let { name, ...metadata } = value;
|
|
1583
|
-
if (!safeEnrichmentName(
|
|
1584
|
-
parsed = { name, ...parseEnrichmentDescriptor(metadata) };
|
|
1582
|
+
let { name: name2, ...metadata } = value;
|
|
1583
|
+
if (!safeEnrichmentName(name2)) throw unavailable2();
|
|
1584
|
+
parsed = { name: name2, ...parseEnrichmentDescriptor(metadata) };
|
|
1585
1585
|
} else parsed = parseFileDescriptor(value);
|
|
1586
1586
|
return checkCurrent(), parsed;
|
|
1587
1587
|
} catch (error) {
|
|
@@ -1658,10 +1658,10 @@ async function multipartCreate(input, metadata, exchange, release = () => {
|
|
|
1658
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();
|
|
1659
1659
|
receipts.push({ partNumber, etag: receipt.etag }), sent += length, lastProgress = Date.now();
|
|
1660
1660
|
}
|
|
1661
|
-
if (upload) for (let
|
|
1662
|
-
let bytes = await request2(() => upload.enrichment(
|
|
1663
|
-
if (bytes.byteLength !== upload.file.enrichments[
|
|
1664
|
-
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)}`, {
|
|
1665
1665
|
method: "POST",
|
|
1666
1666
|
headers: { "content-type": "application/octet-stream", "x-os-transfer": ticket },
|
|
1667
1667
|
body: bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength)
|
|
@@ -1697,11 +1697,11 @@ async function operation(work, initial, parent) {
|
|
|
1697
1697
|
throw error instanceof FileOperationError ? error : unavailable2();
|
|
1698
1698
|
});
|
|
1699
1699
|
}
|
|
1700
|
-
function contentPath(id3,
|
|
1700
|
+
function contentPath(id3, name2) {
|
|
1701
1701
|
let path = idPath(id3);
|
|
1702
|
-
if (
|
|
1703
|
-
if (!safeEnrichmentName(
|
|
1704
|
-
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`;
|
|
1705
1705
|
}
|
|
1706
1706
|
async function read(id3, names) {
|
|
1707
1707
|
let context2 = await resolveFilesContext();
|
|
@@ -1711,14 +1711,14 @@ async function read(id3, names) {
|
|
|
1711
1711
|
}
|
|
1712
1712
|
if (!Array.isArray(names)) throw invalid7();
|
|
1713
1713
|
let distinct = [], seen = /* @__PURE__ */ new Set();
|
|
1714
|
-
for (let
|
|
1715
|
-
if (typeof
|
|
1716
|
-
if (!seen.has(
|
|
1714
|
+
for (let name2 of names) {
|
|
1715
|
+
if (typeof name2 != "string" || !safeEnrichmentName(name2)) throw invalid7();
|
|
1716
|
+
if (!seen.has(name2)) {
|
|
1717
1717
|
if (seen.size === 16) throw invalid7();
|
|
1718
|
-
seen.add(
|
|
1718
|
+
seen.add(name2), distinct.push(name2);
|
|
1719
1719
|
}
|
|
1720
1720
|
}
|
|
1721
|
-
let paths = distinct.map((
|
|
1721
|
+
let paths = distinct.map((name2) => contentPath(id3, name2));
|
|
1722
1722
|
return timed(async (parent) => {
|
|
1723
1723
|
let responses = {};
|
|
1724
1724
|
try {
|
|
@@ -1754,10 +1754,10 @@ var files = {
|
|
|
1754
1754
|
if (!blob && !array3 && !stream) throw invalid7();
|
|
1755
1755
|
let intrinsic = blob ? input.file.size : array3 ? input.file.byteLength : void 0;
|
|
1756
1756
|
if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid7();
|
|
1757
|
-
let
|
|
1758
|
-
|
|
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));
|
|
1759
1759
|
let inputMediaType = blob ? declaredOriginalMediaType(input.file.type) : void 0, metadata = parseFileCreateMetadata({
|
|
1760
|
-
name,
|
|
1760
|
+
name: name2,
|
|
1761
1761
|
size: intrinsic ?? input.size,
|
|
1762
1762
|
path: input.path,
|
|
1763
1763
|
storage: input.storage,
|
|
@@ -1857,7 +1857,7 @@ function validDropboxFileScopes(value) {
|
|
|
1857
1857
|
|
|
1858
1858
|
var ROUTINE_CONNECTION_CREDENTIALS_ENV = "OS_ROUTINE_CONNECTION_CREDENTIALS";
|
|
1859
1859
|
function parseRoutineConnectionNames(value) {
|
|
1860
|
-
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)
|
|
1861
1861
|
throw new Error("Invalid routine connections");
|
|
1862
1862
|
return value;
|
|
1863
1863
|
}
|
|
@@ -1960,9 +1960,9 @@ function equal(a, b) {
|
|
|
1960
1960
|
function createConnections(transport) {
|
|
1961
1961
|
return { async get() {
|
|
1962
1962
|
throw new Error("Connection unavailable");
|
|
1963
|
-
}, airtable(
|
|
1964
|
-
(typeof
|
|
1965
|
-
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);
|
|
1966
1966
|
return {
|
|
1967
1967
|
tables: { list: async () => await call("tables.list", {}) },
|
|
1968
1968
|
records: {
|
|
@@ -1975,9 +1975,9 @@ function createConnections(transport) {
|
|
|
1975
1975
|
};
|
|
1976
1976
|
} };
|
|
1977
1977
|
}
|
|
1978
|
-
async function executeAirtableOperation(
|
|
1979
|
-
let { name, baseId, accessToken } =
|
|
1980
|
-
(!/^[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");
|
|
1981
1981
|
let input;
|
|
1982
1982
|
try {
|
|
1983
1983
|
input = object3(serializable(raw));
|
|
@@ -1986,7 +1986,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
|
|
|
1986
1986
|
}
|
|
1987
1987
|
let mutation = ["records.create", "records.update", "records.delete"].includes(operation2), receipt = (ids2) => ({
|
|
1988
1988
|
provider: "airtable",
|
|
1989
|
-
connection: `airtable/${
|
|
1989
|
+
connection: `airtable/${name2}`,
|
|
1990
1990
|
baseId,
|
|
1991
1991
|
table: input.table,
|
|
1992
1992
|
operation: operation2.slice(8),
|
|
@@ -2107,7 +2107,7 @@ var MANAGED_CONNECTION_CAPABILITY_ENV = "OS_MANAGED_CONNECTION_CAPABILITY";
|
|
|
2107
2107
|
function managedConnections(capability) {
|
|
2108
2108
|
let endpoint = new URL(capability.endpoint);
|
|
2109
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");
|
|
2110
|
-
return createConnections(async (
|
|
2110
|
+
return createConnections(async (name2, operation2, input) => {
|
|
2111
2111
|
let safeInput;
|
|
2112
2112
|
try {
|
|
2113
2113
|
safeInput = serializable(input);
|
|
@@ -2119,7 +2119,7 @@ function managedConnections(capability) {
|
|
|
2119
2119
|
method: "POST",
|
|
2120
2120
|
redirect: "error",
|
|
2121
2121
|
headers: { authorization: `Bearer ${capability.token}`, "content-type": "application/json" },
|
|
2122
|
-
body: JSON.stringify({ name, operation: operation2, input: safeInput }),
|
|
2122
|
+
body: JSON.stringify({ name: name2, operation: operation2, input: safeInput }),
|
|
2123
2123
|
signal: AbortSignal.timeout(125e3)
|
|
2124
2124
|
}), value = await response2.json();
|
|
2125
2125
|
if (!response2.ok) throw new AirtableOperationError(
|
|
@@ -2143,7 +2143,7 @@ async function reportLocalRoutineEffect(value) {
|
|
|
2143
2143
|
}
|
|
2144
2144
|
|
|
2145
2145
|
var local;
|
|
2146
|
-
var airtable = /* @__PURE__ */ createConnections(async (
|
|
2146
|
+
var airtable = /* @__PURE__ */ createConnections(async (name2, operation2, input) => {
|
|
2147
2147
|
throw new AirtableOperationError("Airtable connection unavailable");
|
|
2148
2148
|
});
|
|
2149
2149
|
function runtimeConnections() {
|
|
@@ -2185,28 +2185,28 @@ function validateRecordWrite(value) {
|
|
|
2185
2185
|
}
|
|
2186
2186
|
function validateRecordUpdate(value) {
|
|
2187
2187
|
let input = validateRecordWrite(value);
|
|
2188
|
-
if (input.records.some((
|
|
2188
|
+
if (input.records.some((record4) => !("expectedVersion" in record4)))
|
|
2189
2189
|
throw new InboxContractError("Record creation is unavailable for this operation");
|
|
2190
2190
|
return input;
|
|
2191
2191
|
}
|
|
2192
2192
|
function validateRecordDelete(value) {
|
|
2193
2193
|
let input = serializable(value);
|
|
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((
|
|
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)
|
|
2195
2195
|
throw new InboxContractError("Invalid record deletion batch");
|
|
2196
|
-
for (let
|
|
2197
|
-
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))
|
|
2198
2198
|
throw new InboxContractError("Invalid record deletion");
|
|
2199
2199
|
return structuredClone(input);
|
|
2200
2200
|
}
|
|
2201
2201
|
function validateRecordChange(value) {
|
|
2202
2202
|
let input = serializable(value);
|
|
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((
|
|
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)
|
|
2204
2204
|
throw new InboxContractError("Invalid record change batch");
|
|
2205
2205
|
let writes = [], deletes = [];
|
|
2206
|
-
for (let
|
|
2207
|
-
if (!
|
|
2206
|
+
for (let record4 of input.records) {
|
|
2207
|
+
if (!record4 || typeof record4 != "object" || Array.isArray(record4))
|
|
2208
2208
|
throw new InboxContractError("Invalid record change");
|
|
2209
|
-
"set" in
|
|
2209
|
+
"set" in record4 || "fields" in record4 ? writes.push(record4) : deletes.push(record4);
|
|
2210
2210
|
}
|
|
2211
2211
|
return writes.length && validateRecordWrite({ repository: input.repository, records: writes }), deletes.length && validateRecordDelete({ repository: input.repository, records: deletes }), structuredClone(input);
|
|
2212
2212
|
}
|
|
@@ -2290,8 +2290,8 @@ function json(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
|
2290
2290
|
}
|
|
2291
2291
|
}
|
|
2292
2292
|
function recordReference(value) {
|
|
2293
|
-
let
|
|
2294
|
-
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;
|
|
2295
2295
|
}
|
|
2296
2296
|
function responseDefinition(value) {
|
|
2297
2297
|
let definition = object4(value);
|
|
@@ -2321,7 +2321,7 @@ function responseDefinition(value) {
|
|
|
2321
2321
|
let collection = object4(source.collection);
|
|
2322
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));
|
|
2323
2323
|
let where = object4(source.where ?? {});
|
|
2324
|
-
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))));
|
|
2325
2325
|
let display = object4(source.display);
|
|
2326
2326
|
keys3(display, ["labelFields"]);
|
|
2327
2327
|
let labels = array2(display.labelFields);
|
|
@@ -2329,8 +2329,8 @@ function responseDefinition(value) {
|
|
|
2329
2329
|
let suggestions = array2(source.suggestions ?? []), refs = suggestions.map((value2) => {
|
|
2330
2330
|
let suggestion = object4(value2);
|
|
2331
2331
|
keys3(suggestion, ["record", "reason"], ["record"]);
|
|
2332
|
-
let
|
|
2333
|
-
return assert(
|
|
2332
|
+
let record4 = recordReference(suggestion.record);
|
|
2333
|
+
return assert(record4.repository === collection.repository), "reason" in suggestion && assert(text4(suggestion.reason)), record4.ref;
|
|
2334
2334
|
});
|
|
2335
2335
|
assert(suggestions.length <= 8 && new Set(refs).size === refs.length);
|
|
2336
2336
|
}
|
|
@@ -2364,14 +2364,14 @@ function block(value) {
|
|
|
2364
2364
|
["kind", "label", "initiallyExpanded", ...entry.kind === "record" ? ["record", "view"] : entry.kind === "records" ? ["records", "view"] : ["files"]],
|
|
2365
2365
|
["kind", "label", entry.kind === "record" ? "record" : entry.kind === "records" ? "records" : "files"]
|
|
2366
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") {
|
|
2367
|
-
let
|
|
2368
|
-
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);
|
|
2369
2369
|
return;
|
|
2370
2370
|
}
|
|
2371
2371
|
if (entry.kind === "records") {
|
|
2372
2372
|
let records = array2(entry.records), refs = records.map((value2) => {
|
|
2373
|
-
let
|
|
2374
|
-
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;
|
|
2375
2375
|
});
|
|
2376
2376
|
assert(records.length > 0 && new Set(refs).size === refs.length);
|
|
2377
2377
|
return;
|
|
@@ -2508,8 +2508,8 @@ function parseInboxResult(operation2, value) {
|
|
|
2508
2508
|
let result2 = object4(value);
|
|
2509
2509
|
assert(text4(result2.recordType) && integer(result2.eligibleCount, 0) && integer(result2.matchCount, 0) && Number(result2.matchCount) <= Number(result2.eligibleCount));
|
|
2510
2510
|
let labeled = (value2) => {
|
|
2511
|
-
let
|
|
2512
|
-
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));
|
|
2513
2513
|
};
|
|
2514
2514
|
return array2(result2.matches).forEach(labeled), array2(result2.suggestions).forEach(labeled), "selected" in result2 && labeled(result2.selected), result2;
|
|
2515
2515
|
}
|
|
@@ -2676,7 +2676,7 @@ function appContext(origin, active2) {
|
|
|
2676
2676
|
} catch {
|
|
2677
2677
|
return !1;
|
|
2678
2678
|
}
|
|
2679
|
-
}, 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) => {
|
|
2680
2680
|
let value = JSON.parse(candidate ?? "null");
|
|
2681
2681
|
if (!validPair(value) || value.context.expiresAt > Date.now() + 6e5 || !sameSession(value.context)) throw new Error();
|
|
2682
2682
|
return value;
|
|
@@ -2713,7 +2713,7 @@ function appContext(origin, active2) {
|
|
|
2713
2713
|
if (response2.status >= 500) throw new AppRenewalUnavailable();
|
|
2714
2714
|
if (!response2.ok) throw new Error();
|
|
2715
2715
|
let value = await appResponse(response2, 4096, signal);
|
|
2716
|
-
if (!alive() || !
|
|
2716
|
+
if (!alive() || !bounded3(value)) throw new Error();
|
|
2717
2717
|
return value;
|
|
2718
2718
|
}
|
|
2719
2719
|
function install(value, candidate, raw) {
|
|
@@ -2785,7 +2785,7 @@ function appContext(origin, active2) {
|
|
|
2785
2785
|
return;
|
|
2786
2786
|
}
|
|
2787
2787
|
if (!response2.ok) throw new Error();
|
|
2788
|
-
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();
|
|
2789
2789
|
if (stored() !== previous) {
|
|
2790
2790
|
await synchronize(requestController.signal);
|
|
2791
2791
|
return;
|
|
@@ -2866,16 +2866,16 @@ function appContext(origin, active2) {
|
|
|
2866
2866
|
return requestChecked(`routines/${encodeURIComponent(key)}/${suffix}`, {}, !1, !0);
|
|
2867
2867
|
}
|
|
2868
2868
|
async function requestFiles(suffix, init2, parent) {
|
|
2869
|
-
let
|
|
2869
|
+
let unavailable5 = () => new FileOperationError("unsupported_context", 400);
|
|
2870
2870
|
if (!current2() || !/^(?:|\/[0-9a-f-]{36}(?:\/(?:content|upload|enrichments(?:\/[^/?#]+\/content)?))?)$/i.test(suffix))
|
|
2871
|
-
throw
|
|
2872
|
-
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();
|
|
2873
2873
|
try {
|
|
2874
2874
|
return await hostedContent("", init2, signal, (_url, request2) => untilAborted(
|
|
2875
2875
|
send3(`files${suffix}`, admitted, signal, request2).then((value) => {
|
|
2876
2876
|
if (signal.aborted)
|
|
2877
2877
|
throw value.body?.cancel().catch(() => {
|
|
2878
|
-
}),
|
|
2878
|
+
}), unavailable5();
|
|
2879
2879
|
return value;
|
|
2880
2880
|
}),
|
|
2881
2881
|
signal
|
|
@@ -3182,8 +3182,8 @@ function init({ auth: input }) {
|
|
|
3182
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);
|
|
3183
3183
|
} catch {
|
|
3184
3184
|
}
|
|
3185
|
-
let active2 = !0, revision = 0, person, token, binding = {},
|
|
3186
|
-
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();
|
|
3187
3187
|
if (!active2 || !endpoint || !workspace || globalThis.location.origin !== endpoint) throw new Error("Hosted Data context unavailable.");
|
|
3188
3188
|
let started = revision, { data: { session }, error } = await auth2.getSession();
|
|
3189
3189
|
if (!active2 || globalThis.location.origin !== endpoint || started !== revision || error || !session || person !== void 0 && person !== session.user.id)
|
|
@@ -3202,13 +3202,13 @@ function init({ auth: input }) {
|
|
|
3202
3202
|
memberId: session.user.id,
|
|
3203
3203
|
binding
|
|
3204
3204
|
};
|
|
3205
|
-
}, uninstall = installMemberContext(resolve,
|
|
3206
|
-
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));
|
|
3207
3207
|
};
|
|
3208
3208
|
installedDispose = dispose, stopDisposal = registered?.onDispose(dispose), active2 && (subscription = auth2.onAuthStateChange((event, session) => {
|
|
3209
3209
|
let next = session?.user.id ?? null;
|
|
3210
|
-
(event === "SIGNED_OUT" || person !== void 0 && next !== person ||
|
|
3211
|
-
}).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());
|
|
3212
3212
|
}
|
|
3213
3213
|
var os = { init };
|
|
3214
3214
|
|
|
@@ -3282,7 +3282,7 @@ function createBrowserAuth(runtime) {
|
|
|
3282
3282
|
return;
|
|
3283
3283
|
}
|
|
3284
3284
|
c.session = session;
|
|
3285
|
-
let email = typeof session.user.email == "string" ? session.user.email.trim() : "", metadata = session.user.user_metadata,
|
|
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
3286
|
notify(c, event), publish(c, { status: "signed_in", account, ...pending ? { pending } : {} });
|
|
3287
3287
|
let checkExpiry = () => {
|
|
3288
3288
|
if (!c.active || !c.session) return;
|
|
@@ -3637,7 +3637,60 @@ function routineRunHandle(operations2) {
|
|
|
3637
3637
|
});
|
|
3638
3638
|
}
|
|
3639
3639
|
|
|
3640
|
-
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 {
|
|
3641
3694
|
constructor(reason) {
|
|
3642
3695
|
super(reason);
|
|
3643
3696
|
this.reason = reason;
|
|
@@ -3648,44 +3701,72 @@ var identifier = /^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/, uuid = /^[0-9a-f]{8}-[0-
|
|
|
3648
3701
|
throw new AppRoutineError(reason);
|
|
3649
3702
|
};
|
|
3650
3703
|
function current(context2) {
|
|
3651
|
-
(!context2.isCurrent() || context2.signal.aborted) && fail3("authority_unavailable");
|
|
3704
|
+
(!context2.isCurrent() || context2.kind === "local" && context2.signal.aborted) && fail3("authority_unavailable");
|
|
3652
3705
|
}
|
|
3653
3706
|
function appDescriptors() {
|
|
3654
3707
|
return globalThis[/* @__PURE__ */ Symbol.for("oddington.app.descriptor")]?.routines ?? [];
|
|
3655
3708
|
}
|
|
3656
|
-
async function
|
|
3709
|
+
async function authority(retained = !1) {
|
|
3657
3710
|
let context2 = await resolveAppContext(retained).catch(() => fail3("authority_unavailable"));
|
|
3658
|
-
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;
|
|
3659
3717
|
}
|
|
3660
3718
|
async function request(key, suffix, init2, maximum = SUMMARY_BYTES, retained, read2 = !1) {
|
|
3661
3719
|
(!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable");
|
|
3662
|
-
let context2 = retained
|
|
3720
|
+
let context2 = retained ? await live(retained, read2) : await authority(read2);
|
|
3663
3721
|
current(context2);
|
|
3722
|
+
let deadline = new AbortController(), timeout = context2.kind === "local" ? void 0 : setTimeout(() => deadline.abort(), 2e4);
|
|
3664
3723
|
try {
|
|
3665
|
-
let response2 = await (read2 ? context2.requestRetainedRoutine(key, suffix) : context2.requestRoutine(key, suffix, init2)
|
|
3666
|
-
|
|
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 === "current_deployment_unavailable" || code === "capability_unavailable"))
|
|
3737
|
+
return unavailable4(key, code === "current_deployment_unavailable" ? "not_deployed" : "capability_unavailable");
|
|
3738
|
+
fail3("execution_unavailable");
|
|
3739
|
+
}
|
|
3667
3740
|
let reason = value?.error;
|
|
3668
|
-
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");
|
|
3669
3742
|
}
|
|
3670
3743
|
return value;
|
|
3671
3744
|
} catch (error) {
|
|
3672
3745
|
if (current(context2), error instanceof AppRoutineError) throw error;
|
|
3673
3746
|
fail3("execution_unavailable");
|
|
3747
|
+
} finally {
|
|
3748
|
+
clearTimeout(timeout);
|
|
3674
3749
|
}
|
|
3675
3750
|
}
|
|
3676
|
-
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
|
+
}
|
|
3677
3758
|
let run = value;
|
|
3678
|
-
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;
|
|
3679
3760
|
}
|
|
3680
3761
|
function only(value, allowed) {
|
|
3681
3762
|
return !!value && typeof value == "object" && !Array.isArray(value) && Object.keys(value).every((key) => allowed.split(",").includes(key));
|
|
3682
3763
|
}
|
|
3683
|
-
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;
|
|
3684
3765
|
function optionalTimes(value) {
|
|
3685
3766
|
return (value.startedAt === void 0 || timestamp(value.startedAt)) && (value.finishedAt === void 0 || timestamp(value.finishedAt));
|
|
3686
3767
|
}
|
|
3687
3768
|
function validStep(step) {
|
|
3688
|
-
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));
|
|
3689
3770
|
}
|
|
3690
3771
|
function validPublication(value) {
|
|
3691
3772
|
return value && only(value, value.state === "failed" ? "state,message" : "state") && (["not_needed", "ready", "published"].includes(value.state) || value.state === "failed" && message(value.message));
|
|
@@ -3708,8 +3789,8 @@ function structure(value) {
|
|
|
3708
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);
|
|
3709
3790
|
}
|
|
3710
3791
|
function handle(key, id3, context2) {
|
|
3711
|
-
(!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable"), (typeof id3 != "string" || !
|
|
3712
|
-
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);
|
|
3713
3794
|
return routineRunHandle({
|
|
3714
3795
|
async current() {
|
|
3715
3796
|
return current(context2), read2();
|
|
@@ -3717,26 +3798,44 @@ function handle(key, id3, context2) {
|
|
|
3717
3798
|
async step(step) {
|
|
3718
3799
|
(typeof step != "string" || !identifier.test(step)) && fail3("invalid_input");
|
|
3719
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
|
+
}
|
|
3720
3807
|
return (!only(value, "id,title,status,startedAt,finishedAt,summary,data") || value.id !== step || !validStep(value)) && fail3("execution_unavailable"), value;
|
|
3721
3808
|
},
|
|
3722
3809
|
async publish() {
|
|
3723
|
-
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);
|
|
3724
3811
|
}
|
|
3725
3812
|
});
|
|
3726
3813
|
}
|
|
3727
|
-
|
|
3814
|
+
function unavailable4(key, reason) {
|
|
3728
3815
|
let descriptor = appDescriptors().find((item) => item.id === key);
|
|
3729
|
-
|
|
3730
|
-
let unavailable4 = () => ({
|
|
3816
|
+
return {
|
|
3731
3817
|
...structuredClone(descriptor),
|
|
3732
3818
|
connections: descriptor.connections.map((connection) => ({ ...connection, available: !1 })),
|
|
3733
|
-
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" }]
|
|
3734
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");
|
|
3735
3834
|
try {
|
|
3736
|
-
let value = await request(key, "describe", void 0,
|
|
3737
|
-
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;
|
|
3738
3837
|
} catch {
|
|
3739
|
-
return unavailable4();
|
|
3838
|
+
return unavailable4(key, "capability_unavailable");
|
|
3740
3839
|
}
|
|
3741
3840
|
}
|
|
3742
3841
|
function appRoutineBinding(key) {
|
|
@@ -3755,27 +3854,29 @@ function appRoutineBinding(key) {
|
|
|
3755
3854
|
} catch {
|
|
3756
3855
|
return fail3("invalid_input");
|
|
3757
3856
|
}
|
|
3758
|
-
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);
|
|
3759
3860
|
return handle(key, run.id, context2);
|
|
3760
3861
|
},
|
|
3761
3862
|
runs: Object.freeze({
|
|
3762
3863
|
async list() {
|
|
3763
|
-
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);
|
|
3764
3865
|
if (!Array.isArray(value) || value.length > 20) return fail3("execution_unavailable");
|
|
3765
|
-
let runs = value.map((run) => summary(run, key));
|
|
3866
|
+
let runs = value.map((run) => summary(run, key, context2));
|
|
3766
3867
|
return new Set(runs.map((run) => run.id)).size !== runs.length && fail3("execution_unavailable"), runs;
|
|
3767
3868
|
},
|
|
3768
3869
|
async get(id3) {
|
|
3769
|
-
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));
|
|
3770
3871
|
}
|
|
3771
3872
|
})
|
|
3772
3873
|
});
|
|
3773
3874
|
}
|
|
3774
3875
|
|
|
3775
|
-
var app = Object.freeze({
|
|
3876
|
+
var app = /* @__PURE__ */ Object.freeze({
|
|
3776
3877
|
listRoutines: () => Promise.all(appDescriptors().map(({ id: id3 }) => describeAppRoutine(id3))),
|
|
3777
3878
|
routine: appRoutineBinding,
|
|
3778
|
-
routines: new Proxy(/* @__PURE__ */ Object.create(null), {
|
|
3879
|
+
routines: /* @__PURE__ */ new Proxy(/* @__PURE__ */ Object.create(null), {
|
|
3779
3880
|
get(_target, key) {
|
|
3780
3881
|
if (!(typeof key != "string" || !appDescriptors().some((item) => item.id === key)))
|
|
3781
3882
|
return appRoutineBinding(key);
|
|
@@ -3814,7 +3915,7 @@ function routineDataEnvelope(command) {
|
|
|
3814
3915
|
}
|
|
3815
3916
|
|
|
3816
3917
|
function routinePublicationClient2(options = {}) {
|
|
3817
|
-
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;
|
|
3818
3919
|
if (!workspace || !/^[a-z0-9][a-z0-9-]*$/.test(workspace) || capability !== void 0 && !/^[0-9a-f]{64}$/.test(capability))
|
|
3819
3920
|
throw new Error("A workspace and valid optional routine capability are required");
|
|
3820
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) => {
|
|
@@ -3827,7 +3928,7 @@ function routinePublicationClient2(options = {}) {
|
|
|
3827
3928
|
throw new Error("Member publication requires a host-supplied request");
|
|
3828
3929
|
});
|
|
3829
3930
|
async function send3(operation2, body) {
|
|
3830
|
-
if (
|
|
3931
|
+
if (local2) return await local2(operation2, body);
|
|
3831
3932
|
let writing = operation2 === "records/update", reading = operation2 === "records/read", response2 = await request2(writing || reading ? "/api/data" : `/api/inbox/${operation2}`, {
|
|
3832
3933
|
method: "POST",
|
|
3833
3934
|
headers: {
|
|
@@ -3874,7 +3975,7 @@ function routinePublicationClient2(options = {}) {
|
|
|
3874
3975
|
files: {
|
|
3875
3976
|
async add(value) {
|
|
3876
3977
|
let input = validateFileAddOptions(value);
|
|
3877
|
-
if (
|
|
3978
|
+
if (local2) return validateInboxFile(await local2("files/add", input));
|
|
3878
3979
|
throw workingRoot ? new Error("Inbox file reads require a Node working root") : new Error("Inbox file reads require a working root");
|
|
3879
3980
|
}
|
|
3880
3981
|
},
|