@oddington/sdk 0.1.20 → 0.1.22

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
@@ -1,10 +1,10 @@
1
1
  var InboxContractError = class extends Error {
2
- constructor(message) {
3
- super(message), this.name = "InboxContractError";
2
+ constructor(message2) {
3
+ super(message2), this.name = "InboxContractError";
4
4
  }
5
5
  };
6
- function fail(message) {
7
- throw new InboxContractError(message);
6
+ function fail(message2) {
7
+ throw new InboxContractError(message2);
8
8
  }
9
9
  function object(value, label) {
10
10
  return (!value || typeof value != "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) && fail(`${label} must be a plain object`), value;
@@ -12,8 +12,8 @@ function object(value, label) {
12
12
  function keys(value, allowed, label) {
13
13
  for (let key of Reflect.ownKeys(value)) {
14
14
  (typeof key != "string" || !allowed.includes(key)) && fail(`${label} does not support ${String(key)}`);
15
- let descriptor2 = Object.getOwnPropertyDescriptor(value, key);
16
- (!descriptor2.enumerable || !("value" in descriptor2)) && fail(`${label} must contain only JSON data`);
15
+ let descriptor = Object.getOwnPropertyDescriptor(value, key);
16
+ (!descriptor.enumerable || !("value" in descriptor)) && fail(`${label} must contain only JSON data`);
17
17
  }
18
18
  }
19
19
  function text(value, label) {
@@ -26,8 +26,8 @@ function id(value, label) {
26
26
  function array(value, label) {
27
27
  (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || Reflect.ownKeys(value).length !== value.length + 1) && fail(`${label} must be a dense array`);
28
28
  for (let index = 0; index < value.length; index += 1) {
29
- let descriptor2 = Object.getOwnPropertyDescriptor(value, String(index));
30
- (!descriptor2?.enumerable || !("value" in descriptor2)) && fail(`${label} must contain only JSON data`);
29
+ let descriptor = Object.getOwnPropertyDescriptor(value, String(index));
30
+ (!descriptor?.enumerable || !("value" in descriptor)) && fail(`${label} must contain only JSON data`);
31
31
  }
32
32
  return value;
33
33
  }
@@ -268,12 +268,12 @@ function presentation(source) {
268
268
  return keys(view, ["id", "view", "input"], "view"), { id: id(view.id, "view ID"), view: id(view.view, "view name"), input: serializable(view.input) };
269
269
  });
270
270
  new Set(views.map((view) => view.id)).size !== views.length && fail("Duplicate view ID");
271
- let body2 = source.body === void 0 ? [] : array(source.body, "body").map(validateBlock);
272
- for (let block2 of body2) {
271
+ let body = source.body === void 0 ? [] : array(source.body, "body").map(validateBlock);
272
+ for (let block2 of body) {
273
273
  let targets = block2.kind === "record" ? [block2.view] : block2.kind === "records" ? [block2.view, ...block2.records.map((record3) => record3.view)] : [];
274
274
  for (let target of targets) target !== void 0 && !views.some((view) => view.id === target) && fail(`Unknown Block View target: ${target}`);
275
275
  }
276
- return { title: text(source.title, "title"), description: text(source.description, "description"), views, body: body2 };
276
+ return { title: text(source.title, "title"), description: text(source.description, "description"), views, body };
277
277
  }
278
278
  function validatePublication(value) {
279
279
  let source = object(value, "publication");
@@ -391,44 +391,44 @@ var FileOperationError = class extends Error {
391
391
  retryable;
392
392
  }, 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
393
  function parseFileDescriptor(value) {
394
- let invalid5 = () => {
394
+ let invalid7 = () => {
395
395
  throw new FileOperationError("unavailable", 503, !0);
396
396
  };
397
- if (!value || typeof value != "object" || Array.isArray(value)) return invalid5();
397
+ if (!value || typeof value != "object" || Array.isArray(value)) return invalid7();
398
398
  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 invalid5();
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 invalid7();
400
400
  let d = f.details;
401
401
  if (d.kind === "other") {
402
- if (Object.keys(d).length !== 1 || f.mediaType !== "application/octet-stream") return invalid5();
402
+ if (Object.keys(d).length !== 1 || f.mediaType !== "application/octet-stream") return invalid7();
403
403
  } 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 invalid5();
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 invalid7();
405
405
  } 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 invalid5();
407
- } else return invalid5();
408
- for (let [name, descriptor2] of Object.entries(f.enrichments)) {
409
- if (!safeEnrichmentName(name)) return invalid5();
410
- parseEnrichmentDescriptor(descriptor2);
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 invalid7();
407
+ } else return invalid7();
408
+ for (let [name, descriptor] of Object.entries(f.enrichments)) {
409
+ if (!safeEnrichmentName(name)) return invalid7();
410
+ parseEnrichmentDescriptor(descriptor);
411
411
  }
412
- return new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024 ? invalid5() : f;
412
+ return new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024 ? invalid7() : f;
413
413
  }
414
414
  function parseEnrichmentDescriptor(value) {
415
- let invalid5 = () => {
415
+ let invalid7 = () => {
416
416
  throw new FileOperationError("unavailable", 503, !0);
417
417
  };
418
- if (!value || typeof value != "object" || Array.isArray(value)) return invalid5();
418
+ if (!value || typeof value != "object" || Array.isArray(value)) return invalid7();
419
419
  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) ? invalid5() : d;
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) ? invalid7() : d;
421
421
  }
422
422
  function safeEnrichmentName(value) {
423
423
  return safeFileName(value) && !/^original(?:\.|$)/i.test(value);
424
424
  }
425
425
  function parseFileEnrichMetadata(value, maxBytes) {
426
- let invalid5 = () => {
426
+ let invalid7 = () => {
427
427
  throw new FileOperationError("invalid_input", 400);
428
428
  };
429
- if (!value || typeof value != "object" || Array.isArray(value)) return invalid5();
429
+ if (!value || typeof value != "object" || Array.isArray(value)) return invalid7();
430
430
  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 invalid5();
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 invalid7();
432
432
  if (d.size > maxBytes) throw new FileOperationError("request_too_large", 413);
433
433
  return d;
434
434
  }
@@ -439,23 +439,23 @@ function safeFilePath(value) {
439
439
  return typeof value == "string" && value.length <= 1024 && value.split("/").every(safeFileName);
440
440
  }
441
441
  function parseFileCreateMetadata(value, maxBytes) {
442
- let invalid5 = () => {
442
+ let invalid7 = () => {
443
443
  throw new FileOperationError("invalid_input", 400);
444
444
  };
445
- if (!value || typeof value != "object" || Array.isArray(value)) return invalid5();
445
+ if (!value || typeof value != "object" || Array.isArray(value)) return invalid7();
446
446
  let input = value;
447
- if (Object.keys(input).some((key) => !["name", "path", "storage", "csv", "inputMediaType", "size", "requestKey"].includes(key))) return invalid5();
447
+ if (Object.keys(input).some((key) => !["name", "path", "storage", "csv", "inputMediaType", "size", "requestKey"].includes(key))) return invalid7();
448
448
  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 invalid5();
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 invalid7();
450
450
  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 invalid5();
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 invalid7();
452
452
  let csv;
453
453
  if (input.csv !== void 0) {
454
- if (!input.csv || typeof input.csv != "object" || Array.isArray(input.csv)) return invalid5();
454
+ if (!input.csv || typeof input.csv != "object" || Array.isArray(input.csv)) return invalid7();
455
455
  let hints = input.csv;
456
- if (Object.keys(hints).some((key) => !["encoding", "delimiter", "headerRow"].includes(key))) return invalid5();
456
+ if (Object.keys(hints).some((key) => !["encoding", "delimiter", "headerRow"].includes(key))) return invalid7();
457
457
  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 invalid5();
458
+ if (encoding !== "utf-8" && encoding !== "windows-1252" || ![",", ";", " "].includes(delimiter) || !Number.isSafeInteger(headerRow) || headerRow < 1 || headerRow > 1e5) return invalid7();
459
459
  csv = { encoding, delimiter, headerRow };
460
460
  }
461
461
  return {
@@ -572,54 +572,137 @@ function validateRoutineSchemaValue(schema2, value) {
572
572
  }
573
573
  }
574
574
 
575
- var LIMIT = 256 * 1024, invalid = () => {
575
+ var ROUTINE_DECLARATION_SCHEMA = "https://schemas.oddington.ai/routine/v1.json", ROUTINE_SOURCE_LIMITS = { files: 2e4, bytes: 256 * 1024 * 1024, declarationBytes: 64 * 1024 };
576
+ var invalid = (field) => {
577
+ throw new Error(`Invalid routine declaration: ${field}`);
578
+ }, 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
+ function routineAssetPattern(value) {
580
+ 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
+ }
582
+ function parseRoutineDeclaration(value) {
583
+ let v = object2(value, ["$schema", "access", "runtime", "retry", "assets"], "fields");
584
+ v.$schema !== ROUTINE_DECLARATION_SCHEMA && invalid("$schema");
585
+ let access = object2(v.access === void 0 ? {} : v.access, ["repositories", "connections", "models", "files", "publish"], "access"), rawRepositories = access.repositories === void 0 ? {} : access.repositories, repositories = object2(rawRepositories, rawRepositories && typeof rawRepositories == "object" ? Object.keys(rawRepositories) : [], "access.repositories");
586
+ Object.keys(repositories).length > 64 && invalid("access.repositories");
587
+ let grants = {};
588
+ for (let key of Object.keys(repositories).sort())
589
+ (!routineAlias(key) || !["read", "write"].includes(repositories[key])) && invalid(`access.repositories.${key}`), grants[key] = repositories[key];
590
+ access.files !== void 0 && !["read", "read-write"].includes(access.files) && invalid("access.files");
591
+ let runtime = object2(v.runtime === void 0 ? {} : v.runtime, ["features", "resources", "maxDuration"], "runtime");
592
+ runtime.resources !== void 0 && !["standard", "large"].includes(runtime.resources) && invalid("runtime.resources");
593
+ let duration = runtime.maxDuration === void 0 ? "15m" : runtime.maxDuration;
594
+ (typeof duration != "string" || !/^(?:[1-5][0-9]|60)m$/.test(duration) || Number(duration.slice(0, -1)) < 15) && invalid("runtime.maxDuration");
595
+ let retry = object2(v.retry === void 0 ? {} : v.retry, ["maxAttempts"], "retry"), maxAttempts = retry.maxAttempts === void 0 ? 1 : retry.maxAttempts;
596
+ (!Number.isInteger(maxAttempts) || maxAttempts < 1 || maxAttempts > 3) && invalid("retry.maxAttempts");
597
+ let assets = v.assets === void 0 ? [] : v.assets;
598
+ return (!Array.isArray(assets) || assets.length > 64 || assets.some((item) => !routineAssetPattern(item)) || new Set(assets).size !== assets.length) && invalid("assets"), {
599
+ $schema: ROUTINE_DECLARATION_SCHEMA,
600
+ access: {
601
+ repositories: grants,
602
+ connections: list(access.connections, "access.connections", void 0, !0),
603
+ models: list(access.models, "access.models"),
604
+ ...access.files === void 0 ? {} : { files: access.files },
605
+ publish: list(access.publish, "access.publish", ["asks", "digests"])
606
+ },
607
+ runtime: {
608
+ features: list(runtime.features, "runtime.features", ["python", "documents", "browser"]),
609
+ resources: runtime.resources ?? "standard",
610
+ maxDuration: duration
611
+ },
612
+ retry: { maxAttempts },
613
+ assets: [...assets].sort()
614
+ };
615
+ }
616
+
617
+ var invalid2 = () => {
576
618
  throw new AppRoutineContractError("invalid_value");
577
619
  }, invalidContract2 = () => {
578
620
  throw new AppRoutineContractError("invalid_contract");
579
- }, empty = { type: "object", properties: {}, required: [], additionalProperties: !1 };
580
- function freeze(value) {
621
+ }, routineTitle = (value) => typeof value == "string" && value.trim().length > 0 && value.length <= 256;
622
+ function freezeRoutineMetadata(value) {
581
623
  if (value !== null && typeof value == "object") {
582
- for (let child of Object.values(value)) freeze(child);
624
+ for (let child of Object.values(value)) freezeRoutineMetadata(child);
583
625
  Object.freeze(value);
584
626
  }
585
627
  return value;
586
628
  }
587
- function json(value, ancestors = /* @__PURE__ */ new Set()) {
629
+ function assertRoutineJson(value, ancestors = /* @__PURE__ */ new Set()) {
588
630
  if (value === null || typeof value == "string" || typeof value == "boolean" || typeof value == "number" && Number.isFinite(value)) return;
589
- if (!value || typeof value != "object" || ancestors.has(value)) return invalid();
631
+ if (!value || typeof value != "object" || ancestors.has(value)) return invalid2();
590
632
  let array3 = Array.isArray(value);
591
- if (!array3 && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) return invalid();
592
- let keys5 = Reflect.ownKeys(value);
593
- if (array3 && (keys5.length !== value.length + 1 || !Array.from({ length: value.length }, (_, index) => Object.hasOwn(value, index)).every(Boolean))) return invalid();
633
+ if (!array3 && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) return invalid2();
634
+ let keys4 = Reflect.ownKeys(value);
635
+ if (array3 && (keys4.length !== value.length + 1 || !Array.from({ length: value.length }, (_, index) => Object.hasOwn(value, index)).every(Boolean))) return invalid2();
594
636
  ancestors.add(value);
595
- for (let key of keys5) {
637
+ for (let key of keys4) {
596
638
  if (array3 && key === "length") continue;
597
- if (typeof key != "string") return invalid();
598
- let descriptor2 = Object.getOwnPropertyDescriptor(value, key);
599
- if (!descriptor2.enumerable || !Object.hasOwn(descriptor2, "value")) return invalid();
600
- json(descriptor2.value, ancestors);
639
+ if (typeof key != "string") return invalid2();
640
+ let descriptor = Object.getOwnPropertyDescriptor(value, key);
641
+ if (!descriptor.enumerable || !Object.hasOwn(descriptor, "value")) return invalid2();
642
+ assertRoutineJson(descriptor.value, ancestors);
601
643
  }
602
644
  ancestors.delete(value);
603
645
  }
604
- function capture(schema2, value) {
605
- json(value), validateRoutineSchemaValue(schema2, value);
606
- let encoded = JSON.stringify(value);
607
- return new TextEncoder().encode(encoded).byteLength > LIMIT ? invalid() : freeze(JSON.parse(encoded));
646
+ function assertRoutineFields(value, allowed) {
647
+ 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();
608
648
  }
609
- function declaration(value) {
649
+ function parseRoutineAccess(value) {
610
650
  try {
611
- json(value);
651
+ value !== void 0 && assertRoutineJson(value), assertRoutineFields(value ?? {}, ["repositories", "connections", "models", "files", "publish"]);
652
+ let access = value, names = access?.connections ?? [];
653
+ 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();
654
+ let parsed = parseRoutineDeclaration({ $schema: ROUTINE_DECLARATION_SCHEMA, access: { ...access, connections: [] } }).access;
655
+ return freezeRoutineMetadata({ ...parsed, connections: [...names] });
612
656
  } catch {
613
657
  return invalidContract2();
614
658
  }
615
- return freeze(parseAppRoutineContract({ routine: "definition", input: value, steps: [{ id: "inspect" }] }).input);
659
+ }
660
+
661
+ var LIMIT = 256 * 1024, invalid3 = () => {
662
+ throw new AppRoutineContractError("invalid_value");
663
+ }, invalidContract3 = () => {
664
+ throw new AppRoutineContractError("invalid_contract");
665
+ }, empty = { type: "object", properties: {}, required: [], additionalProperties: !1 };
666
+ function captureJson(value) {
667
+ assertRoutineJson(value);
668
+ let encoded = JSON.stringify(value);
669
+ return new TextEncoder().encode(encoded).byteLength > LIMIT ? invalid3() : freezeRoutineMetadata(JSON.parse(encoded));
670
+ }
671
+ function capture(schema2, value) {
672
+ let captured = captureJson(value);
673
+ return validateRoutineSchemaValue(schema2, captured), captured;
674
+ }
675
+ var schemas = /* @__PURE__ */ new WeakMap();
676
+ function nestedSchema(value) {
677
+ let metadata = schemaMetadata(value);
678
+ return Object.hasOwn(metadata, "default") ? invalidContract3() : metadata.schema;
679
+ }
680
+ function schemaMetadata(value) {
681
+ if (!value || typeof value != "object") return invalidContract3();
682
+ let registered = schemas.get(value);
683
+ if (registered) return registered;
684
+ try {
685
+ assertRoutineJson(value);
686
+ } catch {
687
+ return invalidContract3();
688
+ }
689
+ return { schema: parseAppRoutineContract({ routine: "definition", input: value, steps: [{ id: "inspect" }] }).input };
690
+ }
691
+ function declaration(value, defaults) {
692
+ try {
693
+ assertRoutineJson(value);
694
+ } catch {
695
+ return invalidContract3();
696
+ }
697
+ 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 }) });
698
+ return schemas.set(builder, { schema: parsed, ...defaults ? { default: captured } : {} }), Object.freeze(builder);
616
699
  }
617
700
  var schema = {
618
701
  object(properties) {
619
- return declaration({ type: "object", properties, required: Object.keys(properties), additionalProperties: !1 });
702
+ return declaration({ type: "object", properties: Object.fromEntries(Object.entries(properties).map(([key, value]) => [key, nestedSchema(value)])), required: Object.keys(properties), additionalProperties: !1 });
620
703
  },
621
704
  array(items, options) {
622
- return declaration({ type: "array", items, maxItems: options.maxItems });
705
+ return declaration({ type: "array", items: nestedSchema(items), maxItems: options.maxItems });
623
706
  },
624
707
  string(options = {}) {
625
708
  return declaration({ type: "string", ...options });
@@ -634,75 +717,123 @@ var schema = {
634
717
  return declaration({ type: "boolean" });
635
718
  }
636
719
  }, file = () => declaration({ type: "file" }), definitions = /* @__PURE__ */ new WeakMap(), defineRoutine = (definition) => {
637
- if (!definition || typeof definition != "object" || Object.getPrototypeOf(definition) !== Object.prototype || Reflect.ownKeys(definition).some((key) => typeof key != "string" || !["input", "steps", "result", "run"].includes(key) || !Object.getOwnPropertyDescriptor(definition, key).enumerable || !Object.hasOwn(Object.getOwnPropertyDescriptor(definition, key), "value")) || typeof definition.run != "function") return invalidContract2();
638
- try {
639
- for (let key of ["input", "steps", "result"])
640
- definition[key] !== void 0 && json(definition[key]);
641
- } catch {
642
- return invalidContract2();
720
+ 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();
721
+ 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);
722
+ assertRoutineFields(definition.steps ?? {});
723
+ 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 }));
724
+ parseAppRoutineContract({
725
+ routine: definition.id,
726
+ input: input.schema,
727
+ steps: steps.length ? steps.map(({ id: id3 }) => ({ id: id3 })) : [{ id: "inspect" }],
728
+ ...result2 ? { result: result2 } : {}
729
+ });
730
+ let responses = [], ids = /* @__PURE__ */ new Set();
731
+ if (definition.responses !== void 0) {
732
+ if (!Array.isArray(definition.responses) || definition.responses.length > 64 || Reflect.ownKeys(definition.responses).length !== definition.responses.length + 1) return invalidContract3();
733
+ for (let index = 0; index < definition.responses.length; index++) {
734
+ let descriptor = Object.getOwnPropertyDescriptor(definition.responses, String(index));
735
+ if (!descriptor || !Object.hasOwn(descriptor, "value")) return invalidContract3();
736
+ let response2 = descriptor.value;
737
+ if (assertRoutineFields(response2, ["id", "results", "run"]), !isAppRoutineName(response2.id) || ids.has(response2.id)) return invalidContract3();
738
+ if (ids.add(response2.id), response2.results !== void 0)
739
+ try {
740
+ assertRoutineJson(response2.results);
741
+ } catch {
742
+ return invalidContract3();
743
+ }
744
+ try {
745
+ responses.push(defineHandler(response2));
746
+ } catch {
747
+ return invalidContract3();
748
+ }
749
+ }
643
750
  }
644
- if (definition.steps !== void 0 && (!definition.steps || typeof definition.steps != "object" || Array.isArray(definition.steps))) return invalidContract2();
645
- let steps = definition.steps === void 0 ? [] : Object.entries(definition.steps).map(([id3, summary]) => ({ id: id3, ...summary === null ? {} : { summary } })), parsed = parseAppRoutineContract({
646
- routine: "definition",
647
- input: definition.input === void 0 ? empty : definition.input,
648
- steps: steps.length ? steps : [{ id: "inspect" }],
649
- ...definition.result === void 0 ? {} : { result: definition.result }
650
- }), contract = freeze({
651
- input: parsed.input,
652
- steps: steps.length ? parsed.steps : [],
653
- ...parsed.result === void 0 ? {} : { result: parsed.result }
751
+ let contract = freezeRoutineMetadata({
752
+ id: definition.id,
753
+ ...definition.title === void 0 ? {} : { title: definition.title },
754
+ input: input.schema,
755
+ ...Object.hasOwn(input, "default") ? { inputDefault: input.default } : {},
756
+ access,
757
+ responses: responses.map(({ id: id3 }) => ({ id: id3 })),
758
+ steps,
759
+ ...result2 ? { result: result2 } : {}
654
760
  }), captured = Object.freeze({
655
761
  ...definition,
656
- ...definition.input === void 0 ? {} : { input: contract.input },
657
- ...definition.steps === void 0 ? {} : { steps: freeze(Object.fromEntries(contract.steps.map((step) => [step.id, step.summary ?? null]))) },
658
- ...definition.result === void 0 ? {} : { result: contract.result },
762
+ access,
763
+ steps: Object.freeze(executable),
764
+ responses: Object.freeze(responses),
765
+ ...definition.input === void 0 ? {} : { input: declaration(
766
+ input.schema,
767
+ Object.hasOwn(input, "default") ? { value: input.default } : void 0
768
+ ) },
769
+ ...result2 === void 0 ? {} : { result: declaration(result2) },
659
770
  // Only this authored definition is callable; no generic runner is exported.
660
- run: (input, os2) => executeRoutineDefinition(captured, input, os2)
771
+ run: (input2, os2) => executeRoutineDefinition(captured, input2, os2)
661
772
  });
662
- return definitions.set(captured, { contract, run: definition.run }), captured;
773
+ return definitions.set(captured, { contract, steps: executable, run: definition.run }), captured;
663
774
  };
664
775
  function inspectRoutineDefinition(definition) {
665
- if (!definition || typeof definition != "object") return invalidContract2();
776
+ if (!definition || typeof definition != "object") return invalidContract3();
666
777
  let registered = definitions.get(definition);
667
- return registered ? registered.contract : invalidContract2();
778
+ return registered ? registered.contract : invalidContract3();
668
779
  }
669
780
  function captureRoutineInput(definition, input) {
670
- return capture(inspectRoutineDefinition(definition).input, input);
781
+ let contract = inspectRoutineDefinition(definition);
782
+ return capture(contract.input, input === void 0 && Object.hasOwn(contract, "inputDefault") ? contract.inputDefault : input);
671
783
  }
672
784
  async function executeRoutineDefinition(definition, input, runtime) {
673
- let captured = captureRoutineInput(definition, input), { contract, run } = definitions.get(definition), active2 = !0, broken = !1, reports = Promise.resolve(), os2 = Object.freeze({
674
- ...runtime,
675
- run: freeze({ ...runtime.run }),
676
- async artifact(input2) {
677
- if (!active2) throw new Error("Run authority ended");
678
- if (!runtime.artifact) throw new Error("Run artifact transport unavailable");
679
- return runtime.artifact(input2);
680
- },
681
- step(id3, ...summary) {
682
- if (!active2 || broken || summary.length > 1)
683
- return broken = !0, Promise.reject(new AppRoutineContractError("invalid_value"));
684
- let value;
785
+ let captured = captureRoutineInput(definition, input), { contract, steps, run } = definitions.get(definition), active2 = !0, accepting = !0, broken = !1, work = Promise.resolve(), called = /* @__PURE__ */ new Set(), reached = /* @__PURE__ */ new Set(), guarded = (value, receiver) => typeof value == "function" ? (...args) => {
786
+ if (!active2 || broken) throw new Error("Run authority ended");
787
+ return guarded(Reflect.apply(value, receiver, args));
788
+ } : value && typeof value == "object" && !(value instanceof Promise) ? new Proxy({ ...value }, {
789
+ // Copy the surface so wrapping a frozen host capability does not violate
790
+ // Proxy invariants; methods still receive their original host receiver.
791
+ get(_target, key) {
792
+ return guarded(Reflect.get(value, key, value), value);
793
+ }
794
+ }) : 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({
795
+ ...guarded({
796
+ ...runtime,
797
+ run: freezeRoutineMetadata({ ...runtime.run }),
798
+ inbox: { ...runtime.inbox, publishAsk: (value, options) => runtime.inbox.publishAsk(qualify(value), options) }
799
+ }),
800
+ step(id3, ...input2) {
801
+ let saved;
685
802
  try {
686
- let step = contract.steps.find((step2) => step2.id === id3);
687
- if (!step) return invalid();
688
- if (step.summary === void 0) {
689
- if (summary.length) return invalid();
690
- } else value = capture(step.summary, summary[0]);
803
+ if (!active2 || !accepting || broken || !Object.hasOwn(steps, id3) || called.has(id3) || input2.length > 1) return invalid3();
804
+ input2.length && (saved = captureJson(input2[0])), called.add(id3);
691
805
  } catch (error) {
692
806
  return broken = !0, Promise.reject(error);
693
807
  }
694
- let report = reports.then(() => broken ? invalid() : runtime.step(id3, value));
695
- return reports = report.catch(() => {
808
+ let next = work.then(async () => {
809
+ if (broken) return invalid3();
810
+ reached.add(id3);
811
+ try {
812
+ await runtime.step(id3, { status: "running" });
813
+ let output = await steps[id3].run(saved, os2);
814
+ if (assertRoutineFields(output, ["summary", "data"]), !Object.hasOwn(output, "summary") || !Object.hasOwn(output, "data")) return invalid3();
815
+ let summary2 = captureJson(output.summary), data3 = captureJson(output.data);
816
+ return await runtime.step(id3, { status: "completed", summary: summary2, data: data3 }), freezeRoutineMetadata({ summary: summary2, data: data3 });
817
+ } catch (error) {
818
+ throw broken = !0, await runtime.step(id3, { status: "failed" }), error;
819
+ }
820
+ });
821
+ return work = next.then(() => {
822
+ }, () => {
696
823
  broken = !0;
697
- }), report;
824
+ }), next;
698
825
  }
699
- });
826
+ }), result2, failure;
700
827
  try {
701
- let result2 = await run(captured, os2);
702
- return active2 = !1, await reports, broken ? invalid() : contract.result !== void 0 ? capture(contract.result, result2) : result2 !== void 0 ? invalid() : void 0;
703
- } finally {
704
- active2 = !1;
828
+ result2 = await run(captured, os2);
829
+ } catch (error) {
830
+ failure = error, broken = !0;
705
831
  }
832
+ accepting = !1, await work, active2 = !1;
833
+ for (let step of contract.steps) reached.has(step.id) || await runtime.step(step.id, { status: "skipped" });
834
+ if (broken) throw failure ?? new AppRoutineContractError("invalid_value");
835
+ if (contract.result !== void 0) return capture(contract.result, result2);
836
+ if (result2 !== void 0) return invalid3();
706
837
  }
707
838
 
708
839
  var DataOperationError = class extends Error {
@@ -720,46 +851,46 @@ var DataOperationError = class extends Error {
720
851
  component;
721
852
  };
722
853
 
723
- var invalid2 = () => {
854
+ var invalid4 = () => {
724
855
  throw new DataOperationError("invalid_query");
725
856
  }, historyText = (value) => typeof value == "string" && !/[\u0000\uD800-\uDFFF]/u.test(value);
726
857
  function historyVersion(value) {
727
858
  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);
728
859
  }
729
860
  function historyProperties(value) {
730
- if (!value || typeof value != "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return invalid2();
861
+ if (!value || typeof value != "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return invalid4();
731
862
  let descriptors = Object.getOwnPropertyDescriptors(value);
732
- return Reflect.ownKeys(value).some((key) => typeof key != "string" || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value")) ? invalid2() : descriptors;
863
+ return Reflect.ownKeys(value).some((key) => typeof key != "string" || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value")) ? invalid4() : descriptors;
733
864
  }
734
865
  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);
735
866
  function historyArray(value) {
736
- if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) return invalid2();
867
+ if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) return invalid4();
737
868
  let descriptors = Object.getOwnPropertyDescriptors(value);
738
- if (Reflect.ownKeys(value).length !== value.length + 1) return invalid2();
869
+ if (Reflect.ownKeys(value).length !== value.length + 1) return invalid4();
739
870
  let result2 = [];
740
871
  for (let i = 0; i < value.length; i++) {
741
- let descriptor2 = descriptors[i];
742
- if (!descriptor2?.enumerable || !Object.hasOwn(descriptor2, "value")) return invalid2();
743
- result2.push(descriptor2.value);
872
+ let descriptor = descriptors[i];
873
+ if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value")) return invalid4();
874
+ result2.push(descriptor.value);
744
875
  }
745
876
  return result2;
746
877
  }
747
878
  function captureOptions(value, changes) {
748
879
  if (value === void 0) return {};
749
880
  let descriptors = historyProperties(value), result2 = {}, allowed = changes ? ["collections", "refs", "from", "through", "limit", "after"] : ["limit", "before"];
750
- if (Object.keys(descriptors).some((key) => !allowed.includes(key))) return invalid2();
881
+ if (Object.keys(descriptors).some((key) => !allowed.includes(key))) return invalid4();
751
882
  for (let key of allowed) {
752
883
  if (!Object.hasOwn(descriptors, key)) continue;
753
884
  let scalar = descriptors[key].value;
754
885
  if (key === "collections" || key === "refs") {
755
886
  let values = historyArray(scalar);
756
- if (!values.length || values.length > (key === "collections" ? 16 : 100) || !values.every(key === "collections" ? historyCollection : validRecordRef) || new Set(values).size !== values.length) return invalid2();
887
+ if (!values.length || values.length > (key === "collections" ? 16 : 100) || !values.every(key === "collections" ? historyCollection : validRecordRef) || new Set(values).size !== values.length) return invalid4();
757
888
  result2[key] = values;
758
889
  } else if (key === "limit") {
759
- if (!Number.isInteger(scalar) || scalar < 1 || scalar > (changes ? 500 : 100)) return invalid2();
890
+ if (!Number.isInteger(scalar) || scalar < 1 || scalar > (changes ? 500 : 100)) return invalid4();
760
891
  result2.limit = scalar;
761
892
  } else {
762
- if (!(key === "after" ? historyCursor(scalar) : historyVersion(scalar))) return invalid2();
893
+ if (!(key === "after" ? historyCursor(scalar) : historyVersion(scalar))) return invalid4();
763
894
  result2[key] = scalar;
764
895
  }
765
896
  }
@@ -767,39 +898,39 @@ function captureOptions(value, changes) {
767
898
  }
768
899
  var captureHistoryListOptions = (value) => captureOptions(value, !1), captureHistoryChangesOptions = (value) => captureOptions(value, !0);
769
900
  function captureHistoryInstant(value) {
770
- if (!historyText(value) || value.length > 1024) return invalid2();
901
+ if (!historyText(value) || value.length > 1024) return invalid4();
771
902
  let match = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.\d+)?([Zz]|([+-])(\d{2}):(\d{2}))$/.exec(value);
772
- if (!match) return invalid2();
903
+ if (!match) return invalid4();
773
904
  let [year, month, day, hour, minute, second] = match.slice(1, 7).map(Number), days = new Date(Date.UTC(year, month, 0));
774
- 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 ? invalid2() : value;
905
+ 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;
775
906
  }
776
907
 
777
- var invalid3 = () => {
908
+ var invalid5 = () => {
778
909
  throw new DataOperationError("invalid_query");
779
910
  };
780
911
  function captureRecordsSearchInput(query, options) {
781
- if (!historyText(query)) return invalid3();
912
+ if (!historyText(query)) return invalid5();
782
913
  let length = [...query.trim()].length;
783
- if (length < 1 || length > 256) return invalid3();
914
+ if (length < 1 || length > 256) return invalid5();
784
915
  if (options === void 0) return { query };
785
916
  let descriptors = historyProperties(options);
786
- if (Object.keys(descriptors).some((key) => !["collections", "limit"].includes(key))) return invalid3();
917
+ if (Object.keys(descriptors).some((key) => !["collections", "limit"].includes(key))) return invalid5();
787
918
  let captured = {};
788
919
  if (Object.hasOwn(descriptors, "collections")) {
789
920
  let supplied = descriptors.collections.value;
790
- if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1) return invalid3();
921
+ if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1) return invalid5();
791
922
  let collections = [];
792
923
  for (let index = 0; index < supplied.length; index++) {
793
- let descriptor2 = Object.getOwnPropertyDescriptor(supplied, String(index));
794
- if (!descriptor2?.enumerable || !Object.hasOwn(descriptor2, "value") || !historyText(descriptor2.value)) return invalid3();
795
- collections.push(descriptor2.value);
924
+ let descriptor = Object.getOwnPropertyDescriptor(supplied, String(index));
925
+ if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value") || !historyText(descriptor.value)) return invalid5();
926
+ collections.push(descriptor.value);
796
927
  }
797
- if (new Set(collections).size !== collections.length) return invalid3();
928
+ if (new Set(collections).size !== collections.length) return invalid5();
798
929
  captured.collections = collections;
799
930
  }
800
931
  if (Object.hasOwn(descriptors, "limit")) {
801
932
  let supplied = descriptors.limit.value;
802
- if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100) return invalid3();
933
+ if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100) return invalid5();
803
934
  captured.limit = supplied;
804
935
  }
805
936
  return { query, options: captured };
@@ -1051,7 +1182,7 @@ var data = {
1051
1182
  }
1052
1183
  };
1053
1184
 
1054
- 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, invalid4 = () => new FileOperationError("invalid_input", 400), unavailable = () => new FileOperationError("unavailable", 503, !0), failures = {
1185
+ 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 = {
1055
1186
  400: ["invalid_input", "unsupported_context"],
1056
1187
  401: ["unauthenticated"],
1057
1188
  403: ["access_denied"],
@@ -1068,7 +1199,7 @@ async function boundedBytes(stream, limit) {
1068
1199
  for (; ; ) {
1069
1200
  let { done, value } = await reader.read();
1070
1201
  if (done) break;
1071
- if (!(value instanceof Uint8Array)) throw invalid4();
1202
+ if (!(value instanceof Uint8Array)) throw invalid6();
1072
1203
  if (size += value.byteLength, size > limit) throw new FileOperationError("request_too_large", 413);
1073
1204
  bytes.set(value, size - value.byteLength);
1074
1205
  }
@@ -1119,7 +1250,7 @@ async function hostedContent(url, init2, parent, upstream = fetch) {
1119
1250
  reader?.releaseLock();
1120
1251
  }
1121
1252
  }
1122
- }, body2 = new ReadableStream({
1253
+ }, body = new ReadableStream({
1123
1254
  async pull(controller) {
1124
1255
  try {
1125
1256
  reader ??= source.getReader();
@@ -1133,7 +1264,7 @@ async function hostedContent(url, init2, parent, upstream = fetch) {
1133
1264
  }
1134
1265
  },
1135
1266
  cancel
1136
- }, { highWaterMark: 0 }), wrapped = new Response(body2, { status: response2.status, statusText: response2.statusText, headers: response2.headers });
1267
+ }, { highWaterMark: 0 }), wrapped = new Response(body, { status: response2.status, statusText: response2.statusText, headers: response2.headers });
1137
1268
  for (let key of ["url", "redirected", "type"])
1138
1269
  Object.defineProperty(wrapped, key, { value: response2[key] });
1139
1270
  return wrapped;
@@ -1141,7 +1272,7 @@ async function hostedContent(url, init2, parent, upstream = fetch) {
1141
1272
  throw detach(), delivery.abort(error), error;
1142
1273
  }
1143
1274
  }
1144
- async function send(suffix, init2, descriptor2, initial, parent) {
1275
+ async function send(suffix, init2, descriptor, initial, parent) {
1145
1276
  let original = initial, checkCurrent = (context2 = original) => {
1146
1277
  if (parent?.aborted) throw unavailable();
1147
1278
  if (!original.isCurrent() || context2.url !== original.url) throw new FileOperationError("unsupported_context", 400);
@@ -1152,20 +1283,20 @@ async function send(suffix, init2, descriptor2, initial, parent) {
1152
1283
  checkCurrent(context2);
1153
1284
  try {
1154
1285
  let response2 = await (async () => {
1155
- let url = `${context2.url}${suffix}`, request = {
1286
+ let url = `${context2.url}${suffix}`, request2 = {
1156
1287
  ...init2,
1157
1288
  signal: parent,
1158
1289
  headers: { ...context2.headers, ...init2.headers },
1159
1290
  redirect: "error",
1160
1291
  cache: "no-store"
1161
1292
  };
1162
- return descriptor2 ? fetch(url, request) : hostedContent(url, request, parent);
1293
+ return descriptor ? fetch(url, request2) : hostedContent(url, request2, parent);
1163
1294
  })();
1164
1295
  if (!response2.ok) {
1165
1296
  let value2 = await result(response2), error = value2 && typeof value2 == "object" && "error" in value2 ? value2.error : void 0, received = error && typeof error == "object" && "code" in error ? error.code : void 0, code = failures[response2.status]?.find((code2) => code2 === received);
1166
1297
  throw code ? new FileOperationError(code, response2.status, code === "capacity" || code === "unavailable") : unavailable();
1167
1298
  }
1168
- if (response2.status !== (descriptor2 === 204 ? 204 : 200) || descriptor2 === 204 && response2.body !== null)
1299
+ if (response2.status !== (descriptor === 204 ? 204 : 200) || descriptor === 204 && response2.body !== null)
1169
1300
  throw response2.body?.cancel().catch(() => {
1170
1301
  }), unavailable();
1171
1302
  try {
@@ -1174,13 +1305,13 @@ async function send(suffix, init2, descriptor2, initial, parent) {
1174
1305
  throw response2.body?.cancel().catch(() => {
1175
1306
  }), error;
1176
1307
  }
1177
- if (descriptor2 === 204) return;
1178
- if (!descriptor2) return response2;
1179
- let value = await result(response2, descriptor2 === "control" ? CONTROL_RESULT_BYTES : RESULT_BYTES);
1180
- if (descriptor2 === "control")
1308
+ if (descriptor === 204) return;
1309
+ if (!descriptor) return response2;
1310
+ let value = await result(response2, descriptor === "control" ? CONTROL_RESULT_BYTES : RESULT_BYTES);
1311
+ if (descriptor === "control")
1181
1312
  return checkCurrent(), value;
1182
1313
  let parsed;
1183
- if (descriptor2 === "enrichment") {
1314
+ if (descriptor === "enrichment") {
1184
1315
  if (!value || typeof value != "object" || Array.isArray(value)) throw unavailable();
1185
1316
  let { name, ...metadata } = value;
1186
1317
  if (!safeEnrichmentName(name)) throw unavailable();
@@ -1195,22 +1326,22 @@ async function send(suffix, init2, descriptor2, initial, parent) {
1195
1326
  throw unavailable();
1196
1327
  }
1197
1328
  function idPath(id3) {
1198
- if (typeof id3 != "string" || !FILE_ID_PATTERN.test(id3)) throw invalid4();
1329
+ if (typeof id3 != "string" || !FILE_ID_PATTERN.test(id3)) throw invalid6();
1199
1330
  return `/${id3}`;
1200
1331
  }
1201
1332
  async function multipartCreate(input, metadata, exchange, release = () => {
1202
1333
  active--;
1203
1334
  }, upload) {
1204
- let route = upload ? `${idPath(upload.file.id)}/upload/multipart` : "/multipart", ticket, reader, chunk, offset = 0, receipts = [], pending = /* @__PURE__ */ new Set(), request = (work, timeout = TIMEOUT_MS) => timed((signal) => {
1335
+ let route = upload ? `${idPath(upload.file.id)}/upload/multipart` : "/multipart", ticket, reader, chunk, offset = 0, receipts = [], pending = /* @__PURE__ */ new Set(), request2 = (work, timeout = TIMEOUT_MS) => timed((signal) => {
1205
1336
  let task = work(signal);
1206
1337
  return pending.add(task), task.then(() => pending.delete(task), () => pending.delete(task)), task;
1207
- }, void 0, timeout), control = (body2) => ({
1338
+ }, void 0, timeout), control = (body) => ({
1208
1339
  method: "POST",
1209
1340
  headers: { "content-type": "application/json", ...ticket ? { "x-oddington-transfer": ticket } : {} },
1210
- body: JSON.stringify(body2)
1341
+ body: JSON.stringify(body)
1211
1342
  });
1212
1343
  try {
1213
- let start = await request((signal) => exchange(`${route}/start`, control(upload?.file ?? metadata), "control", signal));
1344
+ let start = await request2((signal) => exchange(`${route}/start`, control(upload?.file ?? metadata), "control", signal));
1214
1345
  if (!start || typeof start != "object" || Array.isArray(start)) throw unavailable();
1215
1346
  let session = start;
1216
1347
  if (Object.keys(session).sort().join(",") !== "partBytes,ticket" || session.partBytes !== PART_BYTES || typeof session.ticket != "string" || !session.ticket || session.ticket.length > 64 * 1024) throw unavailable();
@@ -1218,7 +1349,7 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1218
1349
  let lastProgress = Date.now(), next = async () => {
1219
1350
  try {
1220
1351
  if (Date.now() - lastProgress >= TIMEOUT_MS) throw unavailable();
1221
- let value = await request(() => reader.read(), Math.max(1, TIMEOUT_MS - (Date.now() - lastProgress)));
1352
+ let value = await request2(() => reader.read(), Math.max(1, TIMEOUT_MS - (Date.now() - lastProgress)));
1222
1353
  return value.value?.byteLength && (lastProgress = Date.now()), value;
1223
1354
  } catch (error) {
1224
1355
  throw await reader.cancel(error).catch(() => {
@@ -1230,7 +1361,7 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1230
1361
  if (input.file instanceof Uint8Array) part = input.file.subarray(sent, sent + length).slice();
1231
1362
  else if (input.file instanceof Blob) {
1232
1363
  let slice = input.file.slice(sent, sent + length);
1233
- part = new Uint8Array(await request(() => slice.arrayBuffer()));
1364
+ part = new Uint8Array(await request2(() => slice.arrayBuffer()));
1234
1365
  } else {
1235
1366
  part = new Uint8Array(length);
1236
1367
  let filled = 0;
@@ -1238,20 +1369,20 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1238
1369
  if (!chunk || offset === chunk.byteLength) {
1239
1370
  chunk = void 0, offset = 0;
1240
1371
  let value2 = await next();
1241
- if (value2.done || !(value2.value instanceof Uint8Array) || (chunk = value2.value, chunk.byteLength > metadata.size - sent - filled)) throw invalid4();
1372
+ if (value2.done || !(value2.value instanceof Uint8Array) || (chunk = value2.value, chunk.byteLength > metadata.size - sent - filled)) throw invalid6();
1242
1373
  }
1243
1374
  let take = Math.min(length - filled, chunk.byteLength - offset);
1244
1375
  part.set(chunk.subarray(offset, offset + take), filled), filled += take, offset += take, offset === chunk.byteLength && (chunk = void 0, offset = 0);
1245
1376
  }
1246
1377
  }
1247
- if (part.byteLength !== length) throw invalid4();
1378
+ if (part.byteLength !== length) throw invalid6();
1248
1379
  if (reader && sent + length === metadata.size)
1249
1380
  for (lastProgress = Date.now(); ; ) {
1250
1381
  let value2 = await next();
1251
1382
  if (value2.done) break;
1252
- if (!(value2.value instanceof Uint8Array) || value2.value.byteLength) throw invalid4();
1383
+ if (!(value2.value instanceof Uint8Array) || value2.value.byteLength) throw invalid6();
1253
1384
  }
1254
- let value = await request((signal) => exchange(`${route}/part`, {
1385
+ let value = await request2((signal) => exchange(`${route}/part`, {
1255
1386
  method: "POST",
1256
1387
  headers: { "content-type": "application/octet-stream", "x-oddington-transfer": ticket, "x-oddington-part": String(partNumber) },
1257
1388
  body: part.buffer
@@ -1262,9 +1393,9 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1262
1393
  receipts.push({ partNumber, etag: receipt.etag }), sent += length, lastProgress = Date.now();
1263
1394
  }
1264
1395
  if (upload) for (let name of Object.keys(upload.file.enrichments)) {
1265
- let bytes = await request(() => upload.enrichment(name));
1266
- if (bytes.byteLength !== upload.file.enrichments[name].size || bytes.byteLength > MAX_BYTES) throw invalid4();
1267
- await request((signal) => exchange(`${route}/enrichments/${encodeURIComponent(name)}`, {
1396
+ let bytes = await request2(() => upload.enrichment(name));
1397
+ if (bytes.byteLength !== upload.file.enrichments[name].size || bytes.byteLength > MAX_BYTES) throw invalid6();
1398
+ await request2((signal) => exchange(`${route}/enrichments/${encodeURIComponent(name)}`, {
1268
1399
  method: "POST",
1269
1400
  headers: { "content-type": "application/octet-stream", "x-oddington-transfer": ticket },
1270
1401
  body: bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength)
@@ -1273,13 +1404,13 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1273
1404
  await upload?.beforeComplete();
1274
1405
  let completion = control({ parts: receipts });
1275
1406
  if (new TextEncoder().encode(completion.body).byteLength > 128 * 1024) throw unavailable();
1276
- return parseFileDescriptor(await request(
1407
+ return parseFileDescriptor(await request2(
1277
1408
  (signal) => exchange(`${route}/complete`, completion, !0, signal),
1278
1409
  TIMEOUT_MS + Math.ceil(metadata.size / (1024 * 1024)) * 1e3
1279
1410
  ));
1280
1411
  } catch (error) {
1281
1412
  throw reader && await reader.cancel(error).catch(() => {
1282
- }), ticket && await request((signal) => exchange(`${route}/abort`, control({}), "control", signal)).catch(() => {
1413
+ }), ticket && await request2((signal) => exchange(`${route}/abort`, control({}), "control", signal)).catch(() => {
1283
1414
  }), error instanceof FileOperationError ? error : unavailable();
1284
1415
  } finally {
1285
1416
  chunk = void 0, reader?.releaseLock(), pending.size ? Promise.allSettled([...pending]).then(release) : release();
@@ -1301,7 +1432,7 @@ async function operation(work, initial, parent) {
1301
1432
  function contentPath(id3, name) {
1302
1433
  let path = idPath(id3);
1303
1434
  if (name === void 0) return `${path}/content`;
1304
- if (!safeEnrichmentName(name)) throw invalid4();
1435
+ if (!safeEnrichmentName(name)) throw invalid6();
1305
1436
  return `${path}/enrichments/${encodeURIComponent(name)}/content`;
1306
1437
  }
1307
1438
  async function read(id3, names) {
@@ -1310,12 +1441,12 @@ async function read(id3, names) {
1310
1441
  let path = contentPath(id3, names);
1311
1442
  return operation((context3, signal) => send(path, { method: "GET" }, !1, context3, signal), context2);
1312
1443
  }
1313
- if (!Array.isArray(names)) throw invalid4();
1444
+ if (!Array.isArray(names)) throw invalid6();
1314
1445
  let distinct = [], seen = /* @__PURE__ */ new Set();
1315
1446
  for (let name of names) {
1316
- if (typeof name != "string" || !safeEnrichmentName(name)) throw invalid4();
1447
+ if (typeof name != "string" || !safeEnrichmentName(name)) throw invalid6();
1317
1448
  if (!seen.has(name)) {
1318
- if (seen.size === 16) throw invalid4();
1449
+ if (seen.size === 16) throw invalid6();
1319
1450
  seen.add(name), distinct.push(name);
1320
1451
  }
1321
1452
  }
@@ -1350,11 +1481,11 @@ var files = {
1350
1481
  async create(input, options) {
1351
1482
  let context2 = await resolveFilesContext();
1352
1483
  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")))
1353
- throw invalid4();
1484
+ throw invalid6();
1354
1485
  let blob = input.file instanceof Blob, array3 = input.file instanceof Uint8Array, stream = input.file instanceof ReadableStream;
1355
- if (!blob && !array3 && !stream) throw invalid4();
1486
+ if (!blob && !array3 && !stream) throw invalid6();
1356
1487
  let intrinsic = blob ? input.file.size : array3 ? input.file.byteLength : void 0;
1357
- if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid4();
1488
+ if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid6();
1358
1489
  let name = input.name;
1359
1490
  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));
1360
1491
  let metadata = parseFileCreateMetadata({
@@ -1368,7 +1499,7 @@ var files = {
1368
1499
  }, FILE_ORIGINAL_MAX_BYTES);
1369
1500
  if (!context2.local && metadata.storage === "local") throw new FileOperationError("unsupported_context", 400);
1370
1501
  let header = encodeURIComponent(JSON.stringify(metadata));
1371
- if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid4();
1502
+ if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid6();
1372
1503
  if (active >= MAX_ACTIVE) throw new FileOperationError("capacity", 429, !0);
1373
1504
  return active++, 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) => {
1374
1505
  try {
@@ -1376,7 +1507,7 @@ var files = {
1376
1507
  blob ? input.file.stream() : input.file,
1377
1508
  metadata.size
1378
1509
  );
1379
- if (bytes.byteLength !== metadata.size) throw invalid4();
1510
+ if (bytes.byteLength !== metadata.size) throw invalid6();
1380
1511
  if (signal.aborted) throw unavailable();
1381
1512
  return await send("", {
1382
1513
  method: "POST",
@@ -1392,7 +1523,7 @@ var files = {
1392
1523
  },
1393
1524
  async enrich(input) {
1394
1525
  let context2 = await resolveFilesContext();
1395
- 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 invalid4();
1526
+ 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();
1396
1527
  let path = `${idPath(input.file)}/enrichments`;
1397
1528
  if (typeof input.content == "string" ? input.content.length > MAX_BYTES : input.content.byteLength > MAX_BYTES)
1398
1529
  throw new FileOperationError("request_too_large", 413);
@@ -1409,7 +1540,7 @@ var files = {
1409
1540
  ...input.mediaType === void 0 ? {} : { mediaType: input.mediaType },
1410
1541
  ...input.replace === void 0 ? {} : { replace: input.replace }
1411
1542
  }, MAX_BYTES), header = encodeURIComponent(JSON.stringify(metadata));
1412
- if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid4();
1543
+ if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid6();
1413
1544
  let result2 = await send(path, { method: "POST", headers: {
1414
1545
  "content-type": "application/octet-stream",
1415
1546
  "x-oddington-enrichment": header
@@ -1445,8 +1576,8 @@ function parseConnectionLease(raw, now = Date.now()) {
1445
1576
  }
1446
1577
 
1447
1578
  var AirtableOperationError = class extends Error {
1448
- constructor(message, effect = "unapplied", receipts = []) {
1449
- super(message);
1579
+ constructor(message2, effect = "unapplied", receipts = []) {
1580
+ super(message2);
1450
1581
  this.effect = effect;
1451
1582
  this.receipts = receipts;
1452
1583
  this.name = "AirtableOperationError";
@@ -1456,10 +1587,10 @@ var AirtableOperationError = class extends Error {
1456
1587
  };
1457
1588
 
1458
1589
  var recordId = (v) => typeof v == "string" && /^rec[A-Za-z0-9]+$/.test(v), tableId = (v) => typeof v == "string" && /^tbl[A-Za-z0-9]+$/.test(v);
1459
- function fail2(message) {
1460
- throw new AirtableOperationError(message);
1590
+ function fail2(message2) {
1591
+ throw new AirtableOperationError(message2);
1461
1592
  }
1462
- function object2(v) {
1593
+ function object3(v) {
1463
1594
  return (!v || typeof v != "object" || Array.isArray(v) || ![null, Object.prototype].includes(Object.getPrototypeOf(v))) && fail2("Invalid Airtable data"), v;
1464
1595
  }
1465
1596
  function keys2(v, allowed, required = allowed) {
@@ -1469,7 +1600,7 @@ function text2(v) {
1469
1600
  return typeof v == "string" && v.length > 0 && v.length <= 1024;
1470
1601
  }
1471
1602
  function fields3(v, nonempty = !1) {
1472
- let result2 = object2(v);
1603
+ let result2 = object3(v);
1473
1604
  (nonempty && !Object.keys(result2).length || Object.keys(result2).some((k) => !text2(k))) && fail2("Invalid Airtable fields");
1474
1605
  try {
1475
1606
  return serializable(result2);
@@ -1478,7 +1609,7 @@ function fields3(v, nonempty = !1) {
1478
1609
  }
1479
1610
  }
1480
1611
  function record2(v) {
1481
- let r = object2(v);
1612
+ let r = object3(v);
1482
1613
  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) };
1483
1614
  }
1484
1615
  function equal(a, b) {
@@ -1511,7 +1642,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1511
1642
  (!/^[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");
1512
1643
  let input;
1513
1644
  try {
1514
- input = object2(serializable(raw));
1645
+ input = object3(serializable(raw));
1515
1646
  } catch {
1516
1647
  return fail2("Invalid Airtable input");
1517
1648
  }
@@ -1523,7 +1654,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1523
1654
  operation: operation2.slice(8),
1524
1655
  records: ids2.map((id3) => ({ id: id3 }))
1525
1656
  });
1526
- async function request(path2, init2 = {}, write = !1) {
1657
+ async function request2(path2, init2 = {}, write = !1) {
1527
1658
  let response2;
1528
1659
  try {
1529
1660
  response2 = await (options.fetch ?? fetch)(`https://api.airtable.com/v0/${path2}`, {
@@ -1540,7 +1671,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1540
1671
  }), new AirtableOperationError("Airtable request rejected", write && (response2.status >= 500 || response2.status === 408 || response2.status < 400) ? "uncertain" : "unapplied");
1541
1672
  try {
1542
1673
  if (!response2.headers.get("content-type")?.toLowerCase().includes("application/json")) throw new Error();
1543
- let value = object2(await response2.json()), safe = serializable(value);
1674
+ let value = object3(await response2.json()), safe = serializable(value);
1544
1675
  if (Object.hasOwn(value, "error") || JSON.stringify(safe).includes(accessToken)) throw new Error();
1545
1676
  return value;
1546
1677
  } catch {
@@ -1551,13 +1682,13 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1551
1682
  keys2(input, []);
1552
1683
  let tables = [], seen = /* @__PURE__ */ new Set(), offset;
1553
1684
  do {
1554
- let query2 = new URLSearchParams(offset ? { offset } : {}), page = await request(`meta/bases/${baseId}/tables?${query2}`);
1685
+ let query2 = new URLSearchParams(offset ? { offset } : {}), page = await request2(`meta/bases/${baseId}/tables?${query2}`);
1555
1686
  Array.isArray(page.tables) || fail2("Malformed Airtable tables");
1556
1687
  for (let value of page.tables) {
1557
- let t = object2(value);
1688
+ let t = object3(value);
1558
1689
  (!tableId(t.id) || !text2(t.name) || !text2(t.primaryFieldId) || !Array.isArray(t.fields) || tables.some((existing) => existing.id === t.id)) && fail2("Malformed Airtable table");
1559
1690
  let metadata = t.fields.map((value2) => {
1560
- let f = object2(value2);
1691
+ let f = object3(value2);
1561
1692
  return (typeof f.id != "string" || !/^fld[A-Za-z0-9]+$/.test(f.id) || !text2(f.name) || !text2(f.type)) && fail2("Malformed Airtable field"), { id: f.id, name: f.name, type: f.type, ...f.options === void 0 ? {} : { options: serializable(f.options) } };
1562
1693
  });
1563
1694
  (!metadata.some((f) => f.id === t.primaryFieldId) || new Set(metadata.map((f) => f.id)).size !== metadata.length) && fail2("Malformed Airtable fields"), tables.push({ id: t.id, name: t.name, primaryFieldId: t.primaryFieldId, fields: metadata });
@@ -1570,7 +1701,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1570
1701
  let path = `${baseId}/${encodeURIComponent(input.table)}`;
1571
1702
  if (operation2 === "records.get") {
1572
1703
  keys2(input, ["table", "id"]), recordId(input.id) || fail2("Invalid Airtable record ID");
1573
- let result3 = record2(await request(`${path}/${input.id}`));
1704
+ let result3 = record2(await request2(`${path}/${input.id}`));
1574
1705
  return result3.id !== input.id && fail2("Malformed Airtable record"), result3;
1575
1706
  }
1576
1707
  if (operation2 === "records.list") {
@@ -1580,7 +1711,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1580
1711
  let query2 = new URLSearchParams();
1581
1712
  for (let field of input.fields ?? []) query2.append("fields[]", field);
1582
1713
  offset && query2.set("offset", offset);
1583
- let page = await request(`${path}?${query2}`);
1714
+ let page = await request2(`${path}?${query2}`);
1584
1715
  Array.isArray(page.records) || fail2("Malformed Airtable records");
1585
1716
  for (let value of page.records) {
1586
1717
  let r = record2(value);
@@ -1592,7 +1723,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1592
1723
  }
1593
1724
  mutation || fail2("Unsupported Airtable operation"), keys2(input, ["table", "records"]), (!Array.isArray(input.records) || !input.records.length || input.records.length > 10) && fail2("Invalid Airtable batch");
1594
1725
  let kind = operation2.slice(8), ids = /* @__PURE__ */ new Set(), records = input.records.map((value) => {
1595
- let r = object2(value);
1726
+ let r = object3(value);
1596
1727
  if (keys2(r, kind === "create" ? ["fields"] : kind === "update" ? ["id", "expected", "set"] : ["id", "expected"]), kind === "create") return { fields: fields3(r.fields, !0) };
1597
1728
  (!recordId(r.id) || ids.has(r.id)) && fail2("Invalid Airtable batch record ID"), ids.add(r.id);
1598
1729
  let set = kind === "update" ? fields3(r.set, !0) : void 0;
@@ -1600,7 +1731,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1600
1731
  });
1601
1732
  for (let r of records) {
1602
1733
  if (!("id" in r)) continue;
1603
- let current2 = record2(await request(`${path}/${r.id}`));
1734
+ let current2 = record2(await request2(`${path}/${r.id}`));
1604
1735
  current2.id !== r.id && fail2("Malformed Airtable record");
1605
1736
  for (let [key, value] of Object.entries(r.expected))
1606
1737
  (value === null ? Object.hasOwn(current2.fields, key) : !Object.hasOwn(current2.fields, key) || !equal(current2.fields[key], value)) && fail2("Airtable reviewed values are stale");
@@ -1608,14 +1739,14 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1608
1739
  await options.beforeMutation?.();
1609
1740
  let query = new URLSearchParams();
1610
1741
  if (kind === "delete") for (let id3 of ids) query.append("records[]", id3);
1611
- let result2 = await request(`${path}${kind === "delete" ? `?${query}` : ""}`, {
1742
+ let result2 = await request2(`${path}${kind === "delete" ? `?${query}` : ""}`, {
1612
1743
  method: kind === "create" ? "POST" : kind === "update" ? "PATCH" : "DELETE",
1613
1744
  ...kind === "delete" ? {} : { body: JSON.stringify({ records: records.map((r) => "id" in r ? { id: r.id, fields: r.set } : r) }) }
1614
1745
  }, !0), acknowledged = [], returned = [];
1615
1746
  try {
1616
1747
  if (!Array.isArray(result2.records)) throw new Error();
1617
1748
  for (let value of result2.records) {
1618
- let r = object2(value);
1749
+ let r = object3(value);
1619
1750
  if (!recordId(r.id) || acknowledged.includes(r.id) || kind !== "create" && !ids.has(r.id) || kind === "delete" && r.deleted !== !0) throw new Error();
1620
1751
  acknowledged.push(r.id), kind !== "delete" && returned.push(record2(r));
1621
1752
  }
@@ -1717,8 +1848,8 @@ var connections = /* @__PURE__ */ createConnections(async (name, operation2, inp
1717
1848
  var LOCAL_ROUTINE_VALUE_BYTES = 256 * 1024;
1718
1849
 
1719
1850
  var RECORD_WRITE_INPUT_LIMIT = 8 * 1024 * 1024, RoutineRecordWriteError = class extends Error {
1720
- constructor(message, effect) {
1721
- super(message);
1851
+ constructor(message2, effect) {
1852
+ super(message2);
1722
1853
  this.effect = effect;
1723
1854
  this.name = "RoutineRecordWriteError";
1724
1855
  }
@@ -1769,10 +1900,10 @@ function validateRecordChange(value) {
1769
1900
  return writes.length && validateRecordWrite({ repository: input.repository, records: writes }), deletes.length && validateRecordDelete({ repository: input.repository, records: deletes }), structuredClone(input);
1770
1901
  }
1771
1902
  function validateRoutineRecordWrite(value) {
1772
- let body2 = serializable(value);
1773
- if (!body2 || typeof body2 != "object" || Array.isArray(body2) || Object.keys(body2).sort().join(",") !== "input,requestKey" || typeof body2.requestKey != "string" || !body2.requestKey.trim() || body2.requestKey !== body2.requestKey.trim() || body2.requestKey.length > 512)
1903
+ let body = serializable(value);
1904
+ if (!body || typeof body != "object" || Array.isArray(body) || Object.keys(body).sort().join(",") !== "input,requestKey" || typeof body.requestKey != "string" || !body.requestKey.trim() || body.requestKey !== body.requestKey.trim() || body.requestKey.length > 512)
1774
1905
  throw new InboxContractError("A stable routine request key is required");
1775
- return { input: validateRecordChange(body2.input), requestKey: body2.requestKey };
1906
+ return { input: validateRecordChange(body.input), requestKey: body.requestKey };
1776
1907
  }
1777
1908
  function validCreatePath(value) {
1778
1909
  return value === value.trim() && value.endsWith(".md") && !value.startsWith("/") && value.split("/").every((segment) => !!segment && ![".", ".."].includes(segment) && /^[a-zA-Z0-9_.-]+$/.test(segment));
@@ -1808,10 +1939,10 @@ var operations = {
1808
1939
  function assert(value) {
1809
1940
  if (!value) throw new Error("Invalid Inbox result");
1810
1941
  }
1811
- function object3(value) {
1942
+ function object4(value) {
1812
1943
  return assert(value && typeof value == "object" && !Array.isArray(value) && [Object.prototype, null].includes(Object.getPrototypeOf(value)) && Reflect.ownKeys(value).every((key) => {
1813
- let descriptor2 = typeof key == "string" ? Object.getOwnPropertyDescriptor(value, key) : void 0;
1814
- return !!descriptor2?.enumerable && "value" in descriptor2;
1944
+ let descriptor = typeof key == "string" ? Object.getOwnPropertyDescriptor(value, key) : void 0;
1945
+ return !!descriptor?.enumerable && "value" in descriptor;
1815
1946
  })), value;
1816
1947
  }
1817
1948
  function keys3(value, allowed, required = allowed) {
@@ -1834,41 +1965,41 @@ function optionalDate(value) {
1834
1965
  }
1835
1966
  function array2(value) {
1836
1967
  return assert(Array.isArray(value) && Object.getPrototypeOf(value) === Array.prototype && Reflect.ownKeys(value).length === value.length + 1 && value.every((_entry, index) => {
1837
- let descriptor2 = Object.getOwnPropertyDescriptor(value, String(index));
1838
- return !!descriptor2?.enumerable && "value" in descriptor2;
1968
+ let descriptor = Object.getOwnPropertyDescriptor(value, String(index));
1969
+ return !!descriptor?.enumerable && "value" in descriptor;
1839
1970
  })), value;
1840
1971
  }
1841
- function json2(value, ancestors = /* @__PURE__ */ new Set()) {
1972
+ function json(value, ancestors = /* @__PURE__ */ new Set()) {
1842
1973
  if (value === null || typeof value == "boolean" || typeof value == "string" || typeof value == "number" && Number.isFinite(value)) return value;
1843
1974
  assert(value && typeof value == "object" && !ancestors.has(value)), ancestors.add(value);
1844
1975
  try {
1845
- return Array.isArray(value) ? array2(value).map((entry) => json2(entry, ancestors)) : Object.fromEntries(Object.entries(object3(value)).map(([key, entry]) => [key, json2(entry, ancestors)]));
1976
+ return Array.isArray(value) ? array2(value).map((entry) => json(entry, ancestors)) : Object.fromEntries(Object.entries(object4(value)).map(([key, entry]) => [key, json(entry, ancestors)]));
1846
1977
  } finally {
1847
1978
  ancestors.delete(value);
1848
1979
  }
1849
1980
  }
1850
1981
  function recordReference(value) {
1851
- let record3 = object3(value);
1982
+ let record3 = object4(value);
1852
1983
  return keys3(record3, ["repository", "ref"]), assert(text3(record3.repository) && record3.repository === record3.repository.trim() && /^[a-z0-9][a-z0-9._/-]{0,127}$/.test(record3.repository) && !/\.\.|\/\//.test(record3.repository) && text3(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;
1853
1984
  }
1854
1985
  function responseDefinition(value) {
1855
- let definition = object3(value);
1986
+ let definition = object4(value);
1856
1987
  keys3(definition, ["type", "source"]), assert(definition.type === "selection");
1857
- let source = object3(definition.source);
1988
+ let source = object4(definition.source);
1858
1989
  if (source.type === "authored") {
1859
1990
  keys3(source, ["type", "options", "suggestions", "search"], ["type", "options"]);
1860
1991
  let options = array2(source.options);
1861
1992
  assert(options.length > 0);
1862
1993
  let values = options.map((value2) => {
1863
- let option = object3(value2);
1994
+ let option = object4(value2);
1864
1995
  if (keys3(option, ["value", "label", "description", "note"], ["value", "label"]), assert(text3(option.value) && option.value === option.value.trim() && text3(option.label)), "description" in option && assert(text3(option.description)), "note" in option) {
1865
- let note = object3(option.note);
1996
+ let note = object4(option.note);
1866
1997
  keys3(note, ["placeholder"]), assert(text3(note.placeholder));
1867
1998
  }
1868
1999
  return option.value;
1869
2000
  });
1870
2001
  if (assert(new Set(values).size === values.length), "search" in source || "suggestions" in source) {
1871
- let search = object3(source.search);
2002
+ let search = object4(source.search);
1872
2003
  keys3(search, ["triggerLabel", "placeholder", "emptyLabel"]), assert(text3(search.triggerLabel) && text3(search.placeholder) && text3(search.emptyLabel));
1873
2004
  let suggestions2 = array2(source.suggestions);
1874
2005
  assert(suggestions2.length <= 8 && suggestions2.every((value2) => text3(value2) && values.includes(value2)) && new Set(suggestions2).size === suggestions2.length);
@@ -1876,16 +2007,16 @@ function responseDefinition(value) {
1876
2007
  return;
1877
2008
  }
1878
2009
  assert(source.type === "records"), keys3(source, ["type", "collection", "refPrefix", "where", "display", "suggestions"], ["type", "collection", "display"]);
1879
- let collection = object3(source.collection);
2010
+ let collection = object4(source.collection);
1880
2011
  keys3(collection, ["repository", "name"]), recordReference({ repository: collection.repository, ref: "records/example" }), assert(text3(collection.name) && /^[a-zA-Z0-9_-]+(?:\/[a-zA-Z0-9_-]+)*$/.test(collection.name)), "refPrefix" in source && assert(text3(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));
1881
- let where = object3(source.where ?? {});
2012
+ let where = object4(source.where ?? {});
1882
2013
  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))));
1883
- let display = object3(source.display);
2014
+ let display = object4(source.display);
1884
2015
  keys3(display, ["labelFields"]);
1885
2016
  let labels = array2(display.labelFields);
1886
2017
  assert(labels.length > 0 && labels.length <= 2 && new Set(labels).size === labels.length && labels.every((value2) => text3(value2) && /^[a-zA-Z][a-zA-Z0-9_-]*$/.test(value2)));
1887
2018
  let suggestions = array2(source.suggestions ?? []), refs = suggestions.map((value2) => {
1888
- let suggestion = object3(value2);
2019
+ let suggestion = object4(value2);
1889
2020
  keys3(suggestion, ["record", "reason"], ["record"]);
1890
2021
  let record3 = recordReference(suggestion.record);
1891
2022
  return assert(record3.repository === collection.repository), "reason" in suggestion && assert(text3(suggestion.reason)), record3.ref;
@@ -1893,20 +2024,20 @@ function responseDefinition(value) {
1893
2024
  assert(suggestions.length <= 8 && new Set(refs).size === refs.length);
1894
2025
  }
1895
2026
  function inboxFile(value) {
1896
- let file2 = object3(value);
2027
+ let file2 = object4(value);
1897
2028
  keys3(file2, ["id", "name", "mediaType", "size", "sha256", "details"]), assert(id2(file2.id) && text3(file2.name) && !/[\x00-\x1f\x7f/\\]/.test(file2.name) && text3(file2.mediaType) && /^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/.test(file2.mediaType) && integer(file2.size, 0) && file2.size <= 25 * 1024 * 1024 && typeof file2.sha256 == "string" && /^[0-9a-f]{64}$/.test(file2.sha256));
1898
- let details = object3(file2.details);
2029
+ let details = object4(file2.details);
1899
2030
  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)));
1900
2031
  }
1901
2032
  function fields4(value) {
1902
2033
  let labels = array2(value).map((value2) => {
1903
- let field = object3(value2);
2034
+ let field = object4(value2);
1904
2035
  return keys3(field, ["label", "value"]), assert(text3(field.label) && text3(field.value)), field.label;
1905
2036
  });
1906
2037
  assert(new Set(labels).size === labels.length);
1907
2038
  }
1908
2039
  function block(value) {
1909
- let entry = object3(value);
2040
+ let entry = object4(value);
1910
2041
  if (entry.kind === "rich-text") {
1911
2042
  keys3(entry, ["kind", "markdown"]), assert(text3(entry.markdown));
1912
2043
  return;
@@ -1922,31 +2053,31 @@ function block(value) {
1922
2053
  ["kind", "label", "initiallyExpanded", ...entry.kind === "record" ? ["record", "view"] : entry.kind === "records" ? ["records", "view"] : ["files"]],
1923
2054
  ["kind", "label", entry.kind === "record" ? "record" : entry.kind === "records" ? "records" : "files"]
1924
2055
  ), 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") {
1925
- let record3 = object3(entry.record);
2056
+ let record3 = object4(entry.record);
1926
2057
  keys3(record3, ["ref", "title", "fields"]), assert(text3(record3.ref) && record3.ref === record3.ref.trim() && text3(record3.title)), fields4(record3.fields);
1927
2058
  return;
1928
2059
  }
1929
2060
  if (entry.kind === "records") {
1930
2061
  let records = array2(entry.records), refs = records.map((value2) => {
1931
- let record3 = object3(value2);
2062
+ let record3 = object4(value2);
1932
2063
  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;
1933
2064
  });
1934
2065
  assert(records.length > 0 && new Set(refs).size === refs.length);
1935
2066
  return;
1936
2067
  }
1937
2068
  let files3 = array2(entry.files);
1938
- files3.forEach(inboxFile), assert(files3.length > 0 && new Set(files3.map((value2) => object3(value2).id)).size === files3.length);
2069
+ files3.forEach(inboxFile), assert(files3.length > 0 && new Set(files3.map((value2) => object4(value2).id)).size === files3.length);
1939
2070
  }
1940
2071
  function response(value) {
1941
- let answer = object3(value);
2072
+ let answer = object4(value);
1942
2073
  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;
1943
2074
  }
1944
- function parseInboxRequest(value, questionListContext = "local") {
2075
+ function parseInboxRequest(value) {
1945
2076
  try {
1946
- let envelope = object3(value);
2077
+ let envelope = object4(value);
1947
2078
  assert(Object.keys(envelope).sort().join(",") === "input,operation"), assert(typeof envelope.operation == "string" && Object.hasOwn(operations, envelope.operation));
1948
- let operation2 = envelope.operation, input = { ...object3(envelope.input) }, required = operations[operation2];
1949
- 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" && questionListContext === "hosted" && key === "routines")), operation2 === "questions.list" && questionListContext === "hosted" && (assert(Object.hasOwn(input, "routines")), assert(array2(input.routines).every(isAppRoutineName)));
2079
+ let operation2 = envelope.operation, input = { ...object4(envelope.input) }, required = operations[operation2];
2080
+ 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)));
1950
2081
  for (let key of ["itemId", "personId", "fileId"]) key in input && assert(id2(input[key]));
1951
2082
  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 };
1952
2083
  } catch {
@@ -1954,80 +2085,84 @@ function parseInboxRequest(value, questionListContext = "local") {
1954
2085
  }
1955
2086
  }
1956
2087
  function parseInboxCurrent(value) {
1957
- let current2 = object3(value), workspace = object3(current2.workspace), viewer = object3(current2.viewer);
2088
+ let current2 = object4(value), workspace = object4(current2.workspace), viewer = object4(current2.viewer);
1958
2089
  return assert(id2(workspace.id) && text3(workspace.slug) && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(workspace.slug) && text3(workspace.name) && text3(workspace.locale) && text3(workspace.timezone)), assert(id2(viewer.id) && text3(viewer.name) && text3(viewer.email)), {
1959
2090
  workspace: { id: workspace.id, slug: workspace.slug, name: workspace.name, locale: workspace.locale, timezone: workspace.timezone },
1960
2091
  viewer: { id: viewer.id, name: viewer.name, email: viewer.email }
1961
2092
  };
1962
2093
  }
1963
2094
  function parseInboxItem(value) {
1964
- let item = object3(json2(value));
1965
- 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(object3(item.outcome).outcome)), array2(item.body).forEach(block), array2(item.views).forEach((value2) => {
1966
- let view = object3(value2);
1967
- assert(text3(view.id) && text3(view.view) && text3(view.implementation)), json2(view.input);
2095
+ let item = object4(json(value));
2096
+ 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)), array2(item.body).forEach(block), array2(item.views).forEach((value2) => {
2097
+ let view = object4(value2);
2098
+ assert(text3(view.id) && text3(view.view) && text3(view.implementation)), json(view.input);
1968
2099
  }), array2(item.people).forEach((value2) => {
1969
- let person = object3(value2);
2100
+ let person = object4(value2);
1970
2101
  assert(id2(person.id) && text3(person.name));
1971
2102
  }), array2(item.questions).forEach((value2) => {
1972
- let question2 = object3(value2);
2103
+ let question2 = object4(value2);
1973
2104
  if (assert(text3(question2.id) && id2(question2.to) && text3(question2.prompt) && (question2.instructions === null || text3(question2.instructions, !0)) && typeof question2.available == "boolean"), responseDefinition(question2.response), assert(array2(question2.allowedResponders).every(id2)), question2.acceptedResponse !== null) {
1974
- let accepted = object3(question2.acceptedResponse);
2105
+ let accepted = object4(question2.acceptedResponse);
1975
2106
  assert(id2(accepted.id) && id2(accepted.userId) && date(accepted.acceptedAt)), response(accepted.response), accepted.label === null ? delete accepted.label : "label" in accepted && assert(text3(accepted.label)), "acceptanceOrder" in accepted && assert(integer(accepted.acceptanceOrder));
1976
2107
  }
1977
2108
  if (question2.execution !== null) {
1978
- let execution = object3(question2.execution);
2109
+ let execution = object4(question2.execution);
1979
2110
  if (assert(id2(execution.id) && ["pending", "running", "completed", "failed"].includes(String(execution.state)) && integer(execution.attempt, 0)), "consequence" in execution) {
1980
- let consequence = object3(execution.consequence);
2111
+ let consequence = object4(execution.consequence);
1981
2112
  assert(["pending", "running", "applied", "no-write", "stopped", "partial", "uncertain"].includes(String(consequence.state)) && (consequence.phase === null || ["loading", "invoking", "committing"].includes(String(consequence.phase))) && date(consequence.updatedAt) && typeof consequence.needsReconciliation == "boolean" && (consequence.reason === null || text3(consequence.reason, !0))), array2(consequence.evidence).forEach((value3) => {
1982
- let receipt = object3(value3);
2113
+ let receipt = object4(value3);
1983
2114
  assert(text3(receipt.repository) && text3(receipt.commit) && text3(receipt.diff, !0));
1984
2115
  });
1985
2116
  }
1986
2117
  }
1987
2118
  }), array2(item.linkedAsks).forEach((value2) => {
1988
- let linked = object3(value2);
2119
+ let linked = object4(value2);
1989
2120
  if (assert(id2(linked.id)), linked.state === "unavailable") assert(typeof linked.done == "boolean");
1990
2121
  else if (assert(["yours", "done", "open", "theirs"].includes(String(linked.state)) && text3(linked.title)), linked.state === "theirs") {
1991
- let assignee = object3(linked.assignee);
2122
+ let assignee = object4(linked.assignee);
1992
2123
  assert(id2(assignee.id) && text3(assignee.name));
1993
2124
  }
1994
2125
  }), array2(item.activity).forEach((value2) => {
1995
- let event2 = object3(value2);
1996
- assert(integer(event2.id) && text3(event2.type) && (event2.actorId === null || id2(event2.actorId)) && (event2.questionId === null || text3(event2.questionId)) && integer(event2.revision) && date(event2.createdAt)), object3(event2.data);
2126
+ let event = object4(value2);
2127
+ assert(integer(event.id) && text3(event.type) && (event.actorId === null || id2(event.actorId)) && (event.questionId === null || text3(event.questionId)) && integer(event.revision) && date(event.createdAt)), object4(event.data);
1997
2128
  }), array2(item.work).forEach((value2) => {
1998
- let work = object3(value2);
2129
+ let work = object4(value2);
1999
2130
  assert(id2(work.id) && text3(work.questionId) && text3(work.reason) && optionalDate(work.settledAt));
2000
2131
  }), item;
2001
2132
  }
2002
2133
  function parseAnswerableQuestion(value) {
2003
- let entry = object3(json2(value));
2004
- keys3(entry, ["item", "origin", "question", "recordRefs"]);
2005
- let item = object3(entry.item);
2006
- keys3(item, ["id", "number", "revision", "title", "href"]), assert(id2(item.id) && integer(item.number) && integer(item.revision) && text3(item.title) && text3(item.href));
2007
- let link = new URL(item.href), slug = link.hostname.slice(0, -13);
2008
- assert(link.hostname.endsWith(".oddington.ai") && slug.length <= 63 && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(slug) && !["auth", "www", "api", "os"].includes(slug) && item.href === `https://${slug}.oddington.ai/inbox/${item.id}`);
2009
- let origin = object3(entry.origin);
2010
- keys3(origin, ["routine"]), assert(text3(origin.routine) && origin.routine === origin.routine.trim());
2011
- let question2 = object3(entry.question);
2012
- keys3(question2, ["id", "prompt", "instructions", "response"]), assert(text3(question2.id) && question2.id === question2.id.trim() && text3(question2.prompt) && (question2.instructions === null || text3(question2.instructions, !0))), responseDefinition(question2.response);
2134
+ let entry = object4(json(value));
2135
+ keys3(
2136
+ entry,
2137
+ ["itemId", "revision", "title", "inboxUrl", "questionId", "routine", "prompt", "response", "answerable", "recordRefs", "instructions"],
2138
+ ["itemId", "revision", "title", "inboxUrl", "questionId", "routine", "prompt", "response", "answerable", "recordRefs"]
2139
+ ), assert(id2(entry.itemId) && integer(entry.revision) && text3(entry.title) && text3(entry.inboxUrl));
2140
+ let link = new URL(entry.inboxUrl), slug = link.hostname.slice(0, -13);
2141
+ 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);
2013
2142
  let refs = array2(entry.recordRefs);
2014
- return assert(refs.every((ref) => text3(ref) && ref === ref.trim()) && new Set(refs).size === refs.length), entry;
2143
+ return refs.forEach((value2) => {
2144
+ let ref = object4(value2);
2145
+ keys3(ref, ["repository", "id"]), assert(validRepositoryAlias(ref.repository) && text3(ref.id) && /^[a-zA-Z0-9][a-zA-Z0-9._/-]*$/.test(ref.id) && !ref.id.split("/").some((part) => !part || part === "." || part === ".."));
2146
+ }), assert(new Set(refs.map((value2) => {
2147
+ let ref = object4(value2);
2148
+ return JSON.stringify([ref.repository, ref.id]);
2149
+ })).size === refs.length), entry;
2015
2150
  }
2016
2151
  function parseInboxAcceptance(value) {
2017
- let accepted = object3(value);
2152
+ let accepted = object4(value);
2018
2153
  return assert(id2(accepted.responseId) && date(accepted.acceptedAt)), "executionId" in accepted && assert(id2(accepted.executionId)), "acceptanceOrder" in accepted && assert(integer(accepted.acceptanceOrder)), "label" in accepted && assert(text3(accepted.label)), accepted;
2019
2154
  }
2020
2155
  function parseInboxResult(operation2, value) {
2021
2156
  if (operation2 === "current") return parseInboxCurrent(value);
2022
2157
  if (operation2 === "questions.list") {
2023
- let page = object3(value);
2158
+ let page = object4(value);
2024
2159
  keys3(page, ["questions", "nextBeforeNumber"]);
2025
2160
  let questions = array2(page.questions).map(parseAnswerableQuestion);
2026
2161
  return assert(page.nextBeforeNumber === null || integer(page.nextBeforeNumber)), { questions, nextBeforeNumber: page.nextBeforeNumber };
2027
2162
  }
2028
2163
  if (operation2 === "items.read") return parseInboxItem(value);
2029
2164
  if (operation2 === "items.list") {
2030
- let page = object3(value), items = array2(page.items).map(parseInboxItem);
2165
+ let page = object4(value), items = array2(page.items).map(parseInboxItem);
2031
2166
  return assert(items.length <= 100 && (page.nextBeforeNumber === null || integer(page.nextBeforeNumber))), { items, nextBeforeNumber: page.nextBeforeNumber };
2032
2167
  }
2033
2168
  if (operation2 === "items.see") {
@@ -2035,30 +2170,30 @@ function parseInboxResult(operation2, value) {
2035
2170
  return;
2036
2171
  }
2037
2172
  if (operation2 === "items.markDigestRead") {
2038
- let read2 = object3(value);
2173
+ let read2 = object4(value);
2039
2174
  return assert(integer(read2.activityId) && date(read2.readAt)), read2;
2040
2175
  }
2041
2176
  if (operation2 === "items.rename" || operation2 === "items.setLifecycle") {
2042
- let update = object3(value), item = parseInboxItem(update.item);
2177
+ let update = object4(value), item = parseInboxItem(update.item);
2043
2178
  return assert((update.activityId === null || integer(update.activityId)) && optionalDate(update.changedAt)), { ...update, item };
2044
2179
  }
2045
2180
  if (operation2 === "items.listRecipientCandidates") {
2046
2181
  let candidates = array2(value);
2047
2182
  return candidates.forEach((value2) => {
2048
- let person = object3(value2);
2183
+ let person = object4(value2);
2049
2184
  assert(id2(person.id) && text3(person.name) && text3(person.email));
2050
- }), assert(new Set(candidates.map((value2) => object3(value2).id)).size === candidates.length), candidates;
2185
+ }), assert(new Set(candidates.map((value2) => object4(value2).id)).size === candidates.length), candidates;
2051
2186
  }
2052
2187
  if (operation2 === "items.addRecipient") {
2053
- let addition = object3(value), item = parseInboxItem(addition.item);
2188
+ let addition = object4(value), item = parseInboxItem(addition.item);
2054
2189
  return assert(id2(addition.addedPersonId) && item.people.some((person) => person.id === addition.addedPersonId)), { ...addition, item };
2055
2190
  }
2056
2191
  if (operation2 === "questions.answer") return parseInboxAcceptance(value);
2057
2192
  if (operation2 === "questions.searchRecords") {
2058
- let result2 = object3(value);
2193
+ let result2 = object4(value);
2059
2194
  assert(text3(result2.recordType) && integer(result2.eligibleCount, 0) && integer(result2.matchCount, 0) && Number(result2.matchCount) <= Number(result2.eligibleCount));
2060
2195
  let labeled = (value2) => {
2061
- let record3 = object3(value2);
2196
+ let record3 = object4(value2);
2062
2197
  recordReference({ repository: record3.repository, ref: record3.ref }), assert(text3(record3.label)), "reason" in record3 && assert(text3(record3.reason));
2063
2198
  };
2064
2199
  return array2(result2.matches).forEach(labeled), array2(result2.suggestions).forEach(labeled), "selected" in result2 && labeled(result2.selected), result2;
@@ -2066,9 +2201,9 @@ function parseInboxResult(operation2, value) {
2066
2201
  throw new Error("File content is not a JSON result");
2067
2202
  }
2068
2203
 
2069
- async function limitedBody(request, limit, timeoutMs) {
2070
- if (!request.body) return new Uint8Array();
2071
- let reader = request.body.getReader(), expired = !1, timer = timeoutMs === void 0 ? void 0 : setTimeout(() => {
2204
+ async function limitedBody(request2, limit, timeoutMs) {
2205
+ if (!request2.body) return new Uint8Array();
2206
+ let reader = request2.body.getReader(), expired = !1, timer = timeoutMs === void 0 ? void 0 : setTimeout(() => {
2072
2207
  expired = !0, reader.cancel().catch(() => {
2073
2208
  });
2074
2209
  }, timeoutMs), chunks = [], length = 0;
@@ -2213,7 +2348,7 @@ function appContext(origin, active2) {
2213
2348
  }
2214
2349
  }, cancel = () => {
2215
2350
  controller.abort(), access.abort(), clearTimeout(expiry), clearTimeout(startup), clearTimeout(renewalTimer), clearInterval(monitor), globalThis.removeEventListener?.("storage", storageChanged);
2216
- for (let event2 of ["pageshow", "focus", "visibilitychange"]) globalThis.removeEventListener?.(event2, wake);
2351
+ for (let event of ["pageshow", "focus", "visibilitychange"]) globalThis.removeEventListener?.(event, wake);
2217
2352
  }, invalidate = () => {
2218
2353
  denied = !0, cancel();
2219
2354
  try {
@@ -2226,7 +2361,7 @@ function appContext(origin, active2) {
2226
2361
  } catch {
2227
2362
  return !1;
2228
2363
  }
2229
- }, sameSession = (value) => !binding || ["appId", "memberId", "workspace", "sessionId"].every((key) => value[key] === binding[key]), bounded = (value) => validBinding(value) && value.expiresAt > Date.now() && value.expiresAt <= Date.now() + 6e5 && sameSession(value), readPair = (candidate) => {
2364
+ }, 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) => {
2230
2365
  let value = JSON.parse(candidate ?? "null");
2231
2366
  if (!validPair(value) || value.context.expiresAt > Date.now() + 6e5 || !sameSession(value.context)) throw new Error();
2232
2367
  return value;
@@ -2261,7 +2396,7 @@ function appContext(origin, active2) {
2261
2396
  if (response2.status >= 500) throw new AppRenewalUnavailable();
2262
2397
  if (!response2.ok) throw new Error();
2263
2398
  let value = await appResponse(response2, 4096, signal);
2264
- if (!alive() || !bounded(value)) throw new Error();
2399
+ if (!alive() || !bounded2(value)) throw new Error();
2265
2400
  return value;
2266
2401
  }
2267
2402
  function install(value, candidate, raw) {
@@ -2333,7 +2468,7 @@ function appContext(origin, active2) {
2333
2468
  return;
2334
2469
  }
2335
2470
  if (!response2.ok) throw new Error();
2336
- if (!alive() || !validPair(value) || !bounded(value.context) || (/* @__PURE__ */ new Set([value.credential, value.renewalCredential, pair.credential, pair.renewalCredential])).size !== 4) throw new Error();
2471
+ if (!alive() || !validPair(value) || !bounded2(value.context) || (/* @__PURE__ */ new Set([value.credential, value.renewalCredential, pair.credential, pair.renewalCredential])).size !== 4) throw new Error();
2337
2472
  if (stored() !== previous) {
2338
2473
  await synchronize(requestController.signal);
2339
2474
  return;
@@ -2382,7 +2517,7 @@ function appContext(origin, active2) {
2382
2517
  alive() && resolve().catch(() => {
2383
2518
  });
2384
2519
  };
2385
- for (let event2 of ["pageshow", "focus", "visibilitychange"]) globalThis.addEventListener?.(event2, wake);
2520
+ for (let event of ["pageshow", "focus", "visibilitychange"]) globalThis.addEventListener?.(event, wake);
2386
2521
  let dispose = () => {
2387
2522
  disposed = !0, cancel();
2388
2523
  };
@@ -2497,13 +2632,13 @@ function hostFailure(error, context2) {
2497
2632
  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();
2498
2633
  }
2499
2634
  async function send2(operation2, input) {
2500
- let envelope = operation2 === "questions.list" ? void 0 : parseInboxRequest({ operation: operation2, input }), context2;
2635
+ let envelope = parseInboxRequest({ operation: operation2, input }), context2;
2501
2636
  try {
2502
2637
  context2 = await resolveAppContext();
2503
2638
  } catch {
2504
2639
  throw stale();
2505
2640
  }
2506
- if (envelope ??= parseInboxRequest({ operation: operation2, input }, context2.kind === "local" ? "local" : "hosted"), context2.kind === "local") {
2641
+ if (context2.kind === "local") {
2507
2642
  if (!isAppQuestionOperation(operation2)) throw new InboxOperationError(403, "access_denied");
2508
2643
  let check2 = () => {
2509
2644
  if (!context2.isCurrent() || context2.signal.aborted || context2.expiresAt <= Date.now()) throw stale();
@@ -2524,16 +2659,18 @@ async function send2(operation2, input) {
2524
2659
  }
2525
2660
  if (context2.endpoint !== `https://${context2.workspace}.oddington.ai` || ["auth", "www", "api", "os"].includes(context2.workspace)) throw stale();
2526
2661
  let host;
2527
- try {
2528
- host = await resolveHostedInboxContext(context2);
2529
- } catch (error) {
2530
- throw hostFailure(error, context2);
2662
+ if (!isAppQuestionOperation(operation2)) {
2663
+ try {
2664
+ host = await resolveHostedInboxContext(context2);
2665
+ } catch (error) {
2666
+ throw hostFailure(error, context2);
2667
+ }
2668
+ if (!host) throw unavailable2();
2531
2669
  }
2532
- if (!host) throw unavailable2();
2533
2670
  let check = () => {
2534
- if (!context2.isCurrent() || !host.isCurrent() || !Number.isFinite(context2.expiresAt) || context2.expiresAt <= Date.now()) throw stale();
2671
+ if (!context2.isCurrent() || host && !host.isCurrent() || !Number.isFinite(context2.expiresAt) || context2.expiresAt <= Date.now()) throw stale();
2535
2672
  };
2536
- if (check(), host.context.kind === "focused" && !isAppQuestionOperation(operation2))
2673
+ if (check(), host?.context.kind === "focused")
2537
2674
  throw new InboxOperationError(403, "access_denied");
2538
2675
  try {
2539
2676
  let response2 = await fetch(`${context2.endpoint}/api/inbox`, {
@@ -2567,7 +2704,7 @@ async function send2(operation2, input) {
2567
2704
  } finally {
2568
2705
  reader?.releaseLock();
2569
2706
  }
2570
- }, body2 = new ReadableStream({
2707
+ }, body = new ReadableStream({
2571
2708
  async pull(controller) {
2572
2709
  try {
2573
2710
  check(), reader ??= source.getReader();
@@ -2585,7 +2722,7 @@ async function send2(operation2, input) {
2585
2722
  },
2586
2723
  cancel
2587
2724
  }, { highWaterMark: 0 });
2588
- return new Response(body2, { status: response2.status, headers: response2.headers });
2725
+ return new Response(body, { status: response2.status, headers: response2.headers });
2589
2726
  }
2590
2727
  let bytes = await limitedBody(response2, INBOX_RESULT_BYTES);
2591
2728
  if (check(), !bytes) throw unavailable2();
@@ -2641,33 +2778,24 @@ var inbox = {
2641
2778
  },
2642
2779
  questions: {
2643
2780
  async list(input) {
2644
- let supplied = input === void 0 ? void 0 : parseInboxRequest({ operation: "questions.list", input }, "hosted").input;
2645
- if (supplied && Object.hasOwn(supplied, "beforeNumber")) throw new InboxOperationError(400, "invalid_input");
2646
- let routines = supplied ? Object.freeze(supplied.routines) : void 0, questions = [], beforeNumber, initial;
2781
+ let supplied = parseInboxRequest({ operation: "questions.list", input }).input;
2782
+ if (Object.hasOwn(supplied, "beforeNumber")) throw new InboxOperationError(400, "invalid_input");
2783
+ let routines = Object.freeze(supplied.routines), questions = [], beforeNumber, initial;
2647
2784
  try {
2648
2785
  initial = await resolveAppContext();
2649
2786
  } catch {
2650
2787
  throw stale();
2651
2788
  }
2652
- if (initial.kind === "local" ? input !== void 0 : routines === void 0)
2653
- throw new InboxOperationError(400, "invalid_input");
2654
- let host;
2655
- try {
2656
- host = initial.kind !== "local" && await resolveHostedInboxContext(initial);
2657
- } catch (error) {
2658
- throw hostFailure(error, initial);
2659
- }
2660
- if (initial.kind !== "local" && !host) throw unavailable2();
2661
2789
  let check = () => {
2662
- if (!initial.isCurrent() || host && !host.isCurrent() || initial.expiresAt <= Date.now()) throw stale();
2790
+ if (!initial.isCurrent() || initial.expiresAt <= Date.now()) throw stale();
2663
2791
  };
2664
2792
  do {
2665
2793
  check();
2666
2794
  let page = await send2("questions.list", {
2667
- ...routines === void 0 ? {} : { routines },
2795
+ routines,
2668
2796
  ...beforeNumber === void 0 ? {} : { beforeNumber }
2669
2797
  });
2670
- if (check(), page.questions.some((question2) => question2.item.href !== `https://${initial.workspace}.oddington.ai/inbox/${question2.item.id}` || routines !== void 0 && !routines.includes(question2.origin.routine)) || beforeNumber !== void 0 && (page.questions.some((question2) => question2.item.number >= beforeNumber) || page.nextBeforeNumber !== null && page.nextBeforeNumber >= beforeNumber)) throw unavailable2();
2798
+ 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();
2671
2799
  if (questions.push(...page.questions), page.nextBeforeNumber === null) return questions;
2672
2800
  beforeNumber = page.nextBeforeNumber;
2673
2801
  } while (!0);
@@ -2704,8 +2832,8 @@ function init({ auth: input }) {
2704
2832
  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);
2705
2833
  } catch {
2706
2834
  }
2707
- let active2 = !0, revision = 0, person, token, binding = {}, local = localOrigin ? appContext(localOrigin, () => active2) : void 0, subscription, stopDisposal, uninstall = installMemberContext(async () => {
2708
- if (local) return local.resolve();
2835
+ let active2 = !0, revision = 0, person, token, binding = {}, local2 = localOrigin ? appContext(localOrigin, () => active2) : void 0, subscription, stopDisposal, uninstall = installMemberContext(async () => {
2836
+ if (local2) return local2.resolve();
2709
2837
  if (!active2 || !endpoint || !workspace || globalThis.location.origin !== endpoint) throw new Error("Hosted Data context unavailable.");
2710
2838
  let started = revision, { data: { session }, error } = await auth2.getSession();
2711
2839
  if (!active2 || globalThis.location.origin !== endpoint || started !== revision || error || !session || person !== void 0 && person !== session.user.id)
@@ -2725,12 +2853,12 @@ function init({ auth: input }) {
2725
2853
  binding
2726
2854
  };
2727
2855
  }), dispose = () => {
2728
- active2 && (active2 = !1, local?.dispose(), revision++, subscription?.unsubscribe(), stopDisposal?.(), uninstall(), installedDispose === dispose && (installedDispose = void 0));
2856
+ active2 && (active2 = !1, local2?.dispose(), revision++, subscription?.unsubscribe(), stopDisposal?.(), uninstall(), installedDispose === dispose && (installedDispose = void 0));
2729
2857
  };
2730
- installedDispose = dispose, stopDisposal = registered?.onDispose(dispose), active2 && (subscription = auth2.onAuthStateChange((event2, session) => {
2858
+ installedDispose = dispose, stopDisposal = registered?.onDispose(dispose), active2 && (subscription = auth2.onAuthStateChange((event, session) => {
2731
2859
  let next = session?.user.id ?? null;
2732
- (event2 === "SIGNED_OUT" || person !== void 0 && next !== person || registered && person !== void 0 && event2 === "SIGNED_IN" && token !== session?.access_token) && (revision++, local?.invalidate()), person = next, token = session?.access_token;
2733
- }).data.subscription, local?.start());
2860
+ (event === "SIGNED_OUT" || person !== void 0 && next !== person || registered && person !== void 0 && event === "SIGNED_IN" && token !== session?.access_token) && (revision++, local2?.invalidate()), person = next, token = session?.access_token;
2861
+ }).data.subscription, local2?.start());
2734
2862
  }
2735
2863
  var os = { init };
2736
2864
 
@@ -2780,19 +2908,19 @@ function createBrowserAuth(runtime) {
2780
2908
  } catch {
2781
2909
  }
2782
2910
  }
2783
- function notify(c, event2) {
2911
+ function notify(c, event) {
2784
2912
  for (let listener of c.sessions)
2785
2913
  try {
2786
- listener(event2, event2 === "SIGNED_OUT" ? null : c.session);
2914
+ listener(event, event === "SIGNED_OUT" ? null : c.session);
2787
2915
  } catch {
2788
2916
  }
2789
2917
  }
2790
2918
  function expire(c) {
2791
2919
  !c.active || !c.session && c.state.status === "expired" || (c.revision++, c.timer && clearTimeout(c.timer), c.session = null, publish(c, { status: "expired" }), notify(c, "SIGNED_OUT"));
2792
2920
  }
2793
- function accept(c, event2, session) {
2794
- if (!c.active || event2 === "INITIAL_SESSION" && c.state.status !== "initializing" || event2 === "TOKEN_REFRESHED" && !c.session && c.state.status !== "initializing") return;
2795
- let replaced = c.session?.user?.id !== session?.user?.id || event2 === "SIGNED_OUT" || !!(event2 === "SIGNED_IN" && c.session && session?.access_token !== c.session.access_token);
2921
+ function accept(c, event, session) {
2922
+ if (!c.active || event === "INITIAL_SESSION" && c.state.status !== "initializing" || event === "TOKEN_REFRESHED" && !c.session && c.state.status !== "initializing") return;
2923
+ let replaced = c.session?.user?.id !== session?.user?.id || event === "SIGNED_OUT" || !!(event === "SIGNED_IN" && c.session && session?.access_token !== c.session.access_token);
2796
2924
  replaced && c.revision++, c.timer && clearTimeout(c.timer);
2797
2925
  let pending = c.state.pending;
2798
2926
  if (!session) {
@@ -2805,7 +2933,7 @@ function createBrowserAuth(runtime) {
2805
2933
  }
2806
2934
  c.session = session;
2807
2935
  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 });
2808
- publish(c, { status: "signed_in", account, ...pending ? { pending } : {} }), notify(c, event2);
2936
+ publish(c, { status: "signed_in", account, ...pending ? { pending } : {} }), notify(c, event);
2809
2937
  let checkExpiry = () => {
2810
2938
  if (!c.active || !c.session) return;
2811
2939
  let remaining = c.session.expires_at * 1e3 - Date.now();
@@ -2845,8 +2973,8 @@ function createBrowserAuth(runtime) {
2845
2973
  c.provider.dispose();
2846
2974
  return;
2847
2975
  }
2848
- let subscription = c.provider.onAuthStateChange((event2, session) => {
2849
- c.state.status === "initializing" && c.state.pending === "sign_out" || accept(c, event2, session);
2976
+ let subscription = c.provider.onAuthStateChange((event, session) => {
2977
+ c.state.status === "initializing" && c.state.pending === "sign_out" || accept(c, event, session);
2850
2978
  }).data.subscription;
2851
2979
  c.unsubscribe = () => subscription.unsubscribe();
2852
2980
  let started = c.revision, { data: data3, error } = await c.provider.getSession();
@@ -3008,7 +3136,7 @@ function createBrowserAuth(runtime) {
3008
3136
  if (!active2)
3009
3137
  return callback("SIGNED_OUT", null), { data: { subscription: { unsubscribe() {
3010
3138
  } } } };
3011
- let listener = (event2, session) => callback(event2, session);
3139
+ let listener = (event, session) => callback(event, session);
3012
3140
  return coordinator.sessions.add(listener), sessionObservers.add(listener), callback("INITIAL_SESSION", coordinator.session), { data: { subscription: { unsubscribe() {
3013
3141
  coordinator.sessions.delete(listener), sessionObservers.delete(listener);
3014
3142
  } } } };
@@ -3081,19 +3209,19 @@ async function provider(configuration, guard) {
3081
3209
  }
3082
3210
  },
3083
3211
  fetch: Object.assign(async (input, init2) => {
3084
- let revision = guard.revision(), request = String(input).startsWith(`${configuration.providerUrl}/auth/v1/oauth/authorizations/`) ? authorizationRequest : void 0, rejectStale = () => {
3085
- throw request && (request.rejected = !0), new BrowserAuthError("stale");
3212
+ let revision = guard.revision(), request2 = String(input).startsWith(`${configuration.providerUrl}/auth/v1/oauth/authorizations/`) ? authorizationRequest : void 0, rejectStale = () => {
3213
+ throw request2 && (request2.rejected = !0), new BrowserAuthError("stale");
3086
3214
  };
3087
- request && (!request.current() || !guard.canAuthorize(new Headers(init2?.headers).get("authorization")?.replace(/^Bearer /, "") ?? "")) && rejectStale();
3088
- let response2 = await fetch(input, { ...init2, redirect: "error" }), body2 = await response2.arrayBuffer();
3089
- (!guard.current(revision) || request && !request.current()) && rejectStale();
3215
+ request2 && (!request2.current() || !guard.canAuthorize(new Headers(init2?.headers).get("authorization")?.replace(/^Bearer /, "") ?? "")) && rejectStale();
3216
+ let response2 = await fetch(input, { ...init2, redirect: "error" }), body = await response2.arrayBuffer();
3217
+ (!guard.current(revision) || request2 && !request2.current()) && rejectStale();
3090
3218
  let result2 = new Response(
3091
- [204, 205, 304].includes(response2.status) ? null : body2,
3219
+ [204, 205, 304].includes(response2.status) ? null : body,
3092
3220
  { status: response2.status, statusText: response2.statusText, headers: response2.headers }
3093
- ), json3 = result2.json.bind(result2);
3221
+ ), json2 = result2.json.bind(result2);
3094
3222
  return result2.json = async () => {
3095
- let value = await json3();
3096
- return (!guard.current(revision) || request && !request.current()) && rejectStale(), value && typeof value.access_token == "string" && provenance.set(value.access_token, revision), value;
3223
+ let value = await json2();
3224
+ return (!guard.current(revision) || request2 && !request2.current()) && rejectStale(), value && typeof value.access_token == "string" && provenance.set(value.access_token, revision), value;
3097
3225
  }, result2;
3098
3226
  }, { preconnect: fetch.preconnect })
3099
3227
  });
@@ -3102,15 +3230,15 @@ async function provider(configuration, guard) {
3102
3230
  authorizationQueue = new Promise((resolve) => {
3103
3231
  release = resolve;
3104
3232
  }), await previous;
3105
- let request = { current: current2, rejected: !1 };
3106
- authorizationRequest = request;
3233
+ let request2 = { current: current2, rejected: !1 };
3234
+ authorizationRequest = request2;
3107
3235
  try {
3108
3236
  if (!current2()) throw new BrowserAuthError("stale");
3109
3237
  let result2 = await (kind === "get" ? client.oauth.getAuthorizationDetails(id3) : kind === "approve" ? client.oauth.approveAuthorization(id3, { skipBrowserRedirect: !0 }) : client.oauth.denyAuthorization(id3, { skipBrowserRedirect: !0 }));
3110
- if (request.rejected || !current2()) throw new BrowserAuthError("stale");
3238
+ if (request2.rejected || !current2()) throw new BrowserAuthError("stale");
3111
3239
  return result2;
3112
3240
  } catch (error) {
3113
- throw request.rejected || !current2() ? new BrowserAuthError("stale") : error;
3241
+ throw request2.rejected || !current2() ? new BrowserAuthError("stale") : error;
3114
3242
  } finally {
3115
3243
  authorizationRequest = void 0, release();
3116
3244
  }
@@ -3122,9 +3250,9 @@ async function provider(configuration, guard) {
3122
3250
  deny: (id3, current2) => authorization("deny", id3, current2)
3123
3251
  },
3124
3252
  getSession: () => client.getSession(),
3125
- onAuthStateChange: (callback) => client.onAuthStateChange((event2, session) => {
3253
+ onAuthStateChange: (callback) => client.onAuthStateChange((event, session) => {
3126
3254
  let revision = session ? provenance.get(session.access_token) : void 0;
3127
- revision !== void 0 && !guard.current(revision) || (callback(event2, session), session && provenance.delete(session.access_token));
3255
+ revision !== void 0 && !guard.current(revision) || (callback(event, session), session && provenance.delete(session.access_token));
3128
3256
  }),
3129
3257
  signInWithOtp: (input) => client.signInWithOtp(input),
3130
3258
  verifyOtp: (input) => client.verifyOtp(input),
@@ -3143,188 +3271,166 @@ async function provider(configuration, guard) {
3143
3271
  }
3144
3272
  var auth = /* @__PURE__ */ createBrowserAuth({ provider, failure: (reason) => new BrowserAuthError(reason) });
3145
3273
 
3146
- 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}$/i, isReason = (value) => value === "not_enabled" || value === "authority_unavailable" || value === "execution_unavailable" || value === "invalid_input", AppRoutineError = class extends Error {
3274
+ function routineRunHandle(operations2) {
3275
+ return Object.freeze({
3276
+ current: operations2.current,
3277
+ step: operations2.step,
3278
+ ...operations2.publish ? { publish: operations2.publish } : {},
3279
+ async *watch() {
3280
+ let previous;
3281
+ for (; ; ) {
3282
+ let state = await operations2.current(), encoded = JSON.stringify(state);
3283
+ if (encoded !== previous && (previous = encoded, yield state), state.status === "succeeded" || state.status === "failed") return;
3284
+ await (operations2.wait?.() ?? new Promise((resolve) => setTimeout(resolve, 100)));
3285
+ }
3286
+ }
3287
+ });
3288
+ }
3289
+
3290
+ 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 {
3147
3291
  constructor(reason) {
3148
3292
  super(reason);
3149
3293
  this.reason = reason;
3150
3294
  this.name = "AppRoutineError";
3151
3295
  }
3152
3296
  reason;
3153
- };
3154
- function fail3(reason) {
3297
+ }, fail3 = (reason) => {
3155
3298
  throw new AppRoutineError(reason);
3156
- }
3157
- function object4(value) {
3158
- return !!value && typeof value == "object" && !Array.isArray(value);
3159
- }
3160
- function keys4(value, expected) {
3161
- return Object.keys(value).sort().join(",") === expected;
3162
- }
3299
+ };
3163
3300
  function current(context2) {
3164
3301
  (!context2.isCurrent() || context2.signal.aborted) && fail3("authority_unavailable");
3165
3302
  }
3166
- async function body(context2, response2, maximum) {
3303
+ function appDescriptors() {
3304
+ return globalThis[/* @__PURE__ */ Symbol.for("oddington.app.descriptor")]?.routines ?? [];
3305
+ }
3306
+ async function local() {
3307
+ let context2 = await resolveAppContext().catch(() => fail3("authority_unavailable"));
3308
+ return context2.kind !== "local" ? fail3("execution_unavailable") : (current(context2), context2);
3309
+ }
3310
+ async function request(key, suffix, init2, maximum = SUMMARY_BYTES, retained) {
3311
+ (!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable");
3312
+ let context2 = retained ?? await local();
3313
+ current(context2);
3167
3314
  try {
3168
- let value = await appResponse(response2, maximum, context2.signal);
3169
- return current(context2), response2.ok || (object4(value) && keys4(value, "error") && isReason(value.error) && (value.error === "authority_unavailable" && context2.invalidate(), fail3(value.error)), fail3("authority_unavailable")), value;
3315
+ let response2 = await context2.requestRoutine(key, suffix, init2), value = await appResponse(response2, maximum, context2.signal);
3316
+ if (current(context2), !response2.ok) {
3317
+ let reason = value?.error;
3318
+ reason === "authority_unavailable" && (context2.invalidate(), fail3(reason)), (reason === "invalid_input" || reason === "execution_unavailable") && fail3(reason), fail3("execution_unavailable");
3319
+ }
3320
+ return value;
3170
3321
  } catch (error) {
3171
- if (current(context2), error instanceof AppResponseReadError || error instanceof AppRoutineError) throw error;
3172
- return fail3("execution_unavailable");
3322
+ if (current(context2), error instanceof AppRoutineError) throw error;
3323
+ fail3("execution_unavailable");
3173
3324
  }
3174
3325
  }
3175
- function descriptor(value, key) {
3176
- return (!object4(value) || !keys4(value, "after,key,routine,runId") || value.key !== key || typeof value.runId != "string" || !uuid.test(value.runId) || value.after !== 0 || typeof value.routine != "string" || !identifier.test(value.routine)) && fail3("execution_unavailable"), value;
3326
+ function summary(value, key, id3) {
3327
+ let run = value;
3328
+ 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;
3177
3329
  }
3178
- function safeValue(value, depth = 0) {
3179
- return depth > 32 ? !1 : value === null || typeof value == "string" || typeof value == "boolean" ? !0 : typeof value == "number" ? Number.isFinite(value) : Array.isArray(value) ? value.every((item) => safeValue(item, depth + 1)) : object4(value) && Object.entries(value).every(([key, item]) => !["__proto__", "constructor", "prototype"].includes(key) && safeValue(item, depth + 1));
3330
+ function only(value, allowed) {
3331
+ return !!value && typeof value == "object" && !Array.isArray(value) && Object.keys(value).every((key) => allowed.split(",").includes(key));
3180
3332
  }
3181
- function event(value, run, steps) {
3182
- (!object4(value) || value.runId !== run.runId || value.key !== run.key || value.routine !== run.routine || !Number.isSafeInteger(value.sequence) || value.sequence < 1 || new TextEncoder().encode(JSON.stringify(value)).byteLength > 16 * 1024) && fail3("execution_unavailable");
3183
- let common = "key,routine,runId,sequence,";
3184
- if (value.type === "started" && keys4(value, common + "type") && value.sequence === 1) return { type: "started" };
3185
- if (value.type === "step" && typeof value.id == "string" && identifier.test(value.id) && (!steps || steps.includes(value.id)) && keys4(value, "id," + common + (Object.hasOwn(value, "summary") ? "summary,type" : "type")) && (!Object.hasOwn(value, "summary") || safeValue(value.summary)))
3186
- return {
3187
- type: "step",
3188
- id: value.id,
3189
- ...Object.hasOwn(value, "summary") ? { summary: value.summary } : {}
3190
- };
3191
- if (value.type === "finished") {
3192
- if (value.state === "succeeded" && keys4(value, "key," + (Object.hasOwn(value, "result") ? "result," : "") + "routine,runId,sequence,state,type") && (!Object.hasOwn(value, "result") || safeValue(value.result)))
3193
- return {
3194
- type: "finished",
3195
- state: "succeeded",
3196
- ...Object.hasOwn(value, "result") ? { result: value.result } : {}
3197
- };
3198
- if (value.state === "failed" && value.error === "execution_failed" && keys4(value, "error," + common + "state,type"))
3199
- return { type: "finished", state: "failed", error: "execution_failed" };
3200
- if (value.state === "cancelled" && keys4(value, common + "state,type")) return { type: "finished", state: "cancelled" };
3201
- }
3202
- return fail3("execution_unavailable");
3203
- }
3204
- async function pause(context2, delay) {
3205
- current(context2), await new Promise((resolve, reject) => {
3206
- let abort = () => {
3207
- clearTimeout(timer), reject(new AppRoutineError("authority_unavailable"));
3208
- }, timer = setTimeout(() => {
3209
- context2.signal.removeEventListener("abort", abort), resolve();
3210
- }, delay);
3211
- context2.signal.addEventListener("abort", abort, { once: !0 });
3212
- }), current(context2);
3213
- }
3214
- function handle(context2, run, steps) {
3215
- return Object.freeze({
3216
- async *events(...args) {
3217
- args.length && fail3("invalid_input");
3218
- let cursor = 0, terminal = !1, delay = 100, retainedBytes = 0, seen = [];
3219
- for (; !terminal; ) {
3220
- current(context2);
3221
- let response2;
3222
- try {
3223
- response2 = await context2.requestRoutine(run.key, `runs/${run.runId}/events?after=${cursor}`);
3224
- } catch {
3225
- current(context2), await pause(context2, delay), delay = Math.min(delay * 2, 2e3);
3226
- continue;
3227
- }
3228
- if (response2.status >= 500) {
3229
- await response2.body?.cancel(), await pause(context2, delay), delay = Math.min(delay * 2, 2e3);
3230
- continue;
3231
- }
3232
- let value;
3233
- try {
3234
- value = await body(context2, response2, 80 * 1024);
3235
- } catch (error) {
3236
- if (!(error instanceof AppResponseReadError)) throw error;
3237
- await pause(context2, delay), delay = Math.min(delay * 2, 2e3);
3238
- continue;
3239
- }
3240
- (!object4(value) || !keys4(value, "after,events,terminal") || !Array.isArray(value.events) || value.events.length > 256 || typeof value.terminal != "boolean" || !Number.isSafeInteger(value.after)) && fail3("execution_unavailable");
3241
- let delivery = [];
3242
- for (let raw of value.events) {
3243
- let publicEvent = event(raw, run, steps), encoded = JSON.stringify(raw), sequence = raw.sequence;
3244
- if (sequence <= cursor) {
3245
- seen[sequence - 1] !== encoded && fail3("execution_unavailable");
3246
- continue;
3247
- }
3248
- (terminal || sequence !== cursor + 1 || sequence > 256 || (cursor === 0 ? publicEvent.type !== "started" : publicEvent.type === "started")) && fail3("execution_unavailable"), retainedBytes += new TextEncoder().encode(encoded).byteLength, retainedBytes > 1024 * 1024 && fail3("execution_unavailable"), seen.push(encoded), cursor = sequence, terminal = publicEvent.type === "finished", delivery.push(publicEvent);
3249
- }
3250
- (value.after !== cursor || value.terminal !== terminal) && fail3("execution_unavailable");
3251
- for (let item of delivery)
3252
- current(context2), yield item;
3253
- delay = 100, terminal || await pause(context2, delivery.length ? 100 : 250);
3254
- }
3333
+ 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;
3334
+ function optionalTimes(value) {
3335
+ return (value.startedAt === void 0 || timestamp(value.startedAt)) && (value.finishedAt === void 0 || timestamp(value.finishedAt));
3336
+ }
3337
+ function validStep(step) {
3338
+ 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));
3339
+ }
3340
+ function validPublication(value) {
3341
+ return value && only(value, value.state === "failed" ? "state,message" : "state") && (["not_needed", "ready", "published"].includes(value.state) || value.state === "failed" && message(value.message));
3342
+ }
3343
+ function jsonInput(value, ancestors = /* @__PURE__ */ new Set()) {
3344
+ if (value === null || typeof value == "string" || typeof value == "boolean" || typeof value == "number" && Number.isFinite(value)) return;
3345
+ if (!value || typeof value != "object" || ancestors.has(value)) return fail3("invalid_input");
3346
+ let array3 = Array.isArray(value), keys4 = Reflect.ownKeys(value);
3347
+ if (!array3 && ![Object.prototype, null].includes(Object.getPrototypeOf(value)) || array3 && (keys4.length !== value.length + 1 || !Array.from({ length: value.length }, (_, index) => Object.hasOwn(value, index)).every(Boolean))) return fail3("invalid_input");
3348
+ ancestors.add(value);
3349
+ for (let key of keys4) {
3350
+ if (array3 && key === "length") continue;
3351
+ let descriptor = Object.getOwnPropertyDescriptor(value, key);
3352
+ if (typeof key != "string" || !descriptor.enumerable || !Object.hasOwn(descriptor, "value")) return fail3("invalid_input");
3353
+ jsonInput(descriptor.value, ancestors);
3354
+ }
3355
+ ancestors.delete(value);
3356
+ }
3357
+ function structure(value) {
3358
+ 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);
3359
+ }
3360
+ function handle(key, id3, context2) {
3361
+ return (typeof id3 != "string" || !uuid.test(id3)) && fail3("invalid_input"), routineRunHandle({
3362
+ current: async () => summary(await request(key, `runs/${id3}`, void 0, SUMMARY_BYTES, context2), key, id3),
3363
+ async step(step) {
3364
+ (typeof step != "string" || !identifier.test(step)) && fail3("invalid_input");
3365
+ let value = await request(key, `runs/${id3}/steps/${step}`, void 0, 514 * 1024, context2);
3366
+ return (!only(value, "id,title,status,startedAt,finishedAt,summary,data") || value.id !== step || !validStep(value)) && fail3("execution_unavailable"), value;
3255
3367
  },
3256
- async cancel(...args) {
3257
- args.length && fail3("invalid_input");
3258
- try {
3259
- let value = await body(context2, await context2.requestRoutine(run.key, `runs/${run.runId}/cancel`, { method: "POST" }), 1024);
3260
- (!object4(value) || !keys4(value, "cancelled") || value.cancelled !== !0) && fail3("execution_unavailable");
3261
- } catch (error) {
3262
- if (current(context2), error instanceof AppRoutineError) throw error;
3263
- fail3("execution_unavailable");
3264
- }
3368
+ async publish() {
3369
+ return summary(await request(key, `runs/${id3}/publish`, { method: "POST" }, SUMMARY_BYTES, context2), key, id3);
3265
3370
  }
3266
3371
  });
3267
3372
  }
3268
- async function appRoutineOperation(key, input, recover) {
3269
- let context2;
3270
- try {
3271
- identifier.test(key) || fail3("authority_unavailable");
3272
- let resolved = await resolveAppContext();
3273
- if (resolved.kind !== "local" && fail3("execution_unavailable"), context2 = resolved, recover) {
3274
- let value2 = await body(context2, await context2.requestRoutine(key, "runs"), 16384);
3275
- (!object4(value2) || !keys4(value2, "runs") || !Array.isArray(value2.runs) || value2.runs.length > 20) && fail3("execution_unavailable");
3276
- let runs = value2.runs.map((run) => descriptor(run, key));
3277
- return (new Set(runs.map((run) => run.runId)).size !== runs.length || new Set(runs.map((run) => run.routine)).size > 1) && fail3("execution_unavailable"), runs.map((run) => handle(resolved, run));
3278
- }
3279
- let available = await body(context2, await context2.requestAvailability(key), 16 * 1024);
3280
- object4(available) && keys4(available, "available,reason") && available.available === !1 && isReason(available.reason) && fail3(available.reason), (!object4(available) || !keys4(available, "available,steps") || available.available !== !0 || !Array.isArray(available.steps) || available.steps.length < 1 || available.steps.length > 64 || !available.steps.every((step) => typeof step == "string" && identifier.test(step)) || new Set(available.steps).size !== available.steps.length) && fail3("execution_unavailable");
3281
- let steps = [...available.steps], encoded;
3282
- try {
3283
- encoded = JSON.stringify(input), (encoded === void 0 || new TextEncoder().encode(encoded).byteLength > 16 * 1024) && fail3("invalid_input");
3284
- } catch {
3285
- fail3("invalid_input");
3286
- }
3287
- let value = await body(context2, await context2.requestRoutine(key, "runs", {
3288
- method: "POST",
3289
- body: `{"input":${encoded}}`
3290
- }), 16 * 1024);
3291
- return handle(context2, descriptor(value, key), steps);
3292
- } catch (error) {
3293
- if (context2 && current(context2), error instanceof AppRoutineError) throw error;
3294
- return fail3(context2 ? "execution_unavailable" : "authority_unavailable");
3295
- }
3296
- }
3297
-
3298
- var authorityUnavailable = () => ({ available: !1, reason: "authority_unavailable" }), MAX_RESPONSE_BYTES = 16 * 1024;
3299
- async function availability(key) {
3373
+ async function describeAppRoutine(key) {
3374
+ let descriptor = appDescriptors().find((item) => item.id === key);
3375
+ if (!descriptor) return fail3("authority_unavailable");
3376
+ let unavailable3 = () => ({
3377
+ ...structuredClone(descriptor),
3378
+ connections: descriptor.connections.map((connection) => ({ ...connection, available: !1 })),
3379
+ readiness: { state: "unavailable", reason: "capability_unavailable", message: "Routine capability unavailable." }
3380
+ });
3300
3381
  try {
3301
- if (!/^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/.test(key)) return authorityUnavailable();
3302
- let context2 = await resolveAppContext();
3303
- if (context2.kind !== "local") return { available: !1, reason: "execution_unavailable" };
3304
- let response2 = await context2.requestAvailability(key);
3305
- if (!response2.ok || response2.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase() !== "application/json")
3306
- return authorityUnavailable();
3307
- let value = await appResponse(response2, MAX_RESPONSE_BYTES, context2.signal);
3308
- if (!context2.isCurrent() || !value || typeof value != "object" || Array.isArray(value)) return authorityUnavailable();
3309
- let result2 = value;
3310
- return result2.available === !1 && Object.keys(result2).sort().join(",") === "available,reason" && (result2.reason === "not_enabled" || result2.reason === "authority_unavailable" || result2.reason === "execution_unavailable") ? { available: !1, reason: result2.reason } : result2.available !== !0 || Object.keys(result2).sort().join(",") !== "available,steps" || !Array.isArray(result2.steps) || result2.steps.length < 1 || result2.steps.length > 64 || !result2.steps.every((step) => typeof step == "string" && /^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/.test(step)) || new Set(result2.steps).size !== result2.steps.length ? authorityUnavailable() : { available: !0, steps: [...result2.steps] };
3382
+ let value = await request(key, "describe", void 0, 1048576);
3383
+ 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;
3311
3384
  } catch {
3312
- return authorityUnavailable();
3385
+ return unavailable3();
3313
3386
  }
3314
3387
  }
3315
- var app = Object.freeze({ routines: new Proxy(/* @__PURE__ */ Object.create(null), {
3316
- get(_target, key) {
3317
- if (typeof key == "string")
3318
- return Object.freeze({
3319
- availability: (...args) => args.length ? Promise.resolve(authorityUnavailable()) : availability(key),
3320
- run: (...args) => args.length === 1 ? appRoutineOperation(key, args[0], !1) : Promise.reject(new AppRoutineError("invalid_input")),
3321
- recover: (...args) => args.length === 0 ? appRoutineOperation(key, void 0, !0) : Promise.reject(new AppRoutineError("invalid_input"))
3322
- });
3323
- },
3324
- set: () => !1,
3325
- defineProperty: () => !1,
3326
- deleteProperty: () => !1
3327
- }) });
3388
+ function appRoutineBinding(key) {
3389
+ return Object.freeze({
3390
+ describe: () => describeAppRoutine(key),
3391
+ async run(...args) {
3392
+ args.length > 1 && fail3("invalid_input");
3393
+ let encoded;
3394
+ try {
3395
+ if (args[0] === void 0) encoded = "{}";
3396
+ else {
3397
+ jsonInput(args[0]);
3398
+ let input = JSON.stringify(args[0]);
3399
+ new TextEncoder().encode(input).byteLength > 256 * 1024 && fail3("invalid_input"), encoded = `{"input":${input}}`;
3400
+ }
3401
+ } catch {
3402
+ return fail3("invalid_input");
3403
+ }
3404
+ let context2 = await local(), run = summary(await request(key, "runs", { method: "POST", body: encoded }, SUMMARY_BYTES, context2), key);
3405
+ return handle(key, run.id, context2);
3406
+ },
3407
+ runs: Object.freeze({
3408
+ async list() {
3409
+ let value = await request(key, "runs", void 0, 20 * SUMMARY_BYTES);
3410
+ if (!Array.isArray(value) || value.length > 20) return fail3("execution_unavailable");
3411
+ let runs = value.map((run) => summary(run, key));
3412
+ return new Set(runs.map((run) => run.id)).size !== runs.length && fail3("execution_unavailable"), runs;
3413
+ },
3414
+ async get(id3) {
3415
+ let run = handle(key, id3, await local());
3416
+ return await run.current(), run;
3417
+ }
3418
+ })
3419
+ });
3420
+ }
3421
+
3422
+ var app = Object.freeze({
3423
+ listRoutines: () => Promise.all(appDescriptors().map(({ id: id3 }) => describeAppRoutine(id3))),
3424
+ routines: new Proxy(/* @__PURE__ */ Object.create(null), {
3425
+ get(_target, key) {
3426
+ if (!(typeof key != "string" || !appDescriptors().some((item) => item.id === key)))
3427
+ return appRoutineBinding(key);
3428
+ },
3429
+ set: () => !1,
3430
+ defineProperty: () => !1,
3431
+ deleteProperty: () => !1
3432
+ })
3433
+ });
3328
3434
 
3329
3435
  var LIMIT2 = 16 * 1024, context;
3330
3436
  var appRun = {
@@ -3354,10 +3460,10 @@ function routineDataEnvelope(command) {
3354
3460
  }
3355
3461
 
3356
3462
  function routinePublicationClient2(options = {}) {
3357
- let environment = {}, installed2 = routineTransport(), local = installed2?.request ?? void 0, workspace = installed2 ? "installed" : options.workspace ?? environment.ODDINGTON_ROUTINE_WORKSPACE, capability = options.capability ?? environment.ODDINGTON_ROUTINE_RUN;
3463
+ let environment = {}, installed2 = routineTransport(), local2 = installed2?.request ?? void 0, workspace = installed2 ? "installed" : options.workspace ?? environment.ODDINGTON_ROUTINE_WORKSPACE, capability = options.capability ?? environment.ODDINGTON_ROUTINE_RUN;
3358
3464
  if (!workspace || !/^[a-z0-9][a-z0-9-]*$/.test(workspace) || capability !== void 0 && !/^[0-9a-f]{64}$/.test(capability))
3359
3465
  throw new Error("A workspace and valid optional routine capability are required");
3360
- let workingRoot = options.workingRoot ?? environment.ODDINGTON_INBOX_WORKING_ROOT ?? void 0, headers = capability ? { "x-oddington-run": capability } : {}, request = options.request ?? (capability ? async (path, init2) => {
3466
+ let workingRoot = options.workingRoot ?? environment.ODDINGTON_INBOX_WORKING_ROOT ?? void 0, headers = capability ? { "x-oddington-run": capability } : {}, request2 = options.request ?? (capability ? async (path, init2) => {
3361
3467
  if (path === "/api/data") return fetch(`https://${workspace}.oddington.ai/api/data`, { ...init2, redirect: "error" });
3362
3468
  let origin = `https://${workspace}.oddington.ai`, target = new URL(path, `${origin}/`);
3363
3469
  if (workspace.length > 63 || ["auth", "www", "api", "os"].includes(workspace) || target.origin !== origin || target.search || target.hash || target.username || target.password || !/^\/api\/inbox\/(check|publish|resolve|files)$/.test(path) || init2?.method !== "POST")
@@ -3366,16 +3472,16 @@ function routinePublicationClient2(options = {}) {
3366
3472
  } : async () => {
3367
3473
  throw new Error("Member publication requires a host-supplied request");
3368
3474
  });
3369
- async function send3(operation2, body2) {
3370
- if (local) return await local(operation2, body2);
3371
- let writing = operation2 === "records/update", reading = operation2 === "records/read", response2 = await request(writing || reading ? "/api/data" : `/api/inbox/${operation2}`, {
3475
+ async function send3(operation2, body) {
3476
+ if (local2) return await local2(operation2, body);
3477
+ let writing = operation2 === "records/update", reading = operation2 === "records/read", response2 = await request2(writing || reading ? "/api/data" : `/api/inbox/${operation2}`, {
3372
3478
  method: "POST",
3373
3479
  headers: {
3374
3480
  "content-type": "application/json",
3375
3481
  ...headers,
3376
3482
  ...writing || reading ? { "x-oddington-workspace": workspace, "x-oddington-captured-records": "1" } : {}
3377
3483
  },
3378
- body: JSON.stringify(writing ? routineDataEnvelope(validateRoutineRecordWrite(body2)) : reading ? { operation: "records.select", request: validateRecordRead(body2) } : body2)
3484
+ body: JSON.stringify(writing ? routineDataEnvelope(validateRoutineRecordWrite(body)) : reading ? { operation: "records.select", request: validateRecordRead(body) } : body)
3379
3485
  }), result2 = await response2.json();
3380
3486
  if (!response2.ok && operation2 === "records/update")
3381
3487
  throw new RoutineRecordWriteError(result2.error ?? "Could not confirm routine preparation", result2.effect ?? "uncertain");
@@ -3383,11 +3489,11 @@ function routinePublicationClient2(options = {}) {
3383
3489
  return result2;
3384
3490
  }
3385
3491
  let transport = {
3386
- async publish(body2) {
3387
- return await send3("publish", body2);
3492
+ async publish(body) {
3493
+ return await send3("publish", body);
3388
3494
  },
3389
- async resolve(body2) {
3390
- await send3("resolve", body2);
3495
+ async resolve(body) {
3496
+ await send3("resolve", body);
3391
3497
  }
3392
3498
  };
3393
3499
  async function readRecords(input) {
@@ -3414,12 +3520,12 @@ function routinePublicationClient2(options = {}) {
3414
3520
  files: {
3415
3521
  async add(value) {
3416
3522
  let input = validateFileAddOptions(value);
3417
- if (local) return validateInboxFile(await local("files/add", input));
3523
+ if (local2) return validateInboxFile(await local2("files/add", input));
3418
3524
  throw workingRoot ? new Error("Inbox file reads require a Node working root") : new Error("Inbox file reads require a working root");
3419
3525
  }
3420
3526
  },
3421
- async check(body2) {
3422
- await send3("check", { requestKey: body2.requestKey, item: validatePublication(body2.item) });
3527
+ async check(body) {
3528
+ await send3("check", { requestKey: body.requestKey, item: validatePublication(body.item) });
3423
3529
  }
3424
3530
  };
3425
3531
  }