@oddington/sdk 0.1.21 → 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
@@ -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 invalid6 = () => {
394
+ let invalid7 = () => {
395
395
  throw new FileOperationError("unavailable", 503, !0);
396
396
  };
397
- if (!value || typeof value != "object" || Array.isArray(value)) return invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
407
- } else return invalid6();
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
408
  for (let [name, descriptor] of Object.entries(f.enrichments)) {
409
- if (!safeEnrichmentName(name)) return invalid6();
409
+ if (!safeEnrichmentName(name)) return invalid7();
410
410
  parseEnrichmentDescriptor(descriptor);
411
411
  }
412
- return new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024 ? invalid6() : f;
412
+ return new TextEncoder().encode(JSON.stringify(f)).byteLength > 16 * 1024 ? invalid7() : f;
413
413
  }
414
414
  function parseEnrichmentDescriptor(value) {
415
- let invalid6 = () => {
415
+ let invalid7 = () => {
416
416
  throw new FileOperationError("unavailable", 503, !0);
417
417
  };
418
- if (!value || typeof value != "object" || Array.isArray(value)) return invalid6();
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) ? invalid6() : 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 invalid6 = () => {
426
+ let invalid7 = () => {
427
427
  throw new FileOperationError("invalid_input", 400);
428
428
  };
429
- if (!value || typeof value != "object" || Array.isArray(value)) return invalid6();
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 invalid6();
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 invalid6 = () => {
442
+ let invalid7 = () => {
443
443
  throw new FileOperationError("invalid_input", 400);
444
444
  };
445
- if (!value || typeof value != "object" || Array.isArray(value)) return invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
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,10 +572,10 @@ function validateRoutineSchemaValue(schema2, value) {
572
572
  }
573
573
  }
574
574
 
575
- var ROUTINE_DECLARATION_SCHEMA = "https://schemas.oddington.ai/routine/v1.json";
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
576
  var invalid = (field) => {
577
577
  throw new Error(`Invalid routine declaration: ${field}`);
578
- }, object2 = (value, fields6, field) => ((!value || typeof value != "object" || Array.isArray(value) || Object.keys(value).some((key) => !fields6.includes(key))) && invalid(field), value), routineAlias = (value) => typeof value == "string" && /^[a-z][a-z0-9-]{0,62}$/.test(value), list = (value, field, allowed) => value === void 0 ? [] : ((!Array.isArray(value) || value.length > 64 || value.some((item) => !routineAlias(item) || allowed && !allowed.includes(item)) || new Set(value).size !== value.length) && invalid(field), [...value].sort());
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
579
  function routineAssetPattern(value) {
580
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
581
  }
@@ -599,7 +599,7 @@ function parseRoutineDeclaration(value) {
599
599
  $schema: ROUTINE_DECLARATION_SCHEMA,
600
600
  access: {
601
601
  repositories: grants,
602
- connections: list(access.connections, "access.connections"),
602
+ connections: list(access.connections, "access.connections", void 0, !0),
603
603
  models: list(access.models, "access.models"),
604
604
  ...access.files === void 0 ? {} : { files: access.files },
605
605
  publish: list(access.publish, "access.publish", ["asks", "digests"])
@@ -614,19 +614,19 @@ function parseRoutineDeclaration(value) {
614
614
  };
615
615
  }
616
616
 
617
- var LIMIT = 256 * 1024, invalid2 = () => {
617
+ var invalid2 = () => {
618
618
  throw new AppRoutineContractError("invalid_value");
619
619
  }, invalidContract2 = () => {
620
620
  throw new AppRoutineContractError("invalid_contract");
621
- }, empty = { type: "object", properties: {}, required: [], additionalProperties: !1 };
622
- function freeze(value) {
621
+ }, routineTitle = (value) => typeof value == "string" && value.trim().length > 0 && value.length <= 256;
622
+ function freezeRoutineMetadata(value) {
623
623
  if (value !== null && typeof value == "object") {
624
- for (let child of Object.values(value)) freeze(child);
624
+ for (let child of Object.values(value)) freezeRoutineMetadata(child);
625
625
  Object.freeze(value);
626
626
  }
627
627
  return value;
628
628
  }
629
- function json(value, ancestors = /* @__PURE__ */ new Set()) {
629
+ function assertRoutineJson(value, ancestors = /* @__PURE__ */ new Set()) {
630
630
  if (value === null || typeof value == "string" || typeof value == "boolean" || typeof value == "number" && Number.isFinite(value)) return;
631
631
  if (!value || typeof value != "object" || ancestors.has(value)) return invalid2();
632
632
  let array3 = Array.isArray(value);
@@ -639,14 +639,34 @@ function json(value, ancestors = /* @__PURE__ */ new Set()) {
639
639
  if (typeof key != "string") return invalid2();
640
640
  let descriptor = Object.getOwnPropertyDescriptor(value, key);
641
641
  if (!descriptor.enumerable || !Object.hasOwn(descriptor, "value")) return invalid2();
642
- json(descriptor.value, ancestors);
642
+ assertRoutineJson(descriptor.value, ancestors);
643
643
  }
644
644
  ancestors.delete(value);
645
645
  }
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();
648
+ }
649
+ function parseRoutineAccess(value) {
650
+ try {
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] });
656
+ } catch {
657
+ return invalidContract2();
658
+ }
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 };
646
666
  function captureJson(value) {
647
- json(value);
667
+ assertRoutineJson(value);
648
668
  let encoded = JSON.stringify(value);
649
- return new TextEncoder().encode(encoded).byteLength > LIMIT ? invalid2() : freeze(JSON.parse(encoded));
669
+ return new TextEncoder().encode(encoded).byteLength > LIMIT ? invalid3() : freezeRoutineMetadata(JSON.parse(encoded));
650
670
  }
651
671
  function capture(schema2, value) {
652
672
  let captured = captureJson(value);
@@ -655,26 +675,26 @@ function capture(schema2, value) {
655
675
  var schemas = /* @__PURE__ */ new WeakMap();
656
676
  function nestedSchema(value) {
657
677
  let metadata = schemaMetadata(value);
658
- return Object.hasOwn(metadata, "default") ? invalidContract2() : metadata.schema;
678
+ return Object.hasOwn(metadata, "default") ? invalidContract3() : metadata.schema;
659
679
  }
660
680
  function schemaMetadata(value) {
661
- if (!value || typeof value != "object") return invalidContract2();
681
+ if (!value || typeof value != "object") return invalidContract3();
662
682
  let registered = schemas.get(value);
663
683
  if (registered) return registered;
664
684
  try {
665
- json(value);
685
+ assertRoutineJson(value);
666
686
  } catch {
667
- return invalidContract2();
687
+ return invalidContract3();
668
688
  }
669
689
  return { schema: parseAppRoutineContract({ routine: "definition", input: value, steps: [{ id: "inspect" }] }).input };
670
690
  }
671
691
  function declaration(value, defaults) {
672
692
  try {
673
- json(value);
693
+ assertRoutineJson(value);
674
694
  } catch {
675
- return invalidContract2();
695
+ return invalidContract3();
676
696
  }
677
- let parsed = freeze(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 }) });
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 }) });
678
698
  return schemas.set(builder, { schema: parsed, ...defaults ? { default: captured } : {} }), Object.freeze(builder);
679
699
  }
680
700
  var schema = {
@@ -696,27 +716,11 @@ var schema = {
696
716
  boolean() {
697
717
  return declaration({ type: "boolean" });
698
718
  }
699
- }, file = () => declaration({ type: "file" }), definitions = /* @__PURE__ */ new WeakMap();
700
- function fields3(value, allowed) {
701
- 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();
702
- }
703
- var title = (value) => typeof value == "string" && value.trim().length > 0 && value.length <= 256;
704
- function accessMetadata(value) {
705
- try {
706
- value !== void 0 && json(value), fields3(value ?? {}, ["repositories", "connections", "models", "files", "publish"]);
707
- let access = value, names = access?.connections ?? [];
708
- if (!Array.isArray(names) || names.length > 64 || new Set(names).size !== names.length || names.some((name) => typeof name != "string" || name.split("/").length !== 2 || name.split("/").some((part) => !isAppRoutineName(part)))) return invalidContract2();
709
- let parsed = parseRoutineDeclaration({ $schema: ROUTINE_DECLARATION_SCHEMA, access: { ...access, connections: [] } }).access;
710
- return freeze({ ...parsed, connections: [...names] });
711
- } catch {
712
- return invalidContract2();
713
- }
714
- }
715
- var defineRoutine = (definition) => {
716
- if (fields3(definition, ["id", "title", "input", "steps", "result", "access", "responses", "run"]), !isAppRoutineName(definition.id) || definition.title !== void 0 && !title(definition.title) || typeof definition.run != "function") return invalidContract2();
717
- let input = definition.input === void 0 ? { schema: empty, default: {} } : schemaMetadata(definition.input), result2 = definition.result === void 0 ? void 0 : schemaMetadata(definition.result).schema, access = accessMetadata(definition.access);
718
- fields3(definition.steps ?? {});
719
- let executable = Object.fromEntries(Object.entries(definition.steps ?? {}).map(([id3, step]) => (fields3(step, ["title", "run"]), !title(step.title) || typeof step.run != "function" ? invalidContract2() : [id3, Object.freeze({ title: step.title, run: step.run })]))), steps = Object.entries(executable).map(([id3, step]) => ({ id: id3, title: step.title }));
719
+ }, file = () => declaration({ type: "file" }), definitions = /* @__PURE__ */ new WeakMap(), defineRoutine = (definition) => {
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 }));
720
724
  parseAppRoutineContract({
721
725
  routine: definition.id,
722
726
  input: input.schema,
@@ -725,26 +729,26 @@ var defineRoutine = (definition) => {
725
729
  });
726
730
  let responses = [], ids = /* @__PURE__ */ new Set();
727
731
  if (definition.responses !== void 0) {
728
- if (!Array.isArray(definition.responses) || definition.responses.length > 64 || Reflect.ownKeys(definition.responses).length !== definition.responses.length + 1) return invalidContract2();
732
+ if (!Array.isArray(definition.responses) || definition.responses.length > 64 || Reflect.ownKeys(definition.responses).length !== definition.responses.length + 1) return invalidContract3();
729
733
  for (let index = 0; index < definition.responses.length; index++) {
730
734
  let descriptor = Object.getOwnPropertyDescriptor(definition.responses, String(index));
731
- if (!descriptor || !Object.hasOwn(descriptor, "value")) return invalidContract2();
735
+ if (!descriptor || !Object.hasOwn(descriptor, "value")) return invalidContract3();
732
736
  let response2 = descriptor.value;
733
- if (fields3(response2, ["id", "results", "run"]), !isAppRoutineName(response2.id) || ids.has(response2.id)) return invalidContract2();
737
+ if (assertRoutineFields(response2, ["id", "results", "run"]), !isAppRoutineName(response2.id) || ids.has(response2.id)) return invalidContract3();
734
738
  if (ids.add(response2.id), response2.results !== void 0)
735
739
  try {
736
- json(response2.results);
740
+ assertRoutineJson(response2.results);
737
741
  } catch {
738
- return invalidContract2();
742
+ return invalidContract3();
739
743
  }
740
744
  try {
741
745
  responses.push(defineHandler(response2));
742
746
  } catch {
743
- return invalidContract2();
747
+ return invalidContract3();
744
748
  }
745
749
  }
746
750
  }
747
- let contract = freeze({
751
+ let contract = freezeRoutineMetadata({
748
752
  id: definition.id,
749
753
  ...definition.title === void 0 ? {} : { title: definition.title },
750
754
  input: input.schema,
@@ -769,9 +773,9 @@ var defineRoutine = (definition) => {
769
773
  return definitions.set(captured, { contract, steps: executable, run: definition.run }), captured;
770
774
  };
771
775
  function inspectRoutineDefinition(definition) {
772
- if (!definition || typeof definition != "object") return invalidContract2();
776
+ if (!definition || typeof definition != "object") return invalidContract3();
773
777
  let registered = definitions.get(definition);
774
- return registered ? registered.contract : invalidContract2();
778
+ return registered ? registered.contract : invalidContract3();
775
779
  }
776
780
  function captureRoutineInput(definition, input) {
777
781
  let contract = inspectRoutineDefinition(definition);
@@ -787,29 +791,29 @@ async function executeRoutineDefinition(definition, input, runtime) {
787
791
  get(_target, key) {
788
792
  return guarded(Reflect.get(value, key, value), value);
789
793
  }
790
- }) : value, qualify = (value) => value.questions === void 0 ? value : { ...value, questions: value.questions.map((question2) => question2.handler ? contract.responses.some((handler) => handler.id === question2.handler.id) ? { ...question2, handler: { ...question2.handler, id: `${contract.id}/${question2.handler.id}` } } : invalid2() : question2) }, os2 = Object.freeze({
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({
791
795
  ...guarded({
792
796
  ...runtime,
793
- run: freeze({ ...runtime.run }),
797
+ run: freezeRoutineMetadata({ ...runtime.run }),
794
798
  inbox: { ...runtime.inbox, publishAsk: (value, options) => runtime.inbox.publishAsk(qualify(value), options) }
795
799
  }),
796
800
  step(id3, ...input2) {
797
801
  let saved;
798
802
  try {
799
- if (!active2 || !accepting || broken || !Object.hasOwn(steps, id3) || called.has(id3) || input2.length > 1) return invalid2();
803
+ if (!active2 || !accepting || broken || !Object.hasOwn(steps, id3) || called.has(id3) || input2.length > 1) return invalid3();
800
804
  input2.length && (saved = captureJson(input2[0])), called.add(id3);
801
805
  } catch (error) {
802
806
  return broken = !0, Promise.reject(error);
803
807
  }
804
808
  let next = work.then(async () => {
805
- if (broken) return invalid2();
809
+ if (broken) return invalid3();
806
810
  reached.add(id3);
807
811
  try {
808
812
  await runtime.step(id3, { status: "running" });
809
813
  let output = await steps[id3].run(saved, os2);
810
- if (fields3(output, ["summary", "data"]), !Object.hasOwn(output, "summary") || !Object.hasOwn(output, "data")) return invalid2();
814
+ if (assertRoutineFields(output, ["summary", "data"]), !Object.hasOwn(output, "summary") || !Object.hasOwn(output, "data")) return invalid3();
811
815
  let summary2 = captureJson(output.summary), data3 = captureJson(output.data);
812
- return await runtime.step(id3, { status: "completed", summary: summary2, data: data3 }), freeze({ summary: summary2, data: data3 });
816
+ return await runtime.step(id3, { status: "completed", summary: summary2, data: data3 }), freezeRoutineMetadata({ summary: summary2, data: data3 });
813
817
  } catch (error) {
814
818
  throw broken = !0, await runtime.step(id3, { status: "failed" }), error;
815
819
  }
@@ -829,7 +833,7 @@ async function executeRoutineDefinition(definition, input, runtime) {
829
833
  for (let step of contract.steps) reached.has(step.id) || await runtime.step(step.id, { status: "skipped" });
830
834
  if (broken) throw failure ?? new AppRoutineContractError("invalid_value");
831
835
  if (contract.result !== void 0) return capture(contract.result, result2);
832
- if (result2 !== void 0) return invalid2();
836
+ if (result2 !== void 0) return invalid3();
833
837
  }
834
838
 
835
839
  var DataOperationError = class extends Error {
@@ -847,26 +851,26 @@ var DataOperationError = class extends Error {
847
851
  component;
848
852
  };
849
853
 
850
- var invalid3 = () => {
854
+ var invalid4 = () => {
851
855
  throw new DataOperationError("invalid_query");
852
856
  }, historyText = (value) => typeof value == "string" && !/[\u0000\uD800-\uDFFF]/u.test(value);
853
857
  function historyVersion(value) {
854
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);
855
859
  }
856
860
  function historyProperties(value) {
857
- if (!value || typeof value != "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return invalid3();
861
+ if (!value || typeof value != "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return invalid4();
858
862
  let descriptors = Object.getOwnPropertyDescriptors(value);
859
- return Reflect.ownKeys(value).some((key) => typeof key != "string" || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value")) ? invalid3() : descriptors;
863
+ return Reflect.ownKeys(value).some((key) => typeof key != "string" || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value")) ? invalid4() : descriptors;
860
864
  }
861
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);
862
866
  function historyArray(value) {
863
- if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) return invalid3();
867
+ if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) return invalid4();
864
868
  let descriptors = Object.getOwnPropertyDescriptors(value);
865
- if (Reflect.ownKeys(value).length !== value.length + 1) return invalid3();
869
+ if (Reflect.ownKeys(value).length !== value.length + 1) return invalid4();
866
870
  let result2 = [];
867
871
  for (let i = 0; i < value.length; i++) {
868
872
  let descriptor = descriptors[i];
869
- if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value")) return invalid3();
873
+ if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value")) return invalid4();
870
874
  result2.push(descriptor.value);
871
875
  }
872
876
  return result2;
@@ -874,19 +878,19 @@ function historyArray(value) {
874
878
  function captureOptions(value, changes) {
875
879
  if (value === void 0) return {};
876
880
  let descriptors = historyProperties(value), result2 = {}, allowed = changes ? ["collections", "refs", "from", "through", "limit", "after"] : ["limit", "before"];
877
- if (Object.keys(descriptors).some((key) => !allowed.includes(key))) return invalid3();
881
+ if (Object.keys(descriptors).some((key) => !allowed.includes(key))) return invalid4();
878
882
  for (let key of allowed) {
879
883
  if (!Object.hasOwn(descriptors, key)) continue;
880
884
  let scalar = descriptors[key].value;
881
885
  if (key === "collections" || key === "refs") {
882
886
  let values = historyArray(scalar);
883
- if (!values.length || values.length > (key === "collections" ? 16 : 100) || !values.every(key === "collections" ? historyCollection : validRecordRef) || new Set(values).size !== values.length) return invalid3();
887
+ if (!values.length || values.length > (key === "collections" ? 16 : 100) || !values.every(key === "collections" ? historyCollection : validRecordRef) || new Set(values).size !== values.length) return invalid4();
884
888
  result2[key] = values;
885
889
  } else if (key === "limit") {
886
- if (!Number.isInteger(scalar) || scalar < 1 || scalar > (changes ? 500 : 100)) return invalid3();
890
+ if (!Number.isInteger(scalar) || scalar < 1 || scalar > (changes ? 500 : 100)) return invalid4();
887
891
  result2.limit = scalar;
888
892
  } else {
889
- if (!(key === "after" ? historyCursor(scalar) : historyVersion(scalar))) return invalid3();
893
+ if (!(key === "after" ? historyCursor(scalar) : historyVersion(scalar))) return invalid4();
890
894
  result2[key] = scalar;
891
895
  }
892
896
  }
@@ -894,39 +898,39 @@ function captureOptions(value, changes) {
894
898
  }
895
899
  var captureHistoryListOptions = (value) => captureOptions(value, !1), captureHistoryChangesOptions = (value) => captureOptions(value, !0);
896
900
  function captureHistoryInstant(value) {
897
- if (!historyText(value) || value.length > 1024) return invalid3();
901
+ if (!historyText(value) || value.length > 1024) return invalid4();
898
902
  let match = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.\d+)?([Zz]|([+-])(\d{2}):(\d{2}))$/.exec(value);
899
- if (!match) return invalid3();
903
+ if (!match) return invalid4();
900
904
  let [year, month, day, hour, minute, second] = match.slice(1, 7).map(Number), days = new Date(Date.UTC(year, month, 0));
901
- return days.setUTCFullYear(year), year < 1 || month < 1 || month > 12 || day < 1 || day > days.getUTCDate() || hour > 23 || minute > 59 || second > 59 || Number(match[9] ?? 0) > 23 || Number(match[10] ?? 0) > 59 ? invalid3() : 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;
902
906
  }
903
907
 
904
- var invalid4 = () => {
908
+ var invalid5 = () => {
905
909
  throw new DataOperationError("invalid_query");
906
910
  };
907
911
  function captureRecordsSearchInput(query, options) {
908
- if (!historyText(query)) return invalid4();
912
+ if (!historyText(query)) return invalid5();
909
913
  let length = [...query.trim()].length;
910
- if (length < 1 || length > 256) return invalid4();
914
+ if (length < 1 || length > 256) return invalid5();
911
915
  if (options === void 0) return { query };
912
916
  let descriptors = historyProperties(options);
913
- if (Object.keys(descriptors).some((key) => !["collections", "limit"].includes(key))) return invalid4();
917
+ if (Object.keys(descriptors).some((key) => !["collections", "limit"].includes(key))) return invalid5();
914
918
  let captured = {};
915
919
  if (Object.hasOwn(descriptors, "collections")) {
916
920
  let supplied = descriptors.collections.value;
917
- if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1) return invalid4();
921
+ if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1) return invalid5();
918
922
  let collections = [];
919
923
  for (let index = 0; index < supplied.length; index++) {
920
924
  let descriptor = Object.getOwnPropertyDescriptor(supplied, String(index));
921
- if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value") || !historyText(descriptor.value)) return invalid4();
925
+ if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value") || !historyText(descriptor.value)) return invalid5();
922
926
  collections.push(descriptor.value);
923
927
  }
924
- if (new Set(collections).size !== collections.length) return invalid4();
928
+ if (new Set(collections).size !== collections.length) return invalid5();
925
929
  captured.collections = collections;
926
930
  }
927
931
  if (Object.hasOwn(descriptors, "limit")) {
928
932
  let supplied = descriptors.limit.value;
929
- if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100) return invalid4();
933
+ if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100) return invalid5();
930
934
  captured.limit = supplied;
931
935
  }
932
936
  return { query, options: captured };
@@ -957,8 +961,8 @@ function captureDataDelete(record3) {
957
961
  return !validRecordRef(identity.$ref) || typeof identity.$version != "string" || !identity.$version.length || identity.$version.length > 512 ? invalidChange() : { ref: identity.$ref, expectedVersion: identity.$version };
958
962
  }
959
963
  function captureDataUpdate(record3, set) {
960
- let identity = captureDataDelete(record3), fields6 = mapping(set);
961
- return !Object.keys(fields6).length || Object.keys(fields6).some((key) => key.startsWith("$") || ["id", "type"].includes(key)) ? invalidChange() : { ...identity, set: captureValue(fields6) };
964
+ let identity = captureDataDelete(record3), fields5 = mapping(set);
965
+ return !Object.keys(fields5).length || Object.keys(fields5).some((key) => key.startsWith("$") || ["id", "type"].includes(key)) ? invalidChange() : { ...identity, set: captureValue(fields5) };
962
966
  }
963
967
  function captureIdentities(value, update, allowEmpty = !0) {
964
968
  if (!Array.isArray(value) || !allowEmpty && !value.length || value.length > 1e4) return invalidChange();
@@ -977,14 +981,14 @@ function captureDataCreate(value) {
977
981
  let row = mapping(value);
978
982
  if (!validRecordRef(row.$ref) || Object.keys(row).some((key) => key.startsWith("$") && !["$ref", "$filing"].includes(key)))
979
983
  return invalidChange();
980
- let { $ref: ref, $filing, ...fields6 } = row, filing;
984
+ let { $ref: ref, $filing, ...fields5 } = row, filing;
981
985
  if ($filing !== void 0) {
982
986
  let components = mapping($filing);
983
987
  if (Object.entries(components).some(([name, value2]) => !/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name) || ["constructor", "prototype"].includes(name) || typeof value2 != "string" || !/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value2)))
984
988
  return invalidChange();
985
989
  filing = { ...components };
986
990
  }
987
- return { ref, fields: captureValue(fields6), ...filing ? { filing } : {} };
991
+ return { ref, fields: captureValue(fields5), ...filing ? { filing } : {} };
988
992
  }
989
993
  function captureDataChanges(updatesValue, createsValue = [], deletesValue = []) {
990
994
  let updates = captureDataUpdates(updatesValue, !0);
@@ -992,8 +996,8 @@ function captureDataChanges(updatesValue, createsValue = [], deletesValue = [])
992
996
  let creates = createsValue.map((item) => {
993
997
  let row = mapping(item);
994
998
  if (Object.keys(row).some((key) => !["ref", "fields", "filing"].includes(key)) || !Object.hasOwn(row, "ref") || !Object.hasOwn(row, "fields")) return invalidChange();
995
- let fields6 = mapping(row.fields);
996
- return Object.keys(fields6).some((key) => key.startsWith("$")) ? invalidChange() : captureDataCreate({ ...fields6, $ref: row.ref, ...Object.hasOwn(row, "filing") ? { $filing: row.filing } : {} });
999
+ let fields5 = mapping(row.fields);
1000
+ return Object.keys(fields5).some((key) => key.startsWith("$")) ? invalidChange() : captureDataCreate({ ...fields5, $ref: row.ref, ...Object.hasOwn(row, "filing") ? { $filing: row.filing } : {} });
997
1001
  }), deletes = captureIdentities(deletesValue, !1), refs = [...updates, ...creates, ...deletes].map((item) => item.ref);
998
1002
  return !refs.length || refs.length > 1e4 || new Set(refs).size !== refs.length ? invalidChange() : { updates, creates, deletes };
999
1003
  }
@@ -1178,7 +1182,7 @@ var data = {
1178
1182
  }
1179
1183
  };
1180
1184
 
1181
- 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, invalid5 = () => 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 = {
1182
1186
  400: ["invalid_input", "unsupported_context"],
1183
1187
  401: ["unauthenticated"],
1184
1188
  403: ["access_denied"],
@@ -1195,7 +1199,7 @@ async function boundedBytes(stream, limit) {
1195
1199
  for (; ; ) {
1196
1200
  let { done, value } = await reader.read();
1197
1201
  if (done) break;
1198
- if (!(value instanceof Uint8Array)) throw invalid5();
1202
+ if (!(value instanceof Uint8Array)) throw invalid6();
1199
1203
  if (size += value.byteLength, size > limit) throw new FileOperationError("request_too_large", 413);
1200
1204
  bytes.set(value, size - value.byteLength);
1201
1205
  }
@@ -1322,7 +1326,7 @@ async function send(suffix, init2, descriptor, initial, parent) {
1322
1326
  throw unavailable();
1323
1327
  }
1324
1328
  function idPath(id3) {
1325
- if (typeof id3 != "string" || !FILE_ID_PATTERN.test(id3)) throw invalid5();
1329
+ if (typeof id3 != "string" || !FILE_ID_PATTERN.test(id3)) throw invalid6();
1326
1330
  return `/${id3}`;
1327
1331
  }
1328
1332
  async function multipartCreate(input, metadata, exchange, release = () => {
@@ -1365,18 +1369,18 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1365
1369
  if (!chunk || offset === chunk.byteLength) {
1366
1370
  chunk = void 0, offset = 0;
1367
1371
  let value2 = await next();
1368
- if (value2.done || !(value2.value instanceof Uint8Array) || (chunk = value2.value, chunk.byteLength > metadata.size - sent - filled)) throw invalid5();
1372
+ if (value2.done || !(value2.value instanceof Uint8Array) || (chunk = value2.value, chunk.byteLength > metadata.size - sent - filled)) throw invalid6();
1369
1373
  }
1370
1374
  let take = Math.min(length - filled, chunk.byteLength - offset);
1371
1375
  part.set(chunk.subarray(offset, offset + take), filled), filled += take, offset += take, offset === chunk.byteLength && (chunk = void 0, offset = 0);
1372
1376
  }
1373
1377
  }
1374
- if (part.byteLength !== length) throw invalid5();
1378
+ if (part.byteLength !== length) throw invalid6();
1375
1379
  if (reader && sent + length === metadata.size)
1376
1380
  for (lastProgress = Date.now(); ; ) {
1377
1381
  let value2 = await next();
1378
1382
  if (value2.done) break;
1379
- if (!(value2.value instanceof Uint8Array) || value2.value.byteLength) throw invalid5();
1383
+ if (!(value2.value instanceof Uint8Array) || value2.value.byteLength) throw invalid6();
1380
1384
  }
1381
1385
  let value = await request2((signal) => exchange(`${route}/part`, {
1382
1386
  method: "POST",
@@ -1390,7 +1394,7 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1390
1394
  }
1391
1395
  if (upload) for (let name of Object.keys(upload.file.enrichments)) {
1392
1396
  let bytes = await request2(() => upload.enrichment(name));
1393
- if (bytes.byteLength !== upload.file.enrichments[name].size || bytes.byteLength > MAX_BYTES) throw invalid5();
1397
+ if (bytes.byteLength !== upload.file.enrichments[name].size || bytes.byteLength > MAX_BYTES) throw invalid6();
1394
1398
  await request2((signal) => exchange(`${route}/enrichments/${encodeURIComponent(name)}`, {
1395
1399
  method: "POST",
1396
1400
  headers: { "content-type": "application/octet-stream", "x-oddington-transfer": ticket },
@@ -1428,7 +1432,7 @@ async function operation(work, initial, parent) {
1428
1432
  function contentPath(id3, name) {
1429
1433
  let path = idPath(id3);
1430
1434
  if (name === void 0) return `${path}/content`;
1431
- if (!safeEnrichmentName(name)) throw invalid5();
1435
+ if (!safeEnrichmentName(name)) throw invalid6();
1432
1436
  return `${path}/enrichments/${encodeURIComponent(name)}/content`;
1433
1437
  }
1434
1438
  async function read(id3, names) {
@@ -1437,12 +1441,12 @@ async function read(id3, names) {
1437
1441
  let path = contentPath(id3, names);
1438
1442
  return operation((context3, signal) => send(path, { method: "GET" }, !1, context3, signal), context2);
1439
1443
  }
1440
- if (!Array.isArray(names)) throw invalid5();
1444
+ if (!Array.isArray(names)) throw invalid6();
1441
1445
  let distinct = [], seen = /* @__PURE__ */ new Set();
1442
1446
  for (let name of names) {
1443
- if (typeof name != "string" || !safeEnrichmentName(name)) throw invalid5();
1447
+ if (typeof name != "string" || !safeEnrichmentName(name)) throw invalid6();
1444
1448
  if (!seen.has(name)) {
1445
- if (seen.size === 16) throw invalid5();
1449
+ if (seen.size === 16) throw invalid6();
1446
1450
  seen.add(name), distinct.push(name);
1447
1451
  }
1448
1452
  }
@@ -1477,11 +1481,11 @@ var files = {
1477
1481
  async create(input, options) {
1478
1482
  let context2 = await resolveFilesContext();
1479
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")))
1480
- throw invalid5();
1484
+ throw invalid6();
1481
1485
  let blob = input.file instanceof Blob, array3 = input.file instanceof Uint8Array, stream = input.file instanceof ReadableStream;
1482
- if (!blob && !array3 && !stream) throw invalid5();
1486
+ if (!blob && !array3 && !stream) throw invalid6();
1483
1487
  let intrinsic = blob ? input.file.size : array3 ? input.file.byteLength : void 0;
1484
- if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid5();
1488
+ if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid6();
1485
1489
  let name = input.name;
1486
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));
1487
1491
  let metadata = parseFileCreateMetadata({
@@ -1495,7 +1499,7 @@ var files = {
1495
1499
  }, FILE_ORIGINAL_MAX_BYTES);
1496
1500
  if (!context2.local && metadata.storage === "local") throw new FileOperationError("unsupported_context", 400);
1497
1501
  let header = encodeURIComponent(JSON.stringify(metadata));
1498
- if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid5();
1502
+ if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid6();
1499
1503
  if (active >= MAX_ACTIVE) throw new FileOperationError("capacity", 429, !0);
1500
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) => {
1501
1505
  try {
@@ -1503,7 +1507,7 @@ var files = {
1503
1507
  blob ? input.file.stream() : input.file,
1504
1508
  metadata.size
1505
1509
  );
1506
- if (bytes.byteLength !== metadata.size) throw invalid5();
1510
+ if (bytes.byteLength !== metadata.size) throw invalid6();
1507
1511
  if (signal.aborted) throw unavailable();
1508
1512
  return await send("", {
1509
1513
  method: "POST",
@@ -1519,7 +1523,7 @@ var files = {
1519
1523
  },
1520
1524
  async enrich(input) {
1521
1525
  let context2 = await resolveFilesContext();
1522
- if (!input || typeof input != "object" || Array.isArray(input) || Object.keys(input).some((key) => !["file", "name", "content", "mediaType", "replace"].includes(key)) || typeof input.content != "string" && !(input.content instanceof Uint8Array)) throw invalid5();
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();
1523
1527
  let path = `${idPath(input.file)}/enrichments`;
1524
1528
  if (typeof input.content == "string" ? input.content.length > MAX_BYTES : input.content.byteLength > MAX_BYTES)
1525
1529
  throw new FileOperationError("request_too_large", 413);
@@ -1536,7 +1540,7 @@ var files = {
1536
1540
  ...input.mediaType === void 0 ? {} : { mediaType: input.mediaType },
1537
1541
  ...input.replace === void 0 ? {} : { replace: input.replace }
1538
1542
  }, MAX_BYTES), header = encodeURIComponent(JSON.stringify(metadata));
1539
- if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid5();
1543
+ if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid6();
1540
1544
  let result2 = await send(path, { method: "POST", headers: {
1541
1545
  "content-type": "application/octet-stream",
1542
1546
  "x-oddington-enrichment": header
@@ -1595,7 +1599,7 @@ function keys2(v, allowed, required = allowed) {
1595
1599
  function text2(v) {
1596
1600
  return typeof v == "string" && v.length > 0 && v.length <= 1024;
1597
1601
  }
1598
- function fields4(v, nonempty = !1) {
1602
+ function fields3(v, nonempty = !1) {
1599
1603
  let result2 = object3(v);
1600
1604
  (nonempty && !Object.keys(result2).length || Object.keys(result2).some((k) => !text2(k))) && fail2("Invalid Airtable fields");
1601
1605
  try {
@@ -1606,7 +1610,7 @@ function fields4(v, nonempty = !1) {
1606
1610
  }
1607
1611
  function record2(v) {
1608
1612
  let r = object3(v);
1609
- return (!recordId(r.id) || r.createdTime !== void 0 && (typeof r.createdTime != "string" || !Number.isFinite(Date.parse(r.createdTime)))) && fail2("Malformed Airtable record"), { id: r.id, ...r.createdTime === void 0 ? {} : { createdTime: r.createdTime }, fields: fields4(r.fields) };
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) };
1610
1614
  }
1611
1615
  function equal(a, b) {
1612
1616
  if (a === b) return !0;
@@ -1720,10 +1724,10 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1720
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");
1721
1725
  let kind = operation2.slice(8), ids = /* @__PURE__ */ new Set(), records = input.records.map((value) => {
1722
1726
  let r = object3(value);
1723
- if (keys2(r, kind === "create" ? ["fields"] : kind === "update" ? ["id", "expected", "set"] : ["id", "expected"]), kind === "create") return { fields: fields4(r.fields, !0) };
1727
+ if (keys2(r, kind === "create" ? ["fields"] : kind === "update" ? ["id", "expected", "set"] : ["id", "expected"]), kind === "create") return { fields: fields3(r.fields, !0) };
1724
1728
  (!recordId(r.id) || ids.has(r.id)) && fail2("Invalid Airtable batch record ID"), ids.add(r.id);
1725
- let set = kind === "update" ? fields4(r.set, !0) : void 0;
1726
- return set && Object.values(set).some((value2) => value2 === null) && fail2("Airtable guard null cannot be an update value"), { id: r.id, expected: fields4(r.expected), ...set ? { set } : {} };
1729
+ let set = kind === "update" ? fields3(r.set, !0) : void 0;
1730
+ return set && Object.values(set).some((value2) => value2 === null) && fail2("Airtable guard null cannot be an update value"), { id: r.id, expected: fields3(r.expected), ...set ? { set } : {} };
1727
1731
  });
1728
1732
  for (let r of records) {
1729
1733
  if (!("id" in r)) continue;
@@ -1965,11 +1969,11 @@ function array2(value) {
1965
1969
  return !!descriptor?.enumerable && "value" in descriptor;
1966
1970
  })), value;
1967
1971
  }
1968
- function json2(value, ancestors = /* @__PURE__ */ new Set()) {
1972
+ function json(value, ancestors = /* @__PURE__ */ new Set()) {
1969
1973
  if (value === null || typeof value == "boolean" || typeof value == "string" || typeof value == "number" && Number.isFinite(value)) return value;
1970
1974
  assert(value && typeof value == "object" && !ancestors.has(value)), ancestors.add(value);
1971
1975
  try {
1972
- return Array.isArray(value) ? array2(value).map((entry) => json2(entry, ancestors)) : Object.fromEntries(Object.entries(object4(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)]));
1973
1977
  } finally {
1974
1978
  ancestors.delete(value);
1975
1979
  }
@@ -2025,7 +2029,7 @@ function inboxFile(value) {
2025
2029
  let details = object4(file2.details);
2026
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)));
2027
2031
  }
2028
- function fields5(value) {
2032
+ function fields4(value) {
2029
2033
  let labels = array2(value).map((value2) => {
2030
2034
  let field = object4(value2);
2031
2035
  return keys3(field, ["label", "value"]), assert(text3(field.label) && text3(field.value)), field.label;
@@ -2050,13 +2054,13 @@ function block(value) {
2050
2054
  ["kind", "label", entry.kind === "record" ? "record" : entry.kind === "records" ? "records" : "files"]
2051
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") {
2052
2056
  let record3 = object4(entry.record);
2053
- keys3(record3, ["ref", "title", "fields"]), assert(text3(record3.ref) && record3.ref === record3.ref.trim() && text3(record3.title)), fields5(record3.fields);
2057
+ keys3(record3, ["ref", "title", "fields"]), assert(text3(record3.ref) && record3.ref === record3.ref.trim() && text3(record3.title)), fields4(record3.fields);
2054
2058
  return;
2055
2059
  }
2056
2060
  if (entry.kind === "records") {
2057
2061
  let records = array2(entry.records), refs = records.map((value2) => {
2058
2062
  let record3 = object4(value2);
2059
- return keys3(record3, ["ref", "title", "description", "facts", "view"], ["ref", "title"]), assert(text3(record3.ref) && record3.ref === record3.ref.trim() && text3(record3.title)), "description" in record3 && assert(text3(record3.description)), "facts" in record3 && fields5(record3.facts), "view" in record3 && assert(text3(record3.view) && record3.view === record3.view.trim()), record3.ref;
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;
2060
2064
  });
2061
2065
  assert(records.length > 0 && new Set(refs).size === refs.length);
2062
2066
  return;
@@ -2068,12 +2072,12 @@ function response(value) {
2068
2072
  let answer = object4(value);
2069
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;
2070
2074
  }
2071
- function parseInboxRequest(value, questionListContext = "local") {
2075
+ function parseInboxRequest(value) {
2072
2076
  try {
2073
2077
  let envelope = object4(value);
2074
2078
  assert(Object.keys(envelope).sort().join(",") === "input,operation"), assert(typeof envelope.operation == "string" && Object.hasOwn(operations, envelope.operation));
2075
2079
  let operation2 = envelope.operation, input = { ...object4(envelope.input) }, required = operations[operation2];
2076
- assert(required.every((key) => Object.hasOwn(input, key)) && Object.keys(input).every((key) => required.includes(key) || operation2 === "questions.searchRecords" && key === "selected" || (operation2 === "items.list" || operation2 === "questions.list") && key === "beforeNumber" || operation2 === "questions.list" && questionListContext === "hosted" && key === "routines")), operation2 === "questions.list" && questionListContext === "hosted" && (assert(Object.hasOwn(input, "routines")), assert(array2(input.routines).every(isAppRoutineName)));
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)));
2077
2081
  for (let key of ["itemId", "personId", "fileId"]) key in input && assert(id2(input[key]));
2078
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 };
2079
2083
  } catch {
@@ -2088,10 +2092,10 @@ function parseInboxCurrent(value) {
2088
2092
  };
2089
2093
  }
2090
2094
  function parseInboxItem(value) {
2091
- let item = object4(json2(value));
2092
- return assert(id2(item.id) && id2(item.workspaceId) && integer(item.number) && integer(item.revision) && integer(item.activityVersion, 0) && ["ask", "digest"].includes(String(item.kind)) && ["open", "closed"].includes(String(item.lifecycle)) && text3(item.title) && text3(item.description, !0) && text3(item.author) && date(item.publishedAt) && optionalDate(item.seenAt) && optionalDate(item.digestReadAt)), item.outcome !== null && assert(text3(object4(item.outcome).outcome)), array2(item.body).forEach(block), array2(item.views).forEach((value2) => {
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) => {
2093
2097
  let view = object4(value2);
2094
- assert(text3(view.id) && text3(view.view) && text3(view.implementation)), json2(view.input);
2098
+ assert(text3(view.id) && text3(view.view) && text3(view.implementation)), json(view.input);
2095
2099
  }), array2(item.people).forEach((value2) => {
2096
2100
  let person = object4(value2);
2097
2101
  assert(id2(person.id) && text3(person.name));
@@ -2127,18 +2131,22 @@ function parseInboxItem(value) {
2127
2131
  }), item;
2128
2132
  }
2129
2133
  function parseAnswerableQuestion(value) {
2130
- let entry = object4(json2(value));
2131
- keys3(entry, ["item", "origin", "question", "recordRefs"]);
2132
- let item = object4(entry.item);
2133
- keys3(item, ["id", "number", "revision", "title", "href"]), assert(id2(item.id) && integer(item.number) && integer(item.revision) && text3(item.title) && text3(item.href));
2134
- let link = new URL(item.href), slug = link.hostname.slice(0, -13);
2135
- 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}`);
2136
- let origin = object4(entry.origin);
2137
- keys3(origin, ["routine"]), assert(text3(origin.routine) && origin.routine === origin.routine.trim());
2138
- let question2 = object4(entry.question);
2139
- 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);
2140
2142
  let refs = array2(entry.recordRefs);
2141
- 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;
2142
2150
  }
2143
2151
  function parseInboxAcceptance(value) {
2144
2152
  let accepted = object4(value);
@@ -2624,13 +2632,13 @@ function hostFailure(error, context2) {
2624
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();
2625
2633
  }
2626
2634
  async function send2(operation2, input) {
2627
- let envelope = operation2 === "questions.list" ? void 0 : parseInboxRequest({ operation: operation2, input }), context2;
2635
+ let envelope = parseInboxRequest({ operation: operation2, input }), context2;
2628
2636
  try {
2629
2637
  context2 = await resolveAppContext();
2630
2638
  } catch {
2631
2639
  throw stale();
2632
2640
  }
2633
- if (envelope ??= parseInboxRequest({ operation: operation2, input }, context2.kind === "local" ? "local" : "hosted"), context2.kind === "local") {
2641
+ if (context2.kind === "local") {
2634
2642
  if (!isAppQuestionOperation(operation2)) throw new InboxOperationError(403, "access_denied");
2635
2643
  let check2 = () => {
2636
2644
  if (!context2.isCurrent() || context2.signal.aborted || context2.expiresAt <= Date.now()) throw stale();
@@ -2651,16 +2659,18 @@ async function send2(operation2, input) {
2651
2659
  }
2652
2660
  if (context2.endpoint !== `https://${context2.workspace}.oddington.ai` || ["auth", "www", "api", "os"].includes(context2.workspace)) throw stale();
2653
2661
  let host;
2654
- try {
2655
- host = await resolveHostedInboxContext(context2);
2656
- } catch (error) {
2657
- 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();
2658
2669
  }
2659
- if (!host) throw unavailable2();
2660
2670
  let check = () => {
2661
- 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();
2662
2672
  };
2663
- if (check(), host.context.kind === "focused" && !isAppQuestionOperation(operation2))
2673
+ if (check(), host?.context.kind === "focused")
2664
2674
  throw new InboxOperationError(403, "access_denied");
2665
2675
  try {
2666
2676
  let response2 = await fetch(`${context2.endpoint}/api/inbox`, {
@@ -2768,33 +2778,24 @@ var inbox = {
2768
2778
  },
2769
2779
  questions: {
2770
2780
  async list(input) {
2771
- let supplied = input === void 0 ? void 0 : parseInboxRequest({ operation: "questions.list", input }, "hosted").input;
2772
- if (supplied && Object.hasOwn(supplied, "beforeNumber")) throw new InboxOperationError(400, "invalid_input");
2773
- 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;
2774
2784
  try {
2775
2785
  initial = await resolveAppContext();
2776
2786
  } catch {
2777
2787
  throw stale();
2778
2788
  }
2779
- if (initial.kind === "local" ? input !== void 0 : routines === void 0)
2780
- throw new InboxOperationError(400, "invalid_input");
2781
- let host;
2782
- try {
2783
- host = initial.kind !== "local" && await resolveHostedInboxContext(initial);
2784
- } catch (error) {
2785
- throw hostFailure(error, initial);
2786
- }
2787
- if (initial.kind !== "local" && !host) throw unavailable2();
2788
2789
  let check = () => {
2789
- if (!initial.isCurrent() || host && !host.isCurrent() || initial.expiresAt <= Date.now()) throw stale();
2790
+ if (!initial.isCurrent() || initial.expiresAt <= Date.now()) throw stale();
2790
2791
  };
2791
2792
  do {
2792
2793
  check();
2793
2794
  let page = await send2("questions.list", {
2794
- ...routines === void 0 ? {} : { routines },
2795
+ routines,
2795
2796
  ...beforeNumber === void 0 ? {} : { beforeNumber }
2796
2797
  });
2797
- 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();
2798
2799
  if (questions.push(...page.questions), page.nextBeforeNumber === null) return questions;
2799
2800
  beforeNumber = page.nextBeforeNumber;
2800
2801
  } while (!0);
@@ -3217,9 +3218,9 @@ async function provider(configuration, guard) {
3217
3218
  let result2 = new Response(
3218
3219
  [204, 205, 304].includes(response2.status) ? null : body,
3219
3220
  { status: response2.status, statusText: response2.statusText, headers: response2.headers }
3220
- ), json3 = result2.json.bind(result2);
3221
+ ), json2 = result2.json.bind(result2);
3221
3222
  return result2.json = async () => {
3222
- let value = await json3();
3223
+ let value = await json2();
3223
3224
  return (!guard.current(revision) || request2 && !request2.current()) && rejectStale(), value && typeof value.access_token == "string" && provenance.set(value.access_token, revision), value;
3224
3225
  }, result2;
3225
3226
  }, { preconnect: fetch.preconnect })
@@ -3270,6 +3271,22 @@ async function provider(configuration, guard) {
3270
3271
  }
3271
3272
  var auth = /* @__PURE__ */ createBrowserAuth({ provider, failure: (reason) => new BrowserAuthError(reason) });
3272
3273
 
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
+
3273
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 {
3274
3291
  constructor(reason) {
3275
3292
  super(reason);
@@ -3341,18 +3358,8 @@ function structure(value) {
3341
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);
3342
3359
  }
3343
3360
  function handle(key, id3, context2) {
3344
- (typeof id3 != "string" || !uuid.test(id3)) && fail3("invalid_input");
3345
- let read2 = async () => summary(await request(key, `runs/${id3}`, void 0, SUMMARY_BYTES, context2), key, id3);
3346
- return Object.freeze({
3347
- current: read2,
3348
- async *watch() {
3349
- let previous;
3350
- for (; ; ) {
3351
- let state = await read2(), encoded = JSON.stringify(state);
3352
- if (encoded !== previous && (previous = encoded, yield state), state.status === "succeeded" || state.status === "failed") return;
3353
- await new Promise((resolve) => setTimeout(resolve, 100));
3354
- }
3355
- },
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),
3356
3363
  async step(step) {
3357
3364
  (typeof step != "string" || !identifier.test(step)) && fail3("invalid_input");
3358
3365
  let value = await request(key, `runs/${id3}/steps/${step}`, void 0, 514 * 1024, context2);