@oddington/sdk 0.1.27 → 0.1.29

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