@oddington/sdk 0.1.19 → 0.1.21

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 invalid6 = () => {
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 invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
407
+ } else return invalid6();
408
+ for (let [name, descriptor] of Object.entries(f.enrichments)) {
409
+ if (!safeEnrichmentName(name)) return invalid6();
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 ? invalid6() : f;
413
413
  }
414
414
  function parseEnrichmentDescriptor(value) {
415
- let invalid5 = () => {
415
+ let invalid6 = () => {
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 invalid6();
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) ? invalid6() : 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 invalid6 = () => {
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 invalid6();
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 invalid6();
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 invalid6 = () => {
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 invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
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 invalid6();
459
459
  csv = { encoding, delimiter, headerRow };
460
460
  }
461
461
  return {
@@ -475,7 +475,11 @@ var AppRoutineContractError = class extends Error {
475
475
  this.code = code;
476
476
  }
477
477
  code;
478
- }, propertyName = /^[a-z][A-Za-z0-9]*(?![\s\S])/, stepId = /^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/, routineName = /^[a-z0-9][a-z0-9-]{0,62}(?![\s\S])/, owns = (value, key) => Object.hasOwn(value, key), invalidContract = () => {
478
+ }, propertyName = /^[a-z][A-Za-z0-9]*(?![\s\S])/, stepId = /^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/, routineName = /^[a-z0-9][a-z0-9-]{0,62}(?![\s\S])/;
479
+ function isAppRoutineName(value) {
480
+ return typeof value == "string" && routineName.test(value);
481
+ }
482
+ var owns = (value, key) => Object.hasOwn(value, key), invalidContract = () => {
479
483
  throw new AppRoutineContractError("invalid_contract");
480
484
  }, invalidValue = () => {
481
485
  throw new AppRoutineContractError("invalid_value");
@@ -530,7 +534,7 @@ function parseAppRoutineContract(value) {
530
534
  return invalidContract();
531
535
  }
532
536
  }
533
- if (!record(value) || !fields2(value, ["routine", "input", "steps"], ["result"]) || typeof value.routine != "string" || !routineName.test(value.routine) || !denseArray(value.steps) || value.steps.length < 1 || value.steps.length > 64) return invalidContract();
537
+ if (!record(value) || !fields2(value, ["routine", "input", "steps"], ["result"]) || !isAppRoutineName(value.routine) || !denseArray(value.steps) || value.steps.length < 1 || value.steps.length > 64) return invalidContract();
534
538
  let input = schema2(value.input), result2 = owns(value, "result") ? schema2(value.result) : void 0, ids = /* @__PURE__ */ new Set(), steps = value.steps.map((step) => !record(step) || !fields2(step, ["id"], ["summary"]) || typeof step.id != "string" || !stepId.test(step.id) || ids.has(step.id) ? invalidContract() : (ids.add(step.id), { id: step.id, ...owns(step, "summary") ? { summary: schema2(step.summary) } : {} }));
535
539
  return { routine: value.routine, input, steps, ...result2 === void 0 ? {} : { result: result2 } };
536
540
  }
@@ -568,7 +572,49 @@ function validateRoutineSchemaValue(schema2, value) {
568
572
  }
569
573
  }
570
574
 
571
- var LIMIT = 256 * 1024, invalid = () => {
575
+ var ROUTINE_DECLARATION_SCHEMA = "https://schemas.oddington.ai/routine/v1.json";
576
+ var invalid = (field) => {
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());
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"),
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 LIMIT = 256 * 1024, invalid2 = () => {
572
618
  throw new AppRoutineContractError("invalid_value");
573
619
  }, invalidContract2 = () => {
574
620
  throw new AppRoutineContractError("invalid_contract");
@@ -582,40 +628,61 @@ function freeze(value) {
582
628
  }
583
629
  function json(value, ancestors = /* @__PURE__ */ new Set()) {
584
630
  if (value === null || typeof value == "string" || typeof value == "boolean" || typeof value == "number" && Number.isFinite(value)) return;
585
- if (!value || typeof value != "object" || ancestors.has(value)) return invalid();
631
+ if (!value || typeof value != "object" || ancestors.has(value)) return invalid2();
586
632
  let array3 = Array.isArray(value);
587
- if (!array3 && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) return invalid();
588
- let keys5 = Reflect.ownKeys(value);
589
- 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();
590
636
  ancestors.add(value);
591
- for (let key of keys5) {
637
+ for (let key of keys4) {
592
638
  if (array3 && key === "length") continue;
593
- if (typeof key != "string") return invalid();
594
- let descriptor2 = Object.getOwnPropertyDescriptor(value, key);
595
- if (!descriptor2.enumerable || !Object.hasOwn(descriptor2, "value")) return invalid();
596
- 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
+ json(descriptor.value, ancestors);
597
643
  }
598
644
  ancestors.delete(value);
599
645
  }
600
- function capture(schema2, value) {
601
- json(value), validateRoutineSchemaValue(schema2, value);
646
+ function captureJson(value) {
647
+ json(value);
602
648
  let encoded = JSON.stringify(value);
603
- return new TextEncoder().encode(encoded).byteLength > LIMIT ? invalid() : freeze(JSON.parse(encoded));
649
+ return new TextEncoder().encode(encoded).byteLength > LIMIT ? invalid2() : freeze(JSON.parse(encoded));
650
+ }
651
+ function capture(schema2, value) {
652
+ let captured = captureJson(value);
653
+ return validateRoutineSchemaValue(schema2, captured), captured;
654
+ }
655
+ var schemas = /* @__PURE__ */ new WeakMap();
656
+ function nestedSchema(value) {
657
+ let metadata = schemaMetadata(value);
658
+ return Object.hasOwn(metadata, "default") ? invalidContract2() : metadata.schema;
659
+ }
660
+ function schemaMetadata(value) {
661
+ if (!value || typeof value != "object") return invalidContract2();
662
+ let registered = schemas.get(value);
663
+ if (registered) return registered;
664
+ try {
665
+ json(value);
666
+ } catch {
667
+ return invalidContract2();
668
+ }
669
+ return { schema: parseAppRoutineContract({ routine: "definition", input: value, steps: [{ id: "inspect" }] }).input };
604
670
  }
605
- function declaration(value) {
671
+ function declaration(value, defaults) {
606
672
  try {
607
673
  json(value);
608
674
  } catch {
609
675
  return invalidContract2();
610
676
  }
611
- return freeze(parseAppRoutineContract({ routine: "definition", input: value, steps: [{ id: "inspect" }] }).input);
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 }) });
678
+ return schemas.set(builder, { schema: parsed, ...defaults ? { default: captured } : {} }), Object.freeze(builder);
612
679
  }
613
680
  var schema = {
614
681
  object(properties) {
615
- return declaration({ type: "object", properties, required: Object.keys(properties), additionalProperties: !1 });
682
+ return declaration({ type: "object", properties: Object.fromEntries(Object.entries(properties).map(([key, value]) => [key, nestedSchema(value)])), required: Object.keys(properties), additionalProperties: !1 });
616
683
  },
617
684
  array(items, options) {
618
- return declaration({ type: "array", items, maxItems: options.maxItems });
685
+ return declaration({ type: "array", items: nestedSchema(items), maxItems: options.maxItems });
619
686
  },
620
687
  string(options = {}) {
621
688
  return declaration({ type: "string", ...options });
@@ -629,33 +696,77 @@ var schema = {
629
696
  boolean() {
630
697
  return declaration({ type: "boolean" });
631
698
  }
632
- }, file = () => declaration({ type: "file" }), definitions = /* @__PURE__ */ new WeakMap(), defineRoutine = (definition) => {
633
- 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();
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) {
634
705
  try {
635
- for (let key of ["input", "steps", "result"])
636
- definition[key] !== void 0 && json(definition[key]);
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] });
637
711
  } catch {
638
712
  return invalidContract2();
639
713
  }
640
- if (definition.steps !== void 0 && (!definition.steps || typeof definition.steps != "object" || Array.isArray(definition.steps))) return invalidContract2();
641
- let steps = definition.steps === void 0 ? [] : Object.entries(definition.steps).map(([id3, summary]) => ({ id: id3, ...summary === null ? {} : { summary } })), parsed = parseAppRoutineContract({
642
- routine: "definition",
643
- input: definition.input === void 0 ? empty : definition.input,
644
- steps: steps.length ? steps : [{ id: "inspect" }],
645
- ...definition.result === void 0 ? {} : { result: definition.result }
646
- }), contract = freeze({
647
- input: parsed.input,
648
- steps: steps.length ? parsed.steps : [],
649
- ...parsed.result === void 0 ? {} : { result: parsed.result }
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 }));
720
+ parseAppRoutineContract({
721
+ routine: definition.id,
722
+ input: input.schema,
723
+ steps: steps.length ? steps.map(({ id: id3 }) => ({ id: id3 })) : [{ id: "inspect" }],
724
+ ...result2 ? { result: result2 } : {}
725
+ });
726
+ let responses = [], ids = /* @__PURE__ */ new Set();
727
+ 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();
729
+ for (let index = 0; index < definition.responses.length; index++) {
730
+ let descriptor = Object.getOwnPropertyDescriptor(definition.responses, String(index));
731
+ if (!descriptor || !Object.hasOwn(descriptor, "value")) return invalidContract2();
732
+ let response2 = descriptor.value;
733
+ if (fields3(response2, ["id", "results", "run"]), !isAppRoutineName(response2.id) || ids.has(response2.id)) return invalidContract2();
734
+ if (ids.add(response2.id), response2.results !== void 0)
735
+ try {
736
+ json(response2.results);
737
+ } catch {
738
+ return invalidContract2();
739
+ }
740
+ try {
741
+ responses.push(defineHandler(response2));
742
+ } catch {
743
+ return invalidContract2();
744
+ }
745
+ }
746
+ }
747
+ let contract = freeze({
748
+ id: definition.id,
749
+ ...definition.title === void 0 ? {} : { title: definition.title },
750
+ input: input.schema,
751
+ ...Object.hasOwn(input, "default") ? { inputDefault: input.default } : {},
752
+ access,
753
+ responses: responses.map(({ id: id3 }) => ({ id: id3 })),
754
+ steps,
755
+ ...result2 ? { result: result2 } : {}
650
756
  }), captured = Object.freeze({
651
757
  ...definition,
652
- ...definition.input === void 0 ? {} : { input: contract.input },
653
- ...definition.steps === void 0 ? {} : { steps: freeze(Object.fromEntries(contract.steps.map((step) => [step.id, step.summary ?? null]))) },
654
- ...definition.result === void 0 ? {} : { result: contract.result },
758
+ access,
759
+ steps: Object.freeze(executable),
760
+ responses: Object.freeze(responses),
761
+ ...definition.input === void 0 ? {} : { input: declaration(
762
+ input.schema,
763
+ Object.hasOwn(input, "default") ? { value: input.default } : void 0
764
+ ) },
765
+ ...result2 === void 0 ? {} : { result: declaration(result2) },
655
766
  // Only this authored definition is callable; no generic runner is exported.
656
- run: (input, os2) => executeRoutineDefinition(captured, input, os2)
767
+ run: (input2, os2) => executeRoutineDefinition(captured, input2, os2)
657
768
  });
658
- return definitions.set(captured, { contract, run: definition.run }), captured;
769
+ return definitions.set(captured, { contract, steps: executable, run: definition.run }), captured;
659
770
  };
660
771
  function inspectRoutineDefinition(definition) {
661
772
  if (!definition || typeof definition != "object") return invalidContract2();
@@ -663,42 +774,62 @@ function inspectRoutineDefinition(definition) {
663
774
  return registered ? registered.contract : invalidContract2();
664
775
  }
665
776
  function captureRoutineInput(definition, input) {
666
- return capture(inspectRoutineDefinition(definition).input, input);
777
+ let contract = inspectRoutineDefinition(definition);
778
+ return capture(contract.input, input === void 0 && Object.hasOwn(contract, "inputDefault") ? contract.inputDefault : input);
667
779
  }
668
780
  async function executeRoutineDefinition(definition, input, runtime) {
669
- let captured = captureRoutineInput(definition, input), { contract, run } = definitions.get(definition), active2 = !0, broken = !1, reports = Promise.resolve(), os2 = Object.freeze({
670
- ...runtime,
671
- run: freeze({ ...runtime.run }),
672
- async artifact(input2) {
673
- if (!active2) throw new Error("Run authority ended");
674
- if (!runtime.artifact) throw new Error("Run artifact transport unavailable");
675
- return runtime.artifact(input2);
676
- },
677
- step(id3, ...summary) {
678
- if (!active2 || broken || summary.length > 1)
679
- return broken = !0, Promise.reject(new AppRoutineContractError("invalid_value"));
680
- let value;
781
+ 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) => {
782
+ if (!active2 || broken) throw new Error("Run authority ended");
783
+ return guarded(Reflect.apply(value, receiver, args));
784
+ } : value && typeof value == "object" && !(value instanceof Promise) ? new Proxy({ ...value }, {
785
+ // Copy the surface so wrapping a frozen host capability does not violate
786
+ // Proxy invariants; methods still receive their original host receiver.
787
+ get(_target, key) {
788
+ return guarded(Reflect.get(value, key, value), value);
789
+ }
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({
791
+ ...guarded({
792
+ ...runtime,
793
+ run: freeze({ ...runtime.run }),
794
+ inbox: { ...runtime.inbox, publishAsk: (value, options) => runtime.inbox.publishAsk(qualify(value), options) }
795
+ }),
796
+ step(id3, ...input2) {
797
+ let saved;
681
798
  try {
682
- let step = contract.steps.find((step2) => step2.id === id3);
683
- if (!step) return invalid();
684
- if (step.summary === void 0) {
685
- if (summary.length) return invalid();
686
- } else value = capture(step.summary, summary[0]);
799
+ if (!active2 || !accepting || broken || !Object.hasOwn(steps, id3) || called.has(id3) || input2.length > 1) return invalid2();
800
+ input2.length && (saved = captureJson(input2[0])), called.add(id3);
687
801
  } catch (error) {
688
802
  return broken = !0, Promise.reject(error);
689
803
  }
690
- let report = reports.then(() => broken ? invalid() : runtime.step(id3, value));
691
- return reports = report.catch(() => {
804
+ let next = work.then(async () => {
805
+ if (broken) return invalid2();
806
+ reached.add(id3);
807
+ try {
808
+ await runtime.step(id3, { status: "running" });
809
+ let output = await steps[id3].run(saved, os2);
810
+ if (fields3(output, ["summary", "data"]), !Object.hasOwn(output, "summary") || !Object.hasOwn(output, "data")) return invalid2();
811
+ 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 });
813
+ } catch (error) {
814
+ throw broken = !0, await runtime.step(id3, { status: "failed" }), error;
815
+ }
816
+ });
817
+ return work = next.then(() => {
818
+ }, () => {
692
819
  broken = !0;
693
- }), report;
820
+ }), next;
694
821
  }
695
- });
822
+ }), result2, failure;
696
823
  try {
697
- let result2 = await run(captured, os2);
698
- return active2 = !1, await reports, broken ? invalid() : contract.result !== void 0 ? capture(contract.result, result2) : result2 !== void 0 ? invalid() : void 0;
699
- } finally {
700
- active2 = !1;
824
+ result2 = await run(captured, os2);
825
+ } catch (error) {
826
+ failure = error, broken = !0;
701
827
  }
828
+ accepting = !1, await work, active2 = !1;
829
+ for (let step of contract.steps) reached.has(step.id) || await runtime.step(step.id, { status: "skipped" });
830
+ if (broken) throw failure ?? new AppRoutineContractError("invalid_value");
831
+ if (contract.result !== void 0) return capture(contract.result, result2);
832
+ if (result2 !== void 0) return invalid2();
702
833
  }
703
834
 
704
835
  var DataOperationError = class extends Error {
@@ -716,46 +847,46 @@ var DataOperationError = class extends Error {
716
847
  component;
717
848
  };
718
849
 
719
- var invalid2 = () => {
850
+ var invalid3 = () => {
720
851
  throw new DataOperationError("invalid_query");
721
852
  }, historyText = (value) => typeof value == "string" && !/[\u0000\uD800-\uDFFF]/u.test(value);
722
853
  function historyVersion(value) {
723
854
  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);
724
855
  }
725
856
  function historyProperties(value) {
726
- if (!value || typeof value != "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return invalid2();
857
+ if (!value || typeof value != "object" || Array.isArray(value) || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return invalid3();
727
858
  let descriptors = Object.getOwnPropertyDescriptors(value);
728
- return Reflect.ownKeys(value).some((key) => typeof key != "string" || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value")) ? invalid2() : descriptors;
859
+ return Reflect.ownKeys(value).some((key) => typeof key != "string" || !descriptors[key]?.enumerable || !Object.hasOwn(descriptors[key], "value")) ? invalid3() : descriptors;
729
860
  }
730
861
  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);
731
862
  function historyArray(value) {
732
- if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) return invalid2();
863
+ if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) return invalid3();
733
864
  let descriptors = Object.getOwnPropertyDescriptors(value);
734
- if (Reflect.ownKeys(value).length !== value.length + 1) return invalid2();
865
+ if (Reflect.ownKeys(value).length !== value.length + 1) return invalid3();
735
866
  let result2 = [];
736
867
  for (let i = 0; i < value.length; i++) {
737
- let descriptor2 = descriptors[i];
738
- if (!descriptor2?.enumerable || !Object.hasOwn(descriptor2, "value")) return invalid2();
739
- result2.push(descriptor2.value);
868
+ let descriptor = descriptors[i];
869
+ if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value")) return invalid3();
870
+ result2.push(descriptor.value);
740
871
  }
741
872
  return result2;
742
873
  }
743
874
  function captureOptions(value, changes) {
744
875
  if (value === void 0) return {};
745
876
  let descriptors = historyProperties(value), result2 = {}, allowed = changes ? ["collections", "refs", "from", "through", "limit", "after"] : ["limit", "before"];
746
- if (Object.keys(descriptors).some((key) => !allowed.includes(key))) return invalid2();
877
+ if (Object.keys(descriptors).some((key) => !allowed.includes(key))) return invalid3();
747
878
  for (let key of allowed) {
748
879
  if (!Object.hasOwn(descriptors, key)) continue;
749
880
  let scalar = descriptors[key].value;
750
881
  if (key === "collections" || key === "refs") {
751
882
  let values = historyArray(scalar);
752
- if (!values.length || values.length > (key === "collections" ? 16 : 100) || !values.every(key === "collections" ? historyCollection : validRecordRef) || new Set(values).size !== values.length) return invalid2();
883
+ if (!values.length || values.length > (key === "collections" ? 16 : 100) || !values.every(key === "collections" ? historyCollection : validRecordRef) || new Set(values).size !== values.length) return invalid3();
753
884
  result2[key] = values;
754
885
  } else if (key === "limit") {
755
- if (!Number.isInteger(scalar) || scalar < 1 || scalar > (changes ? 500 : 100)) return invalid2();
886
+ if (!Number.isInteger(scalar) || scalar < 1 || scalar > (changes ? 500 : 100)) return invalid3();
756
887
  result2.limit = scalar;
757
888
  } else {
758
- if (!(key === "after" ? historyCursor(scalar) : historyVersion(scalar))) return invalid2();
889
+ if (!(key === "after" ? historyCursor(scalar) : historyVersion(scalar))) return invalid3();
759
890
  result2[key] = scalar;
760
891
  }
761
892
  }
@@ -763,39 +894,39 @@ function captureOptions(value, changes) {
763
894
  }
764
895
  var captureHistoryListOptions = (value) => captureOptions(value, !1), captureHistoryChangesOptions = (value) => captureOptions(value, !0);
765
896
  function captureHistoryInstant(value) {
766
- if (!historyText(value) || value.length > 1024) return invalid2();
897
+ if (!historyText(value) || value.length > 1024) return invalid3();
767
898
  let match = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.\d+)?([Zz]|([+-])(\d{2}):(\d{2}))$/.exec(value);
768
- if (!match) return invalid2();
899
+ if (!match) return invalid3();
769
900
  let [year, month, day, hour, minute, second] = match.slice(1, 7).map(Number), days = new Date(Date.UTC(year, month, 0));
770
- 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;
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;
771
902
  }
772
903
 
773
- var invalid3 = () => {
904
+ var invalid4 = () => {
774
905
  throw new DataOperationError("invalid_query");
775
906
  };
776
907
  function captureRecordsSearchInput(query, options) {
777
- if (!historyText(query)) return invalid3();
908
+ if (!historyText(query)) return invalid4();
778
909
  let length = [...query.trim()].length;
779
- if (length < 1 || length > 256) return invalid3();
910
+ if (length < 1 || length > 256) return invalid4();
780
911
  if (options === void 0) return { query };
781
912
  let descriptors = historyProperties(options);
782
- if (Object.keys(descriptors).some((key) => !["collections", "limit"].includes(key))) return invalid3();
913
+ if (Object.keys(descriptors).some((key) => !["collections", "limit"].includes(key))) return invalid4();
783
914
  let captured = {};
784
915
  if (Object.hasOwn(descriptors, "collections")) {
785
916
  let supplied = descriptors.collections.value;
786
- if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1) return invalid3();
917
+ if (!Array.isArray(supplied) || supplied.length < 1 || supplied.length > 16 || Reflect.ownKeys(supplied).length !== supplied.length + 1) return invalid4();
787
918
  let collections = [];
788
919
  for (let index = 0; index < supplied.length; index++) {
789
- let descriptor2 = Object.getOwnPropertyDescriptor(supplied, String(index));
790
- if (!descriptor2?.enumerable || !Object.hasOwn(descriptor2, "value") || !historyText(descriptor2.value)) return invalid3();
791
- collections.push(descriptor2.value);
920
+ let descriptor = Object.getOwnPropertyDescriptor(supplied, String(index));
921
+ if (!descriptor?.enumerable || !Object.hasOwn(descriptor, "value") || !historyText(descriptor.value)) return invalid4();
922
+ collections.push(descriptor.value);
792
923
  }
793
- if (new Set(collections).size !== collections.length) return invalid3();
924
+ if (new Set(collections).size !== collections.length) return invalid4();
794
925
  captured.collections = collections;
795
926
  }
796
927
  if (Object.hasOwn(descriptors, "limit")) {
797
928
  let supplied = descriptors.limit.value;
798
- if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100) return invalid3();
929
+ if (!Number.isInteger(supplied) || supplied < 1 || supplied > 100) return invalid4();
799
930
  captured.limit = supplied;
800
931
  }
801
932
  return { query, options: captured };
@@ -826,8 +957,8 @@ function captureDataDelete(record3) {
826
957
  return !validRecordRef(identity.$ref) || typeof identity.$version != "string" || !identity.$version.length || identity.$version.length > 512 ? invalidChange() : { ref: identity.$ref, expectedVersion: identity.$version };
827
958
  }
828
959
  function captureDataUpdate(record3, set) {
829
- let identity = captureDataDelete(record3), fields5 = mapping(set);
830
- return !Object.keys(fields5).length || Object.keys(fields5).some((key) => key.startsWith("$") || ["id", "type"].includes(key)) ? invalidChange() : { ...identity, set: captureValue(fields5) };
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) };
831
962
  }
832
963
  function captureIdentities(value, update, allowEmpty = !0) {
833
964
  if (!Array.isArray(value) || !allowEmpty && !value.length || value.length > 1e4) return invalidChange();
@@ -846,14 +977,14 @@ function captureDataCreate(value) {
846
977
  let row = mapping(value);
847
978
  if (!validRecordRef(row.$ref) || Object.keys(row).some((key) => key.startsWith("$") && !["$ref", "$filing"].includes(key)))
848
979
  return invalidChange();
849
- let { $ref: ref, $filing, ...fields5 } = row, filing;
980
+ let { $ref: ref, $filing, ...fields6 } = row, filing;
850
981
  if ($filing !== void 0) {
851
982
  let components = mapping($filing);
852
983
  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)))
853
984
  return invalidChange();
854
985
  filing = { ...components };
855
986
  }
856
- return { ref, fields: captureValue(fields5), ...filing ? { filing } : {} };
987
+ return { ref, fields: captureValue(fields6), ...filing ? { filing } : {} };
857
988
  }
858
989
  function captureDataChanges(updatesValue, createsValue = [], deletesValue = []) {
859
990
  let updates = captureDataUpdates(updatesValue, !0);
@@ -861,8 +992,8 @@ function captureDataChanges(updatesValue, createsValue = [], deletesValue = [])
861
992
  let creates = createsValue.map((item) => {
862
993
  let row = mapping(item);
863
994
  if (Object.keys(row).some((key) => !["ref", "fields", "filing"].includes(key)) || !Object.hasOwn(row, "ref") || !Object.hasOwn(row, "fields")) return invalidChange();
864
- let fields5 = mapping(row.fields);
865
- return Object.keys(fields5).some((key) => key.startsWith("$")) ? invalidChange() : captureDataCreate({ ...fields5, $ref: row.ref, ...Object.hasOwn(row, "filing") ? { $filing: row.filing } : {} });
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 } : {} });
866
997
  }), deletes = captureIdentities(deletesValue, !1), refs = [...updates, ...creates, ...deletes].map((item) => item.ref);
867
998
  return !refs.length || refs.length > 1e4 || new Set(refs).size !== refs.length ? invalidChange() : { updates, creates, deletes };
868
999
  }
@@ -1047,7 +1178,7 @@ var data = {
1047
1178
  }
1048
1179
  };
1049
1180
 
1050
- 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 = {
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 = {
1051
1182
  400: ["invalid_input", "unsupported_context"],
1052
1183
  401: ["unauthenticated"],
1053
1184
  403: ["access_denied"],
@@ -1064,7 +1195,7 @@ async function boundedBytes(stream, limit) {
1064
1195
  for (; ; ) {
1065
1196
  let { done, value } = await reader.read();
1066
1197
  if (done) break;
1067
- if (!(value instanceof Uint8Array)) throw invalid4();
1198
+ if (!(value instanceof Uint8Array)) throw invalid5();
1068
1199
  if (size += value.byteLength, size > limit) throw new FileOperationError("request_too_large", 413);
1069
1200
  bytes.set(value, size - value.byteLength);
1070
1201
  }
@@ -1115,7 +1246,7 @@ async function hostedContent(url, init2, parent, upstream = fetch) {
1115
1246
  reader?.releaseLock();
1116
1247
  }
1117
1248
  }
1118
- }, body2 = new ReadableStream({
1249
+ }, body = new ReadableStream({
1119
1250
  async pull(controller) {
1120
1251
  try {
1121
1252
  reader ??= source.getReader();
@@ -1129,7 +1260,7 @@ async function hostedContent(url, init2, parent, upstream = fetch) {
1129
1260
  }
1130
1261
  },
1131
1262
  cancel
1132
- }, { highWaterMark: 0 }), wrapped = new Response(body2, { status: response2.status, statusText: response2.statusText, headers: response2.headers });
1263
+ }, { highWaterMark: 0 }), wrapped = new Response(body, { status: response2.status, statusText: response2.statusText, headers: response2.headers });
1133
1264
  for (let key of ["url", "redirected", "type"])
1134
1265
  Object.defineProperty(wrapped, key, { value: response2[key] });
1135
1266
  return wrapped;
@@ -1137,7 +1268,7 @@ async function hostedContent(url, init2, parent, upstream = fetch) {
1137
1268
  throw detach(), delivery.abort(error), error;
1138
1269
  }
1139
1270
  }
1140
- async function send(suffix, init2, descriptor2, initial, parent) {
1271
+ async function send(suffix, init2, descriptor, initial, parent) {
1141
1272
  let original = initial, checkCurrent = (context2 = original) => {
1142
1273
  if (parent?.aborted) throw unavailable();
1143
1274
  if (!original.isCurrent() || context2.url !== original.url) throw new FileOperationError("unsupported_context", 400);
@@ -1148,20 +1279,20 @@ async function send(suffix, init2, descriptor2, initial, parent) {
1148
1279
  checkCurrent(context2);
1149
1280
  try {
1150
1281
  let response2 = await (async () => {
1151
- let url = `${context2.url}${suffix}`, request = {
1282
+ let url = `${context2.url}${suffix}`, request2 = {
1152
1283
  ...init2,
1153
1284
  signal: parent,
1154
1285
  headers: { ...context2.headers, ...init2.headers },
1155
1286
  redirect: "error",
1156
1287
  cache: "no-store"
1157
1288
  };
1158
- return descriptor2 ? fetch(url, request) : hostedContent(url, request, parent);
1289
+ return descriptor ? fetch(url, request2) : hostedContent(url, request2, parent);
1159
1290
  })();
1160
1291
  if (!response2.ok) {
1161
1292
  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);
1162
1293
  throw code ? new FileOperationError(code, response2.status, code === "capacity" || code === "unavailable") : unavailable();
1163
1294
  }
1164
- if (response2.status !== (descriptor2 === 204 ? 204 : 200) || descriptor2 === 204 && response2.body !== null)
1295
+ if (response2.status !== (descriptor === 204 ? 204 : 200) || descriptor === 204 && response2.body !== null)
1165
1296
  throw response2.body?.cancel().catch(() => {
1166
1297
  }), unavailable();
1167
1298
  try {
@@ -1170,13 +1301,13 @@ async function send(suffix, init2, descriptor2, initial, parent) {
1170
1301
  throw response2.body?.cancel().catch(() => {
1171
1302
  }), error;
1172
1303
  }
1173
- if (descriptor2 === 204) return;
1174
- if (!descriptor2) return response2;
1175
- let value = await result(response2, descriptor2 === "control" ? CONTROL_RESULT_BYTES : RESULT_BYTES);
1176
- if (descriptor2 === "control")
1304
+ if (descriptor === 204) return;
1305
+ if (!descriptor) return response2;
1306
+ let value = await result(response2, descriptor === "control" ? CONTROL_RESULT_BYTES : RESULT_BYTES);
1307
+ if (descriptor === "control")
1177
1308
  return checkCurrent(), value;
1178
1309
  let parsed;
1179
- if (descriptor2 === "enrichment") {
1310
+ if (descriptor === "enrichment") {
1180
1311
  if (!value || typeof value != "object" || Array.isArray(value)) throw unavailable();
1181
1312
  let { name, ...metadata } = value;
1182
1313
  if (!safeEnrichmentName(name)) throw unavailable();
@@ -1191,22 +1322,22 @@ async function send(suffix, init2, descriptor2, initial, parent) {
1191
1322
  throw unavailable();
1192
1323
  }
1193
1324
  function idPath(id3) {
1194
- if (typeof id3 != "string" || !FILE_ID_PATTERN.test(id3)) throw invalid4();
1325
+ if (typeof id3 != "string" || !FILE_ID_PATTERN.test(id3)) throw invalid5();
1195
1326
  return `/${id3}`;
1196
1327
  }
1197
1328
  async function multipartCreate(input, metadata, exchange, release = () => {
1198
1329
  active--;
1199
1330
  }, upload) {
1200
- 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) => {
1331
+ 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) => {
1201
1332
  let task = work(signal);
1202
1333
  return pending.add(task), task.then(() => pending.delete(task), () => pending.delete(task)), task;
1203
- }, void 0, timeout), control = (body2) => ({
1334
+ }, void 0, timeout), control = (body) => ({
1204
1335
  method: "POST",
1205
1336
  headers: { "content-type": "application/json", ...ticket ? { "x-oddington-transfer": ticket } : {} },
1206
- body: JSON.stringify(body2)
1337
+ body: JSON.stringify(body)
1207
1338
  });
1208
1339
  try {
1209
- let start = await request((signal) => exchange(`${route}/start`, control(upload?.file ?? metadata), "control", signal));
1340
+ let start = await request2((signal) => exchange(`${route}/start`, control(upload?.file ?? metadata), "control", signal));
1210
1341
  if (!start || typeof start != "object" || Array.isArray(start)) throw unavailable();
1211
1342
  let session = start;
1212
1343
  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();
@@ -1214,7 +1345,7 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1214
1345
  let lastProgress = Date.now(), next = async () => {
1215
1346
  try {
1216
1347
  if (Date.now() - lastProgress >= TIMEOUT_MS) throw unavailable();
1217
- let value = await request(() => reader.read(), Math.max(1, TIMEOUT_MS - (Date.now() - lastProgress)));
1348
+ let value = await request2(() => reader.read(), Math.max(1, TIMEOUT_MS - (Date.now() - lastProgress)));
1218
1349
  return value.value?.byteLength && (lastProgress = Date.now()), value;
1219
1350
  } catch (error) {
1220
1351
  throw await reader.cancel(error).catch(() => {
@@ -1226,7 +1357,7 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1226
1357
  if (input.file instanceof Uint8Array) part = input.file.subarray(sent, sent + length).slice();
1227
1358
  else if (input.file instanceof Blob) {
1228
1359
  let slice = input.file.slice(sent, sent + length);
1229
- part = new Uint8Array(await request(() => slice.arrayBuffer()));
1360
+ part = new Uint8Array(await request2(() => slice.arrayBuffer()));
1230
1361
  } else {
1231
1362
  part = new Uint8Array(length);
1232
1363
  let filled = 0;
@@ -1234,20 +1365,20 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1234
1365
  if (!chunk || offset === chunk.byteLength) {
1235
1366
  chunk = void 0, offset = 0;
1236
1367
  let value2 = await next();
1237
- if (value2.done || !(value2.value instanceof Uint8Array) || (chunk = value2.value, chunk.byteLength > metadata.size - sent - filled)) throw invalid4();
1368
+ if (value2.done || !(value2.value instanceof Uint8Array) || (chunk = value2.value, chunk.byteLength > metadata.size - sent - filled)) throw invalid5();
1238
1369
  }
1239
1370
  let take = Math.min(length - filled, chunk.byteLength - offset);
1240
1371
  part.set(chunk.subarray(offset, offset + take), filled), filled += take, offset += take, offset === chunk.byteLength && (chunk = void 0, offset = 0);
1241
1372
  }
1242
1373
  }
1243
- if (part.byteLength !== length) throw invalid4();
1374
+ if (part.byteLength !== length) throw invalid5();
1244
1375
  if (reader && sent + length === metadata.size)
1245
1376
  for (lastProgress = Date.now(); ; ) {
1246
1377
  let value2 = await next();
1247
1378
  if (value2.done) break;
1248
- if (!(value2.value instanceof Uint8Array) || value2.value.byteLength) throw invalid4();
1379
+ if (!(value2.value instanceof Uint8Array) || value2.value.byteLength) throw invalid5();
1249
1380
  }
1250
- let value = await request((signal) => exchange(`${route}/part`, {
1381
+ let value = await request2((signal) => exchange(`${route}/part`, {
1251
1382
  method: "POST",
1252
1383
  headers: { "content-type": "application/octet-stream", "x-oddington-transfer": ticket, "x-oddington-part": String(partNumber) },
1253
1384
  body: part.buffer
@@ -1258,9 +1389,9 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1258
1389
  receipts.push({ partNumber, etag: receipt.etag }), sent += length, lastProgress = Date.now();
1259
1390
  }
1260
1391
  if (upload) for (let name of Object.keys(upload.file.enrichments)) {
1261
- let bytes = await request(() => upload.enrichment(name));
1262
- if (bytes.byteLength !== upload.file.enrichments[name].size || bytes.byteLength > MAX_BYTES) throw invalid4();
1263
- await request((signal) => exchange(`${route}/enrichments/${encodeURIComponent(name)}`, {
1392
+ let bytes = await request2(() => upload.enrichment(name));
1393
+ if (bytes.byteLength !== upload.file.enrichments[name].size || bytes.byteLength > MAX_BYTES) throw invalid5();
1394
+ await request2((signal) => exchange(`${route}/enrichments/${encodeURIComponent(name)}`, {
1264
1395
  method: "POST",
1265
1396
  headers: { "content-type": "application/octet-stream", "x-oddington-transfer": ticket },
1266
1397
  body: bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength)
@@ -1269,13 +1400,13 @@ async function multipartCreate(input, metadata, exchange, release = () => {
1269
1400
  await upload?.beforeComplete();
1270
1401
  let completion = control({ parts: receipts });
1271
1402
  if (new TextEncoder().encode(completion.body).byteLength > 128 * 1024) throw unavailable();
1272
- return parseFileDescriptor(await request(
1403
+ return parseFileDescriptor(await request2(
1273
1404
  (signal) => exchange(`${route}/complete`, completion, !0, signal),
1274
1405
  TIMEOUT_MS + Math.ceil(metadata.size / (1024 * 1024)) * 1e3
1275
1406
  ));
1276
1407
  } catch (error) {
1277
1408
  throw reader && await reader.cancel(error).catch(() => {
1278
- }), ticket && await request((signal) => exchange(`${route}/abort`, control({}), "control", signal)).catch(() => {
1409
+ }), ticket && await request2((signal) => exchange(`${route}/abort`, control({}), "control", signal)).catch(() => {
1279
1410
  }), error instanceof FileOperationError ? error : unavailable();
1280
1411
  } finally {
1281
1412
  chunk = void 0, reader?.releaseLock(), pending.size ? Promise.allSettled([...pending]).then(release) : release();
@@ -1297,7 +1428,7 @@ async function operation(work, initial, parent) {
1297
1428
  function contentPath(id3, name) {
1298
1429
  let path = idPath(id3);
1299
1430
  if (name === void 0) return `${path}/content`;
1300
- if (!safeEnrichmentName(name)) throw invalid4();
1431
+ if (!safeEnrichmentName(name)) throw invalid5();
1301
1432
  return `${path}/enrichments/${encodeURIComponent(name)}/content`;
1302
1433
  }
1303
1434
  async function read(id3, names) {
@@ -1306,12 +1437,12 @@ async function read(id3, names) {
1306
1437
  let path = contentPath(id3, names);
1307
1438
  return operation((context3, signal) => send(path, { method: "GET" }, !1, context3, signal), context2);
1308
1439
  }
1309
- if (!Array.isArray(names)) throw invalid4();
1440
+ if (!Array.isArray(names)) throw invalid5();
1310
1441
  let distinct = [], seen = /* @__PURE__ */ new Set();
1311
1442
  for (let name of names) {
1312
- if (typeof name != "string" || !safeEnrichmentName(name)) throw invalid4();
1443
+ if (typeof name != "string" || !safeEnrichmentName(name)) throw invalid5();
1313
1444
  if (!seen.has(name)) {
1314
- if (seen.size === 16) throw invalid4();
1445
+ if (seen.size === 16) throw invalid5();
1315
1446
  seen.add(name), distinct.push(name);
1316
1447
  }
1317
1448
  }
@@ -1346,11 +1477,11 @@ var files = {
1346
1477
  async create(input, options) {
1347
1478
  let context2 = await resolveFilesContext();
1348
1479
  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")))
1349
- throw invalid4();
1480
+ throw invalid5();
1350
1481
  let blob = input.file instanceof Blob, array3 = input.file instanceof Uint8Array, stream = input.file instanceof ReadableStream;
1351
- if (!blob && !array3 && !stream) throw invalid4();
1482
+ if (!blob && !array3 && !stream) throw invalid5();
1352
1483
  let intrinsic = blob ? input.file.size : array3 ? input.file.byteLength : void 0;
1353
- if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid4();
1484
+ if (intrinsic !== void 0 && input.size !== void 0 && input.size !== intrinsic) throw invalid5();
1354
1485
  let name = input.name;
1355
1486
  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));
1356
1487
  let metadata = parseFileCreateMetadata({
@@ -1364,7 +1495,7 @@ var files = {
1364
1495
  }, FILE_ORIGINAL_MAX_BYTES);
1365
1496
  if (!context2.local && metadata.storage === "local") throw new FileOperationError("unsupported_context", 400);
1366
1497
  let header = encodeURIComponent(JSON.stringify(metadata));
1367
- if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid4();
1498
+ if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid5();
1368
1499
  if (active >= MAX_ACTIVE) throw new FileOperationError("capacity", 429, !0);
1369
1500
  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) => {
1370
1501
  try {
@@ -1372,7 +1503,7 @@ var files = {
1372
1503
  blob ? input.file.stream() : input.file,
1373
1504
  metadata.size
1374
1505
  );
1375
- if (bytes.byteLength !== metadata.size) throw invalid4();
1506
+ if (bytes.byteLength !== metadata.size) throw invalid5();
1376
1507
  if (signal.aborted) throw unavailable();
1377
1508
  return await send("", {
1378
1509
  method: "POST",
@@ -1388,7 +1519,7 @@ var files = {
1388
1519
  },
1389
1520
  async enrich(input) {
1390
1521
  let context2 = await resolveFilesContext();
1391
- 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();
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();
1392
1523
  let path = `${idPath(input.file)}/enrichments`;
1393
1524
  if (typeof input.content == "string" ? input.content.length > MAX_BYTES : input.content.byteLength > MAX_BYTES)
1394
1525
  throw new FileOperationError("request_too_large", 413);
@@ -1405,7 +1536,7 @@ var files = {
1405
1536
  ...input.mediaType === void 0 ? {} : { mediaType: input.mediaType },
1406
1537
  ...input.replace === void 0 ? {} : { replace: input.replace }
1407
1538
  }, MAX_BYTES), header = encodeURIComponent(JSON.stringify(metadata));
1408
- if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid4();
1539
+ if (new TextEncoder().encode(header).byteLength > METADATA_BYTES) throw invalid5();
1409
1540
  let result2 = await send(path, { method: "POST", headers: {
1410
1541
  "content-type": "application/octet-stream",
1411
1542
  "x-oddington-enrichment": header
@@ -1441,8 +1572,8 @@ function parseConnectionLease(raw, now = Date.now()) {
1441
1572
  }
1442
1573
 
1443
1574
  var AirtableOperationError = class extends Error {
1444
- constructor(message, effect = "unapplied", receipts = []) {
1445
- super(message);
1575
+ constructor(message2, effect = "unapplied", receipts = []) {
1576
+ super(message2);
1446
1577
  this.effect = effect;
1447
1578
  this.receipts = receipts;
1448
1579
  this.name = "AirtableOperationError";
@@ -1452,10 +1583,10 @@ var AirtableOperationError = class extends Error {
1452
1583
  };
1453
1584
 
1454
1585
  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);
1455
- function fail2(message) {
1456
- throw new AirtableOperationError(message);
1586
+ function fail2(message2) {
1587
+ throw new AirtableOperationError(message2);
1457
1588
  }
1458
- function object2(v) {
1589
+ function object3(v) {
1459
1590
  return (!v || typeof v != "object" || Array.isArray(v) || ![null, Object.prototype].includes(Object.getPrototypeOf(v))) && fail2("Invalid Airtable data"), v;
1460
1591
  }
1461
1592
  function keys2(v, allowed, required = allowed) {
@@ -1464,8 +1595,8 @@ function keys2(v, allowed, required = allowed) {
1464
1595
  function text2(v) {
1465
1596
  return typeof v == "string" && v.length > 0 && v.length <= 1024;
1466
1597
  }
1467
- function fields3(v, nonempty = !1) {
1468
- let result2 = object2(v);
1598
+ function fields4(v, nonempty = !1) {
1599
+ let result2 = object3(v);
1469
1600
  (nonempty && !Object.keys(result2).length || Object.keys(result2).some((k) => !text2(k))) && fail2("Invalid Airtable fields");
1470
1601
  try {
1471
1602
  return serializable(result2);
@@ -1474,8 +1605,8 @@ function fields3(v, nonempty = !1) {
1474
1605
  }
1475
1606
  }
1476
1607
  function record2(v) {
1477
- let r = object2(v);
1478
- 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) };
1608
+ 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) };
1479
1610
  }
1480
1611
  function equal(a, b) {
1481
1612
  if (a === b) return !0;
@@ -1507,7 +1638,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1507
1638
  (!/^[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");
1508
1639
  let input;
1509
1640
  try {
1510
- input = object2(serializable(raw));
1641
+ input = object3(serializable(raw));
1511
1642
  } catch {
1512
1643
  return fail2("Invalid Airtable input");
1513
1644
  }
@@ -1519,7 +1650,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1519
1650
  operation: operation2.slice(8),
1520
1651
  records: ids2.map((id3) => ({ id: id3 }))
1521
1652
  });
1522
- async function request(path2, init2 = {}, write = !1) {
1653
+ async function request2(path2, init2 = {}, write = !1) {
1523
1654
  let response2;
1524
1655
  try {
1525
1656
  response2 = await (options.fetch ?? fetch)(`https://api.airtable.com/v0/${path2}`, {
@@ -1536,7 +1667,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1536
1667
  }), new AirtableOperationError("Airtable request rejected", write && (response2.status >= 500 || response2.status === 408 || response2.status < 400) ? "uncertain" : "unapplied");
1537
1668
  try {
1538
1669
  if (!response2.headers.get("content-type")?.toLowerCase().includes("application/json")) throw new Error();
1539
- let value = object2(await response2.json()), safe = serializable(value);
1670
+ let value = object3(await response2.json()), safe = serializable(value);
1540
1671
  if (Object.hasOwn(value, "error") || JSON.stringify(safe).includes(accessToken)) throw new Error();
1541
1672
  return value;
1542
1673
  } catch {
@@ -1547,13 +1678,13 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1547
1678
  keys2(input, []);
1548
1679
  let tables = [], seen = /* @__PURE__ */ new Set(), offset;
1549
1680
  do {
1550
- let query2 = new URLSearchParams(offset ? { offset } : {}), page = await request(`meta/bases/${baseId}/tables?${query2}`);
1681
+ let query2 = new URLSearchParams(offset ? { offset } : {}), page = await request2(`meta/bases/${baseId}/tables?${query2}`);
1551
1682
  Array.isArray(page.tables) || fail2("Malformed Airtable tables");
1552
1683
  for (let value of page.tables) {
1553
- let t = object2(value);
1684
+ let t = object3(value);
1554
1685
  (!tableId(t.id) || !text2(t.name) || !text2(t.primaryFieldId) || !Array.isArray(t.fields) || tables.some((existing) => existing.id === t.id)) && fail2("Malformed Airtable table");
1555
1686
  let metadata = t.fields.map((value2) => {
1556
- let f = object2(value2);
1687
+ let f = object3(value2);
1557
1688
  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) } };
1558
1689
  });
1559
1690
  (!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 });
@@ -1566,7 +1697,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1566
1697
  let path = `${baseId}/${encodeURIComponent(input.table)}`;
1567
1698
  if (operation2 === "records.get") {
1568
1699
  keys2(input, ["table", "id"]), recordId(input.id) || fail2("Invalid Airtable record ID");
1569
- let result3 = record2(await request(`${path}/${input.id}`));
1700
+ let result3 = record2(await request2(`${path}/${input.id}`));
1570
1701
  return result3.id !== input.id && fail2("Malformed Airtable record"), result3;
1571
1702
  }
1572
1703
  if (operation2 === "records.list") {
@@ -1576,7 +1707,7 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1576
1707
  let query2 = new URLSearchParams();
1577
1708
  for (let field of input.fields ?? []) query2.append("fields[]", field);
1578
1709
  offset && query2.set("offset", offset);
1579
- let page = await request(`${path}?${query2}`);
1710
+ let page = await request2(`${path}?${query2}`);
1580
1711
  Array.isArray(page.records) || fail2("Malformed Airtable records");
1581
1712
  for (let value of page.records) {
1582
1713
  let r = record2(value);
@@ -1588,15 +1719,15 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1588
1719
  }
1589
1720
  mutation || fail2("Unsupported Airtable operation"), keys2(input, ["table", "records"]), (!Array.isArray(input.records) || !input.records.length || input.records.length > 10) && fail2("Invalid Airtable batch");
1590
1721
  let kind = operation2.slice(8), ids = /* @__PURE__ */ new Set(), records = input.records.map((value) => {
1591
- let r = object2(value);
1592
- if (keys2(r, kind === "create" ? ["fields"] : kind === "update" ? ["id", "expected", "set"] : ["id", "expected"]), kind === "create") return { fields: fields3(r.fields, !0) };
1722
+ 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) };
1593
1724
  (!recordId(r.id) || ids.has(r.id)) && fail2("Invalid Airtable batch record ID"), ids.add(r.id);
1594
- let set = kind === "update" ? fields3(r.set, !0) : void 0;
1595
- 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 } : {} };
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 } : {} };
1596
1727
  });
1597
1728
  for (let r of records) {
1598
1729
  if (!("id" in r)) continue;
1599
- let current2 = record2(await request(`${path}/${r.id}`));
1730
+ let current2 = record2(await request2(`${path}/${r.id}`));
1600
1731
  current2.id !== r.id && fail2("Malformed Airtable record");
1601
1732
  for (let [key, value] of Object.entries(r.expected))
1602
1733
  (value === null ? Object.hasOwn(current2.fields, key) : !Object.hasOwn(current2.fields, key) || !equal(current2.fields[key], value)) && fail2("Airtable reviewed values are stale");
@@ -1604,14 +1735,14 @@ async function executeAirtableOperation(authority, operation2, raw, options = {}
1604
1735
  await options.beforeMutation?.();
1605
1736
  let query = new URLSearchParams();
1606
1737
  if (kind === "delete") for (let id3 of ids) query.append("records[]", id3);
1607
- let result2 = await request(`${path}${kind === "delete" ? `?${query}` : ""}`, {
1738
+ let result2 = await request2(`${path}${kind === "delete" ? `?${query}` : ""}`, {
1608
1739
  method: kind === "create" ? "POST" : kind === "update" ? "PATCH" : "DELETE",
1609
1740
  ...kind === "delete" ? {} : { body: JSON.stringify({ records: records.map((r) => "id" in r ? { id: r.id, fields: r.set } : r) }) }
1610
1741
  }, !0), acknowledged = [], returned = [];
1611
1742
  try {
1612
1743
  if (!Array.isArray(result2.records)) throw new Error();
1613
1744
  for (let value of result2.records) {
1614
- let r = object2(value);
1745
+ let r = object3(value);
1615
1746
  if (!recordId(r.id) || acknowledged.includes(r.id) || kind !== "create" && !ids.has(r.id) || kind === "delete" && r.deleted !== !0) throw new Error();
1616
1747
  acknowledged.push(r.id), kind !== "delete" && returned.push(record2(r));
1617
1748
  }
@@ -1713,8 +1844,8 @@ var connections = /* @__PURE__ */ createConnections(async (name, operation2, inp
1713
1844
  var LOCAL_ROUTINE_VALUE_BYTES = 256 * 1024;
1714
1845
 
1715
1846
  var RECORD_WRITE_INPUT_LIMIT = 8 * 1024 * 1024, RoutineRecordWriteError = class extends Error {
1716
- constructor(message, effect) {
1717
- super(message);
1847
+ constructor(message2, effect) {
1848
+ super(message2);
1718
1849
  this.effect = effect;
1719
1850
  this.name = "RoutineRecordWriteError";
1720
1851
  }
@@ -1765,10 +1896,10 @@ function validateRecordChange(value) {
1765
1896
  return writes.length && validateRecordWrite({ repository: input.repository, records: writes }), deletes.length && validateRecordDelete({ repository: input.repository, records: deletes }), structuredClone(input);
1766
1897
  }
1767
1898
  function validateRoutineRecordWrite(value) {
1768
- let body2 = serializable(value);
1769
- 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)
1899
+ let body = serializable(value);
1900
+ 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)
1770
1901
  throw new InboxContractError("A stable routine request key is required");
1771
- return { input: validateRecordChange(body2.input), requestKey: body2.requestKey };
1902
+ return { input: validateRecordChange(body.input), requestKey: body.requestKey };
1772
1903
  }
1773
1904
  function validCreatePath(value) {
1774
1905
  return value === value.trim() && value.endsWith(".md") && !value.startsWith("/") && value.split("/").every((segment) => !!segment && ![".", ".."].includes(segment) && /^[a-zA-Z0-9_.-]+$/.test(segment));
@@ -1804,10 +1935,10 @@ var operations = {
1804
1935
  function assert(value) {
1805
1936
  if (!value) throw new Error("Invalid Inbox result");
1806
1937
  }
1807
- function object3(value) {
1938
+ function object4(value) {
1808
1939
  return assert(value && typeof value == "object" && !Array.isArray(value) && [Object.prototype, null].includes(Object.getPrototypeOf(value)) && Reflect.ownKeys(value).every((key) => {
1809
- let descriptor2 = typeof key == "string" ? Object.getOwnPropertyDescriptor(value, key) : void 0;
1810
- return !!descriptor2?.enumerable && "value" in descriptor2;
1940
+ let descriptor = typeof key == "string" ? Object.getOwnPropertyDescriptor(value, key) : void 0;
1941
+ return !!descriptor?.enumerable && "value" in descriptor;
1811
1942
  })), value;
1812
1943
  }
1813
1944
  function keys3(value, allowed, required = allowed) {
@@ -1830,41 +1961,41 @@ function optionalDate(value) {
1830
1961
  }
1831
1962
  function array2(value) {
1832
1963
  return assert(Array.isArray(value) && Object.getPrototypeOf(value) === Array.prototype && Reflect.ownKeys(value).length === value.length + 1 && value.every((_entry, index) => {
1833
- let descriptor2 = Object.getOwnPropertyDescriptor(value, String(index));
1834
- return !!descriptor2?.enumerable && "value" in descriptor2;
1964
+ let descriptor = Object.getOwnPropertyDescriptor(value, String(index));
1965
+ return !!descriptor?.enumerable && "value" in descriptor;
1835
1966
  })), value;
1836
1967
  }
1837
1968
  function json2(value, ancestors = /* @__PURE__ */ new Set()) {
1838
1969
  if (value === null || typeof value == "boolean" || typeof value == "string" || typeof value == "number" && Number.isFinite(value)) return value;
1839
1970
  assert(value && typeof value == "object" && !ancestors.has(value)), ancestors.add(value);
1840
1971
  try {
1841
- return Array.isArray(value) ? array2(value).map((entry) => json2(entry, ancestors)) : Object.fromEntries(Object.entries(object3(value)).map(([key, entry]) => [key, json2(entry, ancestors)]));
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)]));
1842
1973
  } finally {
1843
1974
  ancestors.delete(value);
1844
1975
  }
1845
1976
  }
1846
1977
  function recordReference(value) {
1847
- let record3 = object3(value);
1978
+ let record3 = object4(value);
1848
1979
  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;
1849
1980
  }
1850
1981
  function responseDefinition(value) {
1851
- let definition = object3(value);
1982
+ let definition = object4(value);
1852
1983
  keys3(definition, ["type", "source"]), assert(definition.type === "selection");
1853
- let source = object3(definition.source);
1984
+ let source = object4(definition.source);
1854
1985
  if (source.type === "authored") {
1855
1986
  keys3(source, ["type", "options", "suggestions", "search"], ["type", "options"]);
1856
1987
  let options = array2(source.options);
1857
1988
  assert(options.length > 0);
1858
1989
  let values = options.map((value2) => {
1859
- let option = object3(value2);
1990
+ let option = object4(value2);
1860
1991
  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) {
1861
- let note = object3(option.note);
1992
+ let note = object4(option.note);
1862
1993
  keys3(note, ["placeholder"]), assert(text3(note.placeholder));
1863
1994
  }
1864
1995
  return option.value;
1865
1996
  });
1866
1997
  if (assert(new Set(values).size === values.length), "search" in source || "suggestions" in source) {
1867
- let search = object3(source.search);
1998
+ let search = object4(source.search);
1868
1999
  keys3(search, ["triggerLabel", "placeholder", "emptyLabel"]), assert(text3(search.triggerLabel) && text3(search.placeholder) && text3(search.emptyLabel));
1869
2000
  let suggestions2 = array2(source.suggestions);
1870
2001
  assert(suggestions2.length <= 8 && suggestions2.every((value2) => text3(value2) && values.includes(value2)) && new Set(suggestions2).size === suggestions2.length);
@@ -1872,16 +2003,16 @@ function responseDefinition(value) {
1872
2003
  return;
1873
2004
  }
1874
2005
  assert(source.type === "records"), keys3(source, ["type", "collection", "refPrefix", "where", "display", "suggestions"], ["type", "collection", "display"]);
1875
- let collection = object3(source.collection);
2006
+ let collection = object4(source.collection);
1876
2007
  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));
1877
- let where = object3(source.where ?? {});
2008
+ let where = object4(source.where ?? {});
1878
2009
  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))));
1879
- let display = object3(source.display);
2010
+ let display = object4(source.display);
1880
2011
  keys3(display, ["labelFields"]);
1881
2012
  let labels = array2(display.labelFields);
1882
2013
  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)));
1883
2014
  let suggestions = array2(source.suggestions ?? []), refs = suggestions.map((value2) => {
1884
- let suggestion = object3(value2);
2015
+ let suggestion = object4(value2);
1885
2016
  keys3(suggestion, ["record", "reason"], ["record"]);
1886
2017
  let record3 = recordReference(suggestion.record);
1887
2018
  return assert(record3.repository === collection.repository), "reason" in suggestion && assert(text3(suggestion.reason)), record3.ref;
@@ -1889,20 +2020,20 @@ function responseDefinition(value) {
1889
2020
  assert(suggestions.length <= 8 && new Set(refs).size === refs.length);
1890
2021
  }
1891
2022
  function inboxFile(value) {
1892
- let file2 = object3(value);
2023
+ let file2 = object4(value);
1893
2024
  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));
1894
- let details = object3(file2.details);
2025
+ let details = object4(file2.details);
1895
2026
  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)));
1896
2027
  }
1897
- function fields4(value) {
2028
+ function fields5(value) {
1898
2029
  let labels = array2(value).map((value2) => {
1899
- let field = object3(value2);
2030
+ let field = object4(value2);
1900
2031
  return keys3(field, ["label", "value"]), assert(text3(field.label) && text3(field.value)), field.label;
1901
2032
  });
1902
2033
  assert(new Set(labels).size === labels.length);
1903
2034
  }
1904
2035
  function block(value) {
1905
- let entry = object3(value);
2036
+ let entry = object4(value);
1906
2037
  if (entry.kind === "rich-text") {
1907
2038
  keys3(entry, ["kind", "markdown"]), assert(text3(entry.markdown));
1908
2039
  return;
@@ -1918,112 +2049,112 @@ function block(value) {
1918
2049
  ["kind", "label", "initiallyExpanded", ...entry.kind === "record" ? ["record", "view"] : entry.kind === "records" ? ["records", "view"] : ["files"]],
1919
2050
  ["kind", "label", entry.kind === "record" ? "record" : entry.kind === "records" ? "records" : "files"]
1920
2051
  ), 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") {
1921
- let record3 = object3(entry.record);
1922
- keys3(record3, ["ref", "title", "fields"]), assert(text3(record3.ref) && record3.ref === record3.ref.trim() && text3(record3.title)), fields4(record3.fields);
2052
+ 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);
1923
2054
  return;
1924
2055
  }
1925
2056
  if (entry.kind === "records") {
1926
2057
  let records = array2(entry.records), refs = records.map((value2) => {
1927
- let record3 = object3(value2);
1928
- 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;
2058
+ 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;
1929
2060
  });
1930
2061
  assert(records.length > 0 && new Set(refs).size === refs.length);
1931
2062
  return;
1932
2063
  }
1933
2064
  let files3 = array2(entry.files);
1934
- files3.forEach(inboxFile), assert(files3.length > 0 && new Set(files3.map((value2) => object3(value2).id)).size === files3.length);
2065
+ files3.forEach(inboxFile), assert(files3.length > 0 && new Set(files3.map((value2) => object4(value2).id)).size === files3.length);
1935
2066
  }
1936
2067
  function response(value) {
1937
- let answer = object3(value);
2068
+ let answer = object4(value);
1938
2069
  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;
1939
2070
  }
1940
- function parseInboxRequest(value) {
2071
+ function parseInboxRequest(value, questionListContext = "local") {
1941
2072
  try {
1942
- let envelope = object3(value);
2073
+ let envelope = object4(value);
1943
2074
  assert(Object.keys(envelope).sort().join(",") === "input,operation"), assert(typeof envelope.operation == "string" && Object.hasOwn(operations, envelope.operation));
1944
- let operation2 = envelope.operation, input = object3(envelope.input), required = operations[operation2];
1945
- 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"));
2075
+ 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)));
1946
2077
  for (let key of ["itemId", "personId", "fileId"]) key in input && assert(id2(input[key]));
1947
- 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), { operation: operation2, input };
2078
+ 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 };
1948
2079
  } catch {
1949
2080
  throw new InboxOperationError(400, "invalid_input");
1950
2081
  }
1951
2082
  }
1952
2083
  function parseInboxCurrent(value) {
1953
- let current2 = object3(value), workspace = object3(current2.workspace), viewer = object3(current2.viewer);
2084
+ let current2 = object4(value), workspace = object4(current2.workspace), viewer = object4(current2.viewer);
1954
2085
  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)), {
1955
2086
  workspace: { id: workspace.id, slug: workspace.slug, name: workspace.name, locale: workspace.locale, timezone: workspace.timezone },
1956
2087
  viewer: { id: viewer.id, name: viewer.name, email: viewer.email }
1957
2088
  };
1958
2089
  }
1959
2090
  function parseInboxItem(value) {
1960
- let item = object3(json2(value));
1961
- 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) => {
1962
- let view = object3(value2);
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) => {
2093
+ let view = object4(value2);
1963
2094
  assert(text3(view.id) && text3(view.view) && text3(view.implementation)), json2(view.input);
1964
2095
  }), array2(item.people).forEach((value2) => {
1965
- let person = object3(value2);
2096
+ let person = object4(value2);
1966
2097
  assert(id2(person.id) && text3(person.name));
1967
2098
  }), array2(item.questions).forEach((value2) => {
1968
- let question2 = object3(value2);
2099
+ let question2 = object4(value2);
1969
2100
  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) {
1970
- let accepted = object3(question2.acceptedResponse);
2101
+ let accepted = object4(question2.acceptedResponse);
1971
2102
  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));
1972
2103
  }
1973
2104
  if (question2.execution !== null) {
1974
- let execution = object3(question2.execution);
2105
+ let execution = object4(question2.execution);
1975
2106
  if (assert(id2(execution.id) && ["pending", "running", "completed", "failed"].includes(String(execution.state)) && integer(execution.attempt, 0)), "consequence" in execution) {
1976
- let consequence = object3(execution.consequence);
2107
+ let consequence = object4(execution.consequence);
1977
2108
  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) => {
1978
- let receipt = object3(value3);
2109
+ let receipt = object4(value3);
1979
2110
  assert(text3(receipt.repository) && text3(receipt.commit) && text3(receipt.diff, !0));
1980
2111
  });
1981
2112
  }
1982
2113
  }
1983
2114
  }), array2(item.linkedAsks).forEach((value2) => {
1984
- let linked = object3(value2);
2115
+ let linked = object4(value2);
1985
2116
  if (assert(id2(linked.id)), linked.state === "unavailable") assert(typeof linked.done == "boolean");
1986
2117
  else if (assert(["yours", "done", "open", "theirs"].includes(String(linked.state)) && text3(linked.title)), linked.state === "theirs") {
1987
- let assignee = object3(linked.assignee);
2118
+ let assignee = object4(linked.assignee);
1988
2119
  assert(id2(assignee.id) && text3(assignee.name));
1989
2120
  }
1990
2121
  }), array2(item.activity).forEach((value2) => {
1991
- let event2 = object3(value2);
1992
- 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);
2122
+ let event = object4(value2);
2123
+ 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);
1993
2124
  }), array2(item.work).forEach((value2) => {
1994
- let work = object3(value2);
2125
+ let work = object4(value2);
1995
2126
  assert(id2(work.id) && text3(work.questionId) && text3(work.reason) && optionalDate(work.settledAt));
1996
2127
  }), item;
1997
2128
  }
1998
2129
  function parseAnswerableQuestion(value) {
1999
- let entry = object3(json2(value));
2130
+ let entry = object4(json2(value));
2000
2131
  keys3(entry, ["item", "origin", "question", "recordRefs"]);
2001
- let item = object3(entry.item);
2132
+ let item = object4(entry.item);
2002
2133
  keys3(item, ["id", "number", "revision", "title", "href"]), assert(id2(item.id) && integer(item.number) && integer(item.revision) && text3(item.title) && text3(item.href));
2003
2134
  let link = new URL(item.href), slug = link.hostname.slice(0, -13);
2004
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}`);
2005
- let origin = object3(entry.origin);
2136
+ let origin = object4(entry.origin);
2006
2137
  keys3(origin, ["routine"]), assert(text3(origin.routine) && origin.routine === origin.routine.trim());
2007
- let question2 = object3(entry.question);
2138
+ let question2 = object4(entry.question);
2008
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);
2009
2140
  let refs = array2(entry.recordRefs);
2010
2141
  return assert(refs.every((ref) => text3(ref) && ref === ref.trim()) && new Set(refs).size === refs.length), entry;
2011
2142
  }
2012
2143
  function parseInboxAcceptance(value) {
2013
- let accepted = object3(value);
2144
+ let accepted = object4(value);
2014
2145
  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;
2015
2146
  }
2016
2147
  function parseInboxResult(operation2, value) {
2017
2148
  if (operation2 === "current") return parseInboxCurrent(value);
2018
2149
  if (operation2 === "questions.list") {
2019
- let page = object3(value);
2150
+ let page = object4(value);
2020
2151
  keys3(page, ["questions", "nextBeforeNumber"]);
2021
2152
  let questions = array2(page.questions).map(parseAnswerableQuestion);
2022
2153
  return assert(page.nextBeforeNumber === null || integer(page.nextBeforeNumber)), { questions, nextBeforeNumber: page.nextBeforeNumber };
2023
2154
  }
2024
2155
  if (operation2 === "items.read") return parseInboxItem(value);
2025
2156
  if (operation2 === "items.list") {
2026
- let page = object3(value), items = array2(page.items).map(parseInboxItem);
2157
+ let page = object4(value), items = array2(page.items).map(parseInboxItem);
2027
2158
  return assert(items.length <= 100 && (page.nextBeforeNumber === null || integer(page.nextBeforeNumber))), { items, nextBeforeNumber: page.nextBeforeNumber };
2028
2159
  }
2029
2160
  if (operation2 === "items.see") {
@@ -2031,30 +2162,30 @@ function parseInboxResult(operation2, value) {
2031
2162
  return;
2032
2163
  }
2033
2164
  if (operation2 === "items.markDigestRead") {
2034
- let read2 = object3(value);
2165
+ let read2 = object4(value);
2035
2166
  return assert(integer(read2.activityId) && date(read2.readAt)), read2;
2036
2167
  }
2037
2168
  if (operation2 === "items.rename" || operation2 === "items.setLifecycle") {
2038
- let update = object3(value), item = parseInboxItem(update.item);
2169
+ let update = object4(value), item = parseInboxItem(update.item);
2039
2170
  return assert((update.activityId === null || integer(update.activityId)) && optionalDate(update.changedAt)), { ...update, item };
2040
2171
  }
2041
2172
  if (operation2 === "items.listRecipientCandidates") {
2042
2173
  let candidates = array2(value);
2043
2174
  return candidates.forEach((value2) => {
2044
- let person = object3(value2);
2175
+ let person = object4(value2);
2045
2176
  assert(id2(person.id) && text3(person.name) && text3(person.email));
2046
- }), assert(new Set(candidates.map((value2) => object3(value2).id)).size === candidates.length), candidates;
2177
+ }), assert(new Set(candidates.map((value2) => object4(value2).id)).size === candidates.length), candidates;
2047
2178
  }
2048
2179
  if (operation2 === "items.addRecipient") {
2049
- let addition = object3(value), item = parseInboxItem(addition.item);
2180
+ let addition = object4(value), item = parseInboxItem(addition.item);
2050
2181
  return assert(id2(addition.addedPersonId) && item.people.some((person) => person.id === addition.addedPersonId)), { ...addition, item };
2051
2182
  }
2052
2183
  if (operation2 === "questions.answer") return parseInboxAcceptance(value);
2053
2184
  if (operation2 === "questions.searchRecords") {
2054
- let result2 = object3(value);
2185
+ let result2 = object4(value);
2055
2186
  assert(text3(result2.recordType) && integer(result2.eligibleCount, 0) && integer(result2.matchCount, 0) && Number(result2.matchCount) <= Number(result2.eligibleCount));
2056
2187
  let labeled = (value2) => {
2057
- let record3 = object3(value2);
2188
+ let record3 = object4(value2);
2058
2189
  recordReference({ repository: record3.repository, ref: record3.ref }), assert(text3(record3.label)), "reason" in record3 && assert(text3(record3.reason));
2059
2190
  };
2060
2191
  return array2(result2.matches).forEach(labeled), array2(result2.suggestions).forEach(labeled), "selected" in result2 && labeled(result2.selected), result2;
@@ -2062,9 +2193,9 @@ function parseInboxResult(operation2, value) {
2062
2193
  throw new Error("File content is not a JSON result");
2063
2194
  }
2064
2195
 
2065
- async function limitedBody(request, limit, timeoutMs) {
2066
- if (!request.body) return new Uint8Array();
2067
- let reader = request.body.getReader(), expired = !1, timer = timeoutMs === void 0 ? void 0 : setTimeout(() => {
2196
+ async function limitedBody(request2, limit, timeoutMs) {
2197
+ if (!request2.body) return new Uint8Array();
2198
+ let reader = request2.body.getReader(), expired = !1, timer = timeoutMs === void 0 ? void 0 : setTimeout(() => {
2068
2199
  expired = !0, reader.cancel().catch(() => {
2069
2200
  });
2070
2201
  }, timeoutMs), chunks = [], length = 0;
@@ -2209,7 +2340,7 @@ function appContext(origin, active2) {
2209
2340
  }
2210
2341
  }, cancel = () => {
2211
2342
  controller.abort(), access.abort(), clearTimeout(expiry), clearTimeout(startup), clearTimeout(renewalTimer), clearInterval(monitor), globalThis.removeEventListener?.("storage", storageChanged);
2212
- for (let event2 of ["pageshow", "focus", "visibilitychange"]) globalThis.removeEventListener?.(event2, wake);
2343
+ for (let event of ["pageshow", "focus", "visibilitychange"]) globalThis.removeEventListener?.(event, wake);
2213
2344
  }, invalidate = () => {
2214
2345
  denied = !0, cancel();
2215
2346
  try {
@@ -2222,7 +2353,7 @@ function appContext(origin, active2) {
2222
2353
  } catch {
2223
2354
  return !1;
2224
2355
  }
2225
- }, 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) => {
2356
+ }, 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) => {
2226
2357
  let value = JSON.parse(candidate ?? "null");
2227
2358
  if (!validPair(value) || value.context.expiresAt > Date.now() + 6e5 || !sameSession(value.context)) throw new Error();
2228
2359
  return value;
@@ -2257,7 +2388,7 @@ function appContext(origin, active2) {
2257
2388
  if (response2.status >= 500) throw new AppRenewalUnavailable();
2258
2389
  if (!response2.ok) throw new Error();
2259
2390
  let value = await appResponse(response2, 4096, signal);
2260
- if (!alive() || !bounded(value)) throw new Error();
2391
+ if (!alive() || !bounded2(value)) throw new Error();
2261
2392
  return value;
2262
2393
  }
2263
2394
  function install(value, candidate, raw) {
@@ -2329,7 +2460,7 @@ function appContext(origin, active2) {
2329
2460
  return;
2330
2461
  }
2331
2462
  if (!response2.ok) throw new Error();
2332
- if (!alive() || !validPair(value) || !bounded(value.context) || (/* @__PURE__ */ new Set([value.credential, value.renewalCredential, pair.credential, pair.renewalCredential])).size !== 4) throw new Error();
2463
+ if (!alive() || !validPair(value) || !bounded2(value.context) || (/* @__PURE__ */ new Set([value.credential, value.renewalCredential, pair.credential, pair.renewalCredential])).size !== 4) throw new Error();
2333
2464
  if (stored() !== previous) {
2334
2465
  await synchronize(requestController.signal);
2335
2466
  return;
@@ -2378,7 +2509,7 @@ function appContext(origin, active2) {
2378
2509
  alive() && resolve().catch(() => {
2379
2510
  });
2380
2511
  };
2381
- for (let event2 of ["pageshow", "focus", "visibilitychange"]) globalThis.addEventListener?.(event2, wake);
2512
+ for (let event of ["pageshow", "focus", "visibilitychange"]) globalThis.addEventListener?.(event, wake);
2382
2513
  let dispose = () => {
2383
2514
  disposed = !0, cancel();
2384
2515
  };
@@ -2493,13 +2624,13 @@ function hostFailure(error, context2) {
2493
2624
  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();
2494
2625
  }
2495
2626
  async function send2(operation2, input) {
2496
- let envelope = parseInboxRequest({ operation: operation2, input }), context2;
2627
+ let envelope = operation2 === "questions.list" ? void 0 : parseInboxRequest({ operation: operation2, input }), context2;
2497
2628
  try {
2498
2629
  context2 = await resolveAppContext();
2499
2630
  } catch {
2500
2631
  throw stale();
2501
2632
  }
2502
- if (context2.kind === "local") {
2633
+ if (envelope ??= parseInboxRequest({ operation: operation2, input }, context2.kind === "local" ? "local" : "hosted"), context2.kind === "local") {
2503
2634
  if (!isAppQuestionOperation(operation2)) throw new InboxOperationError(403, "access_denied");
2504
2635
  let check2 = () => {
2505
2636
  if (!context2.isCurrent() || context2.signal.aborted || context2.expiresAt <= Date.now()) throw stale();
@@ -2563,7 +2694,7 @@ async function send2(operation2, input) {
2563
2694
  } finally {
2564
2695
  reader?.releaseLock();
2565
2696
  }
2566
- }, body2 = new ReadableStream({
2697
+ }, body = new ReadableStream({
2567
2698
  async pull(controller) {
2568
2699
  try {
2569
2700
  check(), reader ??= source.getReader();
@@ -2581,7 +2712,7 @@ async function send2(operation2, input) {
2581
2712
  },
2582
2713
  cancel
2583
2714
  }, { highWaterMark: 0 });
2584
- return new Response(body2, { status: response2.status, headers: response2.headers });
2715
+ return new Response(body, { status: response2.status, headers: response2.headers });
2585
2716
  }
2586
2717
  let bytes = await limitedBody(response2, INBOX_RESULT_BYTES);
2587
2718
  if (check(), !bytes) throw unavailable2();
@@ -2636,13 +2767,17 @@ var inbox = {
2636
2767
  addRecipient: async (input) => await send2("items.addRecipient", input)
2637
2768
  },
2638
2769
  questions: {
2639
- async list() {
2640
- let questions = [], beforeNumber, initial;
2770
+ 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;
2641
2774
  try {
2642
2775
  initial = await resolveAppContext();
2643
2776
  } catch {
2644
2777
  throw stale();
2645
2778
  }
2779
+ if (initial.kind === "local" ? input !== void 0 : routines === void 0)
2780
+ throw new InboxOperationError(400, "invalid_input");
2646
2781
  let host;
2647
2782
  try {
2648
2783
  host = initial.kind !== "local" && await resolveHostedInboxContext(initial);
@@ -2655,8 +2790,11 @@ var inbox = {
2655
2790
  };
2656
2791
  do {
2657
2792
  check();
2658
- let page = await send2("questions.list", beforeNumber === void 0 ? {} : { beforeNumber });
2659
- if (check(), page.questions.some((question2) => question2.item.href !== `https://${initial.workspace}.oddington.ai/inbox/${question2.item.id}`) || beforeNumber !== void 0 && (page.questions.some((question2) => question2.item.number >= beforeNumber) || page.nextBeforeNumber !== null && page.nextBeforeNumber >= beforeNumber)) throw unavailable2();
2793
+ let page = await send2("questions.list", {
2794
+ ...routines === void 0 ? {} : { routines },
2795
+ ...beforeNumber === void 0 ? {} : { beforeNumber }
2796
+ });
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();
2660
2798
  if (questions.push(...page.questions), page.nextBeforeNumber === null) return questions;
2661
2799
  beforeNumber = page.nextBeforeNumber;
2662
2800
  } while (!0);
@@ -2693,8 +2831,8 @@ function init({ auth: input }) {
2693
2831
  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);
2694
2832
  } catch {
2695
2833
  }
2696
- let active2 = !0, revision = 0, person, token, binding = {}, local = localOrigin ? appContext(localOrigin, () => active2) : void 0, subscription, stopDisposal, uninstall = installMemberContext(async () => {
2697
- if (local) return local.resolve();
2834
+ let active2 = !0, revision = 0, person, token, binding = {}, local2 = localOrigin ? appContext(localOrigin, () => active2) : void 0, subscription, stopDisposal, uninstall = installMemberContext(async () => {
2835
+ if (local2) return local2.resolve();
2698
2836
  if (!active2 || !endpoint || !workspace || globalThis.location.origin !== endpoint) throw new Error("Hosted Data context unavailable.");
2699
2837
  let started = revision, { data: { session }, error } = await auth2.getSession();
2700
2838
  if (!active2 || globalThis.location.origin !== endpoint || started !== revision || error || !session || person !== void 0 && person !== session.user.id)
@@ -2714,12 +2852,12 @@ function init({ auth: input }) {
2714
2852
  binding
2715
2853
  };
2716
2854
  }), dispose = () => {
2717
- active2 && (active2 = !1, local?.dispose(), revision++, subscription?.unsubscribe(), stopDisposal?.(), uninstall(), installedDispose === dispose && (installedDispose = void 0));
2855
+ active2 && (active2 = !1, local2?.dispose(), revision++, subscription?.unsubscribe(), stopDisposal?.(), uninstall(), installedDispose === dispose && (installedDispose = void 0));
2718
2856
  };
2719
- installedDispose = dispose, stopDisposal = registered?.onDispose(dispose), active2 && (subscription = auth2.onAuthStateChange((event2, session) => {
2857
+ installedDispose = dispose, stopDisposal = registered?.onDispose(dispose), active2 && (subscription = auth2.onAuthStateChange((event, session) => {
2720
2858
  let next = session?.user.id ?? null;
2721
- (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;
2722
- }).data.subscription, local?.start());
2859
+ (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;
2860
+ }).data.subscription, local2?.start());
2723
2861
  }
2724
2862
  var os = { init };
2725
2863
 
@@ -2769,19 +2907,19 @@ function createBrowserAuth(runtime) {
2769
2907
  } catch {
2770
2908
  }
2771
2909
  }
2772
- function notify(c, event2) {
2910
+ function notify(c, event) {
2773
2911
  for (let listener of c.sessions)
2774
2912
  try {
2775
- listener(event2, event2 === "SIGNED_OUT" ? null : c.session);
2913
+ listener(event, event === "SIGNED_OUT" ? null : c.session);
2776
2914
  } catch {
2777
2915
  }
2778
2916
  }
2779
2917
  function expire(c) {
2780
2918
  !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"));
2781
2919
  }
2782
- function accept(c, event2, session) {
2783
- if (!c.active || event2 === "INITIAL_SESSION" && c.state.status !== "initializing" || event2 === "TOKEN_REFRESHED" && !c.session && c.state.status !== "initializing") return;
2784
- let replaced = c.session?.user?.id !== session?.user?.id || event2 === "SIGNED_OUT" || !!(event2 === "SIGNED_IN" && c.session && session?.access_token !== c.session.access_token);
2920
+ function accept(c, event, session) {
2921
+ if (!c.active || event === "INITIAL_SESSION" && c.state.status !== "initializing" || event === "TOKEN_REFRESHED" && !c.session && c.state.status !== "initializing") return;
2922
+ let replaced = c.session?.user?.id !== session?.user?.id || event === "SIGNED_OUT" || !!(event === "SIGNED_IN" && c.session && session?.access_token !== c.session.access_token);
2785
2923
  replaced && c.revision++, c.timer && clearTimeout(c.timer);
2786
2924
  let pending = c.state.pending;
2787
2925
  if (!session) {
@@ -2794,7 +2932,7 @@ function createBrowserAuth(runtime) {
2794
2932
  }
2795
2933
  c.session = session;
2796
2934
  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 });
2797
- publish(c, { status: "signed_in", account, ...pending ? { pending } : {} }), notify(c, event2);
2935
+ publish(c, { status: "signed_in", account, ...pending ? { pending } : {} }), notify(c, event);
2798
2936
  let checkExpiry = () => {
2799
2937
  if (!c.active || !c.session) return;
2800
2938
  let remaining = c.session.expires_at * 1e3 - Date.now();
@@ -2834,8 +2972,8 @@ function createBrowserAuth(runtime) {
2834
2972
  c.provider.dispose();
2835
2973
  return;
2836
2974
  }
2837
- let subscription = c.provider.onAuthStateChange((event2, session) => {
2838
- c.state.status === "initializing" && c.state.pending === "sign_out" || accept(c, event2, session);
2975
+ let subscription = c.provider.onAuthStateChange((event, session) => {
2976
+ c.state.status === "initializing" && c.state.pending === "sign_out" || accept(c, event, session);
2839
2977
  }).data.subscription;
2840
2978
  c.unsubscribe = () => subscription.unsubscribe();
2841
2979
  let started = c.revision, { data: data3, error } = await c.provider.getSession();
@@ -2997,7 +3135,7 @@ function createBrowserAuth(runtime) {
2997
3135
  if (!active2)
2998
3136
  return callback("SIGNED_OUT", null), { data: { subscription: { unsubscribe() {
2999
3137
  } } } };
3000
- let listener = (event2, session) => callback(event2, session);
3138
+ let listener = (event, session) => callback(event, session);
3001
3139
  return coordinator.sessions.add(listener), sessionObservers.add(listener), callback("INITIAL_SESSION", coordinator.session), { data: { subscription: { unsubscribe() {
3002
3140
  coordinator.sessions.delete(listener), sessionObservers.delete(listener);
3003
3141
  } } } };
@@ -3070,19 +3208,19 @@ async function provider(configuration, guard) {
3070
3208
  }
3071
3209
  },
3072
3210
  fetch: Object.assign(async (input, init2) => {
3073
- let revision = guard.revision(), request = String(input).startsWith(`${configuration.providerUrl}/auth/v1/oauth/authorizations/`) ? authorizationRequest : void 0, rejectStale = () => {
3074
- throw request && (request.rejected = !0), new BrowserAuthError("stale");
3211
+ let revision = guard.revision(), request2 = String(input).startsWith(`${configuration.providerUrl}/auth/v1/oauth/authorizations/`) ? authorizationRequest : void 0, rejectStale = () => {
3212
+ throw request2 && (request2.rejected = !0), new BrowserAuthError("stale");
3075
3213
  };
3076
- request && (!request.current() || !guard.canAuthorize(new Headers(init2?.headers).get("authorization")?.replace(/^Bearer /, "") ?? "")) && rejectStale();
3077
- let response2 = await fetch(input, { ...init2, redirect: "error" }), body2 = await response2.arrayBuffer();
3078
- (!guard.current(revision) || request && !request.current()) && rejectStale();
3214
+ request2 && (!request2.current() || !guard.canAuthorize(new Headers(init2?.headers).get("authorization")?.replace(/^Bearer /, "") ?? "")) && rejectStale();
3215
+ let response2 = await fetch(input, { ...init2, redirect: "error" }), body = await response2.arrayBuffer();
3216
+ (!guard.current(revision) || request2 && !request2.current()) && rejectStale();
3079
3217
  let result2 = new Response(
3080
- [204, 205, 304].includes(response2.status) ? null : body2,
3218
+ [204, 205, 304].includes(response2.status) ? null : body,
3081
3219
  { status: response2.status, statusText: response2.statusText, headers: response2.headers }
3082
3220
  ), json3 = result2.json.bind(result2);
3083
3221
  return result2.json = async () => {
3084
3222
  let value = await json3();
3085
- return (!guard.current(revision) || request && !request.current()) && rejectStale(), value && typeof value.access_token == "string" && provenance.set(value.access_token, revision), value;
3223
+ return (!guard.current(revision) || request2 && !request2.current()) && rejectStale(), value && typeof value.access_token == "string" && provenance.set(value.access_token, revision), value;
3086
3224
  }, result2;
3087
3225
  }, { preconnect: fetch.preconnect })
3088
3226
  });
@@ -3091,15 +3229,15 @@ async function provider(configuration, guard) {
3091
3229
  authorizationQueue = new Promise((resolve) => {
3092
3230
  release = resolve;
3093
3231
  }), await previous;
3094
- let request = { current: current2, rejected: !1 };
3095
- authorizationRequest = request;
3232
+ let request2 = { current: current2, rejected: !1 };
3233
+ authorizationRequest = request2;
3096
3234
  try {
3097
3235
  if (!current2()) throw new BrowserAuthError("stale");
3098
3236
  let result2 = await (kind === "get" ? client.oauth.getAuthorizationDetails(id3) : kind === "approve" ? client.oauth.approveAuthorization(id3, { skipBrowserRedirect: !0 }) : client.oauth.denyAuthorization(id3, { skipBrowserRedirect: !0 }));
3099
- if (request.rejected || !current2()) throw new BrowserAuthError("stale");
3237
+ if (request2.rejected || !current2()) throw new BrowserAuthError("stale");
3100
3238
  return result2;
3101
3239
  } catch (error) {
3102
- throw request.rejected || !current2() ? new BrowserAuthError("stale") : error;
3240
+ throw request2.rejected || !current2() ? new BrowserAuthError("stale") : error;
3103
3241
  } finally {
3104
3242
  authorizationRequest = void 0, release();
3105
3243
  }
@@ -3111,9 +3249,9 @@ async function provider(configuration, guard) {
3111
3249
  deny: (id3, current2) => authorization("deny", id3, current2)
3112
3250
  },
3113
3251
  getSession: () => client.getSession(),
3114
- onAuthStateChange: (callback) => client.onAuthStateChange((event2, session) => {
3252
+ onAuthStateChange: (callback) => client.onAuthStateChange((event, session) => {
3115
3253
  let revision = session ? provenance.get(session.access_token) : void 0;
3116
- revision !== void 0 && !guard.current(revision) || (callback(event2, session), session && provenance.delete(session.access_token));
3254
+ revision !== void 0 && !guard.current(revision) || (callback(event, session), session && provenance.delete(session.access_token));
3117
3255
  }),
3118
3256
  signInWithOtp: (input) => client.signInWithOtp(input),
3119
3257
  verifyOtp: (input) => client.verifyOtp(input),
@@ -3132,188 +3270,160 @@ async function provider(configuration, guard) {
3132
3270
  }
3133
3271
  var auth = /* @__PURE__ */ createBrowserAuth({ provider, failure: (reason) => new BrowserAuthError(reason) });
3134
3272
 
3135
- 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 {
3273
+ 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 {
3136
3274
  constructor(reason) {
3137
3275
  super(reason);
3138
3276
  this.reason = reason;
3139
3277
  this.name = "AppRoutineError";
3140
3278
  }
3141
3279
  reason;
3142
- };
3143
- function fail3(reason) {
3280
+ }, fail3 = (reason) => {
3144
3281
  throw new AppRoutineError(reason);
3145
- }
3146
- function object4(value) {
3147
- return !!value && typeof value == "object" && !Array.isArray(value);
3148
- }
3149
- function keys4(value, expected) {
3150
- return Object.keys(value).sort().join(",") === expected;
3151
- }
3282
+ };
3152
3283
  function current(context2) {
3153
3284
  (!context2.isCurrent() || context2.signal.aborted) && fail3("authority_unavailable");
3154
3285
  }
3155
- async function body(context2, response2, maximum) {
3286
+ function appDescriptors() {
3287
+ return globalThis[/* @__PURE__ */ Symbol.for("oddington.app.descriptor")]?.routines ?? [];
3288
+ }
3289
+ async function local() {
3290
+ let context2 = await resolveAppContext().catch(() => fail3("authority_unavailable"));
3291
+ return context2.kind !== "local" ? fail3("execution_unavailable") : (current(context2), context2);
3292
+ }
3293
+ async function request(key, suffix, init2, maximum = SUMMARY_BYTES, retained) {
3294
+ (!identifier.test(key) || !appDescriptors().some((item) => item.id === key)) && fail3("authority_unavailable");
3295
+ let context2 = retained ?? await local();
3296
+ current(context2);
3156
3297
  try {
3157
- let value = await appResponse(response2, maximum, context2.signal);
3158
- 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;
3298
+ let response2 = await context2.requestRoutine(key, suffix, init2), value = await appResponse(response2, maximum, context2.signal);
3299
+ if (current(context2), !response2.ok) {
3300
+ let reason = value?.error;
3301
+ reason === "authority_unavailable" && (context2.invalidate(), fail3(reason)), (reason === "invalid_input" || reason === "execution_unavailable") && fail3(reason), fail3("execution_unavailable");
3302
+ }
3303
+ return value;
3159
3304
  } catch (error) {
3160
- if (current(context2), error instanceof AppResponseReadError || error instanceof AppRoutineError) throw error;
3161
- return fail3("execution_unavailable");
3305
+ if (current(context2), error instanceof AppRoutineError) throw error;
3306
+ fail3("execution_unavailable");
3162
3307
  }
3163
3308
  }
3164
- function descriptor(value, key) {
3165
- 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;
3309
+ function summary(value, key, id3) {
3310
+ let run = value;
3311
+ 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;
3166
3312
  }
3167
- function safeValue(value, depth = 0) {
3168
- 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));
3313
+ function only(value, allowed) {
3314
+ return !!value && typeof value == "object" && !Array.isArray(value) && Object.keys(value).every((key) => allowed.split(",").includes(key));
3169
3315
  }
3170
- function event(value, run, steps) {
3171
- (!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");
3172
- let common = "key,routine,runId,sequence,";
3173
- if (value.type === "started" && keys4(value, common + "type") && value.sequence === 1) return { type: "started" };
3174
- 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)))
3175
- return {
3176
- type: "step",
3177
- id: value.id,
3178
- ...Object.hasOwn(value, "summary") ? { summary: value.summary } : {}
3179
- };
3180
- if (value.type === "finished") {
3181
- if (value.state === "succeeded" && keys4(value, "key," + (Object.hasOwn(value, "result") ? "result," : "") + "routine,runId,sequence,state,type") && (!Object.hasOwn(value, "result") || safeValue(value.result)))
3182
- return {
3183
- type: "finished",
3184
- state: "succeeded",
3185
- ...Object.hasOwn(value, "result") ? { result: value.result } : {}
3186
- };
3187
- if (value.state === "failed" && value.error === "execution_failed" && keys4(value, "error," + common + "state,type"))
3188
- return { type: "finished", state: "failed", error: "execution_failed" };
3189
- if (value.state === "cancelled" && keys4(value, common + "state,type")) return { type: "finished", state: "cancelled" };
3190
- }
3191
- return fail3("execution_unavailable");
3192
- }
3193
- async function pause(context2, delay) {
3194
- current(context2), await new Promise((resolve, reject) => {
3195
- let abort = () => {
3196
- clearTimeout(timer), reject(new AppRoutineError("authority_unavailable"));
3197
- }, timer = setTimeout(() => {
3198
- context2.signal.removeEventListener("abort", abort), resolve();
3199
- }, delay);
3200
- context2.signal.addEventListener("abort", abort, { once: !0 });
3201
- }), current(context2);
3202
- }
3203
- function handle(context2, run, steps) {
3316
+ 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;
3317
+ function optionalTimes(value) {
3318
+ return (value.startedAt === void 0 || timestamp(value.startedAt)) && (value.finishedAt === void 0 || timestamp(value.finishedAt));
3319
+ }
3320
+ function validStep(step) {
3321
+ 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));
3322
+ }
3323
+ function validPublication(value) {
3324
+ return value && only(value, value.state === "failed" ? "state,message" : "state") && (["not_needed", "ready", "published"].includes(value.state) || value.state === "failed" && message(value.message));
3325
+ }
3326
+ function jsonInput(value, ancestors = /* @__PURE__ */ new Set()) {
3327
+ if (value === null || typeof value == "string" || typeof value == "boolean" || typeof value == "number" && Number.isFinite(value)) return;
3328
+ if (!value || typeof value != "object" || ancestors.has(value)) return fail3("invalid_input");
3329
+ let array3 = Array.isArray(value), keys4 = Reflect.ownKeys(value);
3330
+ 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");
3331
+ ancestors.add(value);
3332
+ for (let key of keys4) {
3333
+ if (array3 && key === "length") continue;
3334
+ let descriptor = Object.getOwnPropertyDescriptor(value, key);
3335
+ if (typeof key != "string" || !descriptor.enumerable || !Object.hasOwn(descriptor, "value")) return fail3("invalid_input");
3336
+ jsonInput(descriptor.value, ancestors);
3337
+ }
3338
+ ancestors.delete(value);
3339
+ }
3340
+ function structure(value) {
3341
+ 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
+ }
3343
+ 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);
3204
3346
  return Object.freeze({
3205
- async *events(...args) {
3206
- args.length && fail3("invalid_input");
3207
- let cursor = 0, terminal = !1, delay = 100, retainedBytes = 0, seen = [];
3208
- for (; !terminal; ) {
3209
- current(context2);
3210
- let response2;
3211
- try {
3212
- response2 = await context2.requestRoutine(run.key, `runs/${run.runId}/events?after=${cursor}`);
3213
- } catch {
3214
- current(context2), await pause(context2, delay), delay = Math.min(delay * 2, 2e3);
3215
- continue;
3216
- }
3217
- if (response2.status >= 500) {
3218
- await response2.body?.cancel(), await pause(context2, delay), delay = Math.min(delay * 2, 2e3);
3219
- continue;
3220
- }
3221
- let value;
3222
- try {
3223
- value = await body(context2, response2, 80 * 1024);
3224
- } catch (error) {
3225
- if (!(error instanceof AppResponseReadError)) throw error;
3226
- await pause(context2, delay), delay = Math.min(delay * 2, 2e3);
3227
- continue;
3228
- }
3229
- (!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");
3230
- let delivery = [];
3231
- for (let raw of value.events) {
3232
- let publicEvent = event(raw, run, steps), encoded = JSON.stringify(raw), sequence = raw.sequence;
3233
- if (sequence <= cursor) {
3234
- seen[sequence - 1] !== encoded && fail3("execution_unavailable");
3235
- continue;
3236
- }
3237
- (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);
3238
- }
3239
- (value.after !== cursor || value.terminal !== terminal) && fail3("execution_unavailable");
3240
- for (let item of delivery)
3241
- current(context2), yield item;
3242
- delay = 100, terminal || await pause(context2, delivery.length ? 100 : 250);
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));
3243
3354
  }
3244
3355
  },
3245
- async cancel(...args) {
3246
- args.length && fail3("invalid_input");
3247
- try {
3248
- let value = await body(context2, await context2.requestRoutine(run.key, `runs/${run.runId}/cancel`, { method: "POST" }), 1024);
3249
- (!object4(value) || !keys4(value, "cancelled") || value.cancelled !== !0) && fail3("execution_unavailable");
3250
- } catch (error) {
3251
- if (current(context2), error instanceof AppRoutineError) throw error;
3252
- fail3("execution_unavailable");
3253
- }
3356
+ async step(step) {
3357
+ (typeof step != "string" || !identifier.test(step)) && fail3("invalid_input");
3358
+ let value = await request(key, `runs/${id3}/steps/${step}`, void 0, 514 * 1024, context2);
3359
+ return (!only(value, "id,title,status,startedAt,finishedAt,summary,data") || value.id !== step || !validStep(value)) && fail3("execution_unavailable"), value;
3360
+ },
3361
+ async publish() {
3362
+ return summary(await request(key, `runs/${id3}/publish`, { method: "POST" }, SUMMARY_BYTES, context2), key, id3);
3254
3363
  }
3255
3364
  });
3256
3365
  }
3257
- async function appRoutineOperation(key, input, recover) {
3258
- let context2;
3259
- try {
3260
- identifier.test(key) || fail3("authority_unavailable");
3261
- let resolved = await resolveAppContext();
3262
- if (resolved.kind !== "local" && fail3("execution_unavailable"), context2 = resolved, recover) {
3263
- let value2 = await body(context2, await context2.requestRoutine(key, "runs"), 16384);
3264
- (!object4(value2) || !keys4(value2, "runs") || !Array.isArray(value2.runs) || value2.runs.length > 20) && fail3("execution_unavailable");
3265
- let runs = value2.runs.map((run) => descriptor(run, key));
3266
- 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));
3267
- }
3268
- let available = await body(context2, await context2.requestAvailability(key), 16 * 1024);
3269
- 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");
3270
- let steps = [...available.steps], encoded;
3271
- try {
3272
- encoded = JSON.stringify(input), (encoded === void 0 || new TextEncoder().encode(encoded).byteLength > 16 * 1024) && fail3("invalid_input");
3273
- } catch {
3274
- fail3("invalid_input");
3275
- }
3276
- let value = await body(context2, await context2.requestRoutine(key, "runs", {
3277
- method: "POST",
3278
- body: `{"input":${encoded}}`
3279
- }), 16 * 1024);
3280
- return handle(context2, descriptor(value, key), steps);
3281
- } catch (error) {
3282
- if (context2 && current(context2), error instanceof AppRoutineError) throw error;
3283
- return fail3(context2 ? "execution_unavailable" : "authority_unavailable");
3284
- }
3285
- }
3286
-
3287
- var authorityUnavailable = () => ({ available: !1, reason: "authority_unavailable" }), MAX_RESPONSE_BYTES = 16 * 1024;
3288
- async function availability(key) {
3366
+ async function describeAppRoutine(key) {
3367
+ let descriptor = appDescriptors().find((item) => item.id === key);
3368
+ if (!descriptor) return fail3("authority_unavailable");
3369
+ let unavailable3 = () => ({
3370
+ ...structuredClone(descriptor),
3371
+ connections: descriptor.connections.map((connection) => ({ ...connection, available: !1 })),
3372
+ readiness: { state: "unavailable", reason: "capability_unavailable", message: "Routine capability unavailable." }
3373
+ });
3289
3374
  try {
3290
- if (!/^[a-z0-9]+(?:-[a-z0-9]+)*(?![\s\S])/.test(key)) return authorityUnavailable();
3291
- let context2 = await resolveAppContext();
3292
- if (context2.kind !== "local") return { available: !1, reason: "execution_unavailable" };
3293
- let response2 = await context2.requestAvailability(key);
3294
- if (!response2.ok || response2.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase() !== "application/json")
3295
- return authorityUnavailable();
3296
- let value = await appResponse(response2, MAX_RESPONSE_BYTES, context2.signal);
3297
- if (!context2.isCurrent() || !value || typeof value != "object" || Array.isArray(value)) return authorityUnavailable();
3298
- let result2 = value;
3299
- 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] };
3375
+ let value = await request(key, "describe", void 0, 1048576);
3376
+ 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;
3300
3377
  } catch {
3301
- return authorityUnavailable();
3378
+ return unavailable3();
3302
3379
  }
3303
3380
  }
3304
- var app = Object.freeze({ routines: new Proxy(/* @__PURE__ */ Object.create(null), {
3305
- get(_target, key) {
3306
- if (typeof key == "string")
3307
- return Object.freeze({
3308
- availability: (...args) => args.length ? Promise.resolve(authorityUnavailable()) : availability(key),
3309
- run: (...args) => args.length === 1 ? appRoutineOperation(key, args[0], !1) : Promise.reject(new AppRoutineError("invalid_input")),
3310
- recover: (...args) => args.length === 0 ? appRoutineOperation(key, void 0, !0) : Promise.reject(new AppRoutineError("invalid_input"))
3311
- });
3312
- },
3313
- set: () => !1,
3314
- defineProperty: () => !1,
3315
- deleteProperty: () => !1
3316
- }) });
3381
+ function appRoutineBinding(key) {
3382
+ return Object.freeze({
3383
+ describe: () => describeAppRoutine(key),
3384
+ async run(...args) {
3385
+ args.length > 1 && fail3("invalid_input");
3386
+ let encoded;
3387
+ try {
3388
+ if (args[0] === void 0) encoded = "{}";
3389
+ else {
3390
+ jsonInput(args[0]);
3391
+ let input = JSON.stringify(args[0]);
3392
+ new TextEncoder().encode(input).byteLength > 256 * 1024 && fail3("invalid_input"), encoded = `{"input":${input}}`;
3393
+ }
3394
+ } catch {
3395
+ return fail3("invalid_input");
3396
+ }
3397
+ let context2 = await local(), run = summary(await request(key, "runs", { method: "POST", body: encoded }, SUMMARY_BYTES, context2), key);
3398
+ return handle(key, run.id, context2);
3399
+ },
3400
+ runs: Object.freeze({
3401
+ async list() {
3402
+ let value = await request(key, "runs", void 0, 20 * SUMMARY_BYTES);
3403
+ if (!Array.isArray(value) || value.length > 20) return fail3("execution_unavailable");
3404
+ let runs = value.map((run) => summary(run, key));
3405
+ return new Set(runs.map((run) => run.id)).size !== runs.length && fail3("execution_unavailable"), runs;
3406
+ },
3407
+ async get(id3) {
3408
+ let run = handle(key, id3, await local());
3409
+ return await run.current(), run;
3410
+ }
3411
+ })
3412
+ });
3413
+ }
3414
+
3415
+ var app = Object.freeze({
3416
+ listRoutines: () => Promise.all(appDescriptors().map(({ id: id3 }) => describeAppRoutine(id3))),
3417
+ routines: new Proxy(/* @__PURE__ */ Object.create(null), {
3418
+ get(_target, key) {
3419
+ if (!(typeof key != "string" || !appDescriptors().some((item) => item.id === key)))
3420
+ return appRoutineBinding(key);
3421
+ },
3422
+ set: () => !1,
3423
+ defineProperty: () => !1,
3424
+ deleteProperty: () => !1
3425
+ })
3426
+ });
3317
3427
 
3318
3428
  var LIMIT2 = 16 * 1024, context;
3319
3429
  var appRun = {
@@ -3343,10 +3453,10 @@ function routineDataEnvelope(command) {
3343
3453
  }
3344
3454
 
3345
3455
  function routinePublicationClient2(options = {}) {
3346
- 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;
3456
+ 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;
3347
3457
  if (!workspace || !/^[a-z0-9][a-z0-9-]*$/.test(workspace) || capability !== void 0 && !/^[0-9a-f]{64}$/.test(capability))
3348
3458
  throw new Error("A workspace and valid optional routine capability are required");
3349
- let workingRoot = options.workingRoot ?? environment.ODDINGTON_INBOX_WORKING_ROOT ?? void 0, headers = capability ? { "x-oddington-run": capability } : {}, request = options.request ?? (capability ? async (path, init2) => {
3459
+ let workingRoot = options.workingRoot ?? environment.ODDINGTON_INBOX_WORKING_ROOT ?? void 0, headers = capability ? { "x-oddington-run": capability } : {}, request2 = options.request ?? (capability ? async (path, init2) => {
3350
3460
  if (path === "/api/data") return fetch(`https://${workspace}.oddington.ai/api/data`, { ...init2, redirect: "error" });
3351
3461
  let origin = `https://${workspace}.oddington.ai`, target = new URL(path, `${origin}/`);
3352
3462
  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")
@@ -3355,16 +3465,16 @@ function routinePublicationClient2(options = {}) {
3355
3465
  } : async () => {
3356
3466
  throw new Error("Member publication requires a host-supplied request");
3357
3467
  });
3358
- async function send3(operation2, body2) {
3359
- if (local) return await local(operation2, body2);
3360
- let writing = operation2 === "records/update", reading = operation2 === "records/read", response2 = await request(writing || reading ? "/api/data" : `/api/inbox/${operation2}`, {
3468
+ async function send3(operation2, body) {
3469
+ if (local2) return await local2(operation2, body);
3470
+ let writing = operation2 === "records/update", reading = operation2 === "records/read", response2 = await request2(writing || reading ? "/api/data" : `/api/inbox/${operation2}`, {
3361
3471
  method: "POST",
3362
3472
  headers: {
3363
3473
  "content-type": "application/json",
3364
3474
  ...headers,
3365
3475
  ...writing || reading ? { "x-oddington-workspace": workspace, "x-oddington-captured-records": "1" } : {}
3366
3476
  },
3367
- body: JSON.stringify(writing ? routineDataEnvelope(validateRoutineRecordWrite(body2)) : reading ? { operation: "records.select", request: validateRecordRead(body2) } : body2)
3477
+ body: JSON.stringify(writing ? routineDataEnvelope(validateRoutineRecordWrite(body)) : reading ? { operation: "records.select", request: validateRecordRead(body) } : body)
3368
3478
  }), result2 = await response2.json();
3369
3479
  if (!response2.ok && operation2 === "records/update")
3370
3480
  throw new RoutineRecordWriteError(result2.error ?? "Could not confirm routine preparation", result2.effect ?? "uncertain");
@@ -3372,11 +3482,11 @@ function routinePublicationClient2(options = {}) {
3372
3482
  return result2;
3373
3483
  }
3374
3484
  let transport = {
3375
- async publish(body2) {
3376
- return await send3("publish", body2);
3485
+ async publish(body) {
3486
+ return await send3("publish", body);
3377
3487
  },
3378
- async resolve(body2) {
3379
- await send3("resolve", body2);
3488
+ async resolve(body) {
3489
+ await send3("resolve", body);
3380
3490
  }
3381
3491
  };
3382
3492
  async function readRecords(input) {
@@ -3403,12 +3513,12 @@ function routinePublicationClient2(options = {}) {
3403
3513
  files: {
3404
3514
  async add(value) {
3405
3515
  let input = validateFileAddOptions(value);
3406
- if (local) return validateInboxFile(await local("files/add", input));
3516
+ if (local2) return validateInboxFile(await local2("files/add", input));
3407
3517
  throw workingRoot ? new Error("Inbox file reads require a Node working root") : new Error("Inbox file reads require a working root");
3408
3518
  }
3409
3519
  },
3410
- async check(body2) {
3411
- await send3("check", { requestKey: body2.requestKey, item: validatePublication(body2.item) });
3520
+ async check(body) {
3521
+ await send3("check", { requestKey: body.requestKey, item: validatePublication(body.item) });
3412
3522
  }
3413
3523
  };
3414
3524
  }