@oddington/sdk 0.1.21 → 0.1.23
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 +12 -5
- package/dist/browser.js +439 -323
- package/dist/index.js +7 -7
- package/dist/types/packages/sdk/src/public.d.ts +3 -1
- package/dist/types/packages/sdk/src/routine-definition-types.d.ts +14 -10
- package/dist/types/shared/airtable-contract.d.ts +1 -0
- package/dist/types/shared/app-descriptor.d.ts +3 -0
- package/dist/types/shared/app-routine-contract.d.ts +1 -0
- package/dist/types/shared/connection-runtime.d.ts +20 -0
- package/dist/types/shared/inbox-contract.d.ts +9 -1
- package/dist/types/shared/inbox-member-contract.d.ts +2 -2
- package/dist/types/shared/inbox-member-types.d.ts +30 -19
- package/dist/types/shared/routine-definition-contract.d.ts +33 -0
- package/dist/types/shared/routine-deployment-contract.d.ts +47 -0
- package/dist/types/shared/routine-deployment-path.d.ts +6 -0
- package/dist/types/shared/routine-source-provenance.d.ts +7 -0
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -285,7 +285,7 @@ function validatePublication(value) {
|
|
|
285
285
|
"views",
|
|
286
286
|
"body",
|
|
287
287
|
"notifyImmediately",
|
|
288
|
-
...source.kind === "ask" ? ["questions"] : []
|
|
288
|
+
...source.kind === "ask" ? ["questions", "tags", "recordRefs"] : []
|
|
289
289
|
], "publication"), source.notifyImmediately !== void 0 && typeof source.notifyImmediately != "boolean" && fail("notifyImmediately must be a boolean");
|
|
290
290
|
let itemPresentation = { ...presentation(source), ...source.notifyImmediately === void 0 ? {} : { notifyImmediately: source.notifyImmediately } }, linkedAsks = (itemPresentation.body ?? []).flatMap((block2) => block2.kind === "asks" ? block2.asks : []);
|
|
291
291
|
if (new Set(linkedAsks).size !== linkedAsks.length && fail("Ask belongs to more than one problem"), source.kind === "digest") return {
|
|
@@ -297,10 +297,24 @@ function validatePublication(value) {
|
|
|
297
297
|
let questions = array(source.questions === void 0 ? [] : source.questions, "questions").map((value2) => question(value2));
|
|
298
298
|
new Set(questions.map((entry) => entry.id)).size !== questions.length && fail("Duplicate question ID");
|
|
299
299
|
let extra = source.recipients === void 0 ? [] : distinctPeople(source.recipients, "recipients", !1);
|
|
300
|
-
|
|
300
|
+
!questions.length && !extra.length && fail("Ask requires at least one recipient");
|
|
301
|
+
let tags = array(source.tags === void 0 ? [] : source.tags, "Ask tags").map((value2) => {
|
|
302
|
+
let tag = text(value2, "Ask tag");
|
|
303
|
+
return new TextEncoder().encode(tag).byteLength > 64 && fail("Ask tag exceeds 64 UTF-8 bytes"), tag;
|
|
304
|
+
});
|
|
305
|
+
(tags.length > 32 || new Set(tags).size !== tags.length) && fail("Ask tags exceed bounds or contain duplicates");
|
|
306
|
+
let recordRefs = array(source.recordRefs === void 0 ? [] : source.recordRefs, "Ask Record references").map((value2) => {
|
|
307
|
+
let row = object(value2, "Ask Record reference");
|
|
308
|
+
keys(row, ["repository", "id"], "Ask Record reference");
|
|
309
|
+
let { repository, ref } = validateRecordReference({ repository: row.repository, ref: row.id });
|
|
310
|
+
return { repository, id: ref };
|
|
311
|
+
});
|
|
312
|
+
return new Set(recordRefs.map((ref) => JSON.stringify([ref.repository, ref.id]))).size !== recordRefs.length && fail("Ask Record references contain duplicates"), {
|
|
301
313
|
kind: "ask",
|
|
302
314
|
...itemPresentation,
|
|
303
315
|
questions,
|
|
316
|
+
tags,
|
|
317
|
+
recordRefs,
|
|
304
318
|
recipients: [.../* @__PURE__ */ new Set([...extra, ...questions.flatMap((entry) => [entry.to, ...entry.allowedResponders])])]
|
|
305
319
|
};
|
|
306
320
|
}
|
|
@@ -335,7 +349,7 @@ function createInboxPublisher(transport) {
|
|
|
335
349
|
return {
|
|
336
350
|
async publishAsk(value, options) {
|
|
337
351
|
let source = object(value, "ask");
|
|
338
|
-
keys(source, ["title", "description", "recipients", "views", "body", "questions", "notifyImmediately"], "ask");
|
|
352
|
+
keys(source, ["title", "description", "recipients", "views", "body", "questions", "notifyImmediately", "tags", "recordRefs"], "ask");
|
|
339
353
|
let result2 = await transport.publish({
|
|
340
354
|
requestKey: publicationRequestKey(options),
|
|
341
355
|
item: validatePublication({ ...source, kind: "ask" })
|
|
@@ -391,44 +405,44 @@ var FileOperationError = class extends Error {
|
|
|
391
405
|
retryable;
|
|
392
406
|
}, 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;
|
|
393
407
|
function parseFileDescriptor(value) {
|
|
394
|
-
let
|
|
408
|
+
let invalid7 = () => {
|
|
395
409
|
throw new FileOperationError("unavailable", 503, !0);
|
|
396
410
|
};
|
|
397
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
411
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid7();
|
|
398
412
|
let f = value;
|
|
399
|
-
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
|
|
413
|
+
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 invalid7();
|
|
400
414
|
let d = f.details;
|
|
401
415
|
if (d.kind === "other") {
|
|
402
|
-
if (Object.keys(d).length !== 1 || f.mediaType !== "application/octet-stream") return
|
|
416
|
+
if (Object.keys(d).length !== 1 || f.mediaType !== "application/octet-stream") return invalid7();
|
|
403
417
|
} else if (d.kind === "csv") {
|
|
404
|
-
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
|
|
418
|
+
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 invalid7();
|
|
405
419
|
} else if (d.kind === "pdf") {
|
|
406
|
-
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
|
|
407
|
-
} else return
|
|
420
|
+
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 invalid7();
|
|
421
|
+
} else return invalid7();
|
|
408
422
|
for (let [name, descriptor] of Object.entries(f.enrichments)) {
|
|
409
|
-
if (!safeEnrichmentName(name)) return
|
|
423
|
+
if (!safeEnrichmentName(name)) return invalid7();
|
|
410
424
|
parseEnrichmentDescriptor(descriptor);
|
|
411
425
|
}
|
|
412
|
-
return new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024 ?
|
|
426
|
+
return new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024 ? invalid7() : f;
|
|
413
427
|
}
|
|
414
428
|
function parseEnrichmentDescriptor(value) {
|
|
415
|
-
let
|
|
429
|
+
let invalid7 = () => {
|
|
416
430
|
throw new FileOperationError("unavailable", 503, !0);
|
|
417
431
|
};
|
|
418
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
432
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid7();
|
|
419
433
|
let d = value;
|
|
420
|
-
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) ?
|
|
434
|
+
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) ? invalid7() : d;
|
|
421
435
|
}
|
|
422
436
|
function safeEnrichmentName(value) {
|
|
423
437
|
return safeFileName(value) && !/^original(?:\.|$)/i.test(value);
|
|
424
438
|
}
|
|
425
439
|
function parseFileEnrichMetadata(value, maxBytes) {
|
|
426
|
-
let
|
|
440
|
+
let invalid7 = () => {
|
|
427
441
|
throw new FileOperationError("invalid_input", 400);
|
|
428
442
|
};
|
|
429
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
443
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid7();
|
|
430
444
|
let d = value;
|
|
431
|
-
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
|
|
445
|
+
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 invalid7();
|
|
432
446
|
if (d.size > maxBytes) throw new FileOperationError("request_too_large", 413);
|
|
433
447
|
return d;
|
|
434
448
|
}
|
|
@@ -439,23 +453,23 @@ function safeFilePath(value) {
|
|
|
439
453
|
return typeof value == "string" && value.length <= 1024 && value.split("/").every(safeFileName);
|
|
440
454
|
}
|
|
441
455
|
function parseFileCreateMetadata(value, maxBytes) {
|
|
442
|
-
let
|
|
456
|
+
let invalid7 = () => {
|
|
443
457
|
throw new FileOperationError("invalid_input", 400);
|
|
444
458
|
};
|
|
445
|
-
if (!value || typeof value != "object" || Array.isArray(value)) return
|
|
459
|
+
if (!value || typeof value != "object" || Array.isArray(value)) return invalid7();
|
|
446
460
|
let input = value;
|
|
447
|
-
if (Object.keys(input).some((key) => !["name", "path", "storage", "csv", "inputMediaType", "size", "requestKey"].includes(key))) return
|
|
461
|
+
if (Object.keys(input).some((key) => !["name", "path", "storage", "csv", "inputMediaType", "size", "requestKey"].includes(key))) return invalid7();
|
|
448
462
|
let path = input.path === void 0 ? "Files" : input.path;
|
|
449
|
-
if (!safeFileName(input.name) || !safeFilePath(path) || path.split("/")[0].toLowerCase() === ".os" || input.storage !== void 0 && input.storage !== "remote" && input.storage !== "local" || input.inputMediaType !== void 0 && input.inputMediaType !== "application/pdf" || !Number.isSafeInteger(input.size) || input.size < 0) return
|
|
463
|
+
if (!safeFileName(input.name) || !safeFilePath(path) || path.split("/")[0].toLowerCase() === ".os" || input.storage !== void 0 && input.storage !== "remote" && input.storage !== "local" || input.inputMediaType !== void 0 && input.inputMediaType !== "application/pdf" || !Number.isSafeInteger(input.size) || input.size < 0) return invalid7();
|
|
450
464
|
if (input.size > maxBytes) throw new FileOperationError("request_too_large", 413);
|
|
451
|
-
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
|
|
465
|
+
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 invalid7();
|
|
452
466
|
let csv;
|
|
453
467
|
if (input.csv !== void 0) {
|
|
454
|
-
if (!input.csv || typeof input.csv != "object" || Array.isArray(input.csv)) return
|
|
468
|
+
if (!input.csv || typeof input.csv != "object" || Array.isArray(input.csv)) return invalid7();
|
|
455
469
|
let hints = input.csv;
|
|
456
|
-
if (Object.keys(hints).some((key) => !["encoding", "delimiter", "headerRow"].includes(key))) return
|
|
470
|
+
if (Object.keys(hints).some((key) => !["encoding", "delimiter", "headerRow"].includes(key))) return invalid7();
|
|
457
471
|
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;
|
|
458
|
-
if (encoding !== "utf-8" && encoding !== "windows-1252" || ![",", ";", " "].includes(delimiter) || !Number.isSafeInteger(headerRow) || headerRow < 1 || headerRow > 1e5) return
|
|
472
|
+
if (encoding !== "utf-8" && encoding !== "windows-1252" || ![",", ";", " "].includes(delimiter) || !Number.isSafeInteger(headerRow) || headerRow < 1 || headerRow > 1e5) return invalid7();
|
|
459
473
|
csv = { encoding, delimiter, headerRow };
|
|
460
474
|
}
|
|
461
475
|
return {
|
|
@@ -517,8 +531,9 @@ function parseAppRoutineContract(value) {
|
|
|
517
531
|
case "array":
|
|
518
532
|
return !fields2(value2, ["type", "items", "maxItems"]) || !Number.isSafeInteger(value2.maxItems) || value2.maxItems < 1 || value2.maxItems > 64 ? invalidContract() : { type: "array", items: schema2(value2.items, depth + 1), maxItems: value2.maxItems };
|
|
519
533
|
case "boolean":
|
|
520
|
-
case "file":
|
|
521
534
|
return fields2(value2, ["type"]) ? { type: value2.type } : invalidContract();
|
|
535
|
+
case "file":
|
|
536
|
+
return !fields2(value2, ["type"], ["storage"]) || owns(value2, "storage") && value2.storage !== "local" && value2.storage !== "remote" ? invalidContract() : { type: "file", ...owns(value2, "storage") ? { storage: value2.storage } : {} };
|
|
522
537
|
case "string":
|
|
523
538
|
return !fields2(value2, ["type"], ["maxLength"]) || owns(value2, "maxLength") && (!Number.isSafeInteger(value2.maxLength) || value2.maxLength < 0 || value2.maxLength > 4096) ? invalidContract() : { type: "string", ...owns(value2, "maxLength") ? { maxLength: value2.maxLength } : {} };
|
|
524
539
|
case "integer":
|
|
@@ -572,10 +587,10 @@ function validateRoutineSchemaValue(schema2, value) {
|
|
|
572
587
|
}
|
|
573
588
|
}
|
|
574
589
|
|
|
575
|
-
var ROUTINE_DECLARATION_SCHEMA = "https://schemas.oddington.ai/routine/v1.json";
|
|
590
|
+
var ROUTINE_DECLARATION_SCHEMA = "https://schemas.oddington.ai/routine/v1.json", ROUTINE_SOURCE_LIMITS = { files: 2e4, bytes: 256 * 1024 * 1024, declarationBytes: 64 * 1024 };
|
|
576
591
|
var invalid = (field) => {
|
|
577
592
|
throw new Error(`Invalid routine declaration: ${field}`);
|
|
578
|
-
}, object2 = (value,
|
|
593
|
+
}, object2 = (value, fields5, field) => ((!value || typeof value != "object" || Array.isArray(value) || Object.keys(value).some((key) => !fields5.includes(key))) && invalid(field), value), routineAlias = (value) => typeof value == "string" && /^[a-z][a-z0-9-]{0,62}$/.test(value), list = (value, field, allowed, qualified = !1) => value === void 0 ? [] : ((!Array.isArray(value) || value.length > 64 || value.some((item) => !(routineAlias(item) || qualified && typeof item == "string" && item.split("/").length === 2 && item.split("/").every(routineAlias)) || allowed && !allowed.includes(item)) || new Set(value).size !== value.length) && invalid(field), [...value].sort());
|
|
579
594
|
function routineAssetPattern(value) {
|
|
580
595
|
return typeof value == "string" && value.length <= 512 && !value.startsWith("/") && !value.includes("\\") && !value.includes(":") && value.split("/").every((part) => !!part && part !== "." && part !== ".." && /^[a-zA-Z0-9_.*-]+$/.test(part));
|
|
581
596
|
}
|
|
@@ -599,7 +614,7 @@ function parseRoutineDeclaration(value) {
|
|
|
599
614
|
$schema: ROUTINE_DECLARATION_SCHEMA,
|
|
600
615
|
access: {
|
|
601
616
|
repositories: grants,
|
|
602
|
-
connections: list(access.connections, "access.connections"),
|
|
617
|
+
connections: list(access.connections, "access.connections", void 0, !0),
|
|
603
618
|
models: list(access.models, "access.models"),
|
|
604
619
|
...access.files === void 0 ? {} : { files: access.files },
|
|
605
620
|
publish: list(access.publish, "access.publish", ["asks", "digests"])
|
|
@@ -614,19 +629,19 @@ function parseRoutineDeclaration(value) {
|
|
|
614
629
|
};
|
|
615
630
|
}
|
|
616
631
|
|
|
617
|
-
var
|
|
632
|
+
var invalid2 = () => {
|
|
618
633
|
throw new AppRoutineContractError("invalid_value");
|
|
619
634
|
}, invalidContract2 = () => {
|
|
620
635
|
throw new AppRoutineContractError("invalid_contract");
|
|
621
|
-
},
|
|
622
|
-
function
|
|
636
|
+
}, routineTitle = (value) => typeof value == "string" && value.trim().length > 0 && value.length <= 256;
|
|
637
|
+
function freezeRoutineMetadata(value) {
|
|
623
638
|
if (value !== null && typeof value == "object") {
|
|
624
|
-
for (let child of Object.values(value))
|
|
639
|
+
for (let child of Object.values(value)) freezeRoutineMetadata(child);
|
|
625
640
|
Object.freeze(value);
|
|
626
641
|
}
|
|
627
642
|
return value;
|
|
628
643
|
}
|
|
629
|
-
function
|
|
644
|
+
function assertRoutineJson(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
630
645
|
if (value === null || typeof value == "string" || typeof value == "boolean" || typeof value == "number" && Number.isFinite(value)) return;
|
|
631
646
|
if (!value || typeof value != "object" || ancestors.has(value)) return invalid2();
|
|
632
647
|
let array3 = Array.isArray(value);
|
|
@@ -639,14 +654,34 @@ function json(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
|
639
654
|
if (typeof key != "string") return invalid2();
|
|
640
655
|
let descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
641
656
|
if (!descriptor.enumerable || !Object.hasOwn(descriptor, "value")) return invalid2();
|
|
642
|
-
|
|
657
|
+
assertRoutineJson(descriptor.value, ancestors);
|
|
643
658
|
}
|
|
644
659
|
ancestors.delete(value);
|
|
645
660
|
}
|
|
661
|
+
function assertRoutineFields(value, allowed) {
|
|
662
|
+
if (!value || typeof value != "object" || Object.getPrototypeOf(value) !== Object.prototype || Reflect.ownKeys(value).some((key) => typeof key != "string" || allowed && !allowed.includes(key) || !Object.getOwnPropertyDescriptor(value, key).enumerable || !Object.hasOwn(Object.getOwnPropertyDescriptor(value, key), "value"))) return invalidContract2();
|
|
663
|
+
}
|
|
664
|
+
function parseRoutineAccess(value) {
|
|
665
|
+
try {
|
|
666
|
+
value !== void 0 && assertRoutineJson(value), assertRoutineFields(value ?? {}, ["repositories", "connections", "models", "files", "publish"]);
|
|
667
|
+
let access = value, names = access?.connections ?? [];
|
|
668
|
+
if (!Array.isArray(names) || names.length > 64 || new Set(names).size !== names.length || names.some((name) => typeof name != "string" || name.split("/").length !== 2 || name.split("/").some((part) => !isAppRoutineName(part)))) return invalidContract2();
|
|
669
|
+
let parsed = parseRoutineDeclaration({ $schema: ROUTINE_DECLARATION_SCHEMA, access: { ...access, connections: [] } }).access;
|
|
670
|
+
return freezeRoutineMetadata({ ...parsed, connections: [...names] });
|
|
671
|
+
} catch {
|
|
672
|
+
return invalidContract2();
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
var LIMIT = 256 * 1024, invalid3 = () => {
|
|
677
|
+
throw new AppRoutineContractError("invalid_value");
|
|
678
|
+
}, invalidContract3 = () => {
|
|
679
|
+
throw new AppRoutineContractError("invalid_contract");
|
|
680
|
+
}, empty = { type: "object", properties: {}, required: [], additionalProperties: !1 };
|
|
646
681
|
function captureJson(value) {
|
|
647
|
-
|
|
682
|
+
assertRoutineJson(value);
|
|
648
683
|
let encoded = JSON.stringify(value);
|
|
649
|
-
return new TextEncoder().encode(encoded).byteLength > LIMIT ?
|
|
684
|
+
return new TextEncoder().encode(encoded).byteLength > LIMIT ? invalid3() : freezeRoutineMetadata(JSON.parse(encoded));
|
|
650
685
|
}
|
|
651
686
|
function capture(schema2, value) {
|
|
652
687
|
let captured = captureJson(value);
|
|
@@ -655,26 +690,26 @@ function capture(schema2, value) {
|
|
|
655
690
|
var schemas = /* @__PURE__ */ new WeakMap();
|
|
656
691
|
function nestedSchema(value) {
|
|
657
692
|
let metadata = schemaMetadata(value);
|
|
658
|
-
return Object.hasOwn(metadata, "default") ?
|
|
693
|
+
return Object.hasOwn(metadata, "default") ? invalidContract3() : metadata.schema;
|
|
659
694
|
}
|
|
660
695
|
function schemaMetadata(value) {
|
|
661
|
-
if (!value || typeof value != "object") return
|
|
696
|
+
if (!value || typeof value != "object") return invalidContract3();
|
|
662
697
|
let registered = schemas.get(value);
|
|
663
698
|
if (registered) return registered;
|
|
664
699
|
try {
|
|
665
|
-
|
|
700
|
+
assertRoutineJson(value);
|
|
666
701
|
} catch {
|
|
667
|
-
return
|
|
702
|
+
return invalidContract3();
|
|
668
703
|
}
|
|
669
704
|
return { schema: parseAppRoutineContract({ routine: "definition", input: value, steps: [{ id: "inspect" }] }).input };
|
|
670
705
|
}
|
|
671
706
|
function declaration(value, defaults) {
|
|
672
707
|
try {
|
|
673
|
-
|
|
708
|
+
assertRoutineJson(value);
|
|
674
709
|
} catch {
|
|
675
|
-
return
|
|
710
|
+
return invalidContract3();
|
|
676
711
|
}
|
|
677
|
-
let parsed =
|
|
712
|
+
let parsed = freezeRoutineMetadata(parseAppRoutineContract({ routine: "definition", input: value, steps: [{ id: "inspect" }] }).input), captured = defaults ? capture(parsed, defaults.value) : void 0, builder = Object.defineProperty({ ...parsed }, "default", { value: (value2) => declaration(parsed, { value: value2 }) });
|
|
678
713
|
return schemas.set(builder, { schema: parsed, ...defaults ? { default: captured } : {} }), Object.freeze(builder);
|
|
679
714
|
}
|
|
680
715
|
var schema = {
|
|
@@ -696,27 +731,11 @@ var schema = {
|
|
|
696
731
|
boolean() {
|
|
697
732
|
return declaration({ type: "boolean" });
|
|
698
733
|
}
|
|
699
|
-
}, file = () => declaration({ type: "file" }), definitions = /* @__PURE__ */ new WeakMap()
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
function accessMetadata(value) {
|
|
705
|
-
try {
|
|
706
|
-
value !== void 0 && json(value), fields3(value ?? {}, ["repositories", "connections", "models", "files", "publish"]);
|
|
707
|
-
let access = value, names = access?.connections ?? [];
|
|
708
|
-
if (!Array.isArray(names) || names.length > 64 || new Set(names).size !== names.length || names.some((name) => typeof name != "string" || name.split("/").length !== 2 || name.split("/").some((part) => !isAppRoutineName(part)))) return invalidContract2();
|
|
709
|
-
let parsed = parseRoutineDeclaration({ $schema: ROUTINE_DECLARATION_SCHEMA, access: { ...access, connections: [] } }).access;
|
|
710
|
-
return freeze({ ...parsed, connections: [...names] });
|
|
711
|
-
} catch {
|
|
712
|
-
return invalidContract2();
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
var defineRoutine = (definition) => {
|
|
716
|
-
if (fields3(definition, ["id", "title", "input", "steps", "result", "access", "responses", "run"]), !isAppRoutineName(definition.id) || definition.title !== void 0 && !title(definition.title) || typeof definition.run != "function") return invalidContract2();
|
|
717
|
-
let input = definition.input === void 0 ? { schema: empty, default: {} } : schemaMetadata(definition.input), result2 = definition.result === void 0 ? void 0 : schemaMetadata(definition.result).schema, access = accessMetadata(definition.access);
|
|
718
|
-
fields3(definition.steps ?? {});
|
|
719
|
-
let executable = Object.fromEntries(Object.entries(definition.steps ?? {}).map(([id3, step]) => (fields3(step, ["title", "run"]), !title(step.title) || typeof step.run != "function" ? invalidContract2() : [id3, Object.freeze({ title: step.title, run: step.run })]))), steps = Object.entries(executable).map(([id3, step]) => ({ id: id3, title: step.title }));
|
|
734
|
+
}, file = (options = {}) => (assertRoutineFields(options, ["storage"]), declaration({ type: "file", ...options })), definitions = /* @__PURE__ */ new WeakMap(), defineRoutine = (definition) => {
|
|
735
|
+
if (assertRoutineFields(definition, ["id", "title", "input", "steps", "result", "access", "responses", "run"]), !isAppRoutineName(definition.id) || definition.title !== void 0 && !routineTitle(definition.title) || typeof definition.run != "function") return invalidContract3();
|
|
736
|
+
let input = definition.input === void 0 ? { schema: empty, default: {} } : schemaMetadata(definition.input), result2 = definition.result === void 0 ? void 0 : schemaMetadata(definition.result).schema, access = parseRoutineAccess(definition.access);
|
|
737
|
+
assertRoutineFields(definition.steps ?? {});
|
|
738
|
+
let executable = Object.fromEntries(Object.entries(definition.steps ?? {}).map(([id3, step]) => (assertRoutineFields(step, ["title", "run"]), !routineTitle(step.title) || typeof step.run != "function" ? invalidContract3() : [id3, Object.freeze({ title: step.title, run: step.run })]))), steps = Object.entries(executable).map(([id3, step]) => ({ id: id3, title: step.title }));
|
|
720
739
|
parseAppRoutineContract({
|
|
721
740
|
routine: definition.id,
|
|
722
741
|
input: input.schema,
|
|
@@ -725,26 +744,26 @@ var defineRoutine = (definition) => {
|
|
|
725
744
|
});
|
|
726
745
|
let responses = [], ids = /* @__PURE__ */ new Set();
|
|
727
746
|
if (definition.responses !== void 0) {
|
|
728
|
-
if (!Array.isArray(definition.responses) || definition.responses.length > 64 || Reflect.ownKeys(definition.responses).length !== definition.responses.length + 1) return
|
|
747
|
+
if (!Array.isArray(definition.responses) || definition.responses.length > 64 || Reflect.ownKeys(definition.responses).length !== definition.responses.length + 1) return invalidContract3();
|
|
729
748
|
for (let index = 0; index < definition.responses.length; index++) {
|
|
730
749
|
let descriptor = Object.getOwnPropertyDescriptor(definition.responses, String(index));
|
|
731
|
-
if (!descriptor || !Object.hasOwn(descriptor, "value")) return
|
|
750
|
+
if (!descriptor || !Object.hasOwn(descriptor, "value")) return invalidContract3();
|
|
732
751
|
let response2 = descriptor.value;
|
|
733
|
-
if (
|
|
752
|
+
if (assertRoutineFields(response2, ["id", "results", "run"]), !isAppRoutineName(response2.id) || ids.has(response2.id)) return invalidContract3();
|
|
734
753
|
if (ids.add(response2.id), response2.results !== void 0)
|
|
735
754
|
try {
|
|
736
|
-
|
|
755
|
+
assertRoutineJson(response2.results);
|
|
737
756
|
} catch {
|
|
738
|
-
return
|
|
757
|
+
return invalidContract3();
|
|
739
758
|
}
|
|
740
759
|
try {
|
|
741
760
|
responses.push(defineHandler(response2));
|
|
742
761
|
} catch {
|
|
743
|
-
return
|
|
762
|
+
return invalidContract3();
|
|
744
763
|
}
|
|
745
764
|
}
|
|
746
765
|
}
|
|
747
|
-
let contract =
|
|
766
|
+
let contract = freezeRoutineMetadata({
|
|
748
767
|
id: definition.id,
|
|
749
768
|
...definition.title === void 0 ? {} : { title: definition.title },
|
|
750
769
|
input: input.schema,
|
|
@@ -769,9 +788,9 @@ var defineRoutine = (definition) => {
|
|
|
769
788
|
return definitions.set(captured, { contract, steps: executable, run: definition.run }), captured;
|
|
770
789
|
};
|
|
771
790
|
function inspectRoutineDefinition(definition) {
|
|
772
|
-
if (!definition || typeof definition != "object") return
|
|
791
|
+
if (!definition || typeof definition != "object") return invalidContract3();
|
|
773
792
|
let registered = definitions.get(definition);
|
|
774
|
-
return registered ? registered.contract :
|
|
793
|
+
return registered ? registered.contract : invalidContract3();
|
|
775
794
|
}
|
|
776
795
|
function captureRoutineInput(definition, input) {
|
|
777
796
|
let contract = inspectRoutineDefinition(definition);
|
|
@@ -787,29 +806,35 @@ async function executeRoutineDefinition(definition, input, runtime) {
|
|
|
787
806
|
get(_target, key) {
|
|
788
807
|
return guarded(Reflect.get(value, key, value), value);
|
|
789
808
|
}
|
|
790
|
-
}) : value, qualify = (value) => value.questions === void 0 ? value : { ...value, questions: value.questions.map((question2) => question2.handler ? contract.responses.some((handler) => handler.id === question2.handler.id) ? { ...question2, handler: { ...question2.handler, id: `${contract.id}/${question2.handler.id}` } } :
|
|
809
|
+
}) : value, qualify = (value) => value.questions === void 0 ? value : { ...value, questions: value.questions.map((question2) => question2.handler ? contract.responses.some((handler) => handler.id === question2.handler.id) ? { ...question2, handler: { ...question2.handler, id: `${contract.id}/${question2.handler.id}` } } : invalid3() : question2) }, os2 = Object.freeze({
|
|
791
810
|
...guarded({
|
|
792
811
|
...runtime,
|
|
793
|
-
run:
|
|
812
|
+
run: freezeRoutineMetadata({ ...runtime.run }),
|
|
813
|
+
connections: { ...runtime.connections, get: async (identity) => {
|
|
814
|
+
if (!active2 || broken || !contract.access.connections?.includes(identity)) throw new Error("Connection unavailable");
|
|
815
|
+
let value = await runtime.connections.get(identity);
|
|
816
|
+
if (!active2 || broken) throw new Error("Run authority ended");
|
|
817
|
+
return value;
|
|
818
|
+
} },
|
|
794
819
|
inbox: { ...runtime.inbox, publishAsk: (value, options) => runtime.inbox.publishAsk(qualify(value), options) }
|
|
795
820
|
}),
|
|
796
821
|
step(id3, ...input2) {
|
|
797
822
|
let saved;
|
|
798
823
|
try {
|
|
799
|
-
if (!active2 || !accepting || broken || !Object.hasOwn(steps, id3) || called.has(id3) || input2.length > 1) return
|
|
824
|
+
if (!active2 || !accepting || broken || !Object.hasOwn(steps, id3) || called.has(id3) || input2.length > 1) return invalid3();
|
|
800
825
|
input2.length && (saved = captureJson(input2[0])), called.add(id3);
|
|
801
826
|
} catch (error) {
|
|
802
827
|
return broken = !0, Promise.reject(error);
|
|
803
828
|
}
|
|
804
829
|
let next = work.then(async () => {
|
|
805
|
-
if (broken) return
|
|
830
|
+
if (broken) return invalid3();
|
|
806
831
|
reached.add(id3);
|
|
807
832
|
try {
|
|
808
833
|
await runtime.step(id3, { status: "running" });
|
|
809
834
|
let output = await steps[id3].run(saved, os2);
|
|
810
|
-
if (
|
|
835
|
+
if (assertRoutineFields(output, ["summary", "data"]), !Object.hasOwn(output, "summary") || !Object.hasOwn(output, "data")) return invalid3();
|
|
811
836
|
let summary2 = captureJson(output.summary), data3 = captureJson(output.data);
|
|
812
|
-
return await runtime.step(id3, { status: "completed", summary: summary2, data: data3 }),
|
|
837
|
+
return await runtime.step(id3, { status: "completed", summary: summary2, data: data3 }), freezeRoutineMetadata({ summary: summary2, data: data3 });
|
|
813
838
|
} catch (error) {
|
|
814
839
|
throw broken = !0, await runtime.step(id3, { status: "failed" }), error;
|
|
815
840
|
}
|
|
@@ -829,7 +854,7 @@ async function executeRoutineDefinition(definition, input, runtime) {
|
|
|
829
854
|
for (let step of contract.steps) reached.has(step.id) || await runtime.step(step.id, { status: "skipped" });
|
|
830
855
|
if (broken) throw failure ?? new AppRoutineContractError("invalid_value");
|
|
831
856
|
if (contract.result !== void 0) return capture(contract.result, result2);
|
|
832
|
-
if (result2 !== void 0) return
|
|
857
|
+
if (result2 !== void 0) return invalid3();
|
|
833
858
|
}
|
|
834
859
|
|
|
835
860
|
var DataOperationError = class extends Error {
|
|
@@ -847,26 +872,26 @@ var DataOperationError = class extends Error {
|
|
|
847
872
|
component;
|
|
848
873
|
};
|
|
849
874
|
|
|
850
|
-
var
|
|
875
|
+
var invalid4 = () => {
|
|
851
876
|
throw new DataOperationError("invalid_query");
|
|
852
877
|
}, historyText = (value) => typeof value == "string" && !/[\u0000\uD800-\uDFFF]/u.test(value);
|
|
853
878
|
function historyVersion(value) {
|
|
854
879
|
return historyText(value) && value.length > 0 && new TextEncoder().encode(value).length <= 1024 && !/[\u0000-\u001f\u007f-\u009f]/.test(value) && !/^[0-9a-f]{40}$/i.test(value);
|
|
855
880
|
}
|
|
856
881
|
function historyProperties(value) {
|
|
857
|
-
if (!value || typeof value != "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return
|
|
882
|
+
if (!value || typeof value != "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return invalid4();
|
|
858
883
|
let descriptors = Object.getOwnPropertyDescriptors(value);
|
|
859
|
-
return Reflect.ownKeys(value).some((key) => typeof key != "string" || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value")) ?
|
|
884
|
+
return Reflect.ownKeys(value).some((key) => typeof key != "string" || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value")) ? invalid4() : descriptors;
|
|
860
885
|
}
|
|
861
886
|
var historyCollection = (value) => typeof value == "string" && value.length <= 512 && /^[_a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value), historyCursor = (value) => typeof value == "string" && value.length <= 128 * 1024 && /^history-cursor-v1\.[A-Za-z0-9_-]{1,64}\.[A-Za-z0-9_-]{16}\.[A-Za-z0-9_-]+$/.test(value);
|
|
862
887
|
function historyArray(value) {
|
|
863
|
-
if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) return
|
|
888
|
+
if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) return invalid4();
|
|
864
889
|
let descriptors = Object.getOwnPropertyDescriptors(value);
|
|
865
|
-
if (Reflect.ownKeys(value).length !== value.length + 1) return
|
|
890
|
+
if (Reflect.ownKeys(value).length !== value.length + 1) return invalid4();
|
|
866
891
|
let result2 = [];
|
|
867
892
|
for (let i = 0; i < value.length; i++) {
|
|
868
893
|
let descriptor = descriptors[i];
|
|
869
|
-
if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value")) return
|
|
894
|
+
if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value")) return invalid4();
|
|
870
895
|
result2.push(descriptor.value);
|
|
871
896
|
}
|
|
872
897
|
return result2;
|
|
@@ -874,19 +899,19 @@ function historyArray(value) {
|
|
|
874
899
|
function captureOptions(value, changes) {
|
|
875
900
|
if (value === void 0) return {};
|
|
876
901
|
let descriptors = historyProperties(value), result2 = {}, allowed = changes ? ["collections", "refs", "from", "through", "limit", "after"] : ["limit", "before"];
|
|
877
|
-
if (Object.keys(descriptors).some((key) => !allowed.includes(key))) return
|
|
902
|
+
if (Object.keys(descriptors).some((key) => !allowed.includes(key))) return invalid4();
|
|
878
903
|
for (let key of allowed) {
|
|
879
904
|
if (!Object.hasOwn(descriptors, key)) continue;
|
|
880
905
|
let scalar = descriptors[key].value;
|
|
881
906
|
if (key === "collections" || key === "refs") {
|
|
882
907
|
let values = historyArray(scalar);
|
|
883
|
-
if (!values.length || values.length > (key === "collections" ? 16 : 100) || !values.every(key === "collections" ? historyCollection : validRecordRef) || new Set(values).size !== values.length) return
|
|
908
|
+
if (!values.length || values.length > (key === "collections" ? 16 : 100) || !values.every(key === "collections" ? historyCollection : validRecordRef) || new Set(values).size !== values.length) return invalid4();
|
|
884
909
|
result2[key] = values;
|
|
885
910
|
} else if (key === "limit") {
|
|
886
|
-
if (!Number.isInteger(scalar) || scalar < 1 || scalar > (changes ? 500 : 100)) return
|
|
911
|
+
if (!Number.isInteger(scalar) || scalar < 1 || scalar > (changes ? 500 : 100)) return invalid4();
|
|
887
912
|
result2.limit = scalar;
|
|
888
913
|
} else {
|
|
889
|
-
if (!(key === "after" ? historyCursor(scalar) : historyVersion(scalar))) return
|
|
914
|
+
if (!(key === "after" ? historyCursor(scalar) : historyVersion(scalar))) return invalid4();
|
|
890
915
|
result2[key] = scalar;
|
|
891
916
|
}
|
|
892
917
|
}
|
|
@@ -894,39 +919,39 @@ function captureOptions(value, changes) {
|
|
|
894
919
|
}
|
|
895
920
|
var captureHistoryListOptions = (value) => captureOptions(value, !1), captureHistoryChangesOptions = (value) => captureOptions(value, !0);
|
|
896
921
|
function captureHistoryInstant(value) {
|
|
897
|
-
if (!historyText(value) || value.length > 1024) return
|
|
922
|
+
if (!historyText(value) || value.length > 1024) return invalid4();
|
|
898
923
|
let match = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.\d+)?([Zz]|([+-])(\d{2}):(\d{2}))$/.exec(value);
|
|
899
|
-
if (!match) return
|
|
924
|
+
if (!match) return invalid4();
|
|
900
925
|
let [year, month, day, hour, minute, second] = match.slice(1, 7).map(Number), days = new Date(Date.UTC(year, month, 0));
|
|
901
|
-
return days.setUTCFullYear(year), year < 1 || month < 1 || month > 12 || day < 1 || day > days.getUTCDate() || hour > 23 || minute > 59 || second > 59 || Number(match[9] ?? 0) > 23 || Number(match[10] ?? 0) > 59 ?
|
|
926
|
+
return days.setUTCFullYear(year), year < 1 || month < 1 || month > 12 || day < 1 || day > days.getUTCDate() || hour > 23 || minute > 59 || second > 59 || Number(match[9] ?? 0) > 23 || Number(match[10] ?? 0) > 59 ? invalid4() : value;
|
|
902
927
|
}
|
|
903
928
|
|
|
904
|
-
var
|
|
929
|
+
var invalid5 = () => {
|
|
905
930
|
throw new DataOperationError("invalid_query");
|
|
906
931
|
};
|
|
907
932
|
function captureRecordsSearchInput(query, options) {
|
|
908
|
-
if (!historyText(query)) return
|
|
933
|
+
if (!historyText(query)) return invalid5();
|
|
909
934
|
let length = [...query.trim()].length;
|
|
910
|
-
if (length < 1 || length > 256) return
|
|
935
|
+
if (length < 1 || length > 256) return invalid5();
|
|
911
936
|
if (options === void 0) return { query };
|
|
912
937
|
let descriptors = historyProperties(options);
|
|
913
|
-
if (Object.keys(descriptors).some((key) => !["collections", "limit"].includes(key))) return
|
|
938
|
+
if (Object.keys(descriptors).some((key) => !["collections", "limit"].includes(key))) return invalid5();
|
|
914
939
|
let captured = {};
|
|
915
940
|
if (Object.hasOwn(descriptors, "collections")) {
|
|
916
941
|
let supplied = descriptors.collections.value;
|
|
917
|
-
if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1) return
|
|
942
|
+
if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1) return invalid5();
|
|
918
943
|
let collections = [];
|
|
919
944
|
for (let index = 0; index < supplied.length; index++) {
|
|
920
945
|
let descriptor = Object.getOwnPropertyDescriptor(supplied, String(index));
|
|
921
|
-
if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value") || !historyText(descriptor.value)) return
|
|
946
|
+
if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value") || !historyText(descriptor.value)) return invalid5();
|
|
922
947
|
collections.push(descriptor.value);
|
|
923
948
|
}
|
|
924
|
-
if (new Set(collections).size !== collections.length) return
|
|
949
|
+
if (new Set(collections).size !== collections.length) return invalid5();
|
|
925
950
|
captured.collections = collections;
|
|
926
951
|
}
|
|
927
952
|
if (Object.hasOwn(descriptors, "limit")) {
|
|
928
953
|
let supplied = descriptors.limit.value;
|
|
929
|
-
if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100) return
|
|
954
|
+
if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100) return invalid5();
|
|
930
955
|
captured.limit = supplied;
|
|
931
956
|
}
|
|
932
957
|
return { query, options: captured };
|
|
@@ -957,8 +982,8 @@ function captureDataDelete(record3) {
|
|
|
957
982
|
return !validRecordRef(identity.$ref) || typeof identity.$version != "string" || !identity.$version.length || identity.$version.length > 512 ? invalidChange() : { ref: identity.$ref, expectedVersion: identity.$version };
|
|
958
983
|
}
|
|
959
984
|
function captureDataUpdate(record3, set) {
|
|
960
|
-
let identity = captureDataDelete(record3),
|
|
961
|
-
return !Object.keys(
|
|
985
|
+
let identity = captureDataDelete(record3), fields5 = mapping(set);
|
|
986
|
+
return !Object.keys(fields5).length || Object.keys(fields5).some((key) => key.startsWith("$") || ["id", "type"].includes(key)) ? invalidChange() : { ...identity, set: captureValue(fields5) };
|
|
962
987
|
}
|
|
963
988
|
function captureIdentities(value, update, allowEmpty = !0) {
|
|
964
989
|
if (!Array.isArray(value) || !allowEmpty && !value.length || value.length > 1e4) return invalidChange();
|
|
@@ -977,14 +1002,14 @@ function captureDataCreate(value) {
|
|
|
977
1002
|
let row = mapping(value);
|
|
978
1003
|
if (!validRecordRef(row.$ref) || Object.keys(row).some((key) => key.startsWith("$") && !["$ref", "$filing"].includes(key)))
|
|
979
1004
|
return invalidChange();
|
|
980
|
-
let { $ref: ref, $filing, ...
|
|
1005
|
+
let { $ref: ref, $filing, ...fields5 } = row, filing;
|
|
981
1006
|
if ($filing !== void 0) {
|
|
982
1007
|
let components = mapping($filing);
|
|
983
1008
|
if (Object.entries(components).some(([name, value2]) => !/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name) || ["constructor", "prototype"].includes(name) || typeof value2 != "string" || !/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value2)))
|
|
984
1009
|
return invalidChange();
|
|
985
1010
|
filing = { ...components };
|
|
986
1011
|
}
|
|
987
|
-
return { ref, fields: captureValue(
|
|
1012
|
+
return { ref, fields: captureValue(fields5), ...filing ? { filing } : {} };
|
|
988
1013
|
}
|
|
989
1014
|
function captureDataChanges(updatesValue, createsValue = [], deletesValue = []) {
|
|
990
1015
|
let updates = captureDataUpdates(updatesValue, !0);
|
|
@@ -992,8 +1017,8 @@ function captureDataChanges(updatesValue, createsValue = [], deletesValue = [])
|
|
|
992
1017
|
let creates = createsValue.map((item) => {
|
|
993
1018
|
let row = mapping(item);
|
|
994
1019
|
if (Object.keys(row).some((key) => !["ref", "fields", "filing"].includes(key)) || !Object.hasOwn(row, "ref") || !Object.hasOwn(row, "fields")) return invalidChange();
|
|
995
|
-
let
|
|
996
|
-
return Object.keys(
|
|
1020
|
+
let fields5 = mapping(row.fields);
|
|
1021
|
+
return Object.keys(fields5).some((key) => key.startsWith("$")) ? invalidChange() : captureDataCreate({ ...fields5, $ref: row.ref, ...Object.hasOwn(row, "filing") ? { $filing: row.filing } : {} });
|
|
997
1022
|
}), deletes = captureIdentities(deletesValue, !1), refs = [...updates, ...creates, ...deletes].map((item) => item.ref);
|
|
998
1023
|
return !refs.length || refs.length > 1e4 || new Set(refs).size !== refs.length ? invalidChange() : { updates, creates, deletes };
|
|
999
1024
|
}
|
|
@@ -1025,16 +1050,16 @@ function routineTransport() {
|
|
|
1025
1050
|
return installed;
|
|
1026
1051
|
}
|
|
1027
1052
|
|
|
1028
|
-
var memberContext;
|
|
1029
|
-
function installMemberContext(resolve) {
|
|
1030
|
-
return memberContext = resolve, () => {
|
|
1031
|
-
memberContext === resolve && (memberContext = void 0);
|
|
1053
|
+
var memberContext, retainedContext;
|
|
1054
|
+
function installMemberContext(resolve, retained = resolve) {
|
|
1055
|
+
return memberContext = resolve, retainedContext = retained, () => {
|
|
1056
|
+
memberContext === resolve && (memberContext = void 0, retainedContext = void 0);
|
|
1032
1057
|
};
|
|
1033
1058
|
}
|
|
1034
|
-
async function resolveAppContext() {
|
|
1059
|
+
async function resolveAppContext(retained = !1) {
|
|
1035
1060
|
let host = memberContext;
|
|
1036
1061
|
if (!host) throw new Error("App context unavailable.");
|
|
1037
|
-
let context2 = await host();
|
|
1062
|
+
let context2 = await (retained ? retainedContext : host)();
|
|
1038
1063
|
if (host !== memberContext || !context2.isCurrent() || context2.expiresAt <= Date.now() || context2.kind !== "local" && (typeof context2.accessToken != "string" || !/^[^\s]{1,8192}$/.test(context2.accessToken)))
|
|
1039
1064
|
throw new Error("App context unavailable.");
|
|
1040
1065
|
return context2;
|
|
@@ -1059,13 +1084,22 @@ async function resolveFilesContext() {
|
|
|
1059
1084
|
let environment = {}, host = memberContext;
|
|
1060
1085
|
if (host) {
|
|
1061
1086
|
let context2 = await host();
|
|
1062
|
-
if (context2.
|
|
1087
|
+
if (host !== memberContext || !context2.isCurrent() || context2.expiresAt <= Date.now()) throw new Error();
|
|
1088
|
+
if (context2.kind === "local") return {
|
|
1089
|
+
url: `private:app:${context2.workspace}/${context2.memberId}`,
|
|
1090
|
+
headers: {},
|
|
1091
|
+
isCurrent: context2.isCurrent,
|
|
1092
|
+
signal: context2.signal,
|
|
1093
|
+
local: void 0,
|
|
1094
|
+
localFiles: context2.requestFiles
|
|
1095
|
+
};
|
|
1063
1096
|
if (!Number.isFinite(context2.expiresAt) || context2.expiresAt <= Date.now() || typeof context2.accessToken != "string" || !/^[^\s]{1,8192}$/.test(context2.accessToken)) throw new Error();
|
|
1064
1097
|
return {
|
|
1065
1098
|
...filesContext(context2.workspace, context2.endpoint, { authorization: `Bearer ${context2.accessToken}` }),
|
|
1066
1099
|
isCurrent: context2.isCurrent,
|
|
1067
1100
|
local: void 0,
|
|
1068
|
-
localFiles: void 0
|
|
1101
|
+
localFiles: void 0,
|
|
1102
|
+
signal: void 0
|
|
1069
1103
|
};
|
|
1070
1104
|
}
|
|
1071
1105
|
throw new Error();
|
|
@@ -1178,7 +1212,65 @@ var data = {
|
|
|
1178
1212
|
}
|
|
1179
1213
|
};
|
|
1180
1214
|
|
|
1181
|
-
|
|
1215
|
+
async function hostedContent(url, init2, parent, upstream = fetch, check = async () => {
|
|
1216
|
+
}, failure) {
|
|
1217
|
+
let delivery = new AbortController(), abort = () => delivery.abort(parent.reason);
|
|
1218
|
+
parent.addEventListener("abort", abort, { once: !0 }), parent.aborted && abort();
|
|
1219
|
+
let detach = () => parent.removeEventListener("abort", abort);
|
|
1220
|
+
try {
|
|
1221
|
+
let response2 = await upstream(url, { ...init2, signal: delivery.signal });
|
|
1222
|
+
try {
|
|
1223
|
+
if (await check(), delivery.signal.aborted) throw failure?.() ?? new FileOperationError("unavailable", 503, !0);
|
|
1224
|
+
} catch (error) {
|
|
1225
|
+
throw response2.body?.cancel().catch(() => {
|
|
1226
|
+
}), error;
|
|
1227
|
+
}
|
|
1228
|
+
if (!response2.body)
|
|
1229
|
+
return detach(), response2;
|
|
1230
|
+
let source = response2.body, reader, settled = !1, output, cancel = async (reason) => {
|
|
1231
|
+
if (!settled) {
|
|
1232
|
+
settled = !0, detach(), delivery.signal.removeEventListener("abort", stop), delivery.abort(reason);
|
|
1233
|
+
try {
|
|
1234
|
+
await (reader ? reader.cancel(reason) : source.cancel(reason));
|
|
1235
|
+
} catch (error) {
|
|
1236
|
+
if (error !== delivery.signal.reason && !(error instanceof Error && error.name === "AbortError")) throw error;
|
|
1237
|
+
} finally {
|
|
1238
|
+
reader?.releaseLock();
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
}, stop = () => {
|
|
1242
|
+
if (settled) return;
|
|
1243
|
+
let error = failure?.() ?? delivery.signal.reason;
|
|
1244
|
+
cancel(error).catch(() => {
|
|
1245
|
+
}), output.error(error);
|
|
1246
|
+
}, body = new ReadableStream({
|
|
1247
|
+
start(controller) {
|
|
1248
|
+
output = controller, delivery.signal.addEventListener("abort", stop, { once: !0 }), delivery.signal.aborted && stop();
|
|
1249
|
+
},
|
|
1250
|
+
async pull(controller) {
|
|
1251
|
+
try {
|
|
1252
|
+
if (await check(), settled) return;
|
|
1253
|
+
reader ??= source.getReader();
|
|
1254
|
+
let { done, value } = await reader.read();
|
|
1255
|
+
if (await check(), settled) return;
|
|
1256
|
+
done ? (settled = !0, detach(), delivery.signal.removeEventListener("abort", stop), reader.releaseLock(), controller.close()) : controller.enqueue(value);
|
|
1257
|
+
} catch (error) {
|
|
1258
|
+
if (settled) return;
|
|
1259
|
+
controller.error(failure?.() ?? error), await cancel(error).catch(() => {
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
},
|
|
1263
|
+
cancel
|
|
1264
|
+
}, { highWaterMark: 0 }), wrapped = new Response(body, { status: response2.status, statusText: response2.statusText, headers: response2.headers });
|
|
1265
|
+
for (let key of ["url", "redirected", "type"])
|
|
1266
|
+
Object.defineProperty(wrapped, key, { value: response2[key] });
|
|
1267
|
+
return wrapped;
|
|
1268
|
+
} catch (error) {
|
|
1269
|
+
throw detach(), delivery.abort(error), error;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
var MAX_BYTES = 16 * 1024 * 1024, PART_BYTES = 8 * 1024 * 1024, METADATA_BYTES = 4096, RESULT_BYTES = 16 * 1024, CONTROL_RESULT_BYTES = 128 * 1024, TIMEOUT_MS = 3e4, MAX_ACTIVE = 4, ATTEMPTS = 2, active = 0, invalid6 = () => new FileOperationError("invalid_input", 400), unavailable = () => new FileOperationError("unavailable", 503, !0), failures = {
|
|
1182
1274
|
400: ["invalid_input", "unsupported_context"],
|
|
1183
1275
|
401: ["unauthenticated"],
|
|
1184
1276
|
403: ["access_denied"],
|
|
@@ -1188,19 +1280,26 @@ var MAX_BYTES = 16 * 1024 * 1024, PART_BYTES = 8 * 1024 * 1024, METADATA_BYTES =
|
|
|
1188
1280
|
429: ["capacity"],
|
|
1189
1281
|
503: ["integrity", "unavailable"]
|
|
1190
1282
|
};
|
|
1191
|
-
async function boundedBytes(stream, limit) {
|
|
1283
|
+
async function boundedBytes(stream, limit, signal) {
|
|
1192
1284
|
if (!stream) return new Uint8Array();
|
|
1193
|
-
let reader = stream.getReader(), bytes = new Uint8Array(limit), size = 0
|
|
1285
|
+
let reader = stream.getReader(), bytes = new Uint8Array(limit), size = 0, cancel = () => {
|
|
1286
|
+
reader.cancel().catch(() => {
|
|
1287
|
+
});
|
|
1288
|
+
};
|
|
1289
|
+
signal?.addEventListener("abort", cancel, { once: !0 }), signal?.aborted && cancel();
|
|
1194
1290
|
try {
|
|
1195
1291
|
for (; ; ) {
|
|
1196
1292
|
let { done, value } = await reader.read();
|
|
1293
|
+
if (signal?.aborted) throw unavailable();
|
|
1197
1294
|
if (done) break;
|
|
1198
|
-
if (!(value instanceof Uint8Array)) throw
|
|
1295
|
+
if (!(value instanceof Uint8Array)) throw invalid6();
|
|
1199
1296
|
if (size += value.byteLength, size > limit) throw new FileOperationError("request_too_large", 413);
|
|
1200
1297
|
bytes.set(value, size - value.byteLength);
|
|
1201
1298
|
}
|
|
1299
|
+
} catch (error) {
|
|
1300
|
+
throw cancel(), error;
|
|
1202
1301
|
} finally {
|
|
1203
|
-
reader.releaseLock();
|
|
1302
|
+
signal?.removeEventListener("abort", cancel), reader.releaseLock();
|
|
1204
1303
|
}
|
|
1205
1304
|
return bytes.slice(0, size);
|
|
1206
1305
|
}
|
|
@@ -1224,50 +1323,6 @@ async function result(response2, maximum = RESULT_BYTES) {
|
|
|
1224
1323
|
throw unavailable();
|
|
1225
1324
|
}
|
|
1226
1325
|
}
|
|
1227
|
-
async function hostedContent(url, init2, parent, upstream = fetch) {
|
|
1228
|
-
let delivery = new AbortController(), abort = () => delivery.abort(parent.reason);
|
|
1229
|
-
parent.addEventListener("abort", abort, { once: !0 }), parent.aborted && abort();
|
|
1230
|
-
let detach = () => parent.removeEventListener("abort", abort);
|
|
1231
|
-
try {
|
|
1232
|
-
let response2 = await upstream(url, { ...init2, signal: delivery.signal });
|
|
1233
|
-
if (delivery.signal.aborted)
|
|
1234
|
-
throw response2.body?.cancel().catch(() => {
|
|
1235
|
-
}), unavailable();
|
|
1236
|
-
if (!response2.body)
|
|
1237
|
-
return detach(), response2;
|
|
1238
|
-
let source = response2.body, reader, settled = !1, cancel = async (reason) => {
|
|
1239
|
-
if (!settled) {
|
|
1240
|
-
settled = !0, detach(), delivery.abort(reason);
|
|
1241
|
-
try {
|
|
1242
|
-
await (reader ? reader.cancel(reason) : source.cancel(reason));
|
|
1243
|
-
} catch (error) {
|
|
1244
|
-
if (error !== delivery.signal.reason && !(error instanceof Error && error.name === "AbortError")) throw error;
|
|
1245
|
-
} finally {
|
|
1246
|
-
reader?.releaseLock();
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
}, body = new ReadableStream({
|
|
1250
|
-
async pull(controller) {
|
|
1251
|
-
try {
|
|
1252
|
-
reader ??= source.getReader();
|
|
1253
|
-
let { done, value } = await reader.read();
|
|
1254
|
-
if (settled) return;
|
|
1255
|
-
done ? (settled = !0, detach(), reader.releaseLock(), controller.close()) : controller.enqueue(value);
|
|
1256
|
-
} catch (error) {
|
|
1257
|
-
if (settled) return;
|
|
1258
|
-
controller.error(error), await cancel(error).catch(() => {
|
|
1259
|
-
});
|
|
1260
|
-
}
|
|
1261
|
-
},
|
|
1262
|
-
cancel
|
|
1263
|
-
}, { highWaterMark: 0 }), wrapped = new Response(body, { status: response2.status, statusText: response2.statusText, headers: response2.headers });
|
|
1264
|
-
for (let key of ["url", "redirected", "type"])
|
|
1265
|
-
Object.defineProperty(wrapped, key, { value: response2[key] });
|
|
1266
|
-
return wrapped;
|
|
1267
|
-
} catch (error) {
|
|
1268
|
-
throw detach(), delivery.abort(error), error;
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
1326
|
async function send(suffix, init2, descriptor, initial, parent) {
|
|
1272
1327
|
let original = initial, checkCurrent = (context2 = original) => {
|
|
1273
1328
|
if (parent?.aborted) throw unavailable();
|
|
@@ -1278,7 +1333,7 @@ async function send(suffix, init2, descriptor, initial, parent) {
|
|
|
1278
1333
|
let context2 = await resolveFilesContext();
|
|
1279
1334
|
checkCurrent(context2);
|
|
1280
1335
|
try {
|
|
1281
|
-
let response2 = await (async () => {
|
|
1336
|
+
let response2 = context2.localFiles ? await context2.localFiles(suffix, init2, parent) : await (async () => {
|
|
1282
1337
|
let url = `${context2.url}${suffix}`, request2 = {
|
|
1283
1338
|
...init2,
|
|
1284
1339
|
signal: parent,
|
|
@@ -1322,7 +1377,7 @@ async function send(suffix, init2, descriptor, initial, parent) {
|
|
|
1322
1377
|
throw unavailable();
|
|
1323
1378
|
}
|
|
1324
1379
|
function idPath(id3) {
|
|
1325
|
-
if (typeof id3 != "string" || !FILE_ID_PATTERN.test(id3)) throw
|
|
1380
|
+
if (typeof id3 != "string" || !FILE_ID_PATTERN.test(id3)) throw invalid6();
|
|
1326
1381
|
return `/${id3}`;
|
|
1327
1382
|
}
|
|
1328
1383
|
async function multipartCreate(input, metadata, exchange, release = () => {
|
|
@@ -1365,18 +1420,18 @@ async function multipartCreate(input, metadata, exchange, release = () => {
|
|
|
1365
1420
|
if (!chunk || offset === chunk.byteLength) {
|
|
1366
1421
|
chunk = void 0, offset = 0;
|
|
1367
1422
|
let value2 = await next();
|
|
1368
|
-
if (value2.done || !(value2.value instanceof Uint8Array) || (chunk = value2.value, chunk.byteLength > metadata.size - sent - filled)) throw
|
|
1423
|
+
if (value2.done || !(value2.value instanceof Uint8Array) || (chunk = value2.value, chunk.byteLength > metadata.size - sent - filled)) throw invalid6();
|
|
1369
1424
|
}
|
|
1370
1425
|
let take = Math.min(length - filled, chunk.byteLength - offset);
|
|
1371
1426
|
part.set(chunk.subarray(offset, offset + take), filled), filled += take, offset += take, offset === chunk.byteLength && (chunk = void 0, offset = 0);
|
|
1372
1427
|
}
|
|
1373
1428
|
}
|
|
1374
|
-
if (part.byteLength !== length) throw
|
|
1429
|
+
if (part.byteLength !== length) throw invalid6();
|
|
1375
1430
|
if (reader && sent + length === metadata.size)
|
|
1376
1431
|
for (lastProgress = Date.now(); ; ) {
|
|
1377
1432
|
let value2 = await next();
|
|
1378
1433
|
if (value2.done) break;
|
|
1379
|
-
if (!(value2.value instanceof Uint8Array) || value2.value.byteLength) throw
|
|
1434
|
+
if (!(value2.value instanceof Uint8Array) || value2.value.byteLength) throw invalid6();
|
|
1380
1435
|
}
|
|
1381
1436
|
let value = await request2((signal) => exchange(`${route}/part`, {
|
|
1382
1437
|
method: "POST",
|
|
@@ -1390,7 +1445,7 @@ async function multipartCreate(input, metadata, exchange, release = () => {
|
|
|
1390
1445
|
}
|
|
1391
1446
|
if (upload) for (let name of Object.keys(upload.file.enrichments)) {
|
|
1392
1447
|
let bytes = await request2(() => upload.enrichment(name));
|
|
1393
|
-
if (bytes.byteLength !== upload.file.enrichments[name].size || bytes.byteLength > MAX_BYTES) throw
|
|
1448
|
+
if (bytes.byteLength !== upload.file.enrichments[name].size || bytes.byteLength > MAX_BYTES) throw invalid6();
|
|
1394
1449
|
await request2((signal) => exchange(`${route}/enrichments/${encodeURIComponent(name)}`, {
|
|
1395
1450
|
method: "POST",
|
|
1396
1451
|
headers: { "content-type": "application/octet-stream", "x-oddington-transfer": ticket },
|
|
@@ -1415,20 +1470,22 @@ async function multipartCreate(input, metadata, exchange, release = () => {
|
|
|
1415
1470
|
async function operation(work, initial, parent) {
|
|
1416
1471
|
let context2 = initial ?? await resolveFilesContext();
|
|
1417
1472
|
if (active >= MAX_ACTIVE) throw new FileOperationError("capacity", 429, !0);
|
|
1418
|
-
|
|
1473
|
+
active++;
|
|
1474
|
+
let execute = async (signal2) => {
|
|
1419
1475
|
try {
|
|
1420
|
-
return await work(context2,
|
|
1476
|
+
return await work(context2, signal2);
|
|
1421
1477
|
} finally {
|
|
1422
1478
|
active--;
|
|
1423
1479
|
}
|
|
1424
|
-
}, parent
|
|
1480
|
+
}, signal = context2.signal && parent ? AbortSignal.any([context2.signal, parent]) : context2.signal ?? parent;
|
|
1481
|
+
return context2.localFiles ? execute(signal ?? new AbortController().signal) : timed(execute, signal).catch((error) => {
|
|
1425
1482
|
throw error instanceof FileOperationError ? error : unavailable();
|
|
1426
1483
|
});
|
|
1427
1484
|
}
|
|
1428
1485
|
function contentPath(id3, name) {
|
|
1429
1486
|
let path = idPath(id3);
|
|
1430
1487
|
if (name === void 0) return `${path}/content`;
|
|
1431
|
-
if (!safeEnrichmentName(name)) throw
|
|
1488
|
+
if (!safeEnrichmentName(name)) throw invalid6();
|
|
1432
1489
|
return `${path}/enrichments/${encodeURIComponent(name)}/content`;
|
|
1433
1490
|
}
|
|
1434
1491
|
async function read(id3, names) {
|
|
@@ -1437,12 +1494,12 @@ async function read(id3, names) {
|
|
|
1437
1494
|
let path = contentPath(id3, names);
|
|
1438
1495
|
return operation((context3, signal) => send(path, { method: "GET" }, !1, context3, signal), context2);
|
|
1439
1496
|
}
|
|
1440
|
-
if (!Array.isArray(names)) throw
|
|
1497
|
+
if (!Array.isArray(names)) throw invalid6();
|
|
1441
1498
|
let distinct = [], seen = /* @__PURE__ */ new Set();
|
|
1442
1499
|
for (let name of names) {
|
|
1443
|
-
if (typeof name != "string" || !safeEnrichmentName(name)) throw
|
|
1500
|
+
if (typeof name != "string" || !safeEnrichmentName(name)) throw invalid6();
|
|
1444
1501
|
if (!seen.has(name)) {
|
|
1445
|
-
if (seen.size === 16) throw
|
|
1502
|
+
if (seen.size === 16) throw invalid6();
|
|
1446
1503
|
seen.add(name), distinct.push(name);
|
|
1447
1504
|
}
|
|
1448
1505
|
}
|
|
@@ -1477,11 +1534,11 @@ var files = {
|
|
|
1477
1534
|
async create(input, options) {
|
|
1478
1535
|
let context2 = await resolveFilesContext();
|
|
1479
1536
|
if (!input || typeof input != "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "size", "path", "name", "storage", "csv"].includes(key)) || options !== void 0 && (!options || typeof options != "object" || Array.isArray(options) || Object.keys(options).some((key) => key !== "requestKey")))
|
|
1480
|
-
throw
|
|
1537
|
+
throw invalid6();
|
|
1481
1538
|
let blob = input.file instanceof Blob, array3 = input.file instanceof Uint8Array, stream = input.file instanceof ReadableStream;
|
|
1482
|
-
if (!blob && !array3 && !stream) throw
|
|
1539
|
+
if (!blob && !array3 && !stream) throw invalid6();
|
|
1483
1540
|
let intrinsic = blob ? input.file.size : array3 ? input.file.byteLength : void 0;
|
|
1484
|
-
if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw
|
|
1541
|
+
if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid6();
|
|
1485
1542
|
let name = input.name;
|
|
1486
1543
|
name === void 0 && blob && "name" in input.file && typeof input.file.name == "string" && (name = typeof globalThis.File < "u" && input.file instanceof globalThis.File ? input.file.name : input.file.name.split(/[\\/]/).at(-1));
|
|
1487
1544
|
let metadata = parseFileCreateMetadata({
|
|
@@ -1493,17 +1550,38 @@ var files = {
|
|
|
1493
1550
|
...blob && input.file.type === "application/pdf" ? { inputMediaType: "application/pdf" } : {},
|
|
1494
1551
|
requestKey: options?.requestKey === void 0 ? routineTransport()?.key("files") ?? crypto.randomUUID() : options.requestKey
|
|
1495
1552
|
}, FILE_ORIGINAL_MAX_BYTES);
|
|
1496
|
-
if (!context2.local && metadata.storage === "local") throw new FileOperationError("unsupported_context", 400);
|
|
1553
|
+
if (!context2.local && !context2.localFiles && metadata.storage === "local") throw new FileOperationError("unsupported_context", 400);
|
|
1497
1554
|
let header = encodeURIComponent(JSON.stringify(metadata));
|
|
1498
|
-
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw
|
|
1555
|
+
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid6();
|
|
1499
1556
|
if (active >= MAX_ACTIVE) throw new FileOperationError("capacity", 429, !0);
|
|
1500
|
-
|
|
1557
|
+
if (active++, context2.localFiles && !routineTransport() && metadata.size > MAX_BYTES) {
|
|
1558
|
+
let signal = context2.signal ?? new AbortController().signal, file2 = input.file, offset = 0, body = file2 instanceof Blob ? context2.signal ? file2 : file2.stream() : file2 instanceof ReadableStream ? file2 : new ReadableStream({
|
|
1559
|
+
pull(controller) {
|
|
1560
|
+
if (offset === file2.byteLength) {
|
|
1561
|
+
controller.close();
|
|
1562
|
+
return;
|
|
1563
|
+
}
|
|
1564
|
+
let end = Math.min(offset + 256 * 1024, file2.byteLength);
|
|
1565
|
+
controller.enqueue(file2.subarray(offset, end)), offset = end;
|
|
1566
|
+
}
|
|
1567
|
+
}, { highWaterMark: 0 });
|
|
1568
|
+
try {
|
|
1569
|
+
return await send("", { method: "POST", headers: {
|
|
1570
|
+
"content-type": "application/octet-stream",
|
|
1571
|
+
"x-oddington-file": header
|
|
1572
|
+
}, body }, !0, context2, signal);
|
|
1573
|
+
} finally {
|
|
1574
|
+
active--;
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
return metadata.size > MAX_BYTES ? multipartCreate(input, metadata, (suffix, init2, kind, signal) => kind === !0 ? send(suffix, init2, !0, context2, signal) : send(suffix, init2, "control", context2, signal)) : timed(async (signal) => {
|
|
1501
1578
|
try {
|
|
1502
1579
|
let bytes = array3 ? input.file.slice() : await boundedBytes(
|
|
1503
1580
|
blob ? input.file.stream() : input.file,
|
|
1504
|
-
metadata.size
|
|
1581
|
+
metadata.size,
|
|
1582
|
+
signal
|
|
1505
1583
|
);
|
|
1506
|
-
if (bytes.byteLength !== metadata.size) throw
|
|
1584
|
+
if (bytes.byteLength !== metadata.size) throw invalid6();
|
|
1507
1585
|
if (signal.aborted) throw unavailable();
|
|
1508
1586
|
return await send("", {
|
|
1509
1587
|
method: "POST",
|
|
@@ -1513,13 +1591,13 @@ var files = {
|
|
|
1513
1591
|
} finally {
|
|
1514
1592
|
active--;
|
|
1515
1593
|
}
|
|
1516
|
-
}).catch((error) => {
|
|
1594
|
+
}, context2.signal).catch((error) => {
|
|
1517
1595
|
throw error instanceof FileOperationError ? error : unavailable();
|
|
1518
1596
|
});
|
|
1519
1597
|
},
|
|
1520
1598
|
async enrich(input) {
|
|
1521
1599
|
let context2 = await resolveFilesContext();
|
|
1522
|
-
if (!input || typeof input != "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "name", "content", "mediaType", "replace"].includes(key)) || typeof input.content != "string" && !(input.content instanceof Uint8Array)) throw
|
|
1600
|
+
if (!input || typeof input != "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "name", "content", "mediaType", "replace"].includes(key)) || typeof input.content != "string" && !(input.content instanceof Uint8Array)) throw invalid6();
|
|
1523
1601
|
let path = `${idPath(input.file)}/enrichments`;
|
|
1524
1602
|
if (typeof input.content == "string" ? input.content.length > MAX_BYTES : input.content.byteLength > MAX_BYTES)
|
|
1525
1603
|
throw new FileOperationError("request_too_large", 413);
|
|
@@ -1536,7 +1614,7 @@ var files = {
|
|
|
1536
1614
|
...input.mediaType === void 0 ? {} : { mediaType: input.mediaType },
|
|
1537
1615
|
...input.replace === void 0 ? {} : { replace: input.replace }
|
|
1538
1616
|
}, MAX_BYTES), header = encodeURIComponent(JSON.stringify(metadata));
|
|
1539
|
-
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw
|
|
1617
|
+
if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid6();
|
|
1540
1618
|
let result2 = await send(path, { method: "POST", headers: {
|
|
1541
1619
|
"content-type": "application/octet-stream",
|
|
1542
1620
|
"x-oddington-enrichment": header
|
|
@@ -1557,6 +1635,24 @@ function validGoogleScopes(value) {
|
|
|
1557
1635
|
|
|
1558
1636
|
var ROUTINE_CONNECTION_CREDENTIALS_ENV = "ODDINGTON_ROUTINE_CONNECTION_CREDENTIALS";
|
|
1559
1637
|
var connectionUuid = (v) => typeof v == "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(v);
|
|
1638
|
+
function runtimeConnection(lease) {
|
|
1639
|
+
return lease.provider === "gmail" ? {
|
|
1640
|
+
id: `gmail/${lease.name}`,
|
|
1641
|
+
provider: lease.provider,
|
|
1642
|
+
name: lease.name,
|
|
1643
|
+
accountEmail: lease.accountEmail,
|
|
1644
|
+
scopes: [...lease.scopes],
|
|
1645
|
+
accessToken: lease.accessToken,
|
|
1646
|
+
expiresAt: lease.expiresAt
|
|
1647
|
+
} : {
|
|
1648
|
+
id: `airtable/${lease.name}`,
|
|
1649
|
+
provider: lease.provider,
|
|
1650
|
+
name: lease.name,
|
|
1651
|
+
baseId: lease.baseId,
|
|
1652
|
+
accessToken: lease.accessToken,
|
|
1653
|
+
runExpiresAt: lease.runExpiresAt
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1560
1656
|
function parseConnectionLease(raw, now = Date.now()) {
|
|
1561
1657
|
let v = raw;
|
|
1562
1658
|
if (!v || typeof v != "object" || Array.isArray(v) || !connectionUuid(v.connectionId) || !connectionUuid(v.runId) || typeof v.name != "string" || !/^[a-z0-9][a-z0-9-]{0,62}$/.test(v.name) || typeof v.accessToken != "string" || !/^[A-Za-z0-9._~+/-]{1,8192}={0,2}$/.test(v.accessToken))
|
|
@@ -1595,7 +1691,7 @@ function keys2(v, allowed, required = allowed) {
|
|
|
1595
1691
|
function text2(v) {
|
|
1596
1692
|
return typeof v == "string" && v.length > 0 && v.length <= 1024;
|
|
1597
1693
|
}
|
|
1598
|
-
function
|
|
1694
|
+
function fields3(v, nonempty = !1) {
|
|
1599
1695
|
let result2 = object3(v);
|
|
1600
1696
|
(nonempty && !Object.keys(result2).length || Object.keys(result2).some((k) => !text2(k))) && fail2("Invalid Airtable fields");
|
|
1601
1697
|
try {
|
|
@@ -1606,7 +1702,7 @@ function fields4(v, nonempty = !1) {
|
|
|
1606
1702
|
}
|
|
1607
1703
|
function record2(v) {
|
|
1608
1704
|
let r = object3(v);
|
|
1609
|
-
return (!recordId(r.id) || r.createdTime !== void 0 && (typeof r.createdTime != "string" || !Number.isFinite(Date.parse(r.createdTime)))) && fail2("Malformed Airtable record"), { id: r.id, ...r.createdTime === void 0 ? {} : { createdTime: r.createdTime }, fields:
|
|
1705
|
+
return (!recordId(r.id) || r.createdTime !== void 0 && (typeof r.createdTime != "string" || !Number.isFinite(Date.parse(r.createdTime)))) && fail2("Malformed Airtable record"), { id: r.id, ...r.createdTime === void 0 ? {} : { createdTime: r.createdTime }, fields: fields3(r.fields) };
|
|
1610
1706
|
}
|
|
1611
1707
|
function equal(a, b) {
|
|
1612
1708
|
if (a === b) return !0;
|
|
@@ -1618,7 +1714,9 @@ function equal(a, b) {
|
|
|
1618
1714
|
));
|
|
1619
1715
|
}
|
|
1620
1716
|
function createConnections(transport) {
|
|
1621
|
-
return {
|
|
1717
|
+
return { async get() {
|
|
1718
|
+
throw new Error("Connection unavailable");
|
|
1719
|
+
}, airtable(name) {
|
|
1622
1720
|
(typeof name != "string" || !/^[a-z0-9][a-z0-9-]{0,62}$/.test(name)) && fail2("Invalid Airtable connection name");
|
|
1623
1721
|
let call = (operation2, input) => transport(name, operation2, input);
|
|
1624
1722
|
return {
|
|
@@ -1720,10 +1818,10 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
|
|
|
1720
1818
|
mutation || fail2("Unsupported Airtable operation"), keys2(input, ["table", "records"]), (!Array.isArray(input.records) || !input.records.length || input.records.length > 10) && fail2("Invalid Airtable batch");
|
|
1721
1819
|
let kind = operation2.slice(8), ids = /* @__PURE__ */ new Set(), records = input.records.map((value) => {
|
|
1722
1820
|
let r = object3(value);
|
|
1723
|
-
if (keys2(r, kind === "create" ? ["fields"] : kind === "update" ? ["id", "expected", "set"] : ["id", "expected"]), kind === "create") return { fields:
|
|
1821
|
+
if (keys2(r, kind === "create" ? ["fields"] : kind === "update" ? ["id", "expected", "set"] : ["id", "expected"]), kind === "create") return { fields: fields3(r.fields, !0) };
|
|
1724
1822
|
(!recordId(r.id) || ids.has(r.id)) && fail2("Invalid Airtable batch record ID"), ids.add(r.id);
|
|
1725
|
-
let set = kind === "update" ?
|
|
1726
|
-
return set && Object.values(set).some((value2) => value2 === null) && fail2("Airtable guard null cannot be an update value"), { id: r.id, expected:
|
|
1823
|
+
let set = kind === "update" ? fields3(r.set, !0) : void 0;
|
|
1824
|
+
return set && Object.values(set).some((value2) => value2 === null) && fail2("Airtable guard null cannot be an update value"), { id: r.id, expected: fields3(r.expected), ...set ? { set } : {} };
|
|
1727
1825
|
});
|
|
1728
1826
|
for (let r of records) {
|
|
1729
1827
|
if (!("id" in r)) continue;
|
|
@@ -1800,46 +1898,19 @@ async function reportLocalRoutineEffect(value) {
|
|
|
1800
1898
|
await observer?.(value);
|
|
1801
1899
|
}
|
|
1802
1900
|
|
|
1803
|
-
var
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
if (installed2) return await installed2.request("airtable", { name, operation: operation2, input: serializable(input) });
|
|
1807
|
-
let managed = process.env[MANAGED_CONNECTION_CAPABILITY_ENV];
|
|
1808
|
-
if (managed) {
|
|
1809
|
-
let client = managedConnections(JSON.parse(managed)).airtable(name);
|
|
1810
|
-
return operation2 === "tables.list" ? await client.tables.list() : await client.records[operation2.slice(8)](input);
|
|
1811
|
-
}
|
|
1812
|
-
let raw = JSON.parse(process.env[ROUTINE_CONNECTION_CREDENTIALS_ENV] ?? "[]");
|
|
1813
|
-
if (!Array.isArray(raw)) throw new Error();
|
|
1814
|
-
let leases = raw.map((value) => parseConnectionLease(value));
|
|
1815
|
-
if (leases.some((lease2) => lease2.provider !== "airtable") || new Set(leases.map((lease2) => lease2.name)).size !== leases.length) throw new Error();
|
|
1816
|
-
let lease = leases.find((lease2) => lease2.name === name);
|
|
1817
|
-
if (!lease || lease.provider !== "airtable") throw new Error();
|
|
1818
|
-
let writing = ["records.create", "records.update", "records.delete"].includes(operation2), captured = serializable(input), result2;
|
|
1819
|
-
try {
|
|
1820
|
-
result2 = await executeAirtableOperation(lease, operation2, captured);
|
|
1821
|
-
} catch (error) {
|
|
1822
|
-
throw writing && error instanceof AirtableOperationError && await reportLocalRoutineEffect({
|
|
1823
|
-
type: "effect",
|
|
1824
|
-
connection: `airtable/${name}`,
|
|
1825
|
-
operation: operation2,
|
|
1826
|
-
input: captured,
|
|
1827
|
-
effect: error.effect,
|
|
1828
|
-
receipts: error.receipts
|
|
1829
|
-
}), error;
|
|
1830
|
-
}
|
|
1831
|
-
return writing && await reportLocalRoutineEffect({
|
|
1832
|
-
type: "effect",
|
|
1833
|
-
connection: `airtable/${name}`,
|
|
1834
|
-
operation: operation2,
|
|
1835
|
-
input: captured,
|
|
1836
|
-
effect: "confirmed",
|
|
1837
|
-
receipts: [result2.receipt]
|
|
1838
|
-
}), result2;
|
|
1839
|
-
} catch (error) {
|
|
1840
|
-
throw error instanceof AirtableOperationError ? error : new AirtableOperationError("Airtable connection unavailable");
|
|
1841
|
-
}
|
|
1901
|
+
var local;
|
|
1902
|
+
var airtable = /* @__PURE__ */ createConnections(async (name, operation2, input) => {
|
|
1903
|
+
throw new AirtableOperationError("Airtable connection unavailable");
|
|
1842
1904
|
});
|
|
1905
|
+
function runtimeConnections() {
|
|
1906
|
+
return {
|
|
1907
|
+
...airtable,
|
|
1908
|
+
async get(identity) {
|
|
1909
|
+
throw new Error("Connection unavailable");
|
|
1910
|
+
}
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1913
|
+
var connections = /* @__PURE__ */ runtimeConnections();
|
|
1843
1914
|
|
|
1844
1915
|
var LOCAL_ROUTINE_VALUE_BYTES = 256 * 1024;
|
|
1845
1916
|
|
|
@@ -1965,11 +2036,11 @@ function array2(value) {
|
|
|
1965
2036
|
return !!descriptor?.enumerable && "value" in descriptor;
|
|
1966
2037
|
})), value;
|
|
1967
2038
|
}
|
|
1968
|
-
function
|
|
2039
|
+
function json(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
1969
2040
|
if (value === null || typeof value == "boolean" || typeof value == "string" || typeof value == "number" && Number.isFinite(value)) return value;
|
|
1970
2041
|
assert(value && typeof value == "object" && !ancestors.has(value)), ancestors.add(value);
|
|
1971
2042
|
try {
|
|
1972
|
-
return Array.isArray(value) ? array2(value).map((entry) =>
|
|
2043
|
+
return Array.isArray(value) ? array2(value).map((entry) => json(entry, ancestors)) : Object.fromEntries(Object.entries(object4(value)).map(([key, entry]) => [key, json(entry, ancestors)]));
|
|
1973
2044
|
} finally {
|
|
1974
2045
|
ancestors.delete(value);
|
|
1975
2046
|
}
|
|
@@ -2025,7 +2096,7 @@ function inboxFile(value) {
|
|
|
2025
2096
|
let details = object4(file2.details);
|
|
2026
2097
|
details.kind === "csv" ? (keys3(details, ["kind", "encoding", "delimiter", "headerRow", "dataRows"]), assert(file2.mediaType === "text/csv" && ["utf-8", "windows-1252"].includes(String(details.encoding)) && [",", ";", " "].includes(String(details.delimiter)) && integer(details.headerRow, 0) && integer(details.dataRows, 0))) : details.kind === "pdf" ? (keys3(details, ["kind", "pages"], ["kind"]), assert(file2.mediaType === "application/pdf" && (!("pages" in details) || integer(details.pages)))) : (keys3(details, ["kind"]), assert(details.kind === "other" && !["text/csv", "application/pdf"].includes(file2.mediaType)));
|
|
2027
2098
|
}
|
|
2028
|
-
function
|
|
2099
|
+
function fields4(value) {
|
|
2029
2100
|
let labels = array2(value).map((value2) => {
|
|
2030
2101
|
let field = object4(value2);
|
|
2031
2102
|
return keys3(field, ["label", "value"]), assert(text3(field.label) && text3(field.value)), field.label;
|
|
@@ -2050,13 +2121,13 @@ function block(value) {
|
|
|
2050
2121
|
["kind", "label", entry.kind === "record" ? "record" : entry.kind === "records" ? "records" : "files"]
|
|
2051
2122
|
), assert(text3(entry.label) && (!("initiallyExpanded" in entry) || typeof entry.initiallyExpanded == "boolean") && (!("view" in entry) || text3(entry.view) && entry.view === entry.view.trim())), entry.kind === "record") {
|
|
2052
2123
|
let record3 = object4(entry.record);
|
|
2053
|
-
keys3(record3, ["ref", "title", "fields"]), assert(text3(record3.ref) && record3.ref === record3.ref.trim() && text3(record3.title)),
|
|
2124
|
+
keys3(record3, ["ref", "title", "fields"]), assert(text3(record3.ref) && record3.ref === record3.ref.trim() && text3(record3.title)), fields4(record3.fields);
|
|
2054
2125
|
return;
|
|
2055
2126
|
}
|
|
2056
2127
|
if (entry.kind === "records") {
|
|
2057
2128
|
let records = array2(entry.records), refs = records.map((value2) => {
|
|
2058
2129
|
let record3 = object4(value2);
|
|
2059
|
-
return keys3(record3, ["ref", "title", "description", "facts", "view"], ["ref", "title"]), assert(text3(record3.ref) && record3.ref === record3.ref.trim() && text3(record3.title)), "description" in record3 && assert(text3(record3.description)), "facts" in record3 &&
|
|
2130
|
+
return keys3(record3, ["ref", "title", "description", "facts", "view"], ["ref", "title"]), assert(text3(record3.ref) && record3.ref === record3.ref.trim() && text3(record3.title)), "description" in record3 && assert(text3(record3.description)), "facts" in record3 && fields4(record3.facts), "view" in record3 && assert(text3(record3.view) && record3.view === record3.view.trim()), record3.ref;
|
|
2060
2131
|
});
|
|
2061
2132
|
assert(records.length > 0 && new Set(refs).size === refs.length);
|
|
2062
2133
|
return;
|
|
@@ -2068,12 +2139,12 @@ function response(value) {
|
|
|
2068
2139
|
let answer = object4(value);
|
|
2069
2140
|
return assert(Object.keys(answer).every((key) => ["selection", "note"].includes(key))), typeof answer.selection == "string" ? assert(text3(answer.selection) && answer.selection === answer.selection.trim()) : recordReference(answer.selection), Object.hasOwn(answer, "note") && assert(text3(answer.note)), answer;
|
|
2070
2141
|
}
|
|
2071
|
-
function parseInboxRequest(value
|
|
2142
|
+
function parseInboxRequest(value) {
|
|
2072
2143
|
try {
|
|
2073
2144
|
let envelope = object4(value);
|
|
2074
2145
|
assert(Object.keys(envelope).sort().join(",") === "input,operation"), assert(typeof envelope.operation == "string" && Object.hasOwn(operations, envelope.operation));
|
|
2075
2146
|
let operation2 = envelope.operation, input = { ...object4(envelope.input) }, required = operations[operation2];
|
|
2076
|
-
assert(required.every((key) => Object.hasOwn(input, key)) && Object.keys(input).every((key) => required.includes(key) || operation2 === "questions.searchRecords" && key === "selected" || (operation2 === "items.list" || operation2 === "questions.list") && key === "beforeNumber" || operation2 === "questions.list" &&
|
|
2147
|
+
assert(required.every((key) => Object.hasOwn(input, key)) && Object.keys(input).every((key) => required.includes(key) || operation2 === "questions.searchRecords" && key === "selected" || (operation2 === "items.list" || operation2 === "questions.list") && key === "beforeNumber" || operation2 === "questions.list" && key === "routines")), operation2 === "questions.list" && (assert(Object.hasOwn(input, "routines")), assert(array2(input.routines).every(isAppRoutineName)));
|
|
2077
2148
|
for (let key of ["itemId", "personId", "fileId"]) key in input && assert(id2(input[key]));
|
|
2078
2149
|
return "revision" in input && assert(integer(input.revision)), "beforeNumber" in input && assert(integer(input.beforeNumber)), "questionId" in input && assert(text3(input.questionId) && input.questionId === input.questionId.trim()), "title" in input && assert(text3(input.title)), "lifecycle" in input && assert(input.lifecycle === "open" || input.lifecycle === "closed"), "query" in input && assert(text3(input.query, !0) && input.query.length <= 256), "selected" in input && recordReference(input.selected), "response" in input && response(input.response), assert(new TextEncoder().encode(JSON.stringify(envelope)).byteLength <= INBOX_INPUT_BYTES), "routines" in input && (input.routines = [...new Set(input.routines)]), { operation: operation2, input };
|
|
2079
2150
|
} catch {
|
|
@@ -2088,10 +2159,10 @@ function parseInboxCurrent(value) {
|
|
|
2088
2159
|
};
|
|
2089
2160
|
}
|
|
2090
2161
|
function parseInboxItem(value) {
|
|
2091
|
-
let item = object4(
|
|
2092
|
-
return assert(id2(item.id) && id2(item.workspaceId) && integer(item.number) && integer(item.revision) && integer(item.activityVersion, 0) && ["ask", "digest"].includes(String(item.kind)) && ["open", "closed"].includes(String(item.lifecycle)) && text3(item.title) && text3(item.description, !0) && text3(item.author) && date(item.publishedAt) && optionalDate(item.seenAt) && optionalDate(item.digestReadAt)), item.outcome !== null && assert(text3(object4(item.outcome).outcome)), array2(item.body).forEach(block), array2(item.views).forEach((value2) => {
|
|
2162
|
+
let item = object4(json(value));
|
|
2163
|
+
return assert(id2(item.id) && id2(item.workspaceId) && integer(item.number) && integer(item.revision) && integer(item.activityVersion, 0) && ["ask", "digest"].includes(String(item.kind)) && ["open", "closed"].includes(String(item.lifecycle)) && text3(item.title) && text3(item.description, !0) && text3(item.author) && date(item.publishedAt) && optionalDate(item.seenAt) && optionalDate(item.digestReadAt)), item.outcome !== null && assert(text3(object4(item.outcome).outcome)), "canonicalRoutineId" in item && assert(item.canonicalRoutineId === null || isAppRoutineName(item.canonicalRoutineId)), item.kind === "ask" ? askMetadata(item) : assert(!("tags" in item) && !("recordRefs" in item)), array2(item.body).forEach(block), array2(item.views).forEach((value2) => {
|
|
2093
2164
|
let view = object4(value2);
|
|
2094
|
-
assert(text3(view.id) && text3(view.view) && text3(view.implementation)),
|
|
2165
|
+
assert(text3(view.id) && text3(view.view) && text3(view.implementation)), json(view.input);
|
|
2095
2166
|
}), array2(item.people).forEach((value2) => {
|
|
2096
2167
|
let person = object4(value2);
|
|
2097
2168
|
assert(id2(person.id) && text3(person.name));
|
|
@@ -2127,18 +2198,26 @@ function parseInboxItem(value) {
|
|
|
2127
2198
|
}), item;
|
|
2128
2199
|
}
|
|
2129
2200
|
function parseAnswerableQuestion(value) {
|
|
2130
|
-
let entry = object4(
|
|
2131
|
-
keys3(
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
assert(
|
|
2136
|
-
let
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
let
|
|
2141
|
-
|
|
2201
|
+
let entry = object4(json(value));
|
|
2202
|
+
keys3(
|
|
2203
|
+
entry,
|
|
2204
|
+
["itemId", "revision", "title", "inboxUrl", "questionId", "routine", "prompt", "response", "answerable", "tags", "recordRefs", "instructions"],
|
|
2205
|
+
["itemId", "revision", "title", "inboxUrl", "questionId", "routine", "prompt", "response", "answerable"]
|
|
2206
|
+
), assert(id2(entry.itemId) && integer(entry.revision) && text3(entry.title) && text3(entry.inboxUrl));
|
|
2207
|
+
let link = new URL(entry.inboxUrl), slug = link.hostname.slice(0, -13);
|
|
2208
|
+
return assert(link.hostname.endsWith(".oddington.ai") && slug.length <= 63 && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug) && !["auth", "www", "api", "os"].includes(slug) && entry.inboxUrl === `https://${slug}.oddington.ai/inbox/${entry.itemId}`), assert(isAppRoutineName(entry.routine) && text3(entry.questionId) && entry.questionId === entry.questionId.trim() && text3(entry.prompt) && (!("instructions" in entry) || text3(entry.instructions, !0)) && typeof entry.answerable == "boolean"), responseDefinition(entry.response), askMetadata(entry), entry;
|
|
2209
|
+
}
|
|
2210
|
+
function askMetadata(entry) {
|
|
2211
|
+
let tags = array2(entry.tags === void 0 ? [] : entry.tags);
|
|
2212
|
+
assert(tags.length <= 32 && tags.every((tag) => text3(tag) && new TextEncoder().encode(tag).byteLength <= 64)), assert(new Set(tags).size === tags.length);
|
|
2213
|
+
let refs = array2(entry.recordRefs === void 0 ? [] : entry.recordRefs);
|
|
2214
|
+
refs.forEach((value) => {
|
|
2215
|
+
let ref = object4(value);
|
|
2216
|
+
keys3(ref, ["repository", "id"]), recordReference({ repository: ref.repository, ref: ref.id });
|
|
2217
|
+
}), assert(new Set(refs.map((value) => {
|
|
2218
|
+
let ref = object4(value);
|
|
2219
|
+
return JSON.stringify([ref.repository, ref.id]);
|
|
2220
|
+
})).size === refs.length), entry.tags = tags, entry.recordRefs = refs;
|
|
2142
2221
|
}
|
|
2143
2222
|
function parseInboxAcceptance(value) {
|
|
2144
2223
|
let accepted = object4(value);
|
|
@@ -2368,10 +2447,12 @@ function appContext(origin, active2) {
|
|
|
2368
2447
|
credentials: "omit",
|
|
2369
2448
|
redirect: "error",
|
|
2370
2449
|
cache: "no-store",
|
|
2450
|
+
...init2.body instanceof ReadableStream ? { duplex: "half" } : {},
|
|
2371
2451
|
referrerPolicy: "no-referrer",
|
|
2372
2452
|
signal,
|
|
2373
2453
|
headers: {
|
|
2374
2454
|
...init2.body === void 0 ? {} : { "content-type": "application/json" },
|
|
2455
|
+
...Object.fromEntries(new Headers(init2.headers)),
|
|
2375
2456
|
authorization: `Bearer ${candidate}`
|
|
2376
2457
|
}
|
|
2377
2458
|
});
|
|
@@ -2537,11 +2618,37 @@ function appContext(origin, active2) {
|
|
|
2537
2618
|
async function requestRoutine(key, suffix, init2 = {}) {
|
|
2538
2619
|
return requestChecked(`routines/${encodeURIComponent(key)}/${suffix}`, init2);
|
|
2539
2620
|
}
|
|
2540
|
-
async function
|
|
2621
|
+
async function requestRetainedRoutine(key, suffix) {
|
|
2622
|
+
return requestChecked(`routines/${encodeURIComponent(key)}/${suffix}`, {}, !1, !0);
|
|
2623
|
+
}
|
|
2624
|
+
async function requestFiles(suffix, init2, parent) {
|
|
2625
|
+
let unavailable3 = () => new FileOperationError("unsupported_context", 400);
|
|
2626
|
+
if (!current2() || !/^(?:|\/[0-9a-f-]{36}(?:\/(?:content|upload|enrichments(?:\/[^/?#]+\/content)?))?)$/i.test(suffix))
|
|
2627
|
+
throw unavailable3();
|
|
2628
|
+
let admitted = credential, signal = parent ? AbortSignal.any([access.signal, parent]) : access.signal, failure = () => current2() && !signal.aborted ? new FileOperationError("unavailable", 503, !0) : unavailable3();
|
|
2629
|
+
try {
|
|
2630
|
+
return await hostedContent("", init2, signal, (_url, request2) => untilAborted(
|
|
2631
|
+
send3(`files${suffix}`, admitted, signal, request2).then((value) => {
|
|
2632
|
+
if (signal.aborted)
|
|
2633
|
+
throw value.body?.cancel().catch(() => {
|
|
2634
|
+
}), unavailable3();
|
|
2635
|
+
return value;
|
|
2636
|
+
}),
|
|
2637
|
+
signal
|
|
2638
|
+
), () => settledAccess(signal), failure);
|
|
2639
|
+
} catch {
|
|
2640
|
+
throw failure();
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
async function requestChecked(path, init2, inbox2 = !1, retained2 = !1) {
|
|
2541
2644
|
if (!current2()) throw new Error("Local app context unavailable.");
|
|
2542
|
-
let admitted = credential, signal = access.signal, response2 = await send3(path, credential, signal, init2)
|
|
2543
|
-
|
|
2544
|
-
|
|
2645
|
+
let admitted = credential, signal = access.signal, response2 = await send3(path, credential, signal, init2), check = async () => {
|
|
2646
|
+
if (retained2) {
|
|
2647
|
+
if (signal.aborted || !current2()) throw new Error("Local app context unavailable.");
|
|
2648
|
+
} else await settledAccess(signal);
|
|
2649
|
+
};
|
|
2650
|
+
return await check(), (response2.status === 401 || !inbox2 && response2.status === 403) && admitted === credential && current2() && invalidate(), responseChecks.set(response2, async (value) => {
|
|
2651
|
+
await check(), admitted === credential && current2() && value && typeof value == "object" && "error" in value && value.error === "authority_unavailable" && invalidate();
|
|
2545
2652
|
}), response2;
|
|
2546
2653
|
}
|
|
2547
2654
|
function context2() {
|
|
@@ -2558,8 +2665,10 @@ function appContext(origin, active2) {
|
|
|
2558
2665
|
issued === credential && current2() && invalidate();
|
|
2559
2666
|
},
|
|
2560
2667
|
requestRoutine,
|
|
2668
|
+
requestRetainedRoutine,
|
|
2561
2669
|
requestData,
|
|
2562
2670
|
requestInbox,
|
|
2671
|
+
requestFiles,
|
|
2563
2672
|
requestAvailability: (key) => requestRoutine(key, "availability", { method: "GET" })
|
|
2564
2673
|
};
|
|
2565
2674
|
}
|
|
@@ -2568,22 +2677,22 @@ function appContext(origin, active2) {
|
|
|
2568
2677
|
try {
|
|
2569
2678
|
if (!alive()) throw new Error();
|
|
2570
2679
|
if (!pair) {
|
|
2571
|
-
let candidate2 = stored(),
|
|
2572
|
-
pair =
|
|
2680
|
+
let candidate2 = stored(), retained3 = readPair(candidate2);
|
|
2681
|
+
pair = retained3, binding = { ...retained3.context }, credential = retained3.credential, serialized = candidate2;
|
|
2573
2682
|
}
|
|
2574
2683
|
if (expireAccess(), binding.expiresAt <= Date.now()) {
|
|
2575
2684
|
if (await renew(), !current2()) throw new AppRenewalUnavailable();
|
|
2576
2685
|
return context2();
|
|
2577
2686
|
}
|
|
2578
2687
|
await synchronize();
|
|
2579
|
-
let candidate = stored(),
|
|
2688
|
+
let candidate = stored(), retained2 = readPair(candidate);
|
|
2580
2689
|
if (attempted = candidate ?? void 0, !current2()) throw new AppRenewalUnavailable();
|
|
2581
|
-
let value = await proof(
|
|
2690
|
+
let value = await proof(retained2.credential);
|
|
2582
2691
|
if (stored() !== candidate || serialized !== candidate)
|
|
2583
2692
|
return await synchronize(), context2();
|
|
2584
2693
|
if (!current2()) throw new Error();
|
|
2585
2694
|
if (expiry && binding && value.expiresAt > binding.expiresAt) throw new Error();
|
|
2586
|
-
return (!expiry || value.expiresAt !== binding.expiresAt) && install(value,
|
|
2695
|
+
return (!expiry || value.expiresAt !== binding.expiresAt) && install(value, retained2, candidate), context2();
|
|
2587
2696
|
} catch (error) {
|
|
2588
2697
|
if (alive() && error instanceof AppRenewalUnavailable)
|
|
2589
2698
|
throw new Error();
|
|
@@ -2598,7 +2707,12 @@ function appContext(origin, active2) {
|
|
|
2598
2707
|
}, resolve = () => resolution2 || (resolution2 = resolveOnce().finally(() => {
|
|
2599
2708
|
resolution2 = void 0;
|
|
2600
2709
|
}), resolution2);
|
|
2601
|
-
return { resolve,
|
|
2710
|
+
return { resolve, retained: async () => {
|
|
2711
|
+
if (!expiry && alive() && (binding ? current2() && resolution2 : readPair(stored()).context.expiresAt > Date.now()))
|
|
2712
|
+
return resolve();
|
|
2713
|
+
if (!expiry || !current2()) throw new Error("Local app context unavailable.");
|
|
2714
|
+
return context2();
|
|
2715
|
+
}, start: () => {
|
|
2602
2716
|
startup = setTimeout(() => {
|
|
2603
2717
|
alive() && !resolution2 && !binding && resolve().catch(() => {
|
|
2604
2718
|
});
|
|
@@ -2624,13 +2738,13 @@ function hostFailure(error, context2) {
|
|
|
2624
2738
|
return !context2.isCurrent() || context2.expiresAt <= Date.now() || error instanceof InboxContextError && error.status === 401 ? stale() : error instanceof InboxContextError && error.status === 403 ? new InboxOperationError(403, "access_denied") : unavailable2();
|
|
2625
2739
|
}
|
|
2626
2740
|
async function send2(operation2, input) {
|
|
2627
|
-
let envelope =
|
|
2741
|
+
let envelope = parseInboxRequest({ operation: operation2, input }), context2;
|
|
2628
2742
|
try {
|
|
2629
2743
|
context2 = await resolveAppContext();
|
|
2630
2744
|
} catch {
|
|
2631
2745
|
throw stale();
|
|
2632
2746
|
}
|
|
2633
|
-
if (
|
|
2747
|
+
if (context2.kind === "local") {
|
|
2634
2748
|
if (!isAppQuestionOperation(operation2)) throw new InboxOperationError(403, "access_denied");
|
|
2635
2749
|
let check2 = () => {
|
|
2636
2750
|
if (!context2.isCurrent() || context2.signal.aborted || context2.expiresAt <= Date.now()) throw stale();
|
|
@@ -2651,16 +2765,18 @@ async function send2(operation2, input) {
|
|
|
2651
2765
|
}
|
|
2652
2766
|
if (context2.endpoint !== `https://${context2.workspace}.oddington.ai` || ["auth", "www", "api", "os"].includes(context2.workspace)) throw stale();
|
|
2653
2767
|
let host;
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2768
|
+
if (!isAppQuestionOperation(operation2)) {
|
|
2769
|
+
try {
|
|
2770
|
+
host = await resolveHostedInboxContext(context2);
|
|
2771
|
+
} catch (error) {
|
|
2772
|
+
throw hostFailure(error, context2);
|
|
2773
|
+
}
|
|
2774
|
+
if (!host) throw unavailable2();
|
|
2658
2775
|
}
|
|
2659
|
-
if (!host) throw unavailable2();
|
|
2660
2776
|
let check = () => {
|
|
2661
|
-
if (!context2.isCurrent() || !host.isCurrent() || !Number.isFinite(context2.expiresAt) || context2.expiresAt <= Date.now()) throw stale();
|
|
2777
|
+
if (!context2.isCurrent() || host && !host.isCurrent() || !Number.isFinite(context2.expiresAt) || context2.expiresAt <= Date.now()) throw stale();
|
|
2662
2778
|
};
|
|
2663
|
-
if (check(), host
|
|
2779
|
+
if (check(), host?.context.kind === "focused")
|
|
2664
2780
|
throw new InboxOperationError(403, "access_denied");
|
|
2665
2781
|
try {
|
|
2666
2782
|
let response2 = await fetch(`${context2.endpoint}/api/inbox`, {
|
|
@@ -2768,33 +2884,24 @@ var inbox = {
|
|
|
2768
2884
|
},
|
|
2769
2885
|
questions: {
|
|
2770
2886
|
async list(input) {
|
|
2771
|
-
let supplied =
|
|
2772
|
-
if (
|
|
2773
|
-
let routines =
|
|
2887
|
+
let supplied = parseInboxRequest({ operation: "questions.list", input }).input;
|
|
2888
|
+
if (Object.hasOwn(supplied, "beforeNumber")) throw new InboxOperationError(400, "invalid_input");
|
|
2889
|
+
let routines = Object.freeze(supplied.routines), questions = [], beforeNumber, initial;
|
|
2774
2890
|
try {
|
|
2775
2891
|
initial = await resolveAppContext();
|
|
2776
2892
|
} catch {
|
|
2777
2893
|
throw stale();
|
|
2778
2894
|
}
|
|
2779
|
-
if (initial.kind === "local" ? input !== void 0 : routines === void 0)
|
|
2780
|
-
throw new InboxOperationError(400, "invalid_input");
|
|
2781
|
-
let host;
|
|
2782
|
-
try {
|
|
2783
|
-
host = initial.kind !== "local" && await resolveHostedInboxContext(initial);
|
|
2784
|
-
} catch (error) {
|
|
2785
|
-
throw hostFailure(error, initial);
|
|
2786
|
-
}
|
|
2787
|
-
if (initial.kind !== "local" && !host) throw unavailable2();
|
|
2788
2895
|
let check = () => {
|
|
2789
|
-
if (!initial.isCurrent() ||
|
|
2896
|
+
if (!initial.isCurrent() || initial.expiresAt <= Date.now()) throw stale();
|
|
2790
2897
|
};
|
|
2791
2898
|
do {
|
|
2792
2899
|
check();
|
|
2793
2900
|
let page = await send2("questions.list", {
|
|
2794
|
-
|
|
2901
|
+
routines,
|
|
2795
2902
|
...beforeNumber === void 0 ? {} : { beforeNumber }
|
|
2796
2903
|
});
|
|
2797
|
-
if (check(), page.questions.some((question2) => question2.
|
|
2904
|
+
if (check(), page.questions.some((question2) => question2.inboxUrl !== `https://${initial.workspace}.oddington.ai/inbox/${question2.itemId}` || !routines.includes(question2.routine)) || beforeNumber !== void 0 && page.nextBeforeNumber !== null && page.nextBeforeNumber >= beforeNumber) throw unavailable2();
|
|
2798
2905
|
if (questions.push(...page.questions), page.nextBeforeNumber === null) return questions;
|
|
2799
2906
|
beforeNumber = page.nextBeforeNumber;
|
|
2800
2907
|
} while (!0);
|
|
@@ -2831,8 +2938,8 @@ function init({ auth: input }) {
|
|
|
2831
2938
|
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);
|
|
2832
2939
|
} catch {
|
|
2833
2940
|
}
|
|
2834
|
-
let active2 = !0, revision = 0, person, token, binding = {},
|
|
2835
|
-
if (
|
|
2941
|
+
let active2 = !0, revision = 0, person, token, binding = {}, local3 = localOrigin ? appContext(localOrigin, () => active2) : void 0, subscription, stopDisposal, resolve = async () => {
|
|
2942
|
+
if (local3) return local3.resolve();
|
|
2836
2943
|
if (!active2 || !endpoint || !workspace || globalThis.location.origin !== endpoint) throw new Error("Hosted Data context unavailable.");
|
|
2837
2944
|
let started = revision, { data: { session }, error } = await auth2.getSession();
|
|
2838
2945
|
if (!active2 || globalThis.location.origin !== endpoint || started !== revision || error || !session || person !== void 0 && person !== session.user.id)
|
|
@@ -2851,13 +2958,13 @@ function init({ auth: input }) {
|
|
|
2851
2958
|
memberId: session.user.id,
|
|
2852
2959
|
binding
|
|
2853
2960
|
};
|
|
2854
|
-
}), dispose = () => {
|
|
2855
|
-
active2 && (active2 = !1,
|
|
2961
|
+
}, uninstall = installMemberContext(resolve, local3 ? local3.retained : resolve), dispose = () => {
|
|
2962
|
+
active2 && (active2 = !1, local3?.dispose(), revision++, subscription?.unsubscribe(), stopDisposal?.(), uninstall(), installedDispose === dispose && (installedDispose = void 0));
|
|
2856
2963
|
};
|
|
2857
2964
|
installedDispose = dispose, stopDisposal = registered?.onDispose(dispose), active2 && (subscription = auth2.onAuthStateChange((event, session) => {
|
|
2858
2965
|
let next = session?.user.id ?? null;
|
|
2859
|
-
(event === "SIGNED_OUT" || person !== void 0 && next !== person || registered && person !== void 0 && event === "SIGNED_IN" && token !== session?.access_token) && (revision++,
|
|
2860
|
-
}).data.subscription,
|
|
2966
|
+
(event === "SIGNED_OUT" || person !== void 0 && next !== person || registered && person !== void 0 && event === "SIGNED_IN" && token !== session?.access_token) && (revision++, local3?.invalidate()), person = next, token = session?.access_token;
|
|
2967
|
+
}).data.subscription, local3?.start());
|
|
2861
2968
|
}
|
|
2862
2969
|
var os = { init };
|
|
2863
2970
|
|
|
@@ -3217,9 +3324,9 @@ async function provider(configuration, guard) {
|
|
|
3217
3324
|
let result2 = new Response(
|
|
3218
3325
|
[204, 205, 304].includes(response2.status) ? null : body,
|
|
3219
3326
|
{ status: response2.status, statusText: response2.statusText, headers: response2.headers }
|
|
3220
|
-
),
|
|
3327
|
+
), json2 = result2.json.bind(result2);
|
|
3221
3328
|
return result2.json = async () => {
|
|
3222
|
-
let value = await
|
|
3329
|
+
let value = await json2();
|
|
3223
3330
|
return (!guard.current(revision) || request2 && !request2.current()) && rejectStale(), value && typeof value.access_token == "string" && provenance.set(value.access_token, revision), value;
|
|
3224
3331
|
}, result2;
|
|
3225
3332
|
}, { preconnect: fetch.preconnect })
|
|
@@ -3270,6 +3377,22 @@ async function provider(configuration, guard) {
|
|
|
3270
3377
|
}
|
|
3271
3378
|
var auth = /* @__PURE__ */ createBrowserAuth({ provider, failure: (reason) => new BrowserAuthError(reason) });
|
|
3272
3379
|
|
|
3380
|
+
function routineRunHandle(operations2) {
|
|
3381
|
+
return Object.freeze({
|
|
3382
|
+
current: operations2.current,
|
|
3383
|
+
step: operations2.step,
|
|
3384
|
+
...operations2.publish ? { publish: operations2.publish } : {},
|
|
3385
|
+
async *watch() {
|
|
3386
|
+
let previous;
|
|
3387
|
+
for (; ; ) {
|
|
3388
|
+
let state = await operations2.current(), encoded = JSON.stringify(state);
|
|
3389
|
+
if (encoded !== previous && (previous = encoded, yield state), state.status === "succeeded" || state.status === "failed") return;
|
|
3390
|
+
await (operations2.wait?.() ?? new Promise((resolve) => setTimeout(resolve, 100)));
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
});
|
|
3394
|
+
}
|
|
3395
|
+
|
|
3273
3396
|
var identifier = /^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/, uuid = /^[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 {
|
|
3274
3397
|
constructor(reason) {
|
|
3275
3398
|
super(reason);
|
|
@@ -3286,16 +3409,16 @@ function current(context2) {
|
|
|
3286
3409
|
function appDescriptors() {
|
|
3287
3410
|
return globalThis[/* @__PURE__ */ Symbol.for("oddington.app.descriptor")]?.routines ?? [];
|
|
3288
3411
|
}
|
|
3289
|
-
async function
|
|
3290
|
-
let context2 = await resolveAppContext().catch(() => fail3("authority_unavailable"));
|
|
3412
|
+
async function local2(retained = !1) {
|
|
3413
|
+
let context2 = await resolveAppContext(retained).catch(() => fail3("authority_unavailable"));
|
|
3291
3414
|
return context2.kind !== "local" ? fail3("execution_unavailable") : (current(context2), context2);
|
|
3292
3415
|
}
|
|
3293
|
-
async function request(key, suffix, init2, maximum = SUMMARY_BYTES, retained) {
|
|
3416
|
+
async function request(key, suffix, init2, maximum = SUMMARY_BYTES, retained, read2 = !1) {
|
|
3294
3417
|
(!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable");
|
|
3295
|
-
let context2 = retained ?? await
|
|
3418
|
+
let context2 = retained ?? await local2(read2);
|
|
3296
3419
|
current(context2);
|
|
3297
3420
|
try {
|
|
3298
|
-
let response2 = await context2.requestRoutine(key, suffix, init2), value = await appResponse(response2, maximum, context2.signal);
|
|
3421
|
+
let response2 = await (read2 ? context2.requestRetainedRoutine(key, suffix) : context2.requestRoutine(key, suffix, init2)), value = await appResponse(response2, maximum, context2.signal);
|
|
3299
3422
|
if (current(context2), !response2.ok) {
|
|
3300
3423
|
let reason = value?.error;
|
|
3301
3424
|
reason === "authority_unavailable" && (context2.invalidate(), fail3(reason)), (reason === "invalid_input" || reason === "execution_unavailable") && fail3(reason), fail3("execution_unavailable");
|
|
@@ -3341,21 +3464,15 @@ function structure(value) {
|
|
|
3341
3464
|
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);
|
|
3342
3465
|
}
|
|
3343
3466
|
function handle(key, id3, context2) {
|
|
3344
|
-
(typeof id3 != "string" || !uuid.test(id3)) && fail3("invalid_input");
|
|
3345
|
-
let read2 = async () => summary(await request(key, `runs/${id3}`, void 0, SUMMARY_BYTES, context2), key, id3);
|
|
3346
|
-
return
|
|
3347
|
-
current
|
|
3348
|
-
|
|
3349
|
-
let previous;
|
|
3350
|
-
for (; ; ) {
|
|
3351
|
-
let state = await read2(), encoded = JSON.stringify(state);
|
|
3352
|
-
if (encoded !== previous && (previous = encoded, yield state), state.status === "succeeded" || state.status === "failed") return;
|
|
3353
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
3354
|
-
}
|
|
3467
|
+
(!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable"), (typeof id3 != "string" || !uuid.test(id3)) && fail3("invalid_input");
|
|
3468
|
+
let read2 = async () => summary(await request(key, `runs/${id3}`, void 0, SUMMARY_BYTES, context2, !0), key, id3);
|
|
3469
|
+
return routineRunHandle({
|
|
3470
|
+
async current() {
|
|
3471
|
+
return current(context2), read2();
|
|
3355
3472
|
},
|
|
3356
3473
|
async step(step) {
|
|
3357
3474
|
(typeof step != "string" || !identifier.test(step)) && fail3("invalid_input");
|
|
3358
|
-
let value = await request(key, `runs/${id3}/steps/${step}`, void 0, 514 * 1024, context2);
|
|
3475
|
+
let value = await request(key, `runs/${id3}/steps/${step}`, void 0, 514 * 1024, context2, !0);
|
|
3359
3476
|
return (!only(value, "id,title,status,startedAt,finishedAt,summary,data") || value.id !== step || !validStep(value)) && fail3("execution_unavailable"), value;
|
|
3360
3477
|
},
|
|
3361
3478
|
async publish() {
|
|
@@ -3394,19 +3511,18 @@ function appRoutineBinding(key) {
|
|
|
3394
3511
|
} catch {
|
|
3395
3512
|
return fail3("invalid_input");
|
|
3396
3513
|
}
|
|
3397
|
-
let context2 = await
|
|
3514
|
+
let context2 = await local2(), run = summary(await request(key, "runs", { method: "POST", body: encoded }, SUMMARY_BYTES, context2), key);
|
|
3398
3515
|
return handle(key, run.id, context2);
|
|
3399
3516
|
},
|
|
3400
3517
|
runs: Object.freeze({
|
|
3401
3518
|
async list() {
|
|
3402
|
-
let value = await request(key, "runs", void 0, 20 * SUMMARY_BYTES);
|
|
3519
|
+
let value = await request(key, "runs", void 0, 20 * SUMMARY_BYTES, void 0, !0);
|
|
3403
3520
|
if (!Array.isArray(value) || value.length > 20) return fail3("execution_unavailable");
|
|
3404
3521
|
let runs = value.map((run) => summary(run, key));
|
|
3405
3522
|
return new Set(runs.map((run) => run.id)).size !== runs.length && fail3("execution_unavailable"), runs;
|
|
3406
3523
|
},
|
|
3407
3524
|
async get(id3) {
|
|
3408
|
-
|
|
3409
|
-
return await run.current(), run;
|
|
3525
|
+
return (typeof id3 != "string" || !uuid.test(id3)) && fail3("invalid_input"), (!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable"), handle(key, id3, await local2(!0));
|
|
3410
3526
|
}
|
|
3411
3527
|
})
|
|
3412
3528
|
});
|
|
@@ -3453,7 +3569,7 @@ function routineDataEnvelope(command) {
|
|
|
3453
3569
|
}
|
|
3454
3570
|
|
|
3455
3571
|
function routinePublicationClient2(options = {}) {
|
|
3456
|
-
let environment = {}, installed2 = routineTransport(),
|
|
3572
|
+
let environment = {}, installed2 = routineTransport(), local3 = installed2?.request ?? void 0, workspace = installed2 ? "installed" : options.workspace ?? environment.ODDINGTON_ROUTINE_WORKSPACE, capability = options.capability ?? environment.ODDINGTON_ROUTINE_RUN;
|
|
3457
3573
|
if (!workspace || !/^[a-z0-9][a-z0-9-]*$/.test(workspace) || capability !== void 0 && !/^[0-9a-f]{64}$/.test(capability))
|
|
3458
3574
|
throw new Error("A workspace and valid optional routine capability are required");
|
|
3459
3575
|
let workingRoot = options.workingRoot ?? environment.ODDINGTON_INBOX_WORKING_ROOT ?? void 0, headers = capability ? { "x-oddington-run": capability } : {}, request2 = options.request ?? (capability ? async (path, init2) => {
|
|
@@ -3466,7 +3582,7 @@ function routinePublicationClient2(options = {}) {
|
|
|
3466
3582
|
throw new Error("Member publication requires a host-supplied request");
|
|
3467
3583
|
});
|
|
3468
3584
|
async function send3(operation2, body) {
|
|
3469
|
-
if (
|
|
3585
|
+
if (local3) return await local3(operation2, body);
|
|
3470
3586
|
let writing = operation2 === "records/update", reading = operation2 === "records/read", response2 = await request2(writing || reading ? "/api/data" : `/api/inbox/${operation2}`, {
|
|
3471
3587
|
method: "POST",
|
|
3472
3588
|
headers: {
|
|
@@ -3513,7 +3629,7 @@ function routinePublicationClient2(options = {}) {
|
|
|
3513
3629
|
files: {
|
|
3514
3630
|
async add(value) {
|
|
3515
3631
|
let input = validateFileAddOptions(value);
|
|
3516
|
-
if (
|
|
3632
|
+
if (local3) return validateInboxFile(await local3("files/add", input));
|
|
3517
3633
|
throw workingRoot ? new Error("Inbox file reads require a Node working root") : new Error("Inbox file reads require a working root");
|
|
3518
3634
|
}
|
|
3519
3635
|
},
|