@tensorix/metahub 0.4.0 → 0.5.0

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.
Files changed (47) hide show
  1. package/dist/cli.js +2447 -1619
  2. package/dist/cli.js.map +26 -22
  3. package/dist/core/audit.d.ts +97 -0
  4. package/dist/core/audit.d.ts.map +1 -0
  5. package/dist/core/crdt.d.ts +13 -1
  6. package/dist/core/crdt.d.ts.map +1 -1
  7. package/dist/core/databases.d.ts.map +1 -1
  8. package/dist/core/documents.d.ts +6 -0
  9. package/dist/core/documents.d.ts.map +1 -1
  10. package/dist/core/grants-core.d.ts.map +1 -1
  11. package/dist/core/history.d.ts +31 -0
  12. package/dist/core/history.d.ts.map +1 -1
  13. package/dist/core/indexing.d.ts +1 -1
  14. package/dist/core/integrity.d.ts +1 -1
  15. package/dist/core/integrity.d.ts.map +1 -1
  16. package/dist/core/properties.d.ts +9 -1
  17. package/dist/core/properties.d.ts.map +1 -1
  18. package/dist/core/records.d.ts +5 -0
  19. package/dist/core/records.d.ts.map +1 -1
  20. package/dist/core/relation-cells.d.ts +23 -0
  21. package/dist/core/relation-cells.d.ts.map +1 -0
  22. package/dist/core/resolve.d.ts +4 -0
  23. package/dist/core/resolve.d.ts.map +1 -1
  24. package/dist/core/sync/files.d.ts.map +1 -1
  25. package/dist/core/sync/server.d.ts.map +1 -1
  26. package/dist/core/sync/share-serve.d.ts.map +1 -1
  27. package/dist/db-worker.js +100 -98
  28. package/dist/edge-worker.js +158 -32
  29. package/dist/index.js +2372 -1382
  30. package/dist/index.js.map +18 -16
  31. package/dist/metahub-sdk.js +7 -7
  32. package/dist/mh-runtime.js +1 -1
  33. package/dist/sw.js +7 -7
  34. package/dist/webui/server/assets.d.ts +3 -1
  35. package/dist/webui/server/assets.d.ts.map +1 -1
  36. package/dist/webui/server/changes-route.d.ts +7 -0
  37. package/dist/webui/server/changes-route.d.ts.map +1 -0
  38. package/dist/webui/server/routes.d.ts.map +1 -1
  39. package/dist/webui-fmt-clang.js +1 -1
  40. package/dist/webui-fmt-gofmt.js +1 -1
  41. package/dist/webui-fmt-lua.js +2 -2
  42. package/dist/webui-fmt-ruff.js +2 -2
  43. package/dist/webui-fmt-sh.js +8 -8
  44. package/dist/webui-fmt-taplo.js +2 -2
  45. package/dist/webui-fmt.js +346 -346
  46. package/dist/webui.js +186 -176
  47. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -624,6 +624,15 @@ var init_intent_retention = __esm(() => {
624
624
  });
625
625
 
626
626
  // src/core/crdt.ts
627
+ function setActorTag(tag) {
628
+ if (tag !== null && !ACTOR_TAG_RE.test(tag)) {
629
+ throw new Error(`invalid actor tag: ${tag}`);
630
+ }
631
+ currentActor = tag;
632
+ }
633
+ function actorTag() {
634
+ return currentActor;
635
+ }
627
636
  function withNodeId(node, fn) {
628
637
  const prev = currentNodeOverride;
629
638
  currentNodeOverride = node;
@@ -636,7 +645,7 @@ function withNodeId(node, fn) {
636
645
  function withChangeGroup(label, fn) {
637
646
  if (currentTxn !== null)
638
647
  return fn();
639
- currentTxn = (label ? label + ":" : "") + randomSuffix(8);
648
+ currentTxn = (currentActor ? currentActor + "/" : "") + (label ? label + ":" : "") + randomSuffix(8);
640
649
  try {
641
650
  return fn();
642
651
  } finally {
@@ -806,13 +815,14 @@ function changesAfterSeq(db, seq, opts = {}) {
806
815
  }
807
816
  return { changes: rows.map(({ seq: _seq, ...c }) => c), cursor };
808
817
  }
809
- var CHANGE_COLS, CHANGE_SELECT, currentTxn = null, currentNodeOverride = null, DOMAIN, RECORD_META, OPLOG_ONLY_DATASETS, NOT_NULL_ZERO_COLS;
818
+ var CHANGE_COLS, CHANGE_SELECT, currentTxn = null, currentActor = null, ACTOR_TAG_RE, currentNodeOverride = null, DOMAIN, RECORD_META, OPLOG_ONLY_DATASETS, NOT_NULL_ZERO_COLS;
810
819
  var init_crdt = __esm(() => {
811
820
  init_node();
812
821
  init_ids();
813
822
  init_intent_retention();
814
823
  CHANGE_COLS = ["hlc", "node_id", "dataset", "row_id", "col", "value", "txn"];
815
824
  CHANGE_SELECT = CHANGE_COLS.join(", ");
825
+ ACTOR_TAG_RE = /^[a-z0-9_-]{1,16}$/;
816
826
  DOMAIN = {
817
827
  databases: {
818
828
  table: "databases",
@@ -906,7 +916,7 @@ function ensurePropIndex(db, databaseId, propId) {
906
916
  function maybeAutoIndex(db, databaseId, prop) {
907
917
  if (hasIndex(db, databaseId, prop.id))
908
918
  return;
909
- if (prop.type !== "relation") {
919
+ if (prop.type !== "relation" && prop.type !== "doc") {
910
920
  const row = db.query("SELECT COUNT(*) AS c FROM records WHERE database_id = ? AND __deleted = 0").get(databaseId);
911
921
  if (row.c < AUTO_INDEX_ROW_THRESHOLD)
912
922
  return;
@@ -953,7 +963,15 @@ function setPropertyWidth(db, id, width) {
953
963
  const w = Math.max(80, Math.min(2000, Math.round(width)));
954
964
  return updateProperty(db, id, { config: { ...cur.config ?? {}, width: w } });
955
965
  }
956
- var PROP_TYPES, PROPERTY_COLS, PROPERTY_SELECT, addProperty, updateProperty, removeProperty;
966
+ function getSelectProperty(db, id) {
967
+ const prop = getProperty(db, id);
968
+ if (!prop)
969
+ throw new MhError("not_found", `no such property: ${id}`);
970
+ if (prop.type !== "select" && prop.type !== "multi_select")
971
+ throw new MhError("invalid_input", `${prop.type} property has no options`);
972
+ return { prop, options: prop.config?.options ?? [] };
973
+ }
974
+ var PROP_TYPES, PROPERTY_COLS, PROPERTY_SELECT, addProperty, updateProperty, renameSelectOption, removeSelectOption, removeProperty;
957
975
  var init_properties = __esm(() => {
958
976
  init_ids();
959
977
  init_crdt();
@@ -967,6 +985,7 @@ var init_properties = __esm(() => {
967
985
  "multi_select",
968
986
  "date",
969
987
  "relation",
988
+ "doc",
970
989
  "url"
971
990
  ]);
972
991
  PROPERTY_COLS = ["id", "database_id", "name", "type", "config", "position"];
@@ -984,7 +1003,7 @@ var init_properties = __esm(() => {
984
1003
  emit(db, "properties", id, "type", opts.type);
985
1004
  emit(db, "properties", id, "config", config);
986
1005
  emit(db, "properties", id, "position", opts.position ?? nextPosition(db, databaseId));
987
- if (opts.type === "relation" || opts.indexed === true)
1006
+ if (opts.type === "relation" || opts.type === "doc" || opts.indexed === true)
988
1007
  ensurePropIndex(db, databaseId, id);
989
1008
  return getProperty(db, id);
990
1009
  });
@@ -996,16 +1015,25 @@ var init_properties = __esm(() => {
996
1015
  if (fields.type !== undefined && !PROP_TYPES.has(fields.type))
997
1016
  throw new MhError("invalid_input", `unknown property type: ${fields.type}`);
998
1017
  const effectiveType = fields.type ?? cur.type;
999
- if (fields.config !== undefined)
1000
- validateConfig(effectiveType, fields.config);
1001
- else if (typeChanged)
1002
- validateConfig(fields.type, undefined);
1018
+ let mergedConfig;
1019
+ if (fields.config !== undefined) {
1020
+ const merged = { ...cur.config ?? {} };
1021
+ for (const [k, v] of Object.entries(fields.config)) {
1022
+ if (v === null)
1023
+ delete merged[k];
1024
+ else
1025
+ merged[k] = v;
1026
+ }
1027
+ mergedConfig = merged;
1028
+ validateConfig(effectiveType, mergedConfig);
1029
+ } else if (typeChanged)
1030
+ validateConfig(fields.type, cur.config ?? undefined);
1003
1031
  if (fields.name !== undefined)
1004
1032
  emit(db, "properties", id, "name", fields.name);
1005
1033
  if (fields.type !== undefined)
1006
1034
  emit(db, "properties", id, "type", fields.type);
1007
- if (fields.config !== undefined)
1008
- emit(db, "properties", id, "config", fields.config);
1035
+ if (mergedConfig !== undefined)
1036
+ emit(db, "properties", id, "config", mergedConfig);
1009
1037
  if (fields.position !== undefined)
1010
1038
  emit(db, "properties", id, "position", fields.position);
1011
1039
  if (typeChanged) {
@@ -1015,6 +1043,67 @@ var init_properties = __esm(() => {
1015
1043
  }
1016
1044
  return getProperty(db, id);
1017
1045
  });
1046
+ renameSelectOption = grouped(function renameSelectOption2(db, id, from, to) {
1047
+ const { prop, options } = getSelectProperty(db, id);
1048
+ to = to.trim();
1049
+ if (!to)
1050
+ throw new MhError("invalid_input", "option name must not be empty");
1051
+ if (!options.includes(from))
1052
+ throw new MhError("not_found", `no such option: ${from}`);
1053
+ if (to === from)
1054
+ return { property: prop, renamed: 0 };
1055
+ if (options.includes(to))
1056
+ throw new MhError("conflict", `option already exists: ${to}`);
1057
+ emit(db, "properties", id, "config", {
1058
+ ...prop.config ?? {},
1059
+ options: options.map((o) => o === from ? to : o)
1060
+ });
1061
+ let renamed = 0;
1062
+ if (prop.type === "select") {
1063
+ const rows = db.query("SELECT id FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? = ?").all(prop.database_id, id, from);
1064
+ for (const r of rows)
1065
+ emit(db, "records", r.id, id, to);
1066
+ renamed = rows.length;
1067
+ } else {
1068
+ const rows = db.query("SELECT id, data ->> ? AS v FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? IS NOT NULL").all(id, prop.database_id, id);
1069
+ for (const r of rows) {
1070
+ const vals = JSON.parse(r.v);
1071
+ if (!Array.isArray(vals) || !vals.includes(from))
1072
+ continue;
1073
+ emit(db, "records", r.id, id, [...new Set(vals.map((v) => v === from ? to : v))]);
1074
+ renamed++;
1075
+ }
1076
+ }
1077
+ return { property: getProperty(db, id), renamed };
1078
+ });
1079
+ removeSelectOption = grouped(function removeSelectOption2(db, id, name) {
1080
+ const { prop, options } = getSelectProperty(db, id);
1081
+ if (!options.includes(name))
1082
+ throw new MhError("not_found", `no such option: ${name}`);
1083
+ if (options.length === 1)
1084
+ throw new MhError("invalid_input", "cannot remove the last option; delete the property instead");
1085
+ emit(db, "properties", id, "config", {
1086
+ ...prop.config ?? {},
1087
+ options: options.filter((o) => o !== name)
1088
+ });
1089
+ let cleared = 0;
1090
+ if (prop.type === "select") {
1091
+ const rows = db.query("SELECT id FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? = ?").all(prop.database_id, id, name);
1092
+ for (const r of rows)
1093
+ emit(db, "records", r.id, id, null);
1094
+ cleared = rows.length;
1095
+ } else {
1096
+ const rows = db.query("SELECT id, data ->> ? AS v FROM records WHERE database_id = ? AND __deleted = 0 AND data ->> ? IS NOT NULL").all(id, prop.database_id, id);
1097
+ for (const r of rows) {
1098
+ const vals = JSON.parse(r.v);
1099
+ if (!Array.isArray(vals) || !vals.includes(name))
1100
+ continue;
1101
+ emit(db, "records", r.id, id, vals.filter((v) => v !== name));
1102
+ cleared++;
1103
+ }
1104
+ }
1105
+ return { property: getProperty(db, id), cleared };
1106
+ });
1018
1107
  removeProperty = grouped(function removeProperty2(db, id) {
1019
1108
  const prop = getProperty(db, id);
1020
1109
  if (!prop)
@@ -1088,19 +1177,38 @@ var init_databases = __esm(() => {
1088
1177
  emit(db, "databases", dup.id, "meta", meta);
1089
1178
  }
1090
1179
  const propIdMap = new Map;
1180
+ const selfRelNew = new Set;
1091
1181
  for (const p of listProperties(db, id)) {
1092
- const config = p.config?.database === id ? { ...p.config, database: dup.id } : p.config ?? undefined;
1182
+ const self = p.type === "relation" && p.config?.database === id;
1183
+ const config = self ? { ...p.config, database: dup.id } : p.config ?? undefined;
1093
1184
  const np = addProperty(db, dup.id, { name: p.name, type: p.type, config, position: p.position });
1094
1185
  propIdMap.set(p.id, np.id);
1186
+ if (self)
1187
+ selfRelNew.add(np.id);
1095
1188
  }
1096
- for (const r of listRecords(db, id)) {
1189
+ const srcRecords = listRecords(db, id);
1190
+ const recIdMap = new Map;
1191
+ for (const r of srcRecords) {
1097
1192
  const data = {};
1098
1193
  for (const [pid, v] of Object.entries(r.cells)) {
1099
1194
  const nid = propIdMap.get(pid);
1100
- if (nid)
1101
- data[nid] = v;
1195
+ if (!nid)
1196
+ continue;
1197
+ if (selfRelNew.has(nid) && Array.isArray(v) && v.length > 0)
1198
+ continue;
1199
+ data[nid] = v;
1200
+ }
1201
+ recIdMap.set(r.id, createRecord(db, dup.id, data).id);
1202
+ }
1203
+ for (const r of srcRecords) {
1204
+ const patch = {};
1205
+ for (const [pid, v] of Object.entries(r.cells)) {
1206
+ const nid = propIdMap.get(pid);
1207
+ if (nid && selfRelNew.has(nid) && Array.isArray(v) && v.length > 0)
1208
+ patch[nid] = v.map((x) => recIdMap.get(String(x)) ?? x);
1102
1209
  }
1103
- createRecord(db, dup.id, data);
1210
+ if (Object.keys(patch).length)
1211
+ updateRecord(db, recIdMap.get(r.id), patch);
1104
1212
  }
1105
1213
  return getDatabase(db, dup.id);
1106
1214
  });
@@ -1287,6 +1395,20 @@ function resolveRelation(db, prop, value) {
1287
1395
  }
1288
1396
  throw new MhError("ambiguous", `${prop.name}: ambiguous relation "${value}" (${cands.length} matches); use a full id`);
1289
1397
  }
1398
+ function resolveDoc(db, prop, value) {
1399
+ const cands = resolveCandidates(db, value, { kind: "doc" });
1400
+ const exact = cands.find((c) => c.id === value);
1401
+ if (exact)
1402
+ return exact.id;
1403
+ if (cands.length === 1)
1404
+ return cands[0].id;
1405
+ if (cands.length === 0) {
1406
+ if (idKind(value) === "doc")
1407
+ return value;
1408
+ throw new MhError("not_found", `${prop.name}: no such document: ${value}`);
1409
+ }
1410
+ throw new MhError("ambiguous", `${prop.name}: ambiguous document "${value}" (${cands.length} matches); use a full id`);
1411
+ }
1290
1412
  function coerce(db, prop, value) {
1291
1413
  switch (prop.type) {
1292
1414
  case "text":
@@ -1335,6 +1457,10 @@ function coerce(db, prop, value) {
1335
1457
  const arr = value === null ? [] : Array.isArray(value) ? value : [value];
1336
1458
  return arr.map((v) => resolveRelation(db, prop, String(v)));
1337
1459
  }
1460
+ case "doc": {
1461
+ const arr = value === null ? [] : Array.isArray(value) ? value : [value];
1462
+ return arr.map((v) => resolveDoc(db, prop, String(v)));
1463
+ }
1338
1464
  }
1339
1465
  }
1340
1466
  function propsByName(props) {
@@ -1486,6 +1612,17 @@ function listRecords(db, databaseId, opts = {}) {
1486
1612
  }
1487
1613
  return rows;
1488
1614
  }
1615
+ function recordTitleMap(db, databaseId) {
1616
+ const map = new Map;
1617
+ const tp = titlePropId(db, databaseId);
1618
+ if (!tp)
1619
+ return map;
1620
+ const rows = db.query(`SELECT id, data ->> '${jsonKeyLit(tp)}' AS title FROM records WHERE database_id = ? AND __deleted = 0`).all(databaseId);
1621
+ for (const r of rows)
1622
+ if (r.title)
1623
+ map.set(r.id, String(r.title));
1624
+ return map;
1625
+ }
1489
1626
  var backfillRecordOrderKeys, createRecordPrepared, createRecord, moveRecord, updateRecordPrepared, updateRecord, deleteRecord;
1490
1627
  var init_records = __esm(() => {
1491
1628
  init_ids();
@@ -1556,11 +1693,16 @@ var init_records = __esm(() => {
1556
1693
  return getRecord(db, id);
1557
1694
  });
1558
1695
  updateRecordPrepared = grouped(function updateRecordPrepared2(db, id, cells) {
1559
- const rec = db.query("SELECT id, database_id FROM records WHERE id = ? AND __deleted = 0").get(id);
1696
+ const rec = db.query("SELECT id, database_id, data FROM records WHERE id = ? AND __deleted = 0").get(id);
1560
1697
  if (!rec)
1561
1698
  throw new MhError("not_found", `no such record: ${id}`);
1562
- for (const { prop, value } of cells)
1563
- emit(db, "records", id, prop.id, value);
1699
+ const cur = JSON.parse(rec.data || "{}");
1700
+ for (const { prop, value } of cells) {
1701
+ const exists = Object.hasOwn(cur, prop.id);
1702
+ const same = value === undefined ? !exists : exists && JSON.stringify(value) === JSON.stringify(cur[prop.id]);
1703
+ if (!same)
1704
+ emit(db, "records", id, prop.id, value);
1705
+ }
1564
1706
  return getRecord(db, id);
1565
1707
  });
1566
1708
  updateRecord = grouped(function updateRecord2(db, id, data) {
@@ -1650,6 +1792,14 @@ function listDocuments(db, opts = {}) {
1650
1792
  return db.query(`${cols} AND database_id = ? ${ORDER_BY}`).all(opts.database_id);
1651
1793
  return db.query(`${cols} ${ORDER_BY}`).all();
1652
1794
  }
1795
+ function documentTitleMap(db) {
1796
+ const map = new Map;
1797
+ const rows = db.query("SELECT id, title FROM documents WHERE __deleted = 0").all();
1798
+ for (const r of rows)
1799
+ if (r.title)
1800
+ map.set(r.id, String(r.title));
1801
+ return map;
1802
+ }
1653
1803
  function siblingWhere(parentId) {
1654
1804
  return parentId === null ? { clause: "parent_id IS NULL", args: [] } : { clause: "parent_id = ?", args: [parentId] };
1655
1805
  }
@@ -2525,29 +2675,33 @@ function liveRowCount(db, databaseId) {
2525
2675
  }
2526
2676
  function assertRelationAllowed(set, principalKind, prop) {
2527
2677
  if (principalKind === "public")
2528
- throw new MhError("invalid_input", `${prop.name}: relation properties are not writable anonymously`);
2678
+ throw new MhError("invalid_input", `${prop.name}: ${prop.type} properties are not writable anonymously`);
2679
+ if (prop.type === "doc")
2680
+ throw new MhError("invalid_input", `${prop.name}: doc properties are not writable via shares (grants cannot scope documents)`);
2529
2681
  const target = prop.config?.database;
2530
2682
  if (!target || !grantFor(set, target))
2531
2683
  throw new MhError("invalid_input", `${prop.name}: relation target database is not in this share's grants`);
2532
2684
  }
2685
+ function isLiveRefValue(prop, value) {
2686
+ return (prop.type === "relation" || prop.type === "doc") && value != null && !(Array.isArray(value) && value.length === 0);
2687
+ }
2533
2688
  function assertGuestPayload(db, set, principal, database, values, opts = {}) {
2534
2689
  const limits = opts.limits ?? GUEST_LIMITS;
2535
2690
  const entries = Object.entries(values);
2536
2691
  if (entries.length > limits.maxCells)
2537
2692
  throw new MhError("invalid_input", `too many cells (max ${limits.maxCells})`);
2538
2693
  const props = listProperties(db, database.id);
2539
- const resolved = resolveData(props, values).map(({ prop, value }) => ({
2540
- prop,
2541
- value: coerce(db, prop, value)
2542
- }));
2694
+ const resolved = resolveData(props, values).map(({ prop, value }) => {
2695
+ if (isLiveRefValue(prop, value))
2696
+ assertRelationAllowed(set, principal.kind, prop);
2697
+ return { prop, value: coerce(db, prop, value) };
2698
+ });
2543
2699
  let total = 0;
2544
2700
  for (const { prop, value } of resolved) {
2545
2701
  const size = utf8Len(JSON.stringify(value ?? null));
2546
2702
  if (size > limits.maxValueBytes)
2547
2703
  throw new MhError("invalid_input", `${prop.name}: value too large (max ${limits.maxValueBytes} bytes)`);
2548
2704
  total += size;
2549
- if (prop.type === "relation" && value != null && !(Array.isArray(value) && value.length === 0))
2550
- assertRelationAllowed(set, principal.kind, prop);
2551
2705
  }
2552
2706
  if (total > limits.maxBodyBytes)
2553
2707
  throw new MhError("invalid_input", `payload too large (max ${limits.maxBodyBytes} bytes)`);
@@ -2617,7 +2771,7 @@ function checkGuestChanges(db, set, guestNode, changes, principalKind = "public"
2617
2771
  if (utf8Len(c.value ?? "") > limits.maxValueBytes)
2618
2772
  throw new MhError("invalid_input", `${prop.name}: value too large (max ${limits.maxValueBytes} bytes)`);
2619
2773
  const value = c.value == null ? null : JSON.parse(c.value);
2620
- if (prop.type === "relation" && value != null && !(Array.isArray(value) && value.length === 0))
2774
+ if (isLiveRefValue(prop, value))
2621
2775
  assertRelationAllowed(set, principalKind, prop);
2622
2776
  coerce(db, prop, value);
2623
2777
  }
@@ -3053,69 +3207,69 @@ var init_core = __esm(() => {
3053
3207
  // node_modules/zod/v4/core/util.js
3054
3208
  var exports_util = {};
3055
3209
  __export(exports_util, {
3056
- unwrapMessage: () => unwrapMessage,
3057
- uint8ArrayToHex: () => uint8ArrayToHex,
3058
- uint8ArrayToBase64url: () => uint8ArrayToBase64url,
3059
- uint8ArrayToBase64: () => uint8ArrayToBase64,
3060
- stringifyPrimitive: () => stringifyPrimitive,
3061
- slugify: () => slugify2,
3062
- shallowClone: () => shallowClone,
3063
- safeExtend: () => safeExtend,
3064
- required: () => required,
3065
- randomString: () => randomString,
3066
- propertyKeyTypes: () => propertyKeyTypes,
3067
- promiseAllObject: () => promiseAllObject,
3068
- primitiveTypes: () => primitiveTypes,
3069
- prefixIssues: () => prefixIssues,
3070
- pick: () => pick,
3071
- partial: () => partial,
3072
- parsedType: () => parsedType,
3073
- optionalKeys: () => optionalKeys,
3074
- omit: () => omit,
3075
- objectClone: () => objectClone,
3076
- numKeys: () => numKeys,
3077
- nullish: () => nullish,
3078
- normalizeParams: () => normalizeParams,
3079
- mergeDefs: () => mergeDefs,
3080
- merge: () => merge,
3081
- jsonStringifyReplacer: () => jsonStringifyReplacer,
3082
- joinValues: () => joinValues,
3083
- issue: () => issue,
3084
- isPlainObject: () => isPlainObject,
3085
- isObject: () => isObject,
3086
- hexToUint8Array: () => hexToUint8Array,
3087
- getSizableOrigin: () => getSizableOrigin,
3088
- getParsedType: () => getParsedType,
3089
- getLengthableOrigin: () => getLengthableOrigin,
3090
- getEnumValues: () => getEnumValues,
3091
- getElementAtPath: () => getElementAtPath,
3092
- floatSafeRemainder: () => floatSafeRemainder,
3093
- finalizeIssue: () => finalizeIssue,
3094
- extend: () => extend,
3095
- explicitlyAborted: () => explicitlyAborted,
3096
- escapeRegex: () => escapeRegex,
3097
- esc: () => esc,
3098
- defineLazy: () => defineLazy,
3099
- createTransparentProxy: () => createTransparentProxy,
3100
- cloneDef: () => cloneDef,
3101
- clone: () => clone,
3102
- cleanRegex: () => cleanRegex,
3103
- cleanEnum: () => cleanEnum,
3104
- captureStackTrace: () => captureStackTrace,
3105
- cached: () => cached,
3106
- base64urlToUint8Array: () => base64urlToUint8Array,
3107
- base64ToUint8Array: () => base64ToUint8Array,
3108
- assignProp: () => assignProp,
3109
- assertNotEqual: () => assertNotEqual,
3110
- assertNever: () => assertNever,
3111
- assertIs: () => assertIs,
3112
- assertEqual: () => assertEqual,
3113
- assert: () => assert,
3114
- allowsEval: () => allowsEval,
3115
- aborted: () => aborted,
3116
- NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES,
3210
+ BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
3117
3211
  Class: () => Class,
3118
- BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES
3212
+ NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES,
3213
+ aborted: () => aborted,
3214
+ allowsEval: () => allowsEval,
3215
+ assert: () => assert,
3216
+ assertEqual: () => assertEqual,
3217
+ assertIs: () => assertIs,
3218
+ assertNever: () => assertNever,
3219
+ assertNotEqual: () => assertNotEqual,
3220
+ assignProp: () => assignProp,
3221
+ base64ToUint8Array: () => base64ToUint8Array,
3222
+ base64urlToUint8Array: () => base64urlToUint8Array,
3223
+ cached: () => cached,
3224
+ captureStackTrace: () => captureStackTrace,
3225
+ cleanEnum: () => cleanEnum,
3226
+ cleanRegex: () => cleanRegex,
3227
+ clone: () => clone,
3228
+ cloneDef: () => cloneDef,
3229
+ createTransparentProxy: () => createTransparentProxy,
3230
+ defineLazy: () => defineLazy,
3231
+ esc: () => esc,
3232
+ escapeRegex: () => escapeRegex,
3233
+ explicitlyAborted: () => explicitlyAborted,
3234
+ extend: () => extend,
3235
+ finalizeIssue: () => finalizeIssue,
3236
+ floatSafeRemainder: () => floatSafeRemainder,
3237
+ getElementAtPath: () => getElementAtPath,
3238
+ getEnumValues: () => getEnumValues,
3239
+ getLengthableOrigin: () => getLengthableOrigin,
3240
+ getParsedType: () => getParsedType,
3241
+ getSizableOrigin: () => getSizableOrigin,
3242
+ hexToUint8Array: () => hexToUint8Array,
3243
+ isObject: () => isObject,
3244
+ isPlainObject: () => isPlainObject,
3245
+ issue: () => issue,
3246
+ joinValues: () => joinValues,
3247
+ jsonStringifyReplacer: () => jsonStringifyReplacer,
3248
+ merge: () => merge,
3249
+ mergeDefs: () => mergeDefs,
3250
+ normalizeParams: () => normalizeParams,
3251
+ nullish: () => nullish,
3252
+ numKeys: () => numKeys,
3253
+ objectClone: () => objectClone,
3254
+ omit: () => omit,
3255
+ optionalKeys: () => optionalKeys,
3256
+ parsedType: () => parsedType,
3257
+ partial: () => partial,
3258
+ pick: () => pick,
3259
+ prefixIssues: () => prefixIssues,
3260
+ primitiveTypes: () => primitiveTypes,
3261
+ promiseAllObject: () => promiseAllObject,
3262
+ propertyKeyTypes: () => propertyKeyTypes,
3263
+ randomString: () => randomString,
3264
+ required: () => required,
3265
+ safeExtend: () => safeExtend,
3266
+ shallowClone: () => shallowClone,
3267
+ slugify: () => slugify2,
3268
+ stringifyPrimitive: () => stringifyPrimitive,
3269
+ uint8ArrayToBase64: () => uint8ArrayToBase64,
3270
+ uint8ArrayToBase64url: () => uint8ArrayToBase64url,
3271
+ uint8ArrayToHex: () => uint8ArrayToHex,
3272
+ unwrapMessage: () => unwrapMessage
3119
3273
  });
3120
3274
  function assertEqual(val) {
3121
3275
  return val;
@@ -3974,90 +4128,90 @@ var init_parse = __esm(() => {
3974
4128
  // node_modules/zod/v4/core/regexes.js
3975
4129
  var exports_regexes = {};
3976
4130
  __export(exports_regexes, {
3977
- xid: () => xid,
3978
- uuid7: () => uuid7,
3979
- uuid6: () => uuid6,
3980
- uuid4: () => uuid4,
3981
- uuid: () => uuid,
3982
- uppercase: () => uppercase,
3983
- unicodeEmail: () => unicodeEmail,
3984
- undefined: () => _undefined,
3985
- ulid: () => ulid,
3986
- time: () => time,
3987
- string: () => string,
3988
- sha512_hex: () => sha512_hex,
3989
- sha512_base64url: () => sha512_base64url,
3990
- sha512_base64: () => sha512_base64,
3991
- sha384_hex: () => sha384_hex,
3992
- sha384_base64url: () => sha384_base64url,
3993
- sha384_base64: () => sha384_base64,
3994
- sha256_hex: () => sha256_hex,
3995
- sha256_base64url: () => sha256_base64url,
3996
- sha256_base64: () => sha256_base64,
3997
- sha1_hex: () => sha1_hex,
3998
- sha1_base64url: () => sha1_base64url,
3999
- sha1_base64: () => sha1_base64,
4000
- rfc5322Email: () => rfc5322Email,
4001
- number: () => number,
4002
- null: () => _null,
4003
- nanoid: () => nanoid,
4004
- md5_hex: () => md5_hex,
4005
- md5_base64url: () => md5_base64url,
4006
- md5_base64: () => md5_base64,
4007
- mac: () => mac,
4008
- lowercase: () => lowercase,
4009
- ksuid: () => ksuid,
4010
- ipv6: () => ipv6,
4011
- ipv4: () => ipv4,
4012
- integer: () => integer,
4013
- idnEmail: () => idnEmail,
4014
- httpProtocol: () => httpProtocol,
4015
- html5Email: () => html5Email,
4016
- hostname: () => hostname,
4017
- hex: () => hex,
4018
- guid: () => guid,
4019
- extendedDuration: () => extendedDuration,
4020
- emoji: () => emoji,
4021
- email: () => email,
4022
- e164: () => e164,
4023
- duration: () => duration,
4024
- domain: () => domain,
4025
- datetime: () => datetime,
4026
- date: () => date,
4027
- cuid2: () => cuid2,
4028
- cuid: () => cuid,
4029
- cidrv6: () => cidrv6,
4030
- cidrv4: () => cidrv4,
4031
- browserEmail: () => browserEmail,
4032
- boolean: () => boolean,
4033
- bigint: () => bigint,
4131
+ base64: () => base64,
4034
4132
  base64url: () => base64url,
4035
- base64: () => base64
4036
- });
4037
- function emoji() {
4038
- return new RegExp(_emoji, "u");
4039
- }
4040
- function timeSource(args) {
4041
- const hhmm = `(?:[01]\\d|2[0-3]):[0-5]\\d`;
4042
- const regex = typeof args.precision === "number" ? args.precision === -1 ? `${hhmm}` : args.precision === 0 ? `${hhmm}:[0-5]\\d` : `${hhmm}:[0-5]\\d\\.\\d{${args.precision}}` : `${hhmm}(?::[0-5]\\d(?:\\.\\d+)?)?`;
4043
- return regex;
4044
- }
4045
- function time(args) {
4046
- return new RegExp(`^${timeSource(args)}$`);
4047
- }
4048
- function datetime(args) {
4049
- const time2 = timeSource({ precision: args.precision });
4050
- const opts = ["Z"];
4051
- if (args.local)
4052
- opts.push("");
4053
- if (args.offset)
4054
- opts.push(`([+-](?:[01]\\d|2[0-3]):[0-5]\\d)`);
4055
- const timeRegex = `${time2}(?:${opts.join("|")})`;
4056
- return new RegExp(`^${dateSource}T(?:${timeRegex})$`);
4057
- }
4058
- function fixedBase64(bodyLength, padding) {
4059
- return new RegExp(`^[A-Za-z0-9+/]{${bodyLength}}${padding}$`);
4060
- }
4133
+ bigint: () => bigint,
4134
+ boolean: () => boolean,
4135
+ browserEmail: () => browserEmail,
4136
+ cidrv4: () => cidrv4,
4137
+ cidrv6: () => cidrv6,
4138
+ cuid: () => cuid,
4139
+ cuid2: () => cuid2,
4140
+ date: () => date,
4141
+ datetime: () => datetime,
4142
+ domain: () => domain,
4143
+ duration: () => duration,
4144
+ e164: () => e164,
4145
+ email: () => email,
4146
+ emoji: () => emoji,
4147
+ extendedDuration: () => extendedDuration,
4148
+ guid: () => guid,
4149
+ hex: () => hex,
4150
+ hostname: () => hostname,
4151
+ html5Email: () => html5Email,
4152
+ httpProtocol: () => httpProtocol,
4153
+ idnEmail: () => idnEmail,
4154
+ integer: () => integer,
4155
+ ipv4: () => ipv4,
4156
+ ipv6: () => ipv6,
4157
+ ksuid: () => ksuid,
4158
+ lowercase: () => lowercase,
4159
+ mac: () => mac,
4160
+ md5_base64: () => md5_base64,
4161
+ md5_base64url: () => md5_base64url,
4162
+ md5_hex: () => md5_hex,
4163
+ nanoid: () => nanoid,
4164
+ null: () => _null,
4165
+ number: () => number,
4166
+ rfc5322Email: () => rfc5322Email,
4167
+ sha1_base64: () => sha1_base64,
4168
+ sha1_base64url: () => sha1_base64url,
4169
+ sha1_hex: () => sha1_hex,
4170
+ sha256_base64: () => sha256_base64,
4171
+ sha256_base64url: () => sha256_base64url,
4172
+ sha256_hex: () => sha256_hex,
4173
+ sha384_base64: () => sha384_base64,
4174
+ sha384_base64url: () => sha384_base64url,
4175
+ sha384_hex: () => sha384_hex,
4176
+ sha512_base64: () => sha512_base64,
4177
+ sha512_base64url: () => sha512_base64url,
4178
+ sha512_hex: () => sha512_hex,
4179
+ string: () => string,
4180
+ time: () => time,
4181
+ ulid: () => ulid,
4182
+ undefined: () => _undefined,
4183
+ unicodeEmail: () => unicodeEmail,
4184
+ uppercase: () => uppercase,
4185
+ uuid: () => uuid,
4186
+ uuid4: () => uuid4,
4187
+ uuid6: () => uuid6,
4188
+ uuid7: () => uuid7,
4189
+ xid: () => xid
4190
+ });
4191
+ function emoji() {
4192
+ return new RegExp(_emoji, "u");
4193
+ }
4194
+ function timeSource(args) {
4195
+ const hhmm = `(?:[01]\\d|2[0-3]):[0-5]\\d`;
4196
+ const regex = typeof args.precision === "number" ? args.precision === -1 ? `${hhmm}` : args.precision === 0 ? `${hhmm}:[0-5]\\d` : `${hhmm}:[0-5]\\d\\.\\d{${args.precision}}` : `${hhmm}(?::[0-5]\\d(?:\\.\\d+)?)?`;
4197
+ return regex;
4198
+ }
4199
+ function time(args) {
4200
+ return new RegExp(`^${timeSource(args)}$`);
4201
+ }
4202
+ function datetime(args) {
4203
+ const time2 = timeSource({ precision: args.precision });
4204
+ const opts = ["Z"];
4205
+ if (args.local)
4206
+ opts.push("");
4207
+ if (args.offset)
4208
+ opts.push(`([+-](?:[01]\\d|2[0-3]):[0-5]\\d)`);
4209
+ const timeRegex = `${time2}(?:${opts.join("|")})`;
4210
+ return new RegExp(`^${dateSource}T(?:${timeRegex})$`);
4211
+ }
4212
+ function fixedBase64(bodyLength, padding) {
4213
+ return new RegExp(`^[A-Za-z0-9+/]{${bodyLength}}${padding}$`);
4214
+ }
4061
4215
  function fixedBase64url(length) {
4062
4216
  return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);
4063
4217
  }
@@ -12877,58 +13031,58 @@ var init_yo = __esm(() => {
12877
13031
  // node_modules/zod/v4/locales/index.js
12878
13032
  var exports_locales = {};
12879
13033
  __export(exports_locales, {
12880
- zhTW: () => zh_TW_default,
12881
- zhCN: () => zh_CN_default,
12882
- yo: () => yo_default,
12883
- vi: () => vi_default,
12884
- uz: () => uz_default,
12885
- ur: () => ur_default,
12886
- uk: () => uk_default,
12887
- ua: () => ua_default,
12888
- tr: () => tr_default,
12889
- th: () => th_default,
12890
- ta: () => ta_default,
12891
- sv: () => sv_default,
12892
- sl: () => sl_default,
12893
- ru: () => ru_default,
12894
- ro: () => ro_default,
12895
- pt: () => pt_default,
12896
- ps: () => ps_default,
12897
- pl: () => pl_default,
12898
- ota: () => ota_default,
12899
- no: () => no_default,
12900
- nl: () => nl_default,
12901
- ms: () => ms_default,
12902
- mk: () => mk_default,
12903
- lt: () => lt_default,
12904
- ko: () => ko_default,
12905
- km: () => km_default,
12906
- kh: () => kh_default,
12907
- ka: () => ka_default,
12908
- ja: () => ja_default,
12909
- it: () => it_default,
12910
- is: () => is_default,
12911
- id: () => id_default,
12912
- hy: () => hy_default,
12913
- hu: () => hu_default,
12914
- hr: () => hr_default,
12915
- he: () => he_default,
12916
- frCA: () => fr_CA_default,
12917
- fr: () => fr_default,
12918
- fi: () => fi_default,
12919
- fa: () => fa_default,
12920
- es: () => es_default,
12921
- eo: () => eo_default,
12922
- en: () => en_default,
12923
- el: () => el_default,
12924
- de: () => de_default,
12925
- da: () => da_default,
12926
- cs: () => cs_default,
12927
- ca: () => ca_default,
12928
- bg: () => bg_default,
12929
- be: () => be_default,
13034
+ ar: () => ar_default,
12930
13035
  az: () => az_default,
12931
- ar: () => ar_default
13036
+ be: () => be_default,
13037
+ bg: () => bg_default,
13038
+ ca: () => ca_default,
13039
+ cs: () => cs_default,
13040
+ da: () => da_default,
13041
+ de: () => de_default,
13042
+ el: () => el_default,
13043
+ en: () => en_default,
13044
+ eo: () => eo_default,
13045
+ es: () => es_default,
13046
+ fa: () => fa_default,
13047
+ fi: () => fi_default,
13048
+ fr: () => fr_default,
13049
+ frCA: () => fr_CA_default,
13050
+ he: () => he_default,
13051
+ hr: () => hr_default,
13052
+ hu: () => hu_default,
13053
+ hy: () => hy_default,
13054
+ id: () => id_default,
13055
+ is: () => is_default,
13056
+ it: () => it_default,
13057
+ ja: () => ja_default,
13058
+ ka: () => ka_default,
13059
+ kh: () => kh_default,
13060
+ km: () => km_default,
13061
+ ko: () => ko_default,
13062
+ lt: () => lt_default,
13063
+ mk: () => mk_default,
13064
+ ms: () => ms_default,
13065
+ nl: () => nl_default,
13066
+ no: () => no_default,
13067
+ ota: () => ota_default,
13068
+ pl: () => pl_default,
13069
+ ps: () => ps_default,
13070
+ pt: () => pt_default,
13071
+ ro: () => ro_default,
13072
+ ru: () => ru_default,
13073
+ sl: () => sl_default,
13074
+ sv: () => sv_default,
13075
+ ta: () => ta_default,
13076
+ th: () => th_default,
13077
+ tr: () => tr_default,
13078
+ ua: () => ua_default,
13079
+ uk: () => uk_default,
13080
+ ur: () => ur_default,
13081
+ uz: () => uz_default,
13082
+ vi: () => vi_default,
13083
+ yo: () => yo_default,
13084
+ zhCN: () => zh_CN_default,
13085
+ zhTW: () => zh_TW_default
12932
13086
  });
12933
13087
  var init_locales = __esm(() => {
12934
13088
  init_ar();
@@ -14896,280 +15050,280 @@ var init_json_schema = () => {};
14896
15050
  // node_modules/zod/v4/core/index.js
14897
15051
  var exports_core2 = {};
14898
15052
  __export(exports_core2, {
14899
- version: () => version,
14900
- util: () => exports_util,
14901
- treeifyError: () => treeifyError,
14902
- toJSONSchema: () => toJSONSchema,
14903
- toDotPath: () => toDotPath,
14904
- safeParseAsync: () => safeParseAsync,
14905
- safeParse: () => safeParse,
14906
- safeEncodeAsync: () => safeEncodeAsync,
14907
- safeEncode: () => safeEncode,
14908
- safeDecodeAsync: () => safeDecodeAsync,
14909
- safeDecode: () => safeDecode,
14910
- registry: () => registry,
14911
- regexes: () => exports_regexes,
14912
- process: () => process2,
14913
- prettifyError: () => prettifyError,
14914
- parseAsync: () => parseAsync,
14915
- parse: () => parse,
14916
- meta: () => meta,
14917
- locales: () => exports_locales,
14918
- isValidJWT: () => isValidJWT,
14919
- isValidBase64URL: () => isValidBase64URL,
14920
- isValidBase64: () => isValidBase64,
14921
- initializeContext: () => initializeContext,
14922
- globalRegistry: () => globalRegistry,
14923
- globalConfig: () => globalConfig,
14924
- formatError: () => formatError,
14925
- flattenError: () => flattenError,
14926
- finalize: () => finalize,
14927
- extractDefs: () => extractDefs,
14928
- encodeAsync: () => encodeAsync,
14929
- encode: () => encode,
14930
- describe: () => describe,
14931
- decodeAsync: () => decodeAsync,
14932
- decode: () => decode,
14933
- createToJSONSchemaMethod: () => createToJSONSchemaMethod,
14934
- createStandardJSONSchemaMethod: () => createStandardJSONSchemaMethod,
14935
- config: () => config,
14936
- clone: () => clone,
14937
- _xor: () => _xor,
14938
- _xid: () => _xid,
14939
- _void: () => _void,
14940
- _uuidv7: () => _uuidv7,
14941
- _uuidv6: () => _uuidv6,
14942
- _uuidv4: () => _uuidv4,
14943
- _uuid: () => _uuid,
14944
- _url: () => _url,
14945
- _uppercase: () => _uppercase,
14946
- _unknown: () => _unknown,
14947
- _union: () => _union,
14948
- _undefined: () => _undefined2,
14949
- _ulid: () => _ulid,
14950
- _uint64: () => _uint64,
14951
- _uint32: () => _uint32,
14952
- _tuple: () => _tuple,
14953
- _trim: () => _trim,
14954
- _transform: () => _transform,
14955
- _toUpperCase: () => _toUpperCase,
14956
- _toLowerCase: () => _toLowerCase,
14957
- _templateLiteral: () => _templateLiteral,
14958
- _symbol: () => _symbol,
14959
- _superRefine: () => _superRefine,
14960
- _success: () => _success,
14961
- _stringbool: () => _stringbool,
14962
- _stringFormat: () => _stringFormat,
14963
- _string: () => _string,
14964
- _startsWith: () => _startsWith,
14965
- _slugify: () => _slugify,
14966
- _size: () => _size,
14967
- _set: () => _set,
14968
- _safeParseAsync: () => _safeParseAsync,
14969
- _safeParse: () => _safeParse,
14970
- _safeEncodeAsync: () => _safeEncodeAsync,
14971
- _safeEncode: () => _safeEncode,
14972
- _safeDecodeAsync: () => _safeDecodeAsync,
14973
- _safeDecode: () => _safeDecode,
14974
- _regex: () => _regex,
14975
- _refine: () => _refine,
14976
- _record: () => _record,
14977
- _readonly: () => _readonly,
14978
- _property: () => _property,
14979
- _promise: () => _promise,
14980
- _positive: () => _positive,
14981
- _pipe: () => _pipe,
14982
- _parseAsync: () => _parseAsync,
14983
- _parse: () => _parse,
14984
- _overwrite: () => _overwrite,
14985
- _optional: () => _optional,
14986
- _number: () => _number,
14987
- _nullable: () => _nullable,
14988
- _null: () => _null2,
14989
- _normalize: () => _normalize,
14990
- _nonpositive: () => _nonpositive,
14991
- _nonoptional: () => _nonoptional,
14992
- _nonnegative: () => _nonnegative,
14993
- _never: () => _never,
14994
- _negative: () => _negative,
14995
- _nativeEnum: () => _nativeEnum,
14996
- _nanoid: () => _nanoid,
14997
- _nan: () => _nan,
14998
- _multipleOf: () => _multipleOf,
14999
- _minSize: () => _minSize,
15000
- _minLength: () => _minLength,
15001
- _min: () => _gte,
15002
- _mime: () => _mime,
15003
- _maxSize: () => _maxSize,
15004
- _maxLength: () => _maxLength,
15005
- _max: () => _lte,
15006
- _map: () => _map,
15007
- _mac: () => _mac,
15008
- _lte: () => _lte,
15009
- _lt: () => _lt,
15010
- _lowercase: () => _lowercase,
15011
- _literal: () => _literal,
15012
- _length: () => _length,
15013
- _lazy: () => _lazy,
15014
- _ksuid: () => _ksuid,
15015
- _jwt: () => _jwt,
15016
- _isoTime: () => _isoTime,
15017
- _isoDuration: () => _isoDuration,
15018
- _isoDateTime: () => _isoDateTime,
15019
- _isoDate: () => _isoDate,
15020
- _ipv6: () => _ipv6,
15021
- _ipv4: () => _ipv4,
15022
- _intersection: () => _intersection,
15023
- _int64: () => _int64,
15024
- _int32: () => _int32,
15025
- _int: () => _int,
15026
- _includes: () => _includes,
15027
- _guid: () => _guid,
15028
- _gte: () => _gte,
15029
- _gt: () => _gt,
15030
- _float64: () => _float64,
15031
- _float32: () => _float32,
15032
- _file: () => _file,
15033
- _enum: () => _enum,
15034
- _endsWith: () => _endsWith,
15035
- _encodeAsync: () => _encodeAsync,
15036
- _encode: () => _encode,
15037
- _emoji: () => _emoji2,
15038
- _email: () => _email,
15039
- _e164: () => _e164,
15040
- _discriminatedUnion: () => _discriminatedUnion,
15041
- _default: () => _default,
15042
- _decodeAsync: () => _decodeAsync,
15043
- _decode: () => _decode,
15044
- _date: () => _date,
15045
- _custom: () => _custom,
15046
- _cuid2: () => _cuid2,
15047
- _cuid: () => _cuid,
15048
- _coercedString: () => _coercedString,
15049
- _coercedNumber: () => _coercedNumber,
15050
- _coercedDate: () => _coercedDate,
15051
- _coercedBoolean: () => _coercedBoolean,
15052
- _coercedBigint: () => _coercedBigint,
15053
- _cidrv6: () => _cidrv6,
15054
- _cidrv4: () => _cidrv4,
15055
- _check: () => _check,
15056
- _catch: () => _catch,
15057
- _boolean: () => _boolean,
15058
- _bigint: () => _bigint,
15059
- _base64url: () => _base64url,
15060
- _base64: () => _base64,
15061
- _array: () => _array,
15062
- _any: () => _any,
15063
- TimePrecision: () => TimePrecision,
15064
- NEVER: () => NEVER,
15065
- JSONSchemaGenerator: () => JSONSchemaGenerator,
15066
- JSONSchema: () => exports_json_schema,
15067
- Doc: () => Doc,
15068
- $output: () => $output,
15069
- $input: () => $input,
15070
- $constructor: () => $constructor,
15071
- $brand: () => $brand,
15072
- $ZodXor: () => $ZodXor,
15073
- $ZodXID: () => $ZodXID,
15074
- $ZodVoid: () => $ZodVoid,
15075
- $ZodUnknown: () => $ZodUnknown,
15076
- $ZodUnion: () => $ZodUnion,
15077
- $ZodUndefined: () => $ZodUndefined,
15078
- $ZodUUID: () => $ZodUUID,
15079
- $ZodURL: () => $ZodURL,
15080
- $ZodULID: () => $ZodULID,
15081
- $ZodType: () => $ZodType,
15082
- $ZodTuple: () => $ZodTuple,
15083
- $ZodTransform: () => $ZodTransform,
15084
- $ZodTemplateLiteral: () => $ZodTemplateLiteral,
15085
- $ZodSymbol: () => $ZodSymbol,
15086
- $ZodSuccess: () => $ZodSuccess,
15087
- $ZodStringFormat: () => $ZodStringFormat,
15088
- $ZodString: () => $ZodString,
15089
- $ZodSet: () => $ZodSet,
15090
- $ZodRegistry: () => $ZodRegistry,
15091
- $ZodRecord: () => $ZodRecord,
15092
- $ZodRealError: () => $ZodRealError,
15093
- $ZodReadonly: () => $ZodReadonly,
15094
- $ZodPromise: () => $ZodPromise,
15095
- $ZodPreprocess: () => $ZodPreprocess,
15096
- $ZodPrefault: () => $ZodPrefault,
15097
- $ZodPipe: () => $ZodPipe,
15098
- $ZodOptional: () => $ZodOptional,
15099
- $ZodObjectJIT: () => $ZodObjectJIT,
15100
- $ZodObject: () => $ZodObject,
15101
- $ZodNumberFormat: () => $ZodNumberFormat,
15102
- $ZodNumber: () => $ZodNumber,
15103
- $ZodNullable: () => $ZodNullable,
15104
- $ZodNull: () => $ZodNull,
15105
- $ZodNonOptional: () => $ZodNonOptional,
15106
- $ZodNever: () => $ZodNever,
15107
- $ZodNanoID: () => $ZodNanoID,
15108
- $ZodNaN: () => $ZodNaN,
15109
- $ZodMap: () => $ZodMap,
15110
- $ZodMAC: () => $ZodMAC,
15111
- $ZodLiteral: () => $ZodLiteral,
15112
- $ZodLazy: () => $ZodLazy,
15113
- $ZodKSUID: () => $ZodKSUID,
15114
- $ZodJWT: () => $ZodJWT,
15115
- $ZodIntersection: () => $ZodIntersection,
15116
- $ZodISOTime: () => $ZodISOTime,
15117
- $ZodISODuration: () => $ZodISODuration,
15118
- $ZodISODateTime: () => $ZodISODateTime,
15119
- $ZodISODate: () => $ZodISODate,
15120
- $ZodIPv6: () => $ZodIPv6,
15121
- $ZodIPv4: () => $ZodIPv4,
15122
- $ZodGUID: () => $ZodGUID,
15123
- $ZodFunction: () => $ZodFunction,
15124
- $ZodFile: () => $ZodFile,
15125
- $ZodExactOptional: () => $ZodExactOptional,
15126
- $ZodError: () => $ZodError,
15127
- $ZodEnum: () => $ZodEnum,
15128
- $ZodEncodeError: () => $ZodEncodeError,
15129
- $ZodEmoji: () => $ZodEmoji,
15130
- $ZodEmail: () => $ZodEmail,
15131
- $ZodE164: () => $ZodE164,
15132
- $ZodDiscriminatedUnion: () => $ZodDiscriminatedUnion,
15133
- $ZodDefault: () => $ZodDefault,
15134
- $ZodDate: () => $ZodDate,
15135
- $ZodCustomStringFormat: () => $ZodCustomStringFormat,
15136
- $ZodCustom: () => $ZodCustom,
15137
- $ZodCodec: () => $ZodCodec,
15138
- $ZodCheckUpperCase: () => $ZodCheckUpperCase,
15139
- $ZodCheckStringFormat: () => $ZodCheckStringFormat,
15140
- $ZodCheckStartsWith: () => $ZodCheckStartsWith,
15141
- $ZodCheckSizeEquals: () => $ZodCheckSizeEquals,
15142
- $ZodCheckRegex: () => $ZodCheckRegex,
15143
- $ZodCheckProperty: () => $ZodCheckProperty,
15144
- $ZodCheckOverwrite: () => $ZodCheckOverwrite,
15145
- $ZodCheckNumberFormat: () => $ZodCheckNumberFormat,
15146
- $ZodCheckMultipleOf: () => $ZodCheckMultipleOf,
15147
- $ZodCheckMinSize: () => $ZodCheckMinSize,
15148
- $ZodCheckMinLength: () => $ZodCheckMinLength,
15149
- $ZodCheckMimeType: () => $ZodCheckMimeType,
15150
- $ZodCheckMaxSize: () => $ZodCheckMaxSize,
15151
- $ZodCheckMaxLength: () => $ZodCheckMaxLength,
15152
- $ZodCheckLowerCase: () => $ZodCheckLowerCase,
15153
- $ZodCheckLessThan: () => $ZodCheckLessThan,
15154
- $ZodCheckLengthEquals: () => $ZodCheckLengthEquals,
15155
- $ZodCheckIncludes: () => $ZodCheckIncludes,
15156
- $ZodCheckGreaterThan: () => $ZodCheckGreaterThan,
15157
- $ZodCheckEndsWith: () => $ZodCheckEndsWith,
15158
- $ZodCheckBigIntFormat: () => $ZodCheckBigIntFormat,
15159
- $ZodCheck: () => $ZodCheck,
15160
- $ZodCatch: () => $ZodCatch,
15161
- $ZodCUID2: () => $ZodCUID2,
15162
- $ZodCUID: () => $ZodCUID,
15163
- $ZodCIDRv6: () => $ZodCIDRv6,
15164
- $ZodCIDRv4: () => $ZodCIDRv4,
15165
- $ZodBoolean: () => $ZodBoolean,
15166
- $ZodBigIntFormat: () => $ZodBigIntFormat,
15167
- $ZodBigInt: () => $ZodBigInt,
15168
- $ZodBase64URL: () => $ZodBase64URL,
15169
- $ZodBase64: () => $ZodBase64,
15170
- $ZodAsyncError: () => $ZodAsyncError,
15053
+ $ZodAny: () => $ZodAny,
15171
15054
  $ZodArray: () => $ZodArray,
15172
- $ZodAny: () => $ZodAny
15055
+ $ZodAsyncError: () => $ZodAsyncError,
15056
+ $ZodBase64: () => $ZodBase64,
15057
+ $ZodBase64URL: () => $ZodBase64URL,
15058
+ $ZodBigInt: () => $ZodBigInt,
15059
+ $ZodBigIntFormat: () => $ZodBigIntFormat,
15060
+ $ZodBoolean: () => $ZodBoolean,
15061
+ $ZodCIDRv4: () => $ZodCIDRv4,
15062
+ $ZodCIDRv6: () => $ZodCIDRv6,
15063
+ $ZodCUID: () => $ZodCUID,
15064
+ $ZodCUID2: () => $ZodCUID2,
15065
+ $ZodCatch: () => $ZodCatch,
15066
+ $ZodCheck: () => $ZodCheck,
15067
+ $ZodCheckBigIntFormat: () => $ZodCheckBigIntFormat,
15068
+ $ZodCheckEndsWith: () => $ZodCheckEndsWith,
15069
+ $ZodCheckGreaterThan: () => $ZodCheckGreaterThan,
15070
+ $ZodCheckIncludes: () => $ZodCheckIncludes,
15071
+ $ZodCheckLengthEquals: () => $ZodCheckLengthEquals,
15072
+ $ZodCheckLessThan: () => $ZodCheckLessThan,
15073
+ $ZodCheckLowerCase: () => $ZodCheckLowerCase,
15074
+ $ZodCheckMaxLength: () => $ZodCheckMaxLength,
15075
+ $ZodCheckMaxSize: () => $ZodCheckMaxSize,
15076
+ $ZodCheckMimeType: () => $ZodCheckMimeType,
15077
+ $ZodCheckMinLength: () => $ZodCheckMinLength,
15078
+ $ZodCheckMinSize: () => $ZodCheckMinSize,
15079
+ $ZodCheckMultipleOf: () => $ZodCheckMultipleOf,
15080
+ $ZodCheckNumberFormat: () => $ZodCheckNumberFormat,
15081
+ $ZodCheckOverwrite: () => $ZodCheckOverwrite,
15082
+ $ZodCheckProperty: () => $ZodCheckProperty,
15083
+ $ZodCheckRegex: () => $ZodCheckRegex,
15084
+ $ZodCheckSizeEquals: () => $ZodCheckSizeEquals,
15085
+ $ZodCheckStartsWith: () => $ZodCheckStartsWith,
15086
+ $ZodCheckStringFormat: () => $ZodCheckStringFormat,
15087
+ $ZodCheckUpperCase: () => $ZodCheckUpperCase,
15088
+ $ZodCodec: () => $ZodCodec,
15089
+ $ZodCustom: () => $ZodCustom,
15090
+ $ZodCustomStringFormat: () => $ZodCustomStringFormat,
15091
+ $ZodDate: () => $ZodDate,
15092
+ $ZodDefault: () => $ZodDefault,
15093
+ $ZodDiscriminatedUnion: () => $ZodDiscriminatedUnion,
15094
+ $ZodE164: () => $ZodE164,
15095
+ $ZodEmail: () => $ZodEmail,
15096
+ $ZodEmoji: () => $ZodEmoji,
15097
+ $ZodEncodeError: () => $ZodEncodeError,
15098
+ $ZodEnum: () => $ZodEnum,
15099
+ $ZodError: () => $ZodError,
15100
+ $ZodExactOptional: () => $ZodExactOptional,
15101
+ $ZodFile: () => $ZodFile,
15102
+ $ZodFunction: () => $ZodFunction,
15103
+ $ZodGUID: () => $ZodGUID,
15104
+ $ZodIPv4: () => $ZodIPv4,
15105
+ $ZodIPv6: () => $ZodIPv6,
15106
+ $ZodISODate: () => $ZodISODate,
15107
+ $ZodISODateTime: () => $ZodISODateTime,
15108
+ $ZodISODuration: () => $ZodISODuration,
15109
+ $ZodISOTime: () => $ZodISOTime,
15110
+ $ZodIntersection: () => $ZodIntersection,
15111
+ $ZodJWT: () => $ZodJWT,
15112
+ $ZodKSUID: () => $ZodKSUID,
15113
+ $ZodLazy: () => $ZodLazy,
15114
+ $ZodLiteral: () => $ZodLiteral,
15115
+ $ZodMAC: () => $ZodMAC,
15116
+ $ZodMap: () => $ZodMap,
15117
+ $ZodNaN: () => $ZodNaN,
15118
+ $ZodNanoID: () => $ZodNanoID,
15119
+ $ZodNever: () => $ZodNever,
15120
+ $ZodNonOptional: () => $ZodNonOptional,
15121
+ $ZodNull: () => $ZodNull,
15122
+ $ZodNullable: () => $ZodNullable,
15123
+ $ZodNumber: () => $ZodNumber,
15124
+ $ZodNumberFormat: () => $ZodNumberFormat,
15125
+ $ZodObject: () => $ZodObject,
15126
+ $ZodObjectJIT: () => $ZodObjectJIT,
15127
+ $ZodOptional: () => $ZodOptional,
15128
+ $ZodPipe: () => $ZodPipe,
15129
+ $ZodPrefault: () => $ZodPrefault,
15130
+ $ZodPreprocess: () => $ZodPreprocess,
15131
+ $ZodPromise: () => $ZodPromise,
15132
+ $ZodReadonly: () => $ZodReadonly,
15133
+ $ZodRealError: () => $ZodRealError,
15134
+ $ZodRecord: () => $ZodRecord,
15135
+ $ZodRegistry: () => $ZodRegistry,
15136
+ $ZodSet: () => $ZodSet,
15137
+ $ZodString: () => $ZodString,
15138
+ $ZodStringFormat: () => $ZodStringFormat,
15139
+ $ZodSuccess: () => $ZodSuccess,
15140
+ $ZodSymbol: () => $ZodSymbol,
15141
+ $ZodTemplateLiteral: () => $ZodTemplateLiteral,
15142
+ $ZodTransform: () => $ZodTransform,
15143
+ $ZodTuple: () => $ZodTuple,
15144
+ $ZodType: () => $ZodType,
15145
+ $ZodULID: () => $ZodULID,
15146
+ $ZodURL: () => $ZodURL,
15147
+ $ZodUUID: () => $ZodUUID,
15148
+ $ZodUndefined: () => $ZodUndefined,
15149
+ $ZodUnion: () => $ZodUnion,
15150
+ $ZodUnknown: () => $ZodUnknown,
15151
+ $ZodVoid: () => $ZodVoid,
15152
+ $ZodXID: () => $ZodXID,
15153
+ $ZodXor: () => $ZodXor,
15154
+ $brand: () => $brand,
15155
+ $constructor: () => $constructor,
15156
+ $input: () => $input,
15157
+ $output: () => $output,
15158
+ Doc: () => Doc,
15159
+ JSONSchema: () => exports_json_schema,
15160
+ JSONSchemaGenerator: () => JSONSchemaGenerator,
15161
+ NEVER: () => NEVER,
15162
+ TimePrecision: () => TimePrecision,
15163
+ _any: () => _any,
15164
+ _array: () => _array,
15165
+ _base64: () => _base64,
15166
+ _base64url: () => _base64url,
15167
+ _bigint: () => _bigint,
15168
+ _boolean: () => _boolean,
15169
+ _catch: () => _catch,
15170
+ _check: () => _check,
15171
+ _cidrv4: () => _cidrv4,
15172
+ _cidrv6: () => _cidrv6,
15173
+ _coercedBigint: () => _coercedBigint,
15174
+ _coercedBoolean: () => _coercedBoolean,
15175
+ _coercedDate: () => _coercedDate,
15176
+ _coercedNumber: () => _coercedNumber,
15177
+ _coercedString: () => _coercedString,
15178
+ _cuid: () => _cuid,
15179
+ _cuid2: () => _cuid2,
15180
+ _custom: () => _custom,
15181
+ _date: () => _date,
15182
+ _decode: () => _decode,
15183
+ _decodeAsync: () => _decodeAsync,
15184
+ _default: () => _default,
15185
+ _discriminatedUnion: () => _discriminatedUnion,
15186
+ _e164: () => _e164,
15187
+ _email: () => _email,
15188
+ _emoji: () => _emoji2,
15189
+ _encode: () => _encode,
15190
+ _encodeAsync: () => _encodeAsync,
15191
+ _endsWith: () => _endsWith,
15192
+ _enum: () => _enum,
15193
+ _file: () => _file,
15194
+ _float32: () => _float32,
15195
+ _float64: () => _float64,
15196
+ _gt: () => _gt,
15197
+ _gte: () => _gte,
15198
+ _guid: () => _guid,
15199
+ _includes: () => _includes,
15200
+ _int: () => _int,
15201
+ _int32: () => _int32,
15202
+ _int64: () => _int64,
15203
+ _intersection: () => _intersection,
15204
+ _ipv4: () => _ipv4,
15205
+ _ipv6: () => _ipv6,
15206
+ _isoDate: () => _isoDate,
15207
+ _isoDateTime: () => _isoDateTime,
15208
+ _isoDuration: () => _isoDuration,
15209
+ _isoTime: () => _isoTime,
15210
+ _jwt: () => _jwt,
15211
+ _ksuid: () => _ksuid,
15212
+ _lazy: () => _lazy,
15213
+ _length: () => _length,
15214
+ _literal: () => _literal,
15215
+ _lowercase: () => _lowercase,
15216
+ _lt: () => _lt,
15217
+ _lte: () => _lte,
15218
+ _mac: () => _mac,
15219
+ _map: () => _map,
15220
+ _max: () => _lte,
15221
+ _maxLength: () => _maxLength,
15222
+ _maxSize: () => _maxSize,
15223
+ _mime: () => _mime,
15224
+ _min: () => _gte,
15225
+ _minLength: () => _minLength,
15226
+ _minSize: () => _minSize,
15227
+ _multipleOf: () => _multipleOf,
15228
+ _nan: () => _nan,
15229
+ _nanoid: () => _nanoid,
15230
+ _nativeEnum: () => _nativeEnum,
15231
+ _negative: () => _negative,
15232
+ _never: () => _never,
15233
+ _nonnegative: () => _nonnegative,
15234
+ _nonoptional: () => _nonoptional,
15235
+ _nonpositive: () => _nonpositive,
15236
+ _normalize: () => _normalize,
15237
+ _null: () => _null2,
15238
+ _nullable: () => _nullable,
15239
+ _number: () => _number,
15240
+ _optional: () => _optional,
15241
+ _overwrite: () => _overwrite,
15242
+ _parse: () => _parse,
15243
+ _parseAsync: () => _parseAsync,
15244
+ _pipe: () => _pipe,
15245
+ _positive: () => _positive,
15246
+ _promise: () => _promise,
15247
+ _property: () => _property,
15248
+ _readonly: () => _readonly,
15249
+ _record: () => _record,
15250
+ _refine: () => _refine,
15251
+ _regex: () => _regex,
15252
+ _safeDecode: () => _safeDecode,
15253
+ _safeDecodeAsync: () => _safeDecodeAsync,
15254
+ _safeEncode: () => _safeEncode,
15255
+ _safeEncodeAsync: () => _safeEncodeAsync,
15256
+ _safeParse: () => _safeParse,
15257
+ _safeParseAsync: () => _safeParseAsync,
15258
+ _set: () => _set,
15259
+ _size: () => _size,
15260
+ _slugify: () => _slugify,
15261
+ _startsWith: () => _startsWith,
15262
+ _string: () => _string,
15263
+ _stringFormat: () => _stringFormat,
15264
+ _stringbool: () => _stringbool,
15265
+ _success: () => _success,
15266
+ _superRefine: () => _superRefine,
15267
+ _symbol: () => _symbol,
15268
+ _templateLiteral: () => _templateLiteral,
15269
+ _toLowerCase: () => _toLowerCase,
15270
+ _toUpperCase: () => _toUpperCase,
15271
+ _transform: () => _transform,
15272
+ _trim: () => _trim,
15273
+ _tuple: () => _tuple,
15274
+ _uint32: () => _uint32,
15275
+ _uint64: () => _uint64,
15276
+ _ulid: () => _ulid,
15277
+ _undefined: () => _undefined2,
15278
+ _union: () => _union,
15279
+ _unknown: () => _unknown,
15280
+ _uppercase: () => _uppercase,
15281
+ _url: () => _url,
15282
+ _uuid: () => _uuid,
15283
+ _uuidv4: () => _uuidv4,
15284
+ _uuidv6: () => _uuidv6,
15285
+ _uuidv7: () => _uuidv7,
15286
+ _void: () => _void,
15287
+ _xid: () => _xid,
15288
+ _xor: () => _xor,
15289
+ clone: () => clone,
15290
+ config: () => config,
15291
+ createStandardJSONSchemaMethod: () => createStandardJSONSchemaMethod,
15292
+ createToJSONSchemaMethod: () => createToJSONSchemaMethod,
15293
+ decode: () => decode,
15294
+ decodeAsync: () => decodeAsync,
15295
+ describe: () => describe,
15296
+ encode: () => encode,
15297
+ encodeAsync: () => encodeAsync,
15298
+ extractDefs: () => extractDefs,
15299
+ finalize: () => finalize,
15300
+ flattenError: () => flattenError,
15301
+ formatError: () => formatError,
15302
+ globalConfig: () => globalConfig,
15303
+ globalRegistry: () => globalRegistry,
15304
+ initializeContext: () => initializeContext,
15305
+ isValidBase64: () => isValidBase64,
15306
+ isValidBase64URL: () => isValidBase64URL,
15307
+ isValidJWT: () => isValidJWT,
15308
+ locales: () => exports_locales,
15309
+ meta: () => meta,
15310
+ parse: () => parse,
15311
+ parseAsync: () => parseAsync,
15312
+ prettifyError: () => prettifyError,
15313
+ process: () => process2,
15314
+ regexes: () => exports_regexes,
15315
+ registry: () => registry,
15316
+ safeDecode: () => safeDecode,
15317
+ safeDecodeAsync: () => safeDecodeAsync,
15318
+ safeEncode: () => safeEncode,
15319
+ safeEncodeAsync: () => safeEncodeAsync,
15320
+ safeParse: () => safeParse,
15321
+ safeParseAsync: () => safeParseAsync,
15322
+ toDotPath: () => toDotPath,
15323
+ toJSONSchema: () => toJSONSchema,
15324
+ treeifyError: () => treeifyError,
15325
+ util: () => exports_util,
15326
+ version: () => version
15173
15327
  });
15174
15328
  var init_core2 = __esm(() => {
15175
15329
  init_util();
@@ -15192,35 +15346,35 @@ var init_core2 = __esm(() => {
15192
15346
  // node_modules/zod/v4/classic/checks.js
15193
15347
  var exports_checks2 = {};
15194
15348
  __export(exports_checks2, {
15195
- uppercase: () => _uppercase,
15196
- trim: () => _trim,
15197
- toUpperCase: () => _toUpperCase,
15198
- toLowerCase: () => _toLowerCase,
15199
- startsWith: () => _startsWith,
15200
- slugify: () => _slugify,
15201
- size: () => _size,
15202
- regex: () => _regex,
15203
- property: () => _property,
15204
- positive: () => _positive,
15205
- overwrite: () => _overwrite,
15206
- normalize: () => _normalize,
15207
- nonpositive: () => _nonpositive,
15208
- nonnegative: () => _nonnegative,
15209
- negative: () => _negative,
15210
- multipleOf: () => _multipleOf,
15211
- minSize: () => _minSize,
15212
- minLength: () => _minLength,
15213
- mime: () => _mime,
15214
- maxSize: () => _maxSize,
15215
- maxLength: () => _maxLength,
15216
- lte: () => _lte,
15217
- lt: () => _lt,
15218
- lowercase: () => _lowercase,
15219
- length: () => _length,
15220
- includes: () => _includes,
15221
- gte: () => _gte,
15349
+ endsWith: () => _endsWith,
15222
15350
  gt: () => _gt,
15223
- endsWith: () => _endsWith
15351
+ gte: () => _gte,
15352
+ includes: () => _includes,
15353
+ length: () => _length,
15354
+ lowercase: () => _lowercase,
15355
+ lt: () => _lt,
15356
+ lte: () => _lte,
15357
+ maxLength: () => _maxLength,
15358
+ maxSize: () => _maxSize,
15359
+ mime: () => _mime,
15360
+ minLength: () => _minLength,
15361
+ minSize: () => _minSize,
15362
+ multipleOf: () => _multipleOf,
15363
+ negative: () => _negative,
15364
+ nonnegative: () => _nonnegative,
15365
+ nonpositive: () => _nonpositive,
15366
+ normalize: () => _normalize,
15367
+ overwrite: () => _overwrite,
15368
+ positive: () => _positive,
15369
+ property: () => _property,
15370
+ regex: () => _regex,
15371
+ size: () => _size,
15372
+ slugify: () => _slugify,
15373
+ startsWith: () => _startsWith,
15374
+ toLowerCase: () => _toLowerCase,
15375
+ toUpperCase: () => _toUpperCase,
15376
+ trim: () => _trim,
15377
+ uppercase: () => _uppercase
15224
15378
  });
15225
15379
  var init_checks2 = __esm(() => {
15226
15380
  init_core2();
@@ -15229,14 +15383,14 @@ var init_checks2 = __esm(() => {
15229
15383
  // node_modules/zod/v4/classic/iso.js
15230
15384
  var exports_iso = {};
15231
15385
  __export(exports_iso, {
15232
- time: () => time2,
15233
- duration: () => duration2,
15234
- datetime: () => datetime2,
15235
- date: () => date2,
15236
- ZodISOTime: () => ZodISOTime,
15237
- ZodISODuration: () => ZodISODuration,
15386
+ ZodISODate: () => ZodISODate,
15238
15387
  ZodISODateTime: () => ZodISODateTime,
15239
- ZodISODate: () => ZodISODate
15388
+ ZodISODuration: () => ZodISODuration,
15389
+ ZodISOTime: () => ZodISOTime,
15390
+ date: () => date2,
15391
+ datetime: () => datetime2,
15392
+ duration: () => duration2,
15393
+ time: () => time2
15240
15394
  });
15241
15395
  function datetime2(params) {
15242
15396
  return _isoDateTime(ZodISODateTime, params);
@@ -15334,172 +15488,172 @@ var init_parse2 = __esm(() => {
15334
15488
  // node_modules/zod/v4/classic/schemas.js
15335
15489
  var exports_schemas2 = {};
15336
15490
  __export(exports_schemas2, {
15337
- xor: () => xor,
15338
- xid: () => xid2,
15339
- void: () => _void2,
15340
- uuidv7: () => uuidv7,
15341
- uuidv6: () => uuidv6,
15342
- uuidv4: () => uuidv4,
15343
- uuid: () => uuid2,
15344
- url: () => url,
15345
- unknown: () => unknown,
15346
- union: () => union,
15347
- undefined: () => _undefined3,
15348
- ulid: () => ulid2,
15349
- uint64: () => uint64,
15350
- uint32: () => uint32,
15351
- tuple: () => tuple,
15352
- transform: () => transform,
15353
- templateLiteral: () => templateLiteral,
15354
- symbol: () => symbol,
15355
- superRefine: () => superRefine,
15356
- success: () => success,
15357
- stringbool: () => stringbool,
15358
- stringFormat: () => stringFormat,
15359
- string: () => string2,
15360
- strictObject: () => strictObject,
15361
- set: () => set,
15362
- refine: () => refine,
15363
- record: () => record,
15364
- readonly: () => readonly,
15365
- promise: () => promise,
15366
- preprocess: () => preprocess,
15367
- prefault: () => prefault,
15368
- pipe: () => pipe,
15369
- partialRecord: () => partialRecord,
15370
- optional: () => optional,
15371
- object: () => object,
15372
- number: () => number2,
15373
- nullish: () => nullish2,
15374
- nullable: () => nullable,
15375
- null: () => _null3,
15376
- nonoptional: () => nonoptional,
15377
- never: () => never,
15378
- nativeEnum: () => nativeEnum,
15379
- nanoid: () => nanoid2,
15380
- nan: () => nan,
15381
- meta: () => meta2,
15382
- map: () => map,
15383
- mac: () => mac2,
15384
- looseRecord: () => looseRecord,
15385
- looseObject: () => looseObject,
15386
- literal: () => literal,
15387
- lazy: () => lazy,
15388
- ksuid: () => ksuid2,
15389
- keyof: () => keyof,
15390
- jwt: () => jwt,
15391
- json: () => json,
15392
- ipv6: () => ipv62,
15393
- ipv4: () => ipv42,
15394
- invertCodec: () => invertCodec,
15395
- intersection: () => intersection,
15396
- int64: () => int64,
15397
- int32: () => int32,
15398
- int: () => int,
15399
- instanceof: () => _instanceof,
15400
- httpUrl: () => httpUrl,
15401
- hostname: () => hostname2,
15402
- hex: () => hex2,
15403
- hash: () => hash,
15404
- guid: () => guid2,
15405
- function: () => _function,
15406
- float64: () => float64,
15407
- float32: () => float32,
15408
- file: () => file,
15409
- exactOptional: () => exactOptional,
15410
- enum: () => _enum2,
15411
- emoji: () => emoji2,
15412
- email: () => email2,
15413
- e164: () => e1642,
15414
- discriminatedUnion: () => discriminatedUnion,
15415
- describe: () => describe2,
15416
- date: () => date3,
15417
- custom: () => custom,
15418
- cuid2: () => cuid22,
15419
- cuid: () => cuid3,
15420
- codec: () => codec,
15421
- cidrv6: () => cidrv62,
15422
- cidrv4: () => cidrv42,
15423
- check: () => check,
15424
- catch: () => _catch2,
15425
- boolean: () => boolean2,
15426
- bigint: () => bigint2,
15427
- base64url: () => base64url2,
15428
- base64: () => base642,
15429
- array: () => array,
15430
- any: () => any,
15431
- _function: () => _function,
15432
- _default: () => _default2,
15433
- _ZodString: () => _ZodString,
15434
- ZodXor: () => ZodXor,
15435
- ZodXID: () => ZodXID,
15436
- ZodVoid: () => ZodVoid,
15437
- ZodUnknown: () => ZodUnknown,
15438
- ZodUnion: () => ZodUnion,
15439
- ZodUndefined: () => ZodUndefined,
15440
- ZodUUID: () => ZodUUID,
15441
- ZodURL: () => ZodURL,
15442
- ZodULID: () => ZodULID,
15443
- ZodType: () => ZodType,
15444
- ZodTuple: () => ZodTuple,
15445
- ZodTransform: () => ZodTransform,
15446
- ZodTemplateLiteral: () => ZodTemplateLiteral,
15447
- ZodSymbol: () => ZodSymbol,
15448
- ZodSuccess: () => ZodSuccess,
15449
- ZodStringFormat: () => ZodStringFormat,
15450
- ZodString: () => ZodString,
15451
- ZodSet: () => ZodSet,
15452
- ZodRecord: () => ZodRecord,
15453
- ZodReadonly: () => ZodReadonly,
15454
- ZodPromise: () => ZodPromise,
15455
- ZodPreprocess: () => ZodPreprocess,
15456
- ZodPrefault: () => ZodPrefault,
15457
- ZodPipe: () => ZodPipe,
15458
- ZodOptional: () => ZodOptional,
15459
- ZodObject: () => ZodObject,
15460
- ZodNumberFormat: () => ZodNumberFormat,
15461
- ZodNumber: () => ZodNumber,
15462
- ZodNullable: () => ZodNullable,
15463
- ZodNull: () => ZodNull,
15464
- ZodNonOptional: () => ZodNonOptional,
15465
- ZodNever: () => ZodNever,
15466
- ZodNanoID: () => ZodNanoID,
15467
- ZodNaN: () => ZodNaN,
15468
- ZodMap: () => ZodMap,
15469
- ZodMAC: () => ZodMAC,
15470
- ZodLiteral: () => ZodLiteral,
15471
- ZodLazy: () => ZodLazy,
15472
- ZodKSUID: () => ZodKSUID,
15473
- ZodJWT: () => ZodJWT,
15474
- ZodIntersection: () => ZodIntersection,
15475
- ZodIPv6: () => ZodIPv6,
15476
- ZodIPv4: () => ZodIPv4,
15477
- ZodGUID: () => ZodGUID,
15478
- ZodFunction: () => ZodFunction,
15479
- ZodFile: () => ZodFile,
15480
- ZodExactOptional: () => ZodExactOptional,
15481
- ZodEnum: () => ZodEnum,
15482
- ZodEmoji: () => ZodEmoji,
15483
- ZodEmail: () => ZodEmail,
15484
- ZodE164: () => ZodE164,
15485
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
15486
- ZodDefault: () => ZodDefault,
15487
- ZodDate: () => ZodDate,
15488
- ZodCustomStringFormat: () => ZodCustomStringFormat,
15489
- ZodCustom: () => ZodCustom,
15490
- ZodCodec: () => ZodCodec,
15491
- ZodCatch: () => ZodCatch,
15492
- ZodCUID2: () => ZodCUID2,
15493
- ZodCUID: () => ZodCUID,
15494
- ZodCIDRv6: () => ZodCIDRv6,
15495
- ZodCIDRv4: () => ZodCIDRv4,
15496
- ZodBoolean: () => ZodBoolean,
15497
- ZodBigIntFormat: () => ZodBigIntFormat,
15498
- ZodBigInt: () => ZodBigInt,
15499
- ZodBase64URL: () => ZodBase64URL,
15500
- ZodBase64: () => ZodBase64,
15491
+ ZodAny: () => ZodAny,
15501
15492
  ZodArray: () => ZodArray,
15502
- ZodAny: () => ZodAny
15493
+ ZodBase64: () => ZodBase64,
15494
+ ZodBase64URL: () => ZodBase64URL,
15495
+ ZodBigInt: () => ZodBigInt,
15496
+ ZodBigIntFormat: () => ZodBigIntFormat,
15497
+ ZodBoolean: () => ZodBoolean,
15498
+ ZodCIDRv4: () => ZodCIDRv4,
15499
+ ZodCIDRv6: () => ZodCIDRv6,
15500
+ ZodCUID: () => ZodCUID,
15501
+ ZodCUID2: () => ZodCUID2,
15502
+ ZodCatch: () => ZodCatch,
15503
+ ZodCodec: () => ZodCodec,
15504
+ ZodCustom: () => ZodCustom,
15505
+ ZodCustomStringFormat: () => ZodCustomStringFormat,
15506
+ ZodDate: () => ZodDate,
15507
+ ZodDefault: () => ZodDefault,
15508
+ ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
15509
+ ZodE164: () => ZodE164,
15510
+ ZodEmail: () => ZodEmail,
15511
+ ZodEmoji: () => ZodEmoji,
15512
+ ZodEnum: () => ZodEnum,
15513
+ ZodExactOptional: () => ZodExactOptional,
15514
+ ZodFile: () => ZodFile,
15515
+ ZodFunction: () => ZodFunction,
15516
+ ZodGUID: () => ZodGUID,
15517
+ ZodIPv4: () => ZodIPv4,
15518
+ ZodIPv6: () => ZodIPv6,
15519
+ ZodIntersection: () => ZodIntersection,
15520
+ ZodJWT: () => ZodJWT,
15521
+ ZodKSUID: () => ZodKSUID,
15522
+ ZodLazy: () => ZodLazy,
15523
+ ZodLiteral: () => ZodLiteral,
15524
+ ZodMAC: () => ZodMAC,
15525
+ ZodMap: () => ZodMap,
15526
+ ZodNaN: () => ZodNaN,
15527
+ ZodNanoID: () => ZodNanoID,
15528
+ ZodNever: () => ZodNever,
15529
+ ZodNonOptional: () => ZodNonOptional,
15530
+ ZodNull: () => ZodNull,
15531
+ ZodNullable: () => ZodNullable,
15532
+ ZodNumber: () => ZodNumber,
15533
+ ZodNumberFormat: () => ZodNumberFormat,
15534
+ ZodObject: () => ZodObject,
15535
+ ZodOptional: () => ZodOptional,
15536
+ ZodPipe: () => ZodPipe,
15537
+ ZodPrefault: () => ZodPrefault,
15538
+ ZodPreprocess: () => ZodPreprocess,
15539
+ ZodPromise: () => ZodPromise,
15540
+ ZodReadonly: () => ZodReadonly,
15541
+ ZodRecord: () => ZodRecord,
15542
+ ZodSet: () => ZodSet,
15543
+ ZodString: () => ZodString,
15544
+ ZodStringFormat: () => ZodStringFormat,
15545
+ ZodSuccess: () => ZodSuccess,
15546
+ ZodSymbol: () => ZodSymbol,
15547
+ ZodTemplateLiteral: () => ZodTemplateLiteral,
15548
+ ZodTransform: () => ZodTransform,
15549
+ ZodTuple: () => ZodTuple,
15550
+ ZodType: () => ZodType,
15551
+ ZodULID: () => ZodULID,
15552
+ ZodURL: () => ZodURL,
15553
+ ZodUUID: () => ZodUUID,
15554
+ ZodUndefined: () => ZodUndefined,
15555
+ ZodUnion: () => ZodUnion,
15556
+ ZodUnknown: () => ZodUnknown,
15557
+ ZodVoid: () => ZodVoid,
15558
+ ZodXID: () => ZodXID,
15559
+ ZodXor: () => ZodXor,
15560
+ _ZodString: () => _ZodString,
15561
+ _default: () => _default2,
15562
+ _function: () => _function,
15563
+ any: () => any,
15564
+ array: () => array,
15565
+ base64: () => base642,
15566
+ base64url: () => base64url2,
15567
+ bigint: () => bigint2,
15568
+ boolean: () => boolean2,
15569
+ catch: () => _catch2,
15570
+ check: () => check,
15571
+ cidrv4: () => cidrv42,
15572
+ cidrv6: () => cidrv62,
15573
+ codec: () => codec,
15574
+ cuid: () => cuid3,
15575
+ cuid2: () => cuid22,
15576
+ custom: () => custom,
15577
+ date: () => date3,
15578
+ describe: () => describe2,
15579
+ discriminatedUnion: () => discriminatedUnion,
15580
+ e164: () => e1642,
15581
+ email: () => email2,
15582
+ emoji: () => emoji2,
15583
+ enum: () => _enum2,
15584
+ exactOptional: () => exactOptional,
15585
+ file: () => file,
15586
+ float32: () => float32,
15587
+ float64: () => float64,
15588
+ function: () => _function,
15589
+ guid: () => guid2,
15590
+ hash: () => hash,
15591
+ hex: () => hex2,
15592
+ hostname: () => hostname2,
15593
+ httpUrl: () => httpUrl,
15594
+ instanceof: () => _instanceof,
15595
+ int: () => int,
15596
+ int32: () => int32,
15597
+ int64: () => int64,
15598
+ intersection: () => intersection,
15599
+ invertCodec: () => invertCodec,
15600
+ ipv4: () => ipv42,
15601
+ ipv6: () => ipv62,
15602
+ json: () => json,
15603
+ jwt: () => jwt,
15604
+ keyof: () => keyof,
15605
+ ksuid: () => ksuid2,
15606
+ lazy: () => lazy,
15607
+ literal: () => literal,
15608
+ looseObject: () => looseObject,
15609
+ looseRecord: () => looseRecord,
15610
+ mac: () => mac2,
15611
+ map: () => map,
15612
+ meta: () => meta2,
15613
+ nan: () => nan,
15614
+ nanoid: () => nanoid2,
15615
+ nativeEnum: () => nativeEnum,
15616
+ never: () => never,
15617
+ nonoptional: () => nonoptional,
15618
+ null: () => _null3,
15619
+ nullable: () => nullable,
15620
+ nullish: () => nullish2,
15621
+ number: () => number2,
15622
+ object: () => object,
15623
+ optional: () => optional,
15624
+ partialRecord: () => partialRecord,
15625
+ pipe: () => pipe,
15626
+ prefault: () => prefault,
15627
+ preprocess: () => preprocess,
15628
+ promise: () => promise,
15629
+ readonly: () => readonly,
15630
+ record: () => record,
15631
+ refine: () => refine,
15632
+ set: () => set,
15633
+ strictObject: () => strictObject,
15634
+ string: () => string2,
15635
+ stringFormat: () => stringFormat,
15636
+ stringbool: () => stringbool,
15637
+ success: () => success,
15638
+ superRefine: () => superRefine,
15639
+ symbol: () => symbol,
15640
+ templateLiteral: () => templateLiteral,
15641
+ transform: () => transform,
15642
+ tuple: () => tuple,
15643
+ uint32: () => uint32,
15644
+ uint64: () => uint64,
15645
+ ulid: () => ulid2,
15646
+ undefined: () => _undefined3,
15647
+ union: () => union,
15648
+ unknown: () => unknown,
15649
+ url: () => url,
15650
+ uuid: () => uuid2,
15651
+ uuidv4: () => uuidv4,
15652
+ uuidv6: () => uuidv6,
15653
+ uuidv7: () => uuidv7,
15654
+ void: () => _void2,
15655
+ xid: () => xid2,
15656
+ xor: () => xor
15503
15657
  });
15504
15658
  function _installLazyMethods(inst, group, methods) {
15505
15659
  const proto = Object.getPrototypeOf(inst);
@@ -17206,370 +17360,370 @@ function convertSchema(schema, ctx) {
17206
17360
  }
17207
17361
  return baseSchema;
17208
17362
  }
17209
- function fromJSONSchema(schema, params) {
17210
- if (typeof schema === "boolean") {
17211
- return schema ? z.any() : z.never();
17212
- }
17213
- let normalized;
17214
- try {
17215
- normalized = JSON.parse(JSON.stringify(schema));
17216
- } catch {
17217
- throw new Error("fromJSONSchema input is not valid JSON (possibly cyclic); use $defs/$ref for recursive schemas");
17218
- }
17219
- const version2 = detectVersion(normalized, params?.defaultTarget);
17220
- const defs = normalized.$defs || normalized.definitions || {};
17221
- const ctx = {
17222
- version: version2,
17223
- defs,
17224
- refs: new Map,
17225
- processing: new Set,
17226
- rootSchema: normalized,
17227
- registry: params?.registry ?? globalRegistry
17228
- };
17229
- return convertSchema(normalized, ctx);
17230
- }
17231
- var z, RECOGNIZED_KEYS;
17232
- var init_from_json_schema = __esm(() => {
17233
- init_registries();
17234
- init_checks2();
17235
- init_iso();
17236
- init_schemas2();
17237
- z = {
17238
- ...exports_schemas2,
17239
- ...exports_checks2,
17240
- iso: exports_iso
17241
- };
17242
- RECOGNIZED_KEYS = /* @__PURE__ */ new Set([
17243
- "$schema",
17244
- "$ref",
17245
- "$defs",
17246
- "definitions",
17247
- "$id",
17248
- "id",
17249
- "$comment",
17250
- "$anchor",
17251
- "$vocabulary",
17252
- "$dynamicRef",
17253
- "$dynamicAnchor",
17254
- "type",
17255
- "enum",
17256
- "const",
17257
- "anyOf",
17258
- "oneOf",
17259
- "allOf",
17260
- "not",
17261
- "properties",
17262
- "required",
17263
- "additionalProperties",
17264
- "patternProperties",
17265
- "propertyNames",
17266
- "minProperties",
17267
- "maxProperties",
17268
- "items",
17269
- "prefixItems",
17270
- "additionalItems",
17271
- "minItems",
17272
- "maxItems",
17273
- "uniqueItems",
17274
- "contains",
17275
- "minContains",
17276
- "maxContains",
17277
- "minLength",
17278
- "maxLength",
17279
- "pattern",
17280
- "format",
17281
- "minimum",
17282
- "maximum",
17283
- "exclusiveMinimum",
17284
- "exclusiveMaximum",
17285
- "multipleOf",
17286
- "description",
17287
- "default",
17288
- "contentEncoding",
17289
- "contentMediaType",
17290
- "contentSchema",
17291
- "unevaluatedItems",
17292
- "unevaluatedProperties",
17293
- "if",
17294
- "then",
17295
- "else",
17296
- "dependentSchemas",
17297
- "dependentRequired",
17298
- "nullable",
17299
- "readOnly"
17300
- ]);
17301
- });
17302
-
17303
- // node_modules/zod/v4/classic/coerce.js
17304
- var exports_coerce = {};
17305
- __export(exports_coerce, {
17306
- string: () => string3,
17307
- number: () => number3,
17308
- date: () => date4,
17309
- boolean: () => boolean3,
17310
- bigint: () => bigint3
17311
- });
17312
- function string3(params) {
17313
- return _coercedString(ZodString, params);
17314
- }
17315
- function number3(params) {
17316
- return _coercedNumber(ZodNumber, params);
17317
- }
17318
- function boolean3(params) {
17319
- return _coercedBoolean(ZodBoolean, params);
17320
- }
17321
- function bigint3(params) {
17322
- return _coercedBigint(ZodBigInt, params);
17323
- }
17324
- function date4(params) {
17325
- return _coercedDate(ZodDate, params);
17326
- }
17327
- var init_coerce = __esm(() => {
17328
- init_core2();
17329
- init_schemas2();
17330
- });
17331
-
17332
- // node_modules/zod/v4/classic/external.js
17333
- var exports_external = {};
17334
- __export(exports_external, {
17335
- xor: () => xor,
17336
- xid: () => xid2,
17337
- void: () => _void2,
17338
- uuidv7: () => uuidv7,
17339
- uuidv6: () => uuidv6,
17340
- uuidv4: () => uuidv4,
17341
- uuid: () => uuid2,
17342
- util: () => exports_util,
17343
- url: () => url,
17344
- uppercase: () => _uppercase,
17345
- unknown: () => unknown,
17346
- union: () => union,
17347
- undefined: () => _undefined3,
17348
- ulid: () => ulid2,
17349
- uint64: () => uint64,
17350
- uint32: () => uint32,
17351
- tuple: () => tuple,
17352
- trim: () => _trim,
17353
- treeifyError: () => treeifyError,
17354
- transform: () => transform,
17355
- toUpperCase: () => _toUpperCase,
17356
- toLowerCase: () => _toLowerCase,
17357
- toJSONSchema: () => toJSONSchema,
17358
- templateLiteral: () => templateLiteral,
17359
- symbol: () => symbol,
17360
- superRefine: () => superRefine,
17361
- success: () => success,
17362
- stringbool: () => stringbool,
17363
- stringFormat: () => stringFormat,
17364
- string: () => string2,
17365
- strictObject: () => strictObject,
17366
- startsWith: () => _startsWith,
17367
- slugify: () => _slugify,
17368
- size: () => _size,
17369
- setErrorMap: () => setErrorMap,
17370
- set: () => set,
17371
- safeParseAsync: () => safeParseAsync2,
17372
- safeParse: () => safeParse2,
17373
- safeEncodeAsync: () => safeEncodeAsync2,
17374
- safeEncode: () => safeEncode2,
17375
- safeDecodeAsync: () => safeDecodeAsync2,
17376
- safeDecode: () => safeDecode2,
17377
- registry: () => registry,
17378
- regexes: () => exports_regexes,
17379
- regex: () => _regex,
17380
- refine: () => refine,
17381
- record: () => record,
17382
- readonly: () => readonly,
17383
- property: () => _property,
17384
- promise: () => promise,
17385
- prettifyError: () => prettifyError,
17386
- preprocess: () => preprocess,
17387
- prefault: () => prefault,
17388
- positive: () => _positive,
17389
- pipe: () => pipe,
17390
- partialRecord: () => partialRecord,
17391
- parseAsync: () => parseAsync2,
17392
- parse: () => parse3,
17393
- overwrite: () => _overwrite,
17394
- optional: () => optional,
17395
- object: () => object,
17396
- number: () => number2,
17397
- nullish: () => nullish2,
17398
- nullable: () => nullable,
17399
- null: () => _null3,
17400
- normalize: () => _normalize,
17401
- nonpositive: () => _nonpositive,
17402
- nonoptional: () => nonoptional,
17403
- nonnegative: () => _nonnegative,
17404
- never: () => never,
17405
- negative: () => _negative,
17406
- nativeEnum: () => nativeEnum,
17407
- nanoid: () => nanoid2,
17408
- nan: () => nan,
17409
- multipleOf: () => _multipleOf,
17410
- minSize: () => _minSize,
17411
- minLength: () => _minLength,
17412
- mime: () => _mime,
17413
- meta: () => meta2,
17414
- maxSize: () => _maxSize,
17415
- maxLength: () => _maxLength,
17416
- map: () => map,
17417
- mac: () => mac2,
17418
- lte: () => _lte,
17419
- lt: () => _lt,
17420
- lowercase: () => _lowercase,
17421
- looseRecord: () => looseRecord,
17422
- looseObject: () => looseObject,
17423
- locales: () => exports_locales,
17424
- literal: () => literal,
17425
- length: () => _length,
17426
- lazy: () => lazy,
17427
- ksuid: () => ksuid2,
17428
- keyof: () => keyof,
17429
- jwt: () => jwt,
17430
- json: () => json,
17431
- iso: () => exports_iso,
17432
- ipv6: () => ipv62,
17433
- ipv4: () => ipv42,
17434
- invertCodec: () => invertCodec,
17435
- intersection: () => intersection,
17436
- int64: () => int64,
17437
- int32: () => int32,
17438
- int: () => int,
17439
- instanceof: () => _instanceof,
17440
- includes: () => _includes,
17441
- httpUrl: () => httpUrl,
17442
- hostname: () => hostname2,
17443
- hex: () => hex2,
17444
- hash: () => hash,
17445
- guid: () => guid2,
17446
- gte: () => _gte,
17447
- gt: () => _gt,
17448
- globalRegistry: () => globalRegistry,
17449
- getErrorMap: () => getErrorMap,
17450
- function: () => _function,
17451
- fromJSONSchema: () => fromJSONSchema,
17452
- formatError: () => formatError,
17453
- float64: () => float64,
17454
- float32: () => float32,
17455
- flattenError: () => flattenError,
17456
- file: () => file,
17457
- exactOptional: () => exactOptional,
17458
- enum: () => _enum2,
17459
- endsWith: () => _endsWith,
17460
- encodeAsync: () => encodeAsync2,
17461
- encode: () => encode2,
17462
- emoji: () => emoji2,
17463
- email: () => email2,
17464
- e164: () => e1642,
17465
- discriminatedUnion: () => discriminatedUnion,
17466
- describe: () => describe2,
17467
- decodeAsync: () => decodeAsync2,
17468
- decode: () => decode2,
17469
- date: () => date3,
17470
- custom: () => custom,
17471
- cuid2: () => cuid22,
17472
- cuid: () => cuid3,
17473
- core: () => exports_core2,
17474
- config: () => config,
17475
- coerce: () => exports_coerce,
17476
- codec: () => codec,
17477
- clone: () => clone,
17478
- cidrv6: () => cidrv62,
17479
- cidrv4: () => cidrv42,
17480
- check: () => check,
17481
- catch: () => _catch2,
17482
- boolean: () => boolean2,
17483
- bigint: () => bigint2,
17484
- base64url: () => base64url2,
17485
- base64: () => base642,
17486
- array: () => array,
17487
- any: () => any,
17488
- _function: () => _function,
17489
- _default: () => _default2,
17490
- _ZodString: () => _ZodString,
17491
- ZodXor: () => ZodXor,
17492
- ZodXID: () => ZodXID,
17493
- ZodVoid: () => ZodVoid,
17494
- ZodUnknown: () => ZodUnknown,
17495
- ZodUnion: () => ZodUnion,
17496
- ZodUndefined: () => ZodUndefined,
17497
- ZodUUID: () => ZodUUID,
17498
- ZodURL: () => ZodURL,
17499
- ZodULID: () => ZodULID,
17500
- ZodType: () => ZodType,
17501
- ZodTuple: () => ZodTuple,
17502
- ZodTransform: () => ZodTransform,
17503
- ZodTemplateLiteral: () => ZodTemplateLiteral,
17504
- ZodSymbol: () => ZodSymbol,
17505
- ZodSuccess: () => ZodSuccess,
17506
- ZodStringFormat: () => ZodStringFormat,
17507
- ZodString: () => ZodString,
17508
- ZodSet: () => ZodSet,
17509
- ZodRecord: () => ZodRecord,
17510
- ZodRealError: () => ZodRealError,
17511
- ZodReadonly: () => ZodReadonly,
17512
- ZodPromise: () => ZodPromise,
17513
- ZodPreprocess: () => ZodPreprocess,
17514
- ZodPrefault: () => ZodPrefault,
17515
- ZodPipe: () => ZodPipe,
17516
- ZodOptional: () => ZodOptional,
17517
- ZodObject: () => ZodObject,
17518
- ZodNumberFormat: () => ZodNumberFormat,
17519
- ZodNumber: () => ZodNumber,
17520
- ZodNullable: () => ZodNullable,
17521
- ZodNull: () => ZodNull,
17522
- ZodNonOptional: () => ZodNonOptional,
17523
- ZodNever: () => ZodNever,
17524
- ZodNanoID: () => ZodNanoID,
17525
- ZodNaN: () => ZodNaN,
17526
- ZodMap: () => ZodMap,
17527
- ZodMAC: () => ZodMAC,
17528
- ZodLiteral: () => ZodLiteral,
17529
- ZodLazy: () => ZodLazy,
17530
- ZodKSUID: () => ZodKSUID,
17531
- ZodJWT: () => ZodJWT,
17532
- ZodIssueCode: () => ZodIssueCode,
17533
- ZodIntersection: () => ZodIntersection,
17534
- ZodISOTime: () => ZodISOTime,
17535
- ZodISODuration: () => ZodISODuration,
17536
- ZodISODateTime: () => ZodISODateTime,
17537
- ZodISODate: () => ZodISODate,
17538
- ZodIPv6: () => ZodIPv6,
17539
- ZodIPv4: () => ZodIPv4,
17540
- ZodGUID: () => ZodGUID,
17541
- ZodFunction: () => ZodFunction,
17542
- ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
17543
- ZodFile: () => ZodFile,
17544
- ZodExactOptional: () => ZodExactOptional,
17545
- ZodError: () => ZodError,
17546
- ZodEnum: () => ZodEnum,
17547
- ZodEmoji: () => ZodEmoji,
17548
- ZodEmail: () => ZodEmail,
17549
- ZodE164: () => ZodE164,
17550
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
17551
- ZodDefault: () => ZodDefault,
17552
- ZodDate: () => ZodDate,
17553
- ZodCustomStringFormat: () => ZodCustomStringFormat,
17554
- ZodCustom: () => ZodCustom,
17555
- ZodCodec: () => ZodCodec,
17556
- ZodCatch: () => ZodCatch,
17557
- ZodCUID2: () => ZodCUID2,
17558
- ZodCUID: () => ZodCUID,
17559
- ZodCIDRv6: () => ZodCIDRv6,
17560
- ZodCIDRv4: () => ZodCIDRv4,
17561
- ZodBoolean: () => ZodBoolean,
17562
- ZodBigIntFormat: () => ZodBigIntFormat,
17563
- ZodBigInt: () => ZodBigInt,
17564
- ZodBase64URL: () => ZodBase64URL,
17565
- ZodBase64: () => ZodBase64,
17566
- ZodArray: () => ZodArray,
17567
- ZodAny: () => ZodAny,
17568
- TimePrecision: () => TimePrecision,
17569
- NEVER: () => NEVER,
17570
- $output: () => $output,
17363
+ function fromJSONSchema(schema, params) {
17364
+ if (typeof schema === "boolean") {
17365
+ return schema ? z.any() : z.never();
17366
+ }
17367
+ let normalized;
17368
+ try {
17369
+ normalized = JSON.parse(JSON.stringify(schema));
17370
+ } catch {
17371
+ throw new Error("fromJSONSchema input is not valid JSON (possibly cyclic); use $defs/$ref for recursive schemas");
17372
+ }
17373
+ const version2 = detectVersion(normalized, params?.defaultTarget);
17374
+ const defs = normalized.$defs || normalized.definitions || {};
17375
+ const ctx = {
17376
+ version: version2,
17377
+ defs,
17378
+ refs: new Map,
17379
+ processing: new Set,
17380
+ rootSchema: normalized,
17381
+ registry: params?.registry ?? globalRegistry
17382
+ };
17383
+ return convertSchema(normalized, ctx);
17384
+ }
17385
+ var z, RECOGNIZED_KEYS;
17386
+ var init_from_json_schema = __esm(() => {
17387
+ init_registries();
17388
+ init_checks2();
17389
+ init_iso();
17390
+ init_schemas2();
17391
+ z = {
17392
+ ...exports_schemas2,
17393
+ ...exports_checks2,
17394
+ iso: exports_iso
17395
+ };
17396
+ RECOGNIZED_KEYS = /* @__PURE__ */ new Set([
17397
+ "$schema",
17398
+ "$ref",
17399
+ "$defs",
17400
+ "definitions",
17401
+ "$id",
17402
+ "id",
17403
+ "$comment",
17404
+ "$anchor",
17405
+ "$vocabulary",
17406
+ "$dynamicRef",
17407
+ "$dynamicAnchor",
17408
+ "type",
17409
+ "enum",
17410
+ "const",
17411
+ "anyOf",
17412
+ "oneOf",
17413
+ "allOf",
17414
+ "not",
17415
+ "properties",
17416
+ "required",
17417
+ "additionalProperties",
17418
+ "patternProperties",
17419
+ "propertyNames",
17420
+ "minProperties",
17421
+ "maxProperties",
17422
+ "items",
17423
+ "prefixItems",
17424
+ "additionalItems",
17425
+ "minItems",
17426
+ "maxItems",
17427
+ "uniqueItems",
17428
+ "contains",
17429
+ "minContains",
17430
+ "maxContains",
17431
+ "minLength",
17432
+ "maxLength",
17433
+ "pattern",
17434
+ "format",
17435
+ "minimum",
17436
+ "maximum",
17437
+ "exclusiveMinimum",
17438
+ "exclusiveMaximum",
17439
+ "multipleOf",
17440
+ "description",
17441
+ "default",
17442
+ "contentEncoding",
17443
+ "contentMediaType",
17444
+ "contentSchema",
17445
+ "unevaluatedItems",
17446
+ "unevaluatedProperties",
17447
+ "if",
17448
+ "then",
17449
+ "else",
17450
+ "dependentSchemas",
17451
+ "dependentRequired",
17452
+ "nullable",
17453
+ "readOnly"
17454
+ ]);
17455
+ });
17456
+
17457
+ // node_modules/zod/v4/classic/coerce.js
17458
+ var exports_coerce = {};
17459
+ __export(exports_coerce, {
17460
+ bigint: () => bigint3,
17461
+ boolean: () => boolean3,
17462
+ date: () => date4,
17463
+ number: () => number3,
17464
+ string: () => string3
17465
+ });
17466
+ function string3(params) {
17467
+ return _coercedString(ZodString, params);
17468
+ }
17469
+ function number3(params) {
17470
+ return _coercedNumber(ZodNumber, params);
17471
+ }
17472
+ function boolean3(params) {
17473
+ return _coercedBoolean(ZodBoolean, params);
17474
+ }
17475
+ function bigint3(params) {
17476
+ return _coercedBigint(ZodBigInt, params);
17477
+ }
17478
+ function date4(params) {
17479
+ return _coercedDate(ZodDate, params);
17480
+ }
17481
+ var init_coerce = __esm(() => {
17482
+ init_core2();
17483
+ init_schemas2();
17484
+ });
17485
+
17486
+ // node_modules/zod/v4/classic/external.js
17487
+ var exports_external = {};
17488
+ __export(exports_external, {
17489
+ $brand: () => $brand,
17571
17490
  $input: () => $input,
17572
- $brand: () => $brand
17491
+ $output: () => $output,
17492
+ NEVER: () => NEVER,
17493
+ TimePrecision: () => TimePrecision,
17494
+ ZodAny: () => ZodAny,
17495
+ ZodArray: () => ZodArray,
17496
+ ZodBase64: () => ZodBase64,
17497
+ ZodBase64URL: () => ZodBase64URL,
17498
+ ZodBigInt: () => ZodBigInt,
17499
+ ZodBigIntFormat: () => ZodBigIntFormat,
17500
+ ZodBoolean: () => ZodBoolean,
17501
+ ZodCIDRv4: () => ZodCIDRv4,
17502
+ ZodCIDRv6: () => ZodCIDRv6,
17503
+ ZodCUID: () => ZodCUID,
17504
+ ZodCUID2: () => ZodCUID2,
17505
+ ZodCatch: () => ZodCatch,
17506
+ ZodCodec: () => ZodCodec,
17507
+ ZodCustom: () => ZodCustom,
17508
+ ZodCustomStringFormat: () => ZodCustomStringFormat,
17509
+ ZodDate: () => ZodDate,
17510
+ ZodDefault: () => ZodDefault,
17511
+ ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
17512
+ ZodE164: () => ZodE164,
17513
+ ZodEmail: () => ZodEmail,
17514
+ ZodEmoji: () => ZodEmoji,
17515
+ ZodEnum: () => ZodEnum,
17516
+ ZodError: () => ZodError,
17517
+ ZodExactOptional: () => ZodExactOptional,
17518
+ ZodFile: () => ZodFile,
17519
+ ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
17520
+ ZodFunction: () => ZodFunction,
17521
+ ZodGUID: () => ZodGUID,
17522
+ ZodIPv4: () => ZodIPv4,
17523
+ ZodIPv6: () => ZodIPv6,
17524
+ ZodISODate: () => ZodISODate,
17525
+ ZodISODateTime: () => ZodISODateTime,
17526
+ ZodISODuration: () => ZodISODuration,
17527
+ ZodISOTime: () => ZodISOTime,
17528
+ ZodIntersection: () => ZodIntersection,
17529
+ ZodIssueCode: () => ZodIssueCode,
17530
+ ZodJWT: () => ZodJWT,
17531
+ ZodKSUID: () => ZodKSUID,
17532
+ ZodLazy: () => ZodLazy,
17533
+ ZodLiteral: () => ZodLiteral,
17534
+ ZodMAC: () => ZodMAC,
17535
+ ZodMap: () => ZodMap,
17536
+ ZodNaN: () => ZodNaN,
17537
+ ZodNanoID: () => ZodNanoID,
17538
+ ZodNever: () => ZodNever,
17539
+ ZodNonOptional: () => ZodNonOptional,
17540
+ ZodNull: () => ZodNull,
17541
+ ZodNullable: () => ZodNullable,
17542
+ ZodNumber: () => ZodNumber,
17543
+ ZodNumberFormat: () => ZodNumberFormat,
17544
+ ZodObject: () => ZodObject,
17545
+ ZodOptional: () => ZodOptional,
17546
+ ZodPipe: () => ZodPipe,
17547
+ ZodPrefault: () => ZodPrefault,
17548
+ ZodPreprocess: () => ZodPreprocess,
17549
+ ZodPromise: () => ZodPromise,
17550
+ ZodReadonly: () => ZodReadonly,
17551
+ ZodRealError: () => ZodRealError,
17552
+ ZodRecord: () => ZodRecord,
17553
+ ZodSet: () => ZodSet,
17554
+ ZodString: () => ZodString,
17555
+ ZodStringFormat: () => ZodStringFormat,
17556
+ ZodSuccess: () => ZodSuccess,
17557
+ ZodSymbol: () => ZodSymbol,
17558
+ ZodTemplateLiteral: () => ZodTemplateLiteral,
17559
+ ZodTransform: () => ZodTransform,
17560
+ ZodTuple: () => ZodTuple,
17561
+ ZodType: () => ZodType,
17562
+ ZodULID: () => ZodULID,
17563
+ ZodURL: () => ZodURL,
17564
+ ZodUUID: () => ZodUUID,
17565
+ ZodUndefined: () => ZodUndefined,
17566
+ ZodUnion: () => ZodUnion,
17567
+ ZodUnknown: () => ZodUnknown,
17568
+ ZodVoid: () => ZodVoid,
17569
+ ZodXID: () => ZodXID,
17570
+ ZodXor: () => ZodXor,
17571
+ _ZodString: () => _ZodString,
17572
+ _default: () => _default2,
17573
+ _function: () => _function,
17574
+ any: () => any,
17575
+ array: () => array,
17576
+ base64: () => base642,
17577
+ base64url: () => base64url2,
17578
+ bigint: () => bigint2,
17579
+ boolean: () => boolean2,
17580
+ catch: () => _catch2,
17581
+ check: () => check,
17582
+ cidrv4: () => cidrv42,
17583
+ cidrv6: () => cidrv62,
17584
+ clone: () => clone,
17585
+ codec: () => codec,
17586
+ coerce: () => exports_coerce,
17587
+ config: () => config,
17588
+ core: () => exports_core2,
17589
+ cuid: () => cuid3,
17590
+ cuid2: () => cuid22,
17591
+ custom: () => custom,
17592
+ date: () => date3,
17593
+ decode: () => decode2,
17594
+ decodeAsync: () => decodeAsync2,
17595
+ describe: () => describe2,
17596
+ discriminatedUnion: () => discriminatedUnion,
17597
+ e164: () => e1642,
17598
+ email: () => email2,
17599
+ emoji: () => emoji2,
17600
+ encode: () => encode2,
17601
+ encodeAsync: () => encodeAsync2,
17602
+ endsWith: () => _endsWith,
17603
+ enum: () => _enum2,
17604
+ exactOptional: () => exactOptional,
17605
+ file: () => file,
17606
+ flattenError: () => flattenError,
17607
+ float32: () => float32,
17608
+ float64: () => float64,
17609
+ formatError: () => formatError,
17610
+ fromJSONSchema: () => fromJSONSchema,
17611
+ function: () => _function,
17612
+ getErrorMap: () => getErrorMap,
17613
+ globalRegistry: () => globalRegistry,
17614
+ gt: () => _gt,
17615
+ gte: () => _gte,
17616
+ guid: () => guid2,
17617
+ hash: () => hash,
17618
+ hex: () => hex2,
17619
+ hostname: () => hostname2,
17620
+ httpUrl: () => httpUrl,
17621
+ includes: () => _includes,
17622
+ instanceof: () => _instanceof,
17623
+ int: () => int,
17624
+ int32: () => int32,
17625
+ int64: () => int64,
17626
+ intersection: () => intersection,
17627
+ invertCodec: () => invertCodec,
17628
+ ipv4: () => ipv42,
17629
+ ipv6: () => ipv62,
17630
+ iso: () => exports_iso,
17631
+ json: () => json,
17632
+ jwt: () => jwt,
17633
+ keyof: () => keyof,
17634
+ ksuid: () => ksuid2,
17635
+ lazy: () => lazy,
17636
+ length: () => _length,
17637
+ literal: () => literal,
17638
+ locales: () => exports_locales,
17639
+ looseObject: () => looseObject,
17640
+ looseRecord: () => looseRecord,
17641
+ lowercase: () => _lowercase,
17642
+ lt: () => _lt,
17643
+ lte: () => _lte,
17644
+ mac: () => mac2,
17645
+ map: () => map,
17646
+ maxLength: () => _maxLength,
17647
+ maxSize: () => _maxSize,
17648
+ meta: () => meta2,
17649
+ mime: () => _mime,
17650
+ minLength: () => _minLength,
17651
+ minSize: () => _minSize,
17652
+ multipleOf: () => _multipleOf,
17653
+ nan: () => nan,
17654
+ nanoid: () => nanoid2,
17655
+ nativeEnum: () => nativeEnum,
17656
+ negative: () => _negative,
17657
+ never: () => never,
17658
+ nonnegative: () => _nonnegative,
17659
+ nonoptional: () => nonoptional,
17660
+ nonpositive: () => _nonpositive,
17661
+ normalize: () => _normalize,
17662
+ null: () => _null3,
17663
+ nullable: () => nullable,
17664
+ nullish: () => nullish2,
17665
+ number: () => number2,
17666
+ object: () => object,
17667
+ optional: () => optional,
17668
+ overwrite: () => _overwrite,
17669
+ parse: () => parse3,
17670
+ parseAsync: () => parseAsync2,
17671
+ partialRecord: () => partialRecord,
17672
+ pipe: () => pipe,
17673
+ positive: () => _positive,
17674
+ prefault: () => prefault,
17675
+ preprocess: () => preprocess,
17676
+ prettifyError: () => prettifyError,
17677
+ promise: () => promise,
17678
+ property: () => _property,
17679
+ readonly: () => readonly,
17680
+ record: () => record,
17681
+ refine: () => refine,
17682
+ regex: () => _regex,
17683
+ regexes: () => exports_regexes,
17684
+ registry: () => registry,
17685
+ safeDecode: () => safeDecode2,
17686
+ safeDecodeAsync: () => safeDecodeAsync2,
17687
+ safeEncode: () => safeEncode2,
17688
+ safeEncodeAsync: () => safeEncodeAsync2,
17689
+ safeParse: () => safeParse2,
17690
+ safeParseAsync: () => safeParseAsync2,
17691
+ set: () => set,
17692
+ setErrorMap: () => setErrorMap,
17693
+ size: () => _size,
17694
+ slugify: () => _slugify,
17695
+ startsWith: () => _startsWith,
17696
+ strictObject: () => strictObject,
17697
+ string: () => string2,
17698
+ stringFormat: () => stringFormat,
17699
+ stringbool: () => stringbool,
17700
+ success: () => success,
17701
+ superRefine: () => superRefine,
17702
+ symbol: () => symbol,
17703
+ templateLiteral: () => templateLiteral,
17704
+ toJSONSchema: () => toJSONSchema,
17705
+ toLowerCase: () => _toLowerCase,
17706
+ toUpperCase: () => _toUpperCase,
17707
+ transform: () => transform,
17708
+ treeifyError: () => treeifyError,
17709
+ trim: () => _trim,
17710
+ tuple: () => tuple,
17711
+ uint32: () => uint32,
17712
+ uint64: () => uint64,
17713
+ ulid: () => ulid2,
17714
+ undefined: () => _undefined3,
17715
+ union: () => union,
17716
+ unknown: () => unknown,
17717
+ uppercase: () => _uppercase,
17718
+ url: () => url,
17719
+ util: () => exports_util,
17720
+ uuid: () => uuid2,
17721
+ uuidv4: () => uuidv4,
17722
+ uuidv6: () => uuidv6,
17723
+ uuidv7: () => uuidv7,
17724
+ void: () => _void2,
17725
+ xid: () => xid2,
17726
+ xor: () => xor
17573
17727
  });
17574
17728
  var init_external = __esm(() => {
17575
17729
  init_core2();
@@ -18488,7 +18642,7 @@ var package_default;
18488
18642
  var init_package = __esm(() => {
18489
18643
  package_default = {
18490
18644
  name: "@tensorix/metahub",
18491
- version: "0.4.0",
18645
+ version: "0.5.0",
18492
18646
  description: "Metahub core library and CLI",
18493
18647
  license: "AGPL-3.0-only",
18494
18648
  type: "module",
@@ -18528,6 +18682,7 @@ var init_package = __esm(() => {
18528
18682
  "@codemirror/commands": "6.10.4",
18529
18683
  "@codemirror/state": "6.7.0",
18530
18684
  "@codemirror/view": "6.43.4",
18685
+ "@joplin/turndown-plugin-gfm": "^1.0.67",
18531
18686
  "@sqlite.org/sqlite-wasm": "^3.53.0-build1",
18532
18687
  aws4fetch: "^1.0.20",
18533
18688
  citty: "^0.1.6",
@@ -18536,7 +18691,6 @@ var init_package = __esm(() => {
18536
18691
  preact: "^10.29.2",
18537
18692
  "qrcode-generator": "^2.0.4",
18538
18693
  turndown: "^7.2.4",
18539
- "turndown-plugin-gfm": "^1.0.2",
18540
18694
  zod: "^4.4.3"
18541
18695
  },
18542
18696
  devDependencies: {
@@ -19294,15 +19448,15 @@ function roomUrlOf(config2) {
19294
19448
  // src/core/sync/room-peer.ts
19295
19449
  var exports_room_peer = {};
19296
19450
  __export(exports_room_peer, {
19297
- teardownRoomForShare: () => teardownRoomForShare,
19298
- syncRoomPeer: () => syncRoomPeer,
19299
- roomUrlOf: () => roomUrlOf,
19300
- roomTransport: () => roomTransport,
19301
- roomPeerKey: () => roomPeerKey,
19302
- registerRoomBlobResolver: () => registerRoomBlobResolver,
19303
- pushRoomBlobs: () => pushRoomBlobs,
19451
+ destroyRoom: () => destroyRoom,
19304
19452
  provisionRoomForShare: () => provisionRoomForShare,
19305
- destroyRoom: () => destroyRoom
19453
+ pushRoomBlobs: () => pushRoomBlobs,
19454
+ registerRoomBlobResolver: () => registerRoomBlobResolver,
19455
+ roomPeerKey: () => roomPeerKey,
19456
+ roomTransport: () => roomTransport,
19457
+ roomUrlOf: () => roomUrlOf,
19458
+ syncRoomPeer: () => syncRoomPeer,
19459
+ teardownRoomForShare: () => teardownRoomForShare
19306
19460
  });
19307
19461
  function registerRoomBlobResolver(resolve) {
19308
19462
  defaultBlobResolver = resolve;
@@ -19843,9 +19997,9 @@ var init_site_channel_store = __esm(() => {
19843
19997
  // src/core/sync/site-channel-reconcile.ts
19844
19998
  var exports_site_channel_reconcile = {};
19845
19999
  __export(exports_site_channel_reconcile, {
19846
- reconcileSiteChannelsQuietly: () => reconcileSiteChannelsQuietly,
20000
+ CONTROLLER_STATE_MISSING: () => CONTROLLER_STATE_MISSING,
19847
20001
  reconcileSiteChannels: () => reconcileSiteChannels,
19848
- CONTROLLER_STATE_MISSING: () => CONTROLLER_STATE_MISSING
20002
+ reconcileSiteChannelsQuietly: () => reconcileSiteChannelsQuietly
19849
20003
  });
19850
20004
  async function reconcileSiteChannelsQuietly(db) {
19851
20005
  try {
@@ -22197,8 +22351,8 @@ function safeDecode3(s) {
22197
22351
  // src/core/sync/blob-routes.ts
22198
22352
  var exports_blob_routes = {};
22199
22353
  __export(exports_blob_routes, {
22200
- serveBlob: () => serveBlob,
22201
- blobRoutes: () => blobRoutes
22354
+ blobRoutes: () => blobRoutes,
22355
+ serveBlob: () => serveBlob
22202
22356
  });
22203
22357
  function ext(ct) {
22204
22358
  const t = ct.toLowerCase().split(";")[0].trim();
@@ -23593,8 +23747,8 @@ var init_share_render = __esm(() => {
23593
23747
  // src/core/sync/sites-serve.ts
23594
23748
  var exports_sites_serve = {};
23595
23749
  __export(exports_sites_serve, {
23596
- serveSiteFile: () => serveSiteFile,
23597
- serveSite: () => serveSite
23750
+ serveSite: () => serveSite,
23751
+ serveSiteFile: () => serveSiteFile
23598
23752
  });
23599
23753
  async function serveSite(req, ctx, auth, opts = {}) {
23600
23754
  const url2 = new URL(req.url);
@@ -23889,16 +24043,16 @@ function docEditScript(slug, version2, body) {
23889
24043
  }
23890
24044
  });`;
23891
24045
  }
23892
- function cellText(prop, value) {
24046
+ function cellText(prop, value, titles) {
23893
24047
  if (value === null || value === undefined)
23894
24048
  return "";
23895
24049
  if (prop.type === "checkbox")
23896
24050
  return value ? "\u2713" : "";
23897
24051
  if (Array.isArray(value))
23898
- return value.map((v) => String(v)).join(", ");
24052
+ return value.map((v) => titles?.get(String(v)) ?? String(v)).join(", ");
23899
24053
  return String(value);
23900
24054
  }
23901
- function cellHtml(prop, value) {
24055
+ function cellHtml(prop, value, titles) {
23902
24056
  if (value === null || value === undefined)
23903
24057
  return "";
23904
24058
  if (prop.type === "checkbox")
@@ -23908,7 +24062,7 @@ function cellHtml(prop, value) {
23908
24062
  return `<a href="${escapeHtml(s)}" target="_blank" rel="noreferrer noopener">${escapeHtml(s)}</a>`;
23909
24063
  }
23910
24064
  if (Array.isArray(value))
23911
- return value.map((v) => `<span class="tag">${escapeHtml(String(v))}</span>`).join(" ");
24065
+ return value.map((v) => `<span class="tag">${escapeHtml(titles?.get(String(v)) ?? String(v))}</span>`).join(" ");
23912
24066
  return escapeHtml(String(value));
23913
24067
  }
23914
24068
  function editableType(t) {
@@ -23942,6 +24096,16 @@ async function serveTable(ctx, req, share, sub) {
23942
24096
  if (sub !== "")
23943
24097
  return notFound();
23944
24098
  const records = listRecords(ctx.db, share.target_id);
24099
+ const grants = parseGrantSet(share.grants);
24100
+ const relTitles = new Map;
24101
+ for (const p of props) {
24102
+ const target = p.type === "relation" ? p.config?.database : undefined;
24103
+ if (!target || relTitles.has(target))
24104
+ continue;
24105
+ if (target === share.target_id || grantFor(grants, target))
24106
+ relTitles.set(target, recordTitleMap(ctx.db, target));
24107
+ }
24108
+ const titlesFor = (p) => p.type === "relation" ? relTitles.get(p.config?.database ?? "") : undefined;
23945
24109
  const editable = share.permission === "edit";
23946
24110
  const head = props.map((p) => `<th>${escapeHtml(p.name)}</th>`).join("");
23947
24111
  const rows = records.map((r) => {
@@ -23950,7 +24114,7 @@ async function serveTable(ctx, req, share, sub) {
23950
24114
  if (editable && editableType(p.type)) {
23951
24115
  return `<td contenteditable data-rec="${escapeHtml(r.id)}" data-prop="${escapeHtml(p.id)}" data-type="${p.type}">${escapeHtml(cellText(p, v))}</td>`;
23952
24116
  }
23953
- return `<td>${cellHtml(p, v)}</td>`;
24117
+ return `<td>${cellHtml(p, v, titlesFor(p))}</td>`;
23954
24118
  }).join("");
23955
24119
  return `<tr>${tds}</tr>`;
23956
24120
  }).join("");
@@ -24231,6 +24395,7 @@ var init_share_serve = __esm(() => {
24231
24395
  init_databases();
24232
24396
  init_properties();
24233
24397
  init_records();
24398
+ init_grants_core();
24234
24399
  init_sites();
24235
24400
  init_sites_serve();
24236
24401
  init_blobs();
@@ -24627,9 +24792,9 @@ var init_drop_protocol = __esm(() => {
24627
24792
  // src/core/sync/drop-pull.ts
24628
24793
  var exports_drop_pull = {};
24629
24794
  __export(exports_drop_pull, {
24630
- pullDropsOnce: () => pullDropsOnce,
24795
+ changesMaxSeq: () => changesMaxSeq,
24631
24796
  dropWiredSites: () => dropWiredSites,
24632
- changesMaxSeq: () => changesMaxSeq
24797
+ pullDropsOnce: () => pullDropsOnce
24633
24798
  });
24634
24799
  function dropWiredSites(db) {
24635
24800
  return listSites(db).filter((s) => parseGrantSet(s.public_grants).tables.some((t) => t.ops.includes("create")));
@@ -25167,7 +25332,9 @@ function scalarHtml(specUrl) {
25167
25332
  }
25168
25333
  function startServer(opts = {}) {
25169
25334
  registerRoomBlobResolver(resolveBlob);
25335
+ const tDb = Date.now();
25170
25336
  const db = openMetahub();
25337
+ const dbMs = Date.now() - tDb;
25171
25338
  const node = getNodeId(db);
25172
25339
  const ctx = {
25173
25340
  db,
@@ -25193,6 +25360,7 @@ function startServer(opts = {}) {
25193
25360
  graceMs: DEFAULT_GRACE_MS
25194
25361
  };
25195
25362
  let server;
25363
+ const tServe = Date.now();
25196
25364
  try {
25197
25365
  server = Bun.serve({
25198
25366
  port,
@@ -25274,6 +25442,9 @@ function startServer(opts = {}) {
25274
25442
  }
25275
25443
  throw e;
25276
25444
  }
25445
+ if (opts.debug) {
25446
+ console.log(`[perf] openMetahub ${dbMs}ms, Bun.serve ${Date.now() - tServe}ms`);
25447
+ }
25277
25448
  let timer = null;
25278
25449
  if (autoSync && syncIntervalMs > 0) {
25279
25450
  const IDLE_BACKOFF_MAX_MS = 150000;
@@ -25688,6 +25859,43 @@ var styles_default = ` :root {
25688
25859
  color:var(--danger); margin:0 0 4px 2px; }
25689
25860
  .set-callout { padding:9px 11px; border-radius:var(--radius-sm); background:var(--surface);
25690
25861
  border:1px solid var(--line); color:var(--fg-soft); font-size:var(--fs-xs); line-height:1.55; }
25862
+ /* ---- \u64CD\u4F5C\u5BA1\u8BA1 (settings/audit-page.tsx): the global change feed ---- */
25863
+ .audit-filters { display:flex; gap:6px; margin:2px 0 14px; flex-wrap:wrap; }
25864
+ .audit-chip { display:inline-flex; align-items:center; gap:6px; padding:4px 12px; border-radius:999px;
25865
+ border:1px solid var(--line); background:none; color:var(--fg-soft); font-size:var(--fs-sm); cursor:pointer; }
25866
+ .audit-chip:hover { background:var(--hover); }
25867
+ .audit-chip.on { background:var(--accent-soft); border-color:transparent; color:var(--accent); font-weight:600; }
25868
+ .audit-chip-dot { width:7px; height:7px; border-radius:50%; background:var(--accent); flex:none; }
25869
+ .audit-group-label { font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:.07em;
25870
+ color:var(--muted); margin:18px 0 4px 2px; }
25871
+ .audit-group:first-child .audit-group-label { margin-top:0; }
25872
+ .audit-item { border-bottom:1px solid var(--line); border-radius:var(--radius-sm); }
25873
+ .audit-item:last-child { border-bottom:none; }
25874
+ /* the "AI just did this" cue \u2014 same pulse as the quickboard card flash */
25875
+ .audit-item.flash { animation:audit-flash 1.5s ease-out; }
25876
+ @keyframes audit-flash { 0% { background:var(--accent-soft); } 100% { background:none; } }
25877
+ .audit-item-line { display:flex; align-items:center; gap:8px; padding:9px 4px; cursor:pointer; min-width:0; }
25878
+ .audit-item-line:hover { background:var(--hover); }
25879
+ .audit-when { font-size:var(--fs-sm); color:var(--muted); flex:none; width:74px; }
25880
+ .audit-actor { flex:none; font-size:11px; font-weight:600; padding:1px 7px; border-radius:999px;
25881
+ background:var(--surface); border:1px solid var(--line); color:var(--fg-soft); max-width:110px;
25882
+ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
25883
+ .audit-actor.ai { background:color-mix(in srgb, #8b5cf6 14%, transparent);
25884
+ border-color:color-mix(in srgb, #8b5cf6 35%, transparent); color:#8b5cf6; }
25885
+ .audit-summary { font-size:var(--fs-ui); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
25886
+ .audit-ent { color:inherit; font-weight:600; text-decoration:none; margin-left:2px; }
25887
+ .audit-ent[href]:hover { color:var(--accent); text-decoration:underline; }
25888
+ .audit-dbname { color:var(--muted); font-weight:400; }
25889
+ .audit-spacer { flex:1; }
25890
+ .audit-revert { flex:none; gap:4px; font-size:var(--fs-sm); opacity:0; }
25891
+ .audit-item-line:hover .audit-revert, .audit-revert:disabled { opacity:1; }
25892
+ .audit-caret { flex:none; color:var(--muted); }
25893
+ .audit-detail { padding:0 4px 10px 86px; }
25894
+ .audit-detail-ent-name { font-size:var(--fs-sm); font-weight:600; margin-top:6px; }
25895
+ .audit-blocks { font-size:var(--fs-sm); margin-top:2px; }
25896
+ .audit-more { display:block; margin:14px auto 0; }
25897
+ .audit-foot { font-size:var(--fs-xs); margin-top:18px; line-height:1.6; }
25898
+ @media (hover:none) { .audit-revert { opacity:1; } }
25691
25899
  .set-callout.warn { border-color:color-mix(in srgb,var(--warning,#9a6700) 32%,var(--line)); }
25692
25900
  /* two-fact meta line under a block title (who publishes \xB7 where creds live) \u2014
25693
25901
  answers the questions hiding under "is this bucket for server or browser?" */
@@ -25878,6 +26086,10 @@ var styles_default = ` :root {
25878
26086
  .crumb-sep { flex:none; color:var(--muted); font-weight:400; }
25879
26087
  .iconbtn { width:30px; height:30px; display:grid; place-items:center; border-radius:var(--radius-sm); color:var(--fg-soft); transition:background .12s; }
25880
26088
  .iconbtn:hover { background:var(--hover-2); color:var(--fg); }
26089
+ /* Dead end of the history (topbar back/forward). pointer-events:none also
26090
+ kills the hover background and, on desktop-mac, lets the button revert to
26091
+ the topbar's drag region. */
26092
+ .iconbtn:disabled { opacity:.35; pointer-events:none; }
25881
26093
  /* Reserve the classic-scrollbar gutter up front: view width never changes
25882
26094
  when content grows past one screen \u2014 no jump / rewrap flicker. stable
25883
26095
  ONLY (never both-edges): a left-edge gutter desyncs Chromium's composited
@@ -25957,6 +26169,11 @@ var styles_default = ` :root {
25957
26169
  /* wide mode (\u22EF menu): lift the column cap; the 60px side padding stays as the
25958
26170
  reading gutter and keeps the fixed .doc-toc ticks off the text. */
25959
26171
  .doc.wide-mode { max-width:none; }
26172
+ /* embedded in the record peek drawer: full width, compact padding, a small
26173
+ tail instead of the main view's 36vh, and a smaller title (the row's
26174
+ properties above it are the primary content). Same idiom as .qn-body .doc. */
26175
+ .doc.doc-embed { max-width:none; margin:0; padding:4px 2px 12vh; }
26176
+ .doc.doc-embed .doc-title { font-size:22px; }
25960
26177
  /* floating table of contents: a column of indented tick marks in the right
25961
26178
  gutter that expands to a labelled list on hover (Notion / Vercel-docs style).
25962
26179
  Fixed to the viewport so it never disturbs the centred .doc column. */
@@ -26433,6 +26650,21 @@ var styles_default = ` :root {
26433
26650
  border-bottom:2px solid transparent; margin-bottom:-1px; transition:color .12s; }
26434
26651
  .view-tab.active { color:var(--fg); border-bottom-color:var(--accent); }
26435
26652
  .view-tab:hover { color:var(--fg); } .view-tab svg { width:14px; height:14px; }
26653
+ /* \u6D6E\u7A97\u770B\u677F (right end of the toolbar / board bar, desktop only): a quiet
26654
+ Notion-style secondary pill \u2014 visible as a feature entry, never louder
26655
+ than \u65B0\u5EFA. Hover lifts the pill and nudges the icon's top kanban card up
26656
+ (.i-card, SVG user units). */
26657
+ .popout-btn { display:inline-flex; align-items:center; justify-content:center;
26658
+ width:28px; height:28px;
26659
+ background:var(--bg); border:1px solid var(--line); border-radius:var(--radius-sm);
26660
+ box-shadow:var(--shadow-sm); color:var(--fg-soft); transition:all .15s ease; }
26661
+ .popout-btn .ico { color:var(--muted); transition:color .15s; }
26662
+ .popout-btn:hover { border-color:var(--line-strong); box-shadow:var(--shadow-md);
26663
+ transform:translateY(-1px); color:var(--fg); }
26664
+ .popout-btn:hover .ico { color:var(--fg); }
26665
+ .popout-btn:active { transform:translateY(0); box-shadow:var(--shadow-sm); }
26666
+ .popout-btn .i-card { transition:transform .18s ease; }
26667
+ .popout-btn:hover .i-card { transform:translateY(-2px); }
26436
26668
  .toolbar { display:flex; align-items:center; gap:2px; padding:10px 0; }
26437
26669
  .toolbar .spacer { flex:1; }
26438
26670
  .tbtn { display:flex; align-items:center; gap:6px; padding:5px 9px; border-radius:var(--radius-sm); color:var(--fg-soft); font-size:13px; font-weight:500; }
@@ -26527,6 +26759,12 @@ var styles_default = ` :root {
26527
26759
  background:color-mix(in srgb,var(--c) 15%,transparent); color:var(--c); }
26528
26760
  /* data-resolved (not prefers-color-scheme): tracks a manual dark choice too. */
26529
26761
  :root[data-resolved="dark"] .chip { background:color-mix(in srgb,var(--c) 22%,transparent); color:color-mix(in srgb,var(--c) 75%,#fff); }
26762
+ /* relation chip: an <a> that jumps to the target record */
26763
+ a.chip.rel { text-decoration:none; cursor:pointer; }
26764
+ a.chip.rel:hover { background:color-mix(in srgb,var(--c) 26%,transparent); text-decoration:underline; text-decoration-style:dashed; text-underline-offset:2px; }
26765
+ /* doc chip whose target is deleted/unsynced: muted + dashed, same cue as the
26766
+ editor's .cm-doclink-missing pill */
26767
+ a.chip.rel.doc-missing { background:transparent; color:var(--muted); outline:1px dashed var(--line-strong); outline-offset:-1px; }
26530
26768
  .addrow { display:flex; align-items:center; gap:7px; padding:9px 12px; color:var(--muted); font-size:13px; cursor:pointer; border-top:1px solid var(--line); }
26531
26769
  .addrow:hover { background:var(--hover); color:var(--fg-soft); }
26532
26770
  .gridfoot { display:flex; gap:18px; color:var(--muted); font-size:12px; padding:8px 2px; }
@@ -26738,6 +26976,14 @@ var styles_default = ` :root {
26738
26976
  .proprow .v { flex:1; padding:7px 8px; border-radius:var(--radius-sm); cursor:text; min-height:33px; display:flex; flex-wrap:wrap; gap:3px; align-items:center; }
26739
26977
  .proprow .v:hover { background:var(--hover); }
26740
26978
  .peek-divider { height:1px; background:var(--line); margin:22px 0 18px; }
26979
+ /* linked-document tabs + embedded editor below the peek's property list */
26980
+ .peekdocs-tabs { display:flex; align-items:center; gap:4px; flex-wrap:wrap; margin-bottom:6px; }
26981
+ .peekdocs-tab { border:0; background:none; font:inherit; font-size:var(--fs-sm); font-weight:500; color:var(--muted);
26982
+ padding:5px 10px; border-radius:var(--radius-sm); cursor:pointer; max-width:180px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
26983
+ .peekdocs-tab:hover { background:var(--hover); color:var(--fg-soft); }
26984
+ .peekdocs-tab.active { background:var(--surface-2); color:var(--fg); }
26985
+ .peekdocs-tab.missing { color:var(--muted); text-decoration:line-through; }
26986
+ .peekdocs-open { flex:none; }
26741
26987
 
26742
26988
  /* version history (doc drawer + record peek view) */
26743
26989
  .hist-peek { width:760px; }
@@ -26896,15 +27142,65 @@ var styles_default = ` :root {
26896
27142
  .pop .typegrid .item .lico { margin:0 auto; }
26897
27143
  .pop input.field { width:100%; border:1px solid var(--line-strong); border-radius:var(--radius-sm); padding:7px 9px; outline:none; background:var(--surface); margin:2px; }
26898
27144
  .pop input.field:focus { border-color:var(--accent); }
27145
+ /* select-cell picker: search/create input at the top of the popover */
27146
+ .pop .selsearch { display:flex; align-items:center; gap:7px; margin:2px 2px 6px; padding:6px 9px;
27147
+ border:1px solid var(--line-strong); border-radius:var(--radius-sm); background:var(--surface); color:var(--muted);
27148
+ transition:border-color .12s ease, box-shadow .12s ease, color .12s ease; }
27149
+ .pop .selsearch:focus-within { border-color:var(--accent); color:var(--accent);
27150
+ box-shadow:0 0 0 2.5px color-mix(in srgb, var(--accent) 16%, transparent); }
27151
+ .pop .selsearch input { flex:1; width:0; min-width:0; border:0; background:transparent; outline:none;
27152
+ font:inherit; font-size:var(--fs-ui); color:var(--fg); }
27153
+ .pop .selsearch input::placeholder { color:var(--muted); }
27154
+ .pop .selsearch .clear { display:grid; place-items:center; width:18px; height:18px; margin:-2px -3px -2px 0;
27155
+ border-radius:50%; color:var(--muted); flex:none; }
27156
+ .pop .selsearch .clear:hover { background:var(--hover-2); color:var(--fg); }
27157
+ /* relation record picker: fixed-height list \u2014 the popover is positioned once
27158
+ on open, so async-loaded rows must scroll instead of growing off-screen */
27159
+ .pop .rellist { max-height:264px; overflow-y:auto; }
26899
27160
  .optrow { display:flex; align-items:center; gap:6px; padding:3px 4px; }
26900
27161
  .optrow .chip { flex:1; }
26901
- .optrow .x { width:22px; height:22px; display:grid; place-items:center; color:var(--muted); border-radius:5px; }
26902
- .optrow .x:hover { background:var(--hover-2); color:var(--danger); }
27162
+ .optrow .grip { width:18px; height:22px; display:grid; place-items:center; color:var(--muted); cursor:grab; touch-action:none; flex:none; }
27163
+ .optrow .grip.dim { color:color-mix(in srgb,var(--muted) 40%,transparent); cursor:default; }
27164
+ .optrow .optlabel { flex:1; display:flex; min-width:0; text-align:left; cursor:pointer; }
27165
+ .optrow .x { width:22px; height:22px; display:grid; place-items:center; color:var(--muted); border-radius:5px; flex:none; }
27166
+ .optrow .x:hover { background:var(--hover-2); color:var(--fg); }
27167
+ .optrow .x.del:hover { color:var(--danger); }
27168
+ .optrow .x.ok:hover { color:var(--success); }
27169
+ /* edit-state buttons fade in alongside the pill's ring */
27170
+ .optrow .x.ok, .optrow .x.cancel { animation:optbtn-in .15s ease; }
27171
+ @keyframes optbtn-in { from { opacity:0; } }
27172
+ .optrow.drop-before { box-shadow:inset 0 2px 0 0 var(--accent); }
27173
+ .optrow.drop-after { box-shadow:inset 0 -2px 0 0 var(--accent); }
27174
+ /* In-place pill editor: mirrors .chip metrics exactly (padding/radius/type)
27175
+ so entering edit never changes the row's size \u2014 only a color-matched ring
27176
+ appears. Caret and selection reuse the option's own hue. */
27177
+ /* width:0 kills the input's intrinsic width (browser default ~20ch) so the
27178
+ popover doesn't widen when the row enters edit \u2014 flex:1 does the sizing.
27179
+ The entry animation only fades the ring in: the pill background must stay
27180
+ put or the swap from the chip reads as a flash. */
27181
+ .optrow input.optedit { flex:1; width:0; min-width:0; margin:0; border:0; font:inherit; font-size:var(--fs-sm); font-weight:500;
27182
+ padding:2px 8px; border-radius:5px; background:color-mix(in srgb,var(--c) 15%,transparent); color:var(--c);
27183
+ caret-color:var(--c); outline:1.5px solid color-mix(in srgb,var(--c) 50%,transparent); outline-offset:0;
27184
+ animation:optedit-in .18s ease; }
27185
+ @keyframes optedit-in { from { outline-color:transparent; } }
27186
+ .optrow input.optedit::selection { background:color-mix(in srgb,var(--c) 28%,transparent); }
27187
+ :root[data-resolved="dark"] .optrow input.optedit { background:color-mix(in srgb,var(--c) 22%,transparent);
27188
+ color:color-mix(in srgb,var(--c) 75%,#fff); caret-color:color-mix(in srgb,var(--c) 75%,#fff); }
27189
+ /* Ghost add-row: quiet until it's needed \u2014 plus icon in the grip slot, a
27190
+ bare borderless input; hover/focus tints the row like a menu item. */
27191
+ .optrow.optadd { border-radius:var(--radius-sm); }
27192
+ .optrow.optadd:hover, .optrow.optadd:focus-within { background:var(--hover-2); }
27193
+ .optrow.optadd input { flex:1; width:0; min-width:0; margin:0; border:0; background:transparent; font:inherit;
27194
+ font-size:var(--fs-sm); padding:2px 8px; color:var(--fg); outline:none; }
27195
+ .optrow.optadd input::placeholder { color:var(--muted); }
26903
27196
 
26904
27197
  /* modal */
26905
27198
  .modal-scrim { position:fixed; inset:0; background:rgba(15,15,25,.4); z-index:100; display:flex; align-items:center; justify-content:center;
26906
27199
  opacity:0; pointer-events:none; transition:opacity .15s; padding:20px; }
26907
27200
  .modal-scrim.open { opacity:1; pointer-events:auto; }
27201
+ /* opt-in (openModal aboveMenus): stack one dialog over the menu layer (115)
27202
+ so a confirm can appear without dismissing an open popover */
27203
+ .modal-scrim.above-menus { z-index:130; }
26908
27204
  .modal { background:var(--bg); border-radius:var(--radius-xl); box-shadow:var(--shadow-lg); width:440px; max-width:100%; max-height:100%; display:flex; flex-direction:column; overflow:hidden; }
26909
27205
  .modal-head { padding:20px 22px 0; }
26910
27206
  .modal-head h3 { margin:0; font-size:18px; font-weight:700; letter-spacing:-.01em; }
@@ -27069,9 +27365,17 @@ var styles_default = ` :root {
27069
27365
  .board-count { color:var(--muted); font-size:12px; font-weight:600; }
27070
27366
  .board-col-head .iconbtn.sm { width:24px; height:24px; }
27071
27367
  .board-col-body { display:flex; flex-direction:column; gap:7px; padding:0 8px 8px; overflow-y:auto; }
27072
- .kcard { background:var(--bg); border:1px solid var(--line); border-radius:var(--radius-sm); padding:9px 10px; box-shadow:var(--shadow-sm);
27368
+ .kcard { position:relative; background:var(--bg); border:1px solid var(--line); border-radius:var(--radius-sm); padding:9px 10px; box-shadow:var(--shadow-sm);
27073
27369
  cursor:grab; display:flex; flex-direction:column; gap:5px; touch-action:none; transition:border-color .1s,box-shadow .1s; }
27074
27370
  .kcard:hover { border-color:var(--line-strong); }
27371
+ /* hover-only open button, top-right \u2014 same pattern as the grid's .rowactions */
27372
+ .kcard-actions { position:absolute; top:6px; right:6px; opacity:0; pointer-events:none; transition:opacity .1s; }
27373
+ .kcard:hover .kcard-actions { opacity:1; pointer-events:auto; }
27374
+ /* inline title editing: the same .kcard-title div made contentEditable, so a
27375
+ wrapped title keeps its line count; negative margin swallows the padding so
27376
+ the text doesn't shift on entering edit */
27377
+ .kcard-title[contenteditable] { outline:1.5px solid var(--accent); border-radius:4px;
27378
+ padding:2px 5px; margin:-2px -5px; background:var(--bg); cursor:text; }
27075
27379
  .kcard.drag-source { opacity:.4; }
27076
27380
  .kcard.dragging-ghost { position:fixed; left:0; top:0; z-index:120; pointer-events:none; cursor:grabbing;
27077
27381
  box-shadow:var(--shadow-lg); opacity:.95; transform:translate3d(-9999px,0,0); }
@@ -27306,6 +27610,7 @@ var styles_default = ` :root {
27306
27610
  @media (hover: none) {
27307
27611
  .code-tools { opacity:1; transform:none; pointer-events:auto; }
27308
27612
  .rowactions { opacity:1; pointer-events:auto; }
27613
+ .kcard-actions { opacity:1; pointer-events:auto; }
27309
27614
  .cal-add, .filerow .facts,
27310
27615
  .navitem .acts { opacity:1; }
27311
27616
  /* the pill handles survive on touch (focus-driven, not hover-driven), but
@@ -27380,25 +27685,137 @@ var styles_default = ` :root {
27380
27685
  border-color:var(--accent);
27381
27686
  background:var(--accent) center/10px no-repeat
27382
27687
  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l5 5L20 7'/%3E%3C/svg%3E"); }
27383
- /* Compact menus inside the quick-note window only (dropdown + slash command
27384
- share .pop/.item/.lico with the main app; scope under body.quicknote so the
27385
- main app keeps its roomier density). */
27386
- body.quicknote .pop { padding:5px; border-radius:9px; }
27387
- body.quicknote .pop .lbl { padding:4px 8px 2px; font-size:10px; }
27388
- body.quicknote .pop .item { padding:5px 9px; gap:8px; font-size:var(--fs-sm); }
27389
- body.quicknote .pop .item .t { font-size:var(--fs-sm); }
27390
- body.quicknote .pop .item .d { font-size:10.5px; }
27391
- body.quicknote .pop .item .lico { width:22px; height:22px; }
27392
- body.quicknote .pop .item .lico.plain { width:20px; height:20px; }
27393
- body.quicknote .pop .sep { margin:4px 4px; }
27394
-
27395
- /* Quick Notes shortcut capture (desktop only). */
27688
+ /* Compact menus inside the quick windows only (dropdown + slash command
27689
+ share .pop/.item/.lico with the main app; scope under the quick window
27690
+ body classes so the main app keeps its roomier density). */
27691
+ body.quicknote .pop, body.quickboard .pop { padding:5px; border-radius:9px; }
27692
+ body.quicknote .pop .lbl, body.quickboard .pop .lbl { padding:4px 8px 2px; font-size:10px; }
27693
+ body.quicknote .pop .item, body.quickboard .pop .item { padding:5px 9px; gap:8px; font-size:var(--fs-sm); }
27694
+ body.quicknote .pop .item .t, body.quickboard .pop .item .t { font-size:var(--fs-sm); }
27695
+ body.quicknote .pop .item .d, body.quickboard .pop .item .d { font-size:10.5px; }
27696
+ body.quicknote .pop .item .lico, body.quickboard .pop .item .lico { width:22px; height:22px; }
27697
+ body.quicknote .pop .item .lico.plain, body.quickboard .pop .item .lico.plain { width:20px; height:20px; }
27698
+ body.quicknote .pop .sep, body.quickboard .pop .sep { margin:4px 4px; }
27699
+ /* Search box inside quick-window popovers: compact glass field \u2014 translucent
27700
+ fill over the vibrancy pane instead of the app's opaque surface. */
27701
+ body.quicknote .pop .selsearch, body.quickboard .pop .selsearch { margin:1px 1px 5px; padding:5px 8px;
27702
+ border-radius:7px; background:color-mix(in srgb, var(--surface) 60%, transparent); }
27703
+ body.quicknote .pop .selsearch input, body.quickboard .pop .selsearch input { font-size:var(--fs-sm); }
27704
+
27705
+ /* Quick Board window (desktop, loaded at #board). Same shell idiom as the
27706
+ quick-note window above: transparent body so the macOS vibrancy shows,
27707
+ top bar = drag region with opted-out buttons, popups clamped below the
27708
+ bar. Design: a "desktop glass widget" \u2014 one pane of glass (no bar
27709
+ divider), option-colored column washes, and the live feed made visible
27710
+ (breathing dot; poke-touched cards pulse once). All scoped under
27711
+ body.quickboard; the main app's board is untouched. */
27712
+ body.quickboard { background:transparent; --pop-top-inset:44px; }
27713
+ html:has(body.quickboard) { background:transparent; }
27714
+ body.quickboard #app { display:block; width:100vw; height:100vh; height:100dvh; }
27715
+ .qb { display:flex; flex-direction:column; width:100%; height:100vh; height:100dvh; overflow:hidden;
27716
+ background:color-mix(in srgb, var(--bg) 20%, transparent); }
27717
+ .qb-bar { display:flex; align-items:center; gap:6px; padding:6px 10px;
27718
+ user-select:none; -webkit-app-region:drag; }
27719
+ body.desktop-mac .qb-bar { padding-left:76px; }
27720
+ /* The brand doubles as the database switcher \u2014 a Notion-style page-switcher
27721
+ chip (emoji + name + chevron); opts out of the drag region. */
27722
+ .qb-brand { display:inline-flex; align-items:center; gap:5px; min-width:0; max-width:60%;
27723
+ font-size:13px; font-weight:600; color:var(--fg);
27724
+ padding:3px 8px; border-radius:var(--radius-sm); -webkit-app-region:no-drag;
27725
+ transition:background .12s; }
27726
+ .qb-brand:hover { background:var(--hover-2); }
27727
+ .qb-brand .qb-emoji { font-size:14px; line-height:1; flex:none; }
27728
+ .qb-brand .qb-name { min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
27729
+ .qb-brand svg { flex:none; color:var(--muted); }
27730
+ .qb-actions { display:flex; align-items:center; gap:2px; margin-left:auto; -webkit-app-region:no-drag; }
27731
+ .qb-actions .iconbtn { width:26px; height:26px; }
27732
+ .qb-actions .iconbtn.active { color:var(--accent); background:var(--hover-2); }
27733
+ /* Live-feed dot: green + breathing halo while the SSE stream is up, muted
27734
+ and still while reconnecting \u2014 the one honest signal that AI edits will
27735
+ appear by themselves. */
27736
+ .qb-live { width:6px; height:6px; border-radius:50%; margin:0 8px 0 4px; flex:none;
27737
+ background:var(--muted); }
27738
+ .qb-live.on { background:var(--success); animation:qb-breathe 2s ease-out infinite; }
27739
+ @keyframes qb-breathe {
27740
+ 0% { box-shadow:0 0 0 0 color-mix(in srgb, var(--success) 40%, transparent); }
27741
+ 70% { box-shadow:0 0 0 5px transparent; }
27742
+ 100% { box-shadow:0 0 0 0 transparent; }
27743
+ }
27744
+ .qb-body { flex:1; min-height:0; overflow:auto; scrollbar-width:thin;
27745
+ -webkit-app-region:no-drag; padding:0 10px; }
27746
+ /* Product-grade empty state (no databases yet / booting). */
27747
+ .qb-empty { display:flex; flex-direction:column; align-items:center; justify-content:center;
27748
+ height:100%; gap:4px; text-align:center; padding:0 32px; }
27749
+ .qb-empty > svg { width:32px; height:32px; stroke-width:1.25; color:var(--muted); opacity:.55; margin-bottom:6px; }
27750
+ .qb-empty-title { font-size:14px; font-weight:600; color:var(--fg-soft); }
27751
+ .qb-empty-sub { font-size:var(--fs-sm); color:var(--muted); line-height:1.6; max-width:280px; }
27752
+ body.quickboard .view-placeholder { display:flex; align-items:center; justify-content:center;
27753
+ height:70%; text-align:center; color:var(--muted); border:0; background:none; }
27754
+ /* Board at widget density: borderless columns washed with 6% of their
27755
+ option color (--col-tint, set inline by board.tsx), stretched to the
27756
+ window rather than the main app's topbar-based calc; vibrancy reads
27757
+ through the gutters between the washes. */
27758
+ body.quickboard .board-wrap { margin-top:0; }
27759
+ body.quickboard .board-bar { padding:6px 0 8px; }
27760
+ body.quickboard .board { min-height:0; padding-bottom:10px; gap:10px; }
27761
+ body.quickboard .board-col { flex:0 0 232px; width:232px;
27762
+ max-height:calc(100vh - 112px); max-height:calc(100dvh - 112px);
27763
+ border:0; border-radius:var(--radius-lg);
27764
+ background:color-mix(in srgb, var(--col-tint) 6%, transparent); }
27765
+ body.quickboard .board-count { color:var(--col-tint); }
27766
+ /* Cards: a lighter pane of the same glass (not opaque white \u2014 the column
27767
+ wash and vibrancy read through), a 3px option-color edge, gentle hover
27768
+ lift that also firms the pane up for reading. */
27769
+ body.quickboard .kcard { background:color-mix(in srgb, var(--bg) 52%, transparent);
27770
+ border-color:color-mix(in srgb, var(--line) 55%, transparent);
27771
+ border-left:3px solid var(--col-tint);
27772
+ padding-left:9px; transition:border-color .1s, box-shadow .12s, transform .12s, background .12s; }
27773
+ body.quickboard .kcard:hover { transform:translateY(-1px); box-shadow:var(--shadow-md);
27774
+ background:color-mix(in srgb, var(--bg) 78%, transparent); }
27775
+ body.quickboard .kcard-title { font-size:var(--fs-sm); }
27776
+ body.quickboard .kcard-field { font-size:var(--fs-xs); }
27777
+ /* The drag ghost is cloned onto <body> \u2014 outside any column, so --col-tint
27778
+ is gone and a see-through pane over arbitrary content reads badly. Firm
27779
+ it up and drop the edge tint while in flight. */
27780
+ body.quickboard .kcard.dragging-ghost { background:color-mix(in srgb, var(--bg) 88%, transparent);
27781
+ border-left-color:var(--line-strong); }
27782
+ /* One-shot pulse on cards a live-feed poke just changed ("AI moved this"). */
27783
+ body.quickboard .kcard.flash { animation:qb-card-flash 1.2s ease-out; }
27784
+ @keyframes qb-card-flash {
27785
+ 0% { background:var(--accent-soft); box-shadow:0 0 0 1.5px var(--accent); }
27786
+ 100% { background:color-mix(in srgb, var(--bg) 52%, transparent); box-shadow:var(--shadow-sm); }
27787
+ }
27788
+ /* The record peek drawer shares its width preference with the main app
27789
+ (mh.peekW) \u2014 cap it so it never swallows the whole small window. */
27790
+ body.quickboard .peek { max-width:92vw; }
27791
+
27792
+ /* Quick-window shortcut capture (desktop only; shared by note + board). */
27396
27793
  .qn-shortcut { min-width:140px; justify-content:center; font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC",sans-serif; }
27397
27794
  .qn-shortcut.capturing { outline:2px solid var(--accent); color:var(--accent); }
27398
27795
  .qn-keys { display:inline-flex; align-items:center; gap:6px; }
27399
27796
  .qn-key { line-height:1; }
27400
27797
  .qn-key.sym { font-size:1.15em; line-height:1; } /* \u2318 \u21E7 glyphs render smaller \u2014 bump to match letters */
27401
27798
 
27799
+ /* File-editor window (desktop, loaded at #file?path=\u2026 \u2014 the .txt/.md "open
27800
+ with" surface). Same shell idiom as quicknote: top bar = drag region with
27801
+ opted-out buttons, single full-bleed column, popups clamped below the bar. */
27802
+ body.file-window { --pop-top-inset:46px; }
27803
+ body.file-window #app { display:block; width:100vw; height:100vh; height:100dvh; }
27804
+ .fw { display:flex; flex-direction:column; width:100%; height:100vh; height:100dvh; overflow:hidden; background:var(--bg); }
27805
+ .fw-bar { display:flex; align-items:center; gap:8px; padding:7px 12px;
27806
+ user-select:none; -webkit-app-region:drag;
27807
+ background:var(--surface); border-bottom:1px solid var(--line); }
27808
+ /* macOS only: clear the inset traffic lights (frame is native elsewhere). */
27809
+ body.desktop-mac .fw-bar { padding-left:84px; }
27810
+ .fw-name { flex:1; min-width:0; font-size:13px; font-weight:600; color:var(--fg-soft);
27811
+ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
27812
+ .fw-dirty { color:var(--accent); font-size:15px; }
27813
+ .fw-actions { display:flex; align-items:center; gap:6px; -webkit-app-region:no-drag; }
27814
+ .fw-actions .btn { padding:4px 10px; font-size:12px; }
27815
+ .fw-body { flex:1; overflow:auto; scrollbar-gutter:stable; scrollbar-width:thin; -webkit-app-region:no-drag; }
27816
+ /* Bar is ~45px, not the main ~50px topbar the find bar assumes. */
27817
+ body.file-window .find-bar { top:52px; }
27818
+
27402
27819
  /* No-origin bootstrap: enroll screen + hydration splash (data-blind shell). */
27403
27820
  .enroll-splash { min-height:100dvh; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px; padding:24px; }
27404
27821
  .enroll-spinner { width:26px; height:26px; border-radius:50%; border:2.5px solid var(--line-strong); border-top-color:var(--accent); animation:enroll-spin .8s linear infinite; }
@@ -27717,6 +28134,7 @@ var injected = {
27717
28134
  sdk: null
27718
28135
  };
27719
28136
  var injectedWasm = null;
28137
+ var injectedWasmLoader = null;
27720
28138
  var injectedFmtWasm = {};
27721
28139
  function toArrayBuffer(w) {
27722
28140
  return w.byteOffset === 0 && w.byteLength === w.buffer.byteLength ? w.buffer : w.slice().buffer;
@@ -27727,7 +28145,13 @@ function setWebuiBundle(bundle) {
27727
28145
  injected.dbWorker = bundle.dbWorker;
27728
28146
  injected.runtime = bundle.runtime;
27729
28147
  injected.sdk = bundle.sdk;
27730
- injectedWasm = toArrayBuffer(bundle.wasm);
28148
+ if (typeof bundle.wasm === "function") {
28149
+ injectedWasmLoader = bundle.wasm;
28150
+ injectedWasm = null;
28151
+ } else {
28152
+ injectedWasm = toArrayBuffer(bundle.wasm);
28153
+ injectedWasmLoader = null;
28154
+ }
27731
28155
  for (const p of FMT_PROVIDERS) {
27732
28156
  const js = bundle.fmt?.[p.js];
27733
28157
  if (js != null)
@@ -27753,6 +28177,7 @@ function newestSourceMtime(dir) {
27753
28177
  function bundleGetter(opts) {
27754
28178
  let cached2 = null;
27755
28179
  let cachedMtime = 0;
28180
+ let building = null;
27756
28181
  return async () => {
27757
28182
  const fromBinary = injected[opts.key];
27758
28183
  if (fromBinary != null)
@@ -27763,15 +28188,24 @@ function bundleGetter(opts) {
27763
28188
  for (const extra of opts.extraDirs ?? []) {
27764
28189
  newest = Math.max(newest, newestSourceMtime(fileURLToPath(new URL(extra, import.meta.url))));
27765
28190
  }
27766
- if (cached2 == null || newest > cachedMtime) {
27767
- const entry = fileURLToPath(new URL(opts.entry, import.meta.url));
27768
- const res = await Bun.build({ entrypoints: [entry], target: "browser" });
27769
- if (!res.success)
27770
- throw new AggregateError(res.logs, `${opts.dist} build failed`);
27771
- cached2 = await res.outputs[0].text();
27772
- cachedMtime = newest;
28191
+ if (cached2 != null && newest <= cachedMtime)
28192
+ return cached2;
28193
+ if (!building) {
28194
+ building = (async () => {
28195
+ const t = Date.now();
28196
+ const entry = fileURLToPath(new URL(opts.entry, import.meta.url));
28197
+ const res = await Bun.build({ entrypoints: [entry], target: "browser" });
28198
+ if (!res.success)
28199
+ throw new AggregateError(res.logs, `${opts.dist} build failed`);
28200
+ cached2 = await res.outputs[0].text();
28201
+ cachedMtime = newest;
28202
+ console.log(`[perf] ${opts.dist} dev build ${Date.now() - t}ms`);
28203
+ return cached2;
28204
+ })().finally(() => {
28205
+ building = null;
28206
+ });
27773
28207
  }
27774
- return cached2;
28208
+ return building;
27775
28209
  }
27776
28210
  if (cached2 == null) {
27777
28211
  const prebuilt = Bun.file(fileURLToPath(new URL(`./${opts.dist}`, import.meta.url)));
@@ -27823,6 +28257,10 @@ async function getSw() {
27823
28257
  async function getWasm() {
27824
28258
  if (injectedWasm != null)
27825
28259
  return injectedWasm;
28260
+ if (injectedWasmLoader != null) {
28261
+ injectedWasm = toArrayBuffer(await injectedWasmLoader());
28262
+ return injectedWasm;
28263
+ }
27826
28264
  const path = RUNNING_FROM_SOURCE ? join5(dirname(Bun.resolveSync("@sqlite.org/sqlite-wasm", fileURLToPath(new URL(".", import.meta.url)))), "sqlite3.wasm") : fileURLToPath(new URL("./sqlite3.wasm", import.meta.url));
27827
28265
  const f = Bun.file(path);
27828
28266
  if (!await f.exists()) {
@@ -27853,21 +28291,34 @@ async function warmWebui() {
27853
28291
  await getJs();
27854
28292
  } catch {}
27855
28293
  }
27856
- function asset(body, contentType) {
27857
- return new Response(body, {
27858
- headers: { "content-type": contentType, "cache-control": "no-store" }
27859
- });
28294
+ var etagCache = new Map;
28295
+ function etagFor(body) {
28296
+ let tag = etagCache.get(body);
28297
+ if (!tag) {
28298
+ if (etagCache.size > 64)
28299
+ etagCache.clear();
28300
+ tag = `"${new Bun.CryptoHasher("sha256").update(body).digest("hex").slice(0, 16)}"`;
28301
+ etagCache.set(body, tag);
28302
+ }
28303
+ return tag;
28304
+ }
28305
+ function asset(req, body, contentType) {
28306
+ const tag = etagFor(body);
28307
+ const headers = { "content-type": contentType, "cache-control": "no-cache", etag: tag };
28308
+ if (req.headers.get("if-none-match") === tag)
28309
+ return new Response(null, { status: 304, headers });
28310
+ return new Response(body, { headers });
27860
28311
  }
27861
28312
  async function serveWebui(req) {
27862
28313
  if (req.method !== "GET")
27863
28314
  return null;
27864
28315
  const { pathname } = new URL(req.url);
27865
28316
  if (pathname === "/")
27866
- return asset(HTML2, "text/html; charset=utf-8");
28317
+ return asset(req, HTML2, "text/html; charset=utf-8");
27867
28318
  if (pathname === "/webui.css")
27868
- return asset(await getCss(), "text/css; charset=utf-8");
28319
+ return asset(req, await getCss(), "text/css; charset=utf-8");
27869
28320
  if (pathname === "/manifest.webmanifest")
27870
- return asset(MANIFEST, "application/manifest+json");
28321
+ return asset(req, MANIFEST, "application/manifest+json");
27871
28322
  const icon = ICONS[pathname];
27872
28323
  if (icon) {
27873
28324
  return new Response(Buffer.from(icon, "base64"), {
@@ -27906,7 +28357,7 @@ async function serveWebui(req) {
27906
28357
  const getter = script[pathname];
27907
28358
  if (getter) {
27908
28359
  try {
27909
- return asset(await getter(), "text/javascript; charset=utf-8");
28360
+ return asset(req, await getter(), "text/javascript; charset=utf-8");
27910
28361
  } catch (e) {
27911
28362
  console.error(`[webui] failed to serve ${pathname} \u2014`, e);
27912
28363
  return new Response(`webui build failed: ${e}`, { status: 500 });
@@ -27935,12 +28386,19 @@ function hlcMillis(hlc2) {
27935
28386
  function hlcIso(hlc2) {
27936
28387
  return new Date(hlcMillis(hlc2)).toISOString();
27937
28388
  }
28389
+ function parseTxn(txn) {
28390
+ let rest = txn ?? "";
28391
+ let actor = null;
28392
+ const slash = rest.indexOf("/");
28393
+ if (slash > 0) {
28394
+ actor = rest.slice(0, slash);
28395
+ rest = rest.slice(slash + 1);
28396
+ }
28397
+ const kind = rest.startsWith("repair:") ? "repair" : rest.startsWith("revert:") ? "revert" : "user";
28398
+ return { actor, kind };
28399
+ }
27938
28400
  function revisionKind(txn) {
27939
- if (txn?.startsWith("repair:"))
27940
- return "repair";
27941
- if (txn?.startsWith("revert:"))
27942
- return "revert";
27943
- return "user";
28401
+ return parseTxn(txn).kind;
27944
28402
  }
27945
28403
  function clusterRevisions(changes) {
27946
28404
  const groups = [];
@@ -28033,6 +28491,7 @@ function listDocumentRevisions(db2, id) {
28033
28491
  at: hlcIso(last.hlc),
28034
28492
  node_id: last.node_id,
28035
28493
  kind: revisionKind(last.txn),
28494
+ actor: parseTxn(last.txn).actor,
28036
28495
  changes: group.length,
28037
28496
  created,
28038
28497
  deleted,
@@ -28151,6 +28610,7 @@ function recordRevisionOf(group) {
28151
28610
  at: hlcIso(last.hlc),
28152
28611
  node_id: last.node_id,
28153
28612
  kind: revisionKind(last.txn),
28613
+ actor: parseTxn(last.txn).actor,
28154
28614
  changes: group.length,
28155
28615
  created,
28156
28616
  deleted,
@@ -28290,6 +28750,7 @@ function listPropertyRevisions(db2, id) {
28290
28750
  at: hlcIso(last.hlc),
28291
28751
  node_id: last.node_id,
28292
28752
  kind: revisionKind(last.txn),
28753
+ actor: parseTxn(last.txn).actor,
28293
28754
  changes: group.length,
28294
28755
  created,
28295
28756
  deleted,
@@ -28351,7 +28812,7 @@ var revertProperty = grouped(function revertProperty2(db2, id, to) {
28351
28812
  emit(db2, "properties", id, "__deleted", 0);
28352
28813
  const schemaTxns = new Set(db2.query("SELECT DISTINCT txn FROM crdt_changes WHERE dataset = 'properties' AND row_id = ? AND hlc > ? AND txn IS NOT NULL").all(id, to).map((r) => r.txn));
28353
28814
  const cellChanges = db2.query("SELECT row_id, hlc, value, txn FROM crdt_changes WHERE dataset = 'records' AND col = ? ORDER BY row_id, hlc").all(id);
28354
- const isCascade = (txn) => txn !== null && (schemaTxns.has(txn) || txn.startsWith("repair:"));
28815
+ const isCascade = (txn) => txn !== null && (schemaTxns.has(txn) || parseTxn(txn).kind === "repair");
28355
28816
  let restored = 0;
28356
28817
  let skipped = 0;
28357
28818
  let i = 0;
@@ -28397,6 +28858,302 @@ function recordFieldHistory(db2, id, propId) {
28397
28858
  }));
28398
28859
  }
28399
28860
 
28861
+ // src/core/audit.ts
28862
+ init_crdt();
28863
+ init_errors();
28864
+ function isMetaCol(dataset, col) {
28865
+ if (dataset === "records")
28866
+ return RECORD_META.has(col);
28867
+ return col === "created_hlc" || col === "__deleted";
28868
+ }
28869
+ function oplogExclude() {
28870
+ return {
28871
+ sql: [...OPLOG_ONLY_DATASETS].map(() => "dataset != ?"),
28872
+ params: [...OPLOG_ONLY_DATASETS]
28873
+ };
28874
+ }
28875
+ function changesOfTxn(db2, txn, beforeHlc) {
28876
+ const ex = oplogExclude();
28877
+ const wheres = ["txn = ?", ...ex.sql];
28878
+ const params = [txn, ...ex.params];
28879
+ if (beforeHlc) {
28880
+ wheres.push("hlc < ?");
28881
+ params.push(beforeHlc);
28882
+ }
28883
+ return db2.query(`SELECT ${CHANGE_SELECT} FROM crdt_changes WHERE ${wheres.join(" AND ")} ORDER BY hlc`).all(...params);
28884
+ }
28885
+ function databaseName(db2, id, c) {
28886
+ if (!id)
28887
+ return null;
28888
+ if (!c.dbNames.has(id)) {
28889
+ const row = db2.query("SELECT name FROM databases WHERE id = ?").get(id);
28890
+ c.dbNames.set(id, row?.name ?? null);
28891
+ }
28892
+ return c.dbNames.get(id);
28893
+ }
28894
+ function titlePropOf(db2, databaseId, c) {
28895
+ if (!c.titleProps.has(databaseId)) {
28896
+ const row = db2.query("SELECT id FROM properties WHERE database_id = ? AND type = 'text' AND __deleted = 0 ORDER BY position LIMIT 1").get(databaseId);
28897
+ c.titleProps.set(databaseId, row?.id ?? null);
28898
+ }
28899
+ return c.titleProps.get(databaseId) ?? null;
28900
+ }
28901
+ function resolveEntity2(db2, dataset, id, c) {
28902
+ if (dataset === "records") {
28903
+ const row = db2.query("SELECT database_id, data FROM records WHERE id = ?").get(id);
28904
+ if (!row)
28905
+ return { label: null, database_id: null };
28906
+ const titleProp = row.database_id ? titlePropOf(db2, row.database_id, c) : null;
28907
+ const data = JSON.parse(row.data || "{}");
28908
+ const label = titleProp && data[titleProp] != null ? String(data[titleProp]) : null;
28909
+ return { label, database_id: row.database_id };
28910
+ }
28911
+ if (dataset === "documents") {
28912
+ const row = db2.query("SELECT title, database_id FROM documents WHERE id = ?").get(id);
28913
+ return { label: row?.title ?? null, database_id: row?.database_id ?? null };
28914
+ }
28915
+ if (dataset === "properties") {
28916
+ const row = db2.query("SELECT name, database_id FROM properties WHERE id = ?").get(id);
28917
+ return { label: row?.name ?? null, database_id: row?.database_id ?? null };
28918
+ }
28919
+ if (dataset === "databases") {
28920
+ return { label: databaseName(db2, id, c), database_id: id };
28921
+ }
28922
+ if (dataset === "sites") {
28923
+ const row = db2.query("SELECT title, name FROM sites WHERE id = ?").get(id);
28924
+ return { label: row?.title ?? row?.name ?? null, database_id: null };
28925
+ }
28926
+ return { label: null, database_id: null };
28927
+ }
28928
+ function blockDocId(db2, group, blockId) {
28929
+ for (const ch of group) {
28930
+ if (ch.dataset === "doc_blocks" && ch.row_id === blockId && ch.col === "doc_id" && ch.value)
28931
+ return JSON.parse(ch.value);
28932
+ }
28933
+ const head = db2.query("SELECT doc_id FROM doc_blocks WHERE id = ?").get(blockId);
28934
+ if (head?.doc_id)
28935
+ return head.doc_id;
28936
+ const past = db2.query("SELECT value FROM crdt_changes WHERE dataset = 'doc_blocks' AND row_id = ? AND col = 'doc_id' AND value IS NOT NULL ORDER BY hlc DESC LIMIT 1").get(blockId);
28937
+ return past ? JSON.parse(past.value) : null;
28938
+ }
28939
+ function entryOf(db2, group, c) {
28940
+ const accs = new Map;
28941
+ const acc = (dataset, id) => {
28942
+ const key = dataset + "\x00" + id;
28943
+ let a = accs.get(key);
28944
+ if (!a) {
28945
+ a = {
28946
+ dataset,
28947
+ id,
28948
+ created: false,
28949
+ deleted: false,
28950
+ fields: new Set,
28951
+ blocksChanged: new Set,
28952
+ blocksDeleted: new Set
28953
+ };
28954
+ accs.set(key, a);
28955
+ }
28956
+ return a;
28957
+ };
28958
+ for (const ch of group) {
28959
+ if (ch.dataset === "doc_blocks") {
28960
+ const docId = blockDocId(db2, group, ch.row_id);
28961
+ const a2 = docId ? acc("documents", docId) : acc("doc_blocks", ch.row_id);
28962
+ if (ch.col === "__deleted" && flagSet(ch.value))
28963
+ a2.blocksDeleted.add(ch.row_id);
28964
+ else
28965
+ a2.blocksChanged.add(ch.row_id);
28966
+ continue;
28967
+ }
28968
+ const a = acc(ch.dataset, ch.row_id);
28969
+ if (ch.col === "created_hlc" || ch.dataset === "properties" && ch.col === "database_id")
28970
+ a.created = true;
28971
+ else if (ch.col === "__deleted")
28972
+ a.deleted = flagSet(ch.value);
28973
+ if (!isMetaCol(ch.dataset, ch.col))
28974
+ a.fields.add(ch.col);
28975
+ }
28976
+ const entities = [...accs.values()].map((a) => {
28977
+ const { label, database_id } = resolveEntity2(db2, a.dataset, a.id, c);
28978
+ return {
28979
+ dataset: a.dataset,
28980
+ id: a.id,
28981
+ label,
28982
+ database_id,
28983
+ database_label: a.dataset === "databases" ? null : databaseName(db2, database_id, c),
28984
+ created: a.created,
28985
+ deleted: a.deleted,
28986
+ fields: a.fields.size,
28987
+ blocks_changed: [...a.blocksChanged].filter((b) => !a.blocksDeleted.has(b)).length,
28988
+ blocks_deleted: a.blocksDeleted.size
28989
+ };
28990
+ });
28991
+ const last = group[group.length - 1];
28992
+ const { actor, kind } = parseTxn(last.txn);
28993
+ return {
28994
+ version: last.hlc,
28995
+ at: hlcIso(last.hlc),
28996
+ node_id: last.node_id,
28997
+ kind,
28998
+ actor,
28999
+ txn: last.txn,
29000
+ changes: group.length,
29001
+ entities
29002
+ };
29003
+ }
29004
+ function listAuditEntries(db2, opts = {}) {
29005
+ const limit = Math.max(1, Math.min(opts.limit ?? 50, 200));
29006
+ if (opts.actor !== undefined && !ACTOR_TAG_RE.test(opts.actor))
29007
+ throw new MhError("invalid_input", `invalid actor tag: ${opts.actor}`);
29008
+ const chunk = Math.min(Math.max(limit * 40, 800), 8000);
29009
+ const ex = oplogExclude();
29010
+ const wheres = [...ex.sql];
29011
+ const params = [...ex.params];
29012
+ if (opts.before) {
29013
+ wheres.push("hlc < ?");
29014
+ params.push(opts.before);
29015
+ }
29016
+ if (opts.actor !== undefined) {
29017
+ wheres.push("txn >= ?", "txn < ?");
29018
+ params.push(opts.actor + "/", opts.actor + "0");
29019
+ }
29020
+ const rows = db2.query(`SELECT ${CHANGE_SELECT} FROM crdt_changes
29021
+ ${wheres.length ? "WHERE " + wheres.join(" AND ") : ""}
29022
+ ORDER BY hlc DESC LIMIT ?`).all(...params, chunk);
29023
+ const exhausted = rows.length < chunk;
29024
+ rows.reverse();
29025
+ let groups = clusterRevisions(rows);
29026
+ if (!exhausted && groups.length > 0) {
29027
+ const txn = groups[0][0].txn;
29028
+ if (txn !== null)
29029
+ groups[0] = changesOfTxn(db2, txn, opts.before);
29030
+ else if (groups.length > 1)
29031
+ groups = groups.slice(1);
29032
+ }
29033
+ const caches = { dbNames: new Map, titleProps: new Map };
29034
+ const newestFirst = groups.reverse();
29035
+ const kept = newestFirst.slice(0, limit);
29036
+ const entries = kept.map((g) => entryOf(db2, g, caches));
29037
+ const more = !exhausted || newestFirst.length > limit;
29038
+ const next = more && kept.length ? kept[kept.length - 1][0].hlc : null;
29039
+ return { entries, next };
29040
+ }
29041
+ function valueBefore(db2, dataset, rowId, col, hlc2) {
29042
+ return db2.query("SELECT value FROM crdt_changes WHERE dataset = ? AND row_id = ? AND col = ? AND hlc < ? ORDER BY hlc DESC LIMIT 1").get(dataset, rowId, col, hlc2) ?? undefined;
29043
+ }
29044
+ function colLabel(db2, dataset, col) {
29045
+ if (dataset !== "records")
29046
+ return col;
29047
+ const row = db2.query("SELECT name FROM properties WHERE id = ?").get(col);
29048
+ return row?.name ?? col;
29049
+ }
29050
+ function auditEntryDetail(db2, txn) {
29051
+ const group = changesOfTxn(db2, txn);
29052
+ if (!group.length)
29053
+ throw new MhError("not_found", `no change group: ${txn}`);
29054
+ const caches = { dbNames: new Map, titleProps: new Map };
29055
+ const entry = entryOf(db2, group, caches);
29056
+ const first = new Map;
29057
+ const lastWrite = new Map;
29058
+ for (const ch of group) {
29059
+ const key = ch.dataset + "\x00" + ch.row_id + "\x00" + ch.col;
29060
+ if (!first.has(key))
29061
+ first.set(key, ch);
29062
+ lastWrite.set(key, ch);
29063
+ }
29064
+ const entities = entry.entities.map((e) => ({
29065
+ ...e,
29066
+ diffs: [],
29067
+ block_diffs: []
29068
+ }));
29069
+ const byKey = new Map(entities.map((e) => [e.dataset + "\x00" + e.id, e]));
29070
+ for (const [key, ch] of lastWrite) {
29071
+ const f = first.get(key);
29072
+ const diff = (label) => {
29073
+ const out = { col: ch.dataset === "doc_blocks" ? ch.row_id : ch.col, label };
29074
+ const prev = valueBefore(db2, ch.dataset, ch.row_id, ch.col, f.hlc);
29075
+ if (prev && prev.value !== null)
29076
+ out.before = JSON.parse(prev.value);
29077
+ if (ch.value !== null)
29078
+ out.after = JSON.parse(ch.value);
29079
+ return out;
29080
+ };
29081
+ if (ch.dataset === "doc_blocks") {
29082
+ if (ch.col !== "text")
29083
+ continue;
29084
+ const docId = blockDocId(db2, group, ch.row_id);
29085
+ const ent = byKey.get(docId ? "documents\x00" + docId : "doc_blocks\x00" + ch.row_id);
29086
+ ent?.block_diffs.push(diff("block"));
29087
+ continue;
29088
+ }
29089
+ if (isMetaCol(ch.dataset, ch.col))
29090
+ continue;
29091
+ byKey.get(ch.dataset + "\x00" + ch.row_id)?.diffs.push(diff(colLabel(db2, ch.dataset, ch.col)));
29092
+ }
29093
+ return { ...entry, entities };
29094
+ }
29095
+ var revertChangeGroup = grouped(function revertChangeGroup2(db2, txn) {
29096
+ const group = changesOfTxn(db2, txn);
29097
+ if (!group.length)
29098
+ throw new MhError("not_found", `no change group: ${txn}`);
29099
+ const byRow = new Map;
29100
+ for (const ch of group) {
29101
+ const key = ch.dataset + "\x00" + ch.row_id;
29102
+ let list = byRow.get(key);
29103
+ if (!list)
29104
+ byRow.set(key, list = []);
29105
+ list.push(ch);
29106
+ }
29107
+ let restored = 0;
29108
+ let skippedRegisters = 0;
29109
+ let removedRows = 0;
29110
+ let skippedRows = 0;
29111
+ for (const rowChanges2 of byRow.values()) {
29112
+ const { dataset, row_id } = rowChanges2[0];
29113
+ const earliest = rowChanges2[0].hlc;
29114
+ const preexisting = db2.query("SELECT 1 AS x FROM crdt_changes WHERE dataset = ? AND row_id = ? AND hlc < ? LIMIT 1").get(dataset, row_id, earliest);
29115
+ if (!preexisting) {
29116
+ const foreign = db2.query("SELECT 1 AS x FROM crdt_changes WHERE dataset = ? AND row_id = ? AND txn IS NOT ? LIMIT 1").get(dataset, row_id, txn);
29117
+ if (foreign) {
29118
+ skippedRows++;
29119
+ continue;
29120
+ }
29121
+ const lastDeleted = [...rowChanges2].reverse().find((c) => c.col === "__deleted");
29122
+ if (lastDeleted && flagSet(lastDeleted.value))
29123
+ continue;
29124
+ emit(db2, dataset, row_id, "__deleted", 1);
29125
+ removedRows++;
29126
+ continue;
29127
+ }
29128
+ const firstWrite = new Map;
29129
+ for (const ch of rowChanges2)
29130
+ if (!firstWrite.has(ch.col))
29131
+ firstWrite.set(ch.col, ch);
29132
+ for (const [col, f] of firstWrite) {
29133
+ const winner = db2.query("SELECT value, txn FROM crdt_changes WHERE dataset = ? AND row_id = ? AND col = ? ORDER BY hlc DESC LIMIT 1").get(dataset, row_id, col);
29134
+ if (winner.txn !== txn) {
29135
+ skippedRegisters++;
29136
+ continue;
29137
+ }
29138
+ const prev = valueBefore(db2, dataset, row_id, col, f.hlc);
29139
+ const target = prev === undefined ? col === "__deleted" ? 0 : undefined : prev.value === null ? undefined : JSON.parse(prev.value);
29140
+ const targetJson = target === undefined ? null : JSON.stringify(target);
29141
+ if (targetJson === winner.value)
29142
+ continue;
29143
+ emit(db2, dataset, row_id, col, target);
29144
+ restored++;
29145
+ }
29146
+ }
29147
+ return {
29148
+ txn,
29149
+ changed: restored > 0 || removedRows > 0,
29150
+ restored_registers: restored,
29151
+ skipped_registers: skippedRegisters,
29152
+ removed_rows: removedRows,
29153
+ skipped_rows: skippedRows
29154
+ };
29155
+ }, "revert");
29156
+
28400
29157
  // src/webui/server/routes.ts
28401
29158
  init_node();
28402
29159
  init_blobs();
@@ -29397,6 +30154,132 @@ function isPeer(db2, url2) {
29397
30154
  return listShareServers(db2).some((s) => s.url === url2);
29398
30155
  }
29399
30156
 
30157
+ // src/webui/server/changes-route.ts
30158
+ init_zod();
30159
+ init_crdt();
30160
+ var POLL_MS = 1000;
30161
+ var HEARTBEAT_MS = 8000;
30162
+ var BATCH_LIMIT = 1000;
30163
+ var ROW_IDS_CAP = 500;
30164
+ function collectSince(db2, since) {
30165
+ const datasets = new Set;
30166
+ const rowIds = new Set;
30167
+ let truncated = false;
30168
+ let cursor = since;
30169
+ for (;; ) {
30170
+ const batch = changesAfterSeq(db2, cursor, { limit: BATCH_LIMIT });
30171
+ for (const c of batch.changes) {
30172
+ datasets.add(c.dataset);
30173
+ if (rowIds.size < ROW_IDS_CAP)
30174
+ rowIds.add(c.row_id);
30175
+ else
30176
+ truncated = true;
30177
+ }
30178
+ cursor = batch.cursor;
30179
+ if (batch.changes.length < BATCH_LIMIT)
30180
+ break;
30181
+ }
30182
+ return { datasets: [...datasets], rowIds: [...rowIds], cursor, truncated };
30183
+ }
30184
+ function highWater(db2) {
30185
+ const top = db2.query("SELECT MAX(seq) AS m FROM crdt_changes").get();
30186
+ return top.m ?? 0;
30187
+ }
30188
+ var sse = (event, data) => `event: ${event}
30189
+ data: ${JSON.stringify(data)}
30190
+
30191
+ `;
30192
+ var pollers = new WeakMap;
30193
+ function tick(db2, poller) {
30194
+ if (highWater(db2) <= poller.cursor)
30195
+ return;
30196
+ const payload = collectSince(db2, poller.cursor);
30197
+ poller.cursor = payload.cursor;
30198
+ if (!payload.datasets.length)
30199
+ return;
30200
+ const text = sse("changes", payload);
30201
+ for (const send of [...poller.subs])
30202
+ send(text);
30203
+ }
30204
+ function attach(db2, send) {
30205
+ let poller = pollers.get(db2);
30206
+ if (!poller) {
30207
+ poller = {
30208
+ subs: new Set,
30209
+ cursor: highWater(db2),
30210
+ timer: setInterval(() => tick(db2, poller), POLL_MS),
30211
+ hb: setInterval(() => {
30212
+ for (const s of [...poller.subs])
30213
+ s(`: hb
30214
+
30215
+ `);
30216
+ }, HEARTBEAT_MS)
30217
+ };
30218
+ pollers.set(db2, poller);
30219
+ }
30220
+ poller.subs.add(send);
30221
+ }
30222
+ function detach(db2, send) {
30223
+ const poller = pollers.get(db2);
30224
+ if (!poller || !poller.subs.delete(send))
30225
+ return;
30226
+ if (poller.subs.size === 0) {
30227
+ clearInterval(poller.timer);
30228
+ clearInterval(poller.hb);
30229
+ pollers.delete(db2);
30230
+ }
30231
+ }
30232
+ var changesRoutes = [
30233
+ {
30234
+ method: "GET",
30235
+ path: "/api/changes",
30236
+ summary: "Server-sent event stream of oplog change pokes ({datasets, rowIds, cursor}). " + "Reconnect with ?since=<cursor> to catch up on changes missed while disconnected.",
30237
+ response: exports_external.any().describe("text/event-stream \u2014 `hello` {cursor} on connect, then `changes` {datasets, rowIds, cursor, truncated}"),
30238
+ handler(req, { db: db2 }) {
30239
+ const sinceRaw = new URL(req.url).searchParams.get("since");
30240
+ const since = sinceRaw != null && /^\d+$/.test(sinceRaw) ? Number(sinceRaw) : null;
30241
+ const enc = new TextEncoder;
30242
+ let send = () => {};
30243
+ let closed = false;
30244
+ const close = () => {
30245
+ if (closed)
30246
+ return;
30247
+ closed = true;
30248
+ detach(db2, send);
30249
+ };
30250
+ const stream = new ReadableStream({
30251
+ start: (controller) => {
30252
+ send = (text) => {
30253
+ if (closed)
30254
+ return;
30255
+ try {
30256
+ controller.enqueue(enc.encode(text));
30257
+ } catch {
30258
+ close();
30259
+ }
30260
+ };
30261
+ attach(db2, send);
30262
+ send(sse("hello", { cursor: since ?? highWater(db2) }));
30263
+ if (since != null && since < highWater(db2)) {
30264
+ const payload = collectSince(db2, since);
30265
+ if (payload.datasets.length)
30266
+ send(sse("changes", payload));
30267
+ }
30268
+ },
30269
+ cancel: () => close()
30270
+ });
30271
+ req.signal.addEventListener("abort", close);
30272
+ return new Response(stream, {
30273
+ headers: {
30274
+ "content-type": "text/event-stream; charset=utf-8",
30275
+ "cache-control": "no-store",
30276
+ "x-accel-buffering": "no"
30277
+ }
30278
+ });
30279
+ }
30280
+ }
30281
+ ];
30282
+
29400
30283
  // src/webui/server/site-hosting-routes.ts
29401
30284
  init_zod();
29402
30285
  init_errors();
@@ -31024,6 +31907,8 @@ var UpdatePropertyReq = exports_external.object({
31024
31907
  position: exports_external.number().optional()
31025
31908
  });
31026
31909
  var SetWidthReq = exports_external.object({ width: exports_external.number() });
31910
+ var RenameOptionReq = exports_external.object({ from: exports_external.string(), to: exports_external.string() });
31911
+ var RemoveOptionReq = exports_external.object({ name: exports_external.string() });
31027
31912
  var RecordValuesReq = exports_external.record(exports_external.string(), exports_external.any()).describe("Flat { column: value } cell patch (keyed by property name).");
31028
31913
  var CreateDocumentReq = exports_external.object({
31029
31914
  title: exports_external.string(),
@@ -31046,10 +31931,56 @@ var RevisionBase = exports_external.object({
31046
31931
  at: exports_external.string().describe("Wall-clock time of the revision (ISO 8601)"),
31047
31932
  node_id: exports_external.string(),
31048
31933
  kind: exports_external.enum(["user", "repair", "revert"]).describe("Source of the revision"),
31934
+ actor: exports_external.string().nullable().describe('Actor tag from the change group ("ai" = agent-driven CLI write)'),
31049
31935
  changes: exports_external.number(),
31050
31936
  created: exports_external.boolean(),
31051
31937
  deleted: exports_external.boolean()
31052
31938
  });
31939
+ var AuditEntitySchema = exports_external.object({
31940
+ dataset: exports_external.string(),
31941
+ id: exports_external.string(),
31942
+ label: exports_external.string().nullable(),
31943
+ database_id: exports_external.string().nullable(),
31944
+ database_label: exports_external.string().nullable(),
31945
+ created: exports_external.boolean(),
31946
+ deleted: exports_external.boolean(),
31947
+ fields: exports_external.number(),
31948
+ blocks_changed: exports_external.number(),
31949
+ blocks_deleted: exports_external.number()
31950
+ });
31951
+ var AuditEntryBase = exports_external.object({
31952
+ version: exports_external.string(),
31953
+ at: exports_external.string(),
31954
+ node_id: exports_external.string(),
31955
+ kind: exports_external.enum(["user", "repair", "revert"]),
31956
+ actor: exports_external.string().nullable(),
31957
+ txn: exports_external.string().nullable().describe("Change-group id; null for legacy display-only entries"),
31958
+ changes: exports_external.number()
31959
+ });
31960
+ var AuditPageSchema = exports_external.object({
31961
+ entries: exports_external.array(AuditEntryBase.extend({ entities: exports_external.array(AuditEntitySchema) })),
31962
+ next: exports_external.string().nullable().describe("Pass as `before` for the next (older) page")
31963
+ });
31964
+ var AuditDiffSchema = exports_external.object({
31965
+ col: exports_external.string(),
31966
+ label: exports_external.string(),
31967
+ before: exports_external.any().optional(),
31968
+ after: exports_external.any().optional()
31969
+ });
31970
+ var AuditEntryDetailSchema = AuditEntryBase.extend({
31971
+ entities: exports_external.array(AuditEntitySchema.extend({
31972
+ diffs: exports_external.array(AuditDiffSchema),
31973
+ block_diffs: exports_external.array(AuditDiffSchema)
31974
+ }))
31975
+ });
31976
+ var RevertGroupResultSchema = exports_external.object({
31977
+ txn: exports_external.string(),
31978
+ changed: exports_external.boolean(),
31979
+ restored_registers: exports_external.number(),
31980
+ skipped_registers: exports_external.number(),
31981
+ removed_rows: exports_external.number(),
31982
+ skipped_rows: exports_external.number()
31983
+ });
31053
31984
  var DocRevisionSchema = RevisionBase.extend({
31054
31985
  title_changed: exports_external.boolean(),
31055
31986
  blocks_changed: exports_external.number(),
@@ -31314,6 +32245,34 @@ var webuiRoutes = [
31314
32245
  });
31315
32246
  })
31316
32247
  },
32248
+ {
32249
+ method: "GET",
32250
+ path: "/api/audit",
32251
+ summary: "The global audit feed: every change group across the whole hub, newest first. " + "Query: ?limit=<n>&before=<cursor>&actor=<tag>",
32252
+ response: AuditPageSchema,
32253
+ handler: handle3((req, { db: db2 }) => {
32254
+ const limit = opt(req, "limit");
32255
+ return listAuditEntries(db2, {
32256
+ limit: limit ? Number(limit) : undefined,
32257
+ before: opt(req, "before") || undefined,
32258
+ actor: opt(req, "actor") || undefined
32259
+ });
32260
+ })
32261
+ },
32262
+ {
32263
+ method: "GET",
32264
+ path: "/api/audit/entry",
32265
+ summary: "Expand one audit entry with per-register before/after diffs. Query: ?txn=<id>",
32266
+ response: AuditEntryDetailSchema,
32267
+ handler: handle3((req, { db: db2 }) => auditEntryDetail(db2, need3(req, "txn")))
32268
+ },
32269
+ {
32270
+ method: "POST",
32271
+ path: "/api/audit/revert",
32272
+ summary: "Undo one change group as a new forward revision; registers overwritten since are kept. Query: ?txn=<id>",
32273
+ response: RevertGroupResultSchema,
32274
+ handler: handle3((req, { db: db2 }) => revertChangeGroup(db2, need3(req, "txn")))
32275
+ },
31317
32276
  {
31318
32277
  method: "GET",
31319
32278
  path: "/api/properties",
@@ -31335,7 +32294,7 @@ var webuiRoutes = [
31335
32294
  {
31336
32295
  method: "PATCH",
31337
32296
  path: "/api/property",
31338
- summary: "Update a property: rename, change type, edit config/options, reorder. Query: ?id=<id>",
32297
+ summary: "Update a property: rename, change type, edit config, reorder. `config` is merged key-wise into the current config (set a key to null to remove it). Query: ?id=<id>",
31339
32298
  request: UpdatePropertyReq,
31340
32299
  response: PropertySchema,
31341
32300
  handler: handle3(async (req, { db: db2 }) => {
@@ -31343,6 +32302,28 @@ var webuiRoutes = [
31343
32302
  return updateProperty(db2, need3(req, "id"), body);
31344
32303
  })
31345
32304
  },
32305
+ {
32306
+ method: "POST",
32307
+ path: "/api/property/option/rename",
32308
+ summary: "Rename a select/multi_select option and rewrite every cell using the old name. Query: ?id=<id>",
32309
+ request: RenameOptionReq,
32310
+ response: exports_external.object({ property: PropertySchema, renamed: exports_external.number() }),
32311
+ handler: handle3(async (req, { db: db2 }) => {
32312
+ const body = await req.json();
32313
+ return renameSelectOption(db2, need3(req, "id"), body.from, body.to);
32314
+ })
32315
+ },
32316
+ {
32317
+ method: "POST",
32318
+ path: "/api/property/option/remove",
32319
+ summary: "Remove a select/multi_select option and clear it from every cell using it. Query: ?id=<id>",
32320
+ request: RemoveOptionReq,
32321
+ response: exports_external.object({ property: PropertySchema, cleared: exports_external.number() }),
32322
+ handler: handle3(async (req, { db: db2 }) => {
32323
+ const body = await req.json();
32324
+ return removeSelectOption(db2, need3(req, "id"), body.name);
32325
+ })
32326
+ },
31346
32327
  {
31347
32328
  method: "PATCH",
31348
32329
  path: "/api/property/width",
@@ -31606,266 +32587,275 @@ var webuiRoutes = [
31606
32587
  handler: handle3((req, { db: db2 }) => {
31607
32588
  const limit = opt(req, "limit");
31608
32589
  return search(db2, need3(req, "q"), { limit: limit ? Number(limit) : undefined });
31609
- })
31610
- },
31611
- {
31612
- method: "GET",
31613
- path: "/api/blob-cache",
31614
- summary: "Local blob cache stats + clear policy + device/bucket roster (Settings storage panel). " + "A blob is clearable only once a presence verify confirmed a designated anchor holds it.",
31615
- response: BlobCacheSchema,
31616
- handler: handle3((_req, { db: db2 }) => blobCacheInfo(db2))
31617
- },
31618
- {
31619
- method: "POST",
31620
- path: "/api/blob-cache/verify",
31621
- summary: "Verify NOW which cached blobs the designated anchors durably hold (bucket LIST / " + "device /api/blobs/has), recording the per-blob `anchored` flag that gates clearing. " + "Returns the refreshed cache info incl. any unreachable anchors. Run on panel open / refresh.",
31622
- response: BlobCacheSchema,
31623
- handler: handle3(async (_req, { db: db2 }) => {
31624
- const r = await verifyAnchorPresence(db2);
31625
- return blobCacheInfo(db2, r.unreachable);
31626
- })
31627
- },
31628
- {
31629
- method: "POST",
31630
- path: "/api/blob-cache/clear",
31631
- summary: "Drop locally-cached blob bytes a full blob device durably holds (the reference stays; bytes re-download on demand). Returns bytes freed.",
31632
- response: ClearResultSchema,
31633
- handler: handle3((_req, { db: db2 }) => clearCache(db2))
31634
- },
31635
- {
31636
- method: "POST",
31637
- path: "/api/blob-cache/pin",
31638
- summary: "Pin/unpin a cached blob by hash (node-local; never synced). Pinned blobs are kept by both manual clear and automatic quota eviction.",
31639
- request: PinReq,
31640
- response: PinResSchema,
31641
- handler: handle3(async (req, { db: db2 }) => {
31642
- const body = await req.json();
31643
- reconcileCache(db2);
31644
- if (!setPinned(db2, body.hash, body.pinned))
31645
- throw new MhError("not_found", `blob not in cache: ${body.hash}`);
31646
- return { hash: body.hash, pinned: body.pinned };
31647
- })
31648
- },
31649
- {
31650
- method: "GET",
31651
- path: "/api/blobs",
31652
- summary: "Per-blob detail for the Settings blob manager: size, content type, last access, " + "and the pinned/pending/clearable/referenced flags the popup sorts, filters and acts on.",
31653
- response: BlobListSchema,
31654
- handler: handle3((_req, { db: db2 }) => blobList(db2))
31655
- },
31656
- {
31657
- method: "POST",
31658
- path: "/api/blobs/clear",
31659
- summary: "Drop bytes for a chosen subset of clearable blobs (the reference stays; bytes re-download on demand). " + "Pinned / non-clearable hashes are skipped. Returns bytes freed and skipped count.",
31660
- request: HashListReq,
31661
- response: ClearResultSchema,
31662
- handler: handle3(async (req, { db: db2 }) => {
31663
- const body = await req.json();
31664
- return clearBlobs(db2, body.hashes ?? []);
31665
- })
31666
- },
31667
- {
31668
- method: "POST",
31669
- path: "/api/blobs/delete",
31670
- summary: "Permanently delete a chosen subset of ORPHAN blobs (not referenced by any live document/site). " + "Still-referenced hashes are refused (skipped) so an in-use file is never removed. Returns bytes freed.",
31671
- request: HashListReq,
31672
- response: GcResultSchema,
31673
- handler: handle3(async (req, { db: db2 }) => {
31674
- const body = await req.json();
31675
- return deleteOrphanBlobs(db2, body.hashes ?? []);
31676
- })
31677
- },
31678
- {
31679
- method: "POST",
31680
- path: "/api/blob-policy",
31681
- summary: "Set the full blob device(s) and/or redundancy (all|any). Anchor designation only \u2014 clearing is decided locally per device.",
31682
- request: SetBlobPolicyReq,
31683
- response: SetBlobPolicyResSchema,
31684
- handler: handle3(async (req, { db: db2 }) => {
31685
- const body = await req.json();
31686
- if (body.full_nodes)
31687
- setFullNodes(db2, body.full_nodes);
31688
- if (body.redundancy)
31689
- setRedundancy(db2, body.redundancy);
31690
- return { policy: readPolicy(db2) };
31691
- })
31692
- },
31693
- ...shareRoutes,
31694
- ...siteHostingRoutes,
31695
- ...edgeRoutes
31696
- ];
31697
- export {
31698
- writeFileRow,
31699
- withTxnId,
31700
- withNodeId,
31701
- withChangeGroup,
31702
- webuiRoutes,
31703
- warmWebui,
31704
- verifyBlobBytes,
31705
- updateSite,
31706
- updateRecordPrepared,
31707
- updateRecord,
31708
- updateProperty,
31709
- updateDocument,
31710
- updateDatabase,
31711
- toBytes,
31712
- syncWithPeer,
31713
- startServer,
31714
- slugify,
31715
- siteLifecycle,
31716
- siteCacheControl,
31717
- sha256Hex,
31718
- setWebuiBundle,
31719
- setSitePublicGrants,
31720
- setPropertyWidth,
31721
- setNodeLabel,
31722
- setCurrentDatabase,
31723
- serveWebui,
31724
- serializeDocBlocks,
31725
- search,
31726
- runSchema,
31727
- resolveSiteFileRow,
31728
- resolveSite,
31729
- resolveRef,
31730
- resolveEntity,
31731
- resolveData,
31732
- resolveCandidates,
31733
- removeProperty,
31734
- reconcile,
31735
- rebuildSearchIndex,
31736
- randomSuffix,
31737
- putFileInline,
31738
- putFile,
31739
- putBlobAt,
31740
- putBlob,
31741
- publishDirectory,
31742
- prependDocument,
31743
- prepareRecordCells,
31744
- parseHlc,
31745
- parseDocBlocks,
31746
- openMetahub,
31747
- observeHlc,
31748
- normalizeSitePath,
31749
- normalizeSiteName,
31750
- nextHlc,
31751
- newId,
31752
- moveRecord,
31753
- moveDocument,
31754
- migrateSiteChannels,
31755
- migrateRecords,
31756
- migratePeers,
31757
- migrateOplog,
31758
- migrateDocuments,
31759
- migrateDocBlocks,
31760
- metahubHome,
31761
- maybeAutoIndex,
31762
- makeId,
31763
- loopbackUiRejection,
31764
- liveFileRowIfSame,
31765
- listSites,
31766
- listRecords,
31767
- listProperties,
31768
- listFiles,
31769
- listDocuments,
31770
- listDatabases,
31771
- keysBetween,
31772
- keyBetween,
31773
- isTextType,
31774
- isSitePublic,
31775
- isImageType,
31776
- initSchema,
31777
- ingest,
31778
- inferContentType,
31779
- idKind,
31780
- hasIndex,
31781
- grouped,
31782
- getSiteByName,
31783
- getSite,
31784
- getRecord,
31785
- getProperty,
31786
- getNodeLabel,
31787
- getNodeId,
31788
- getFileRow,
31789
- getFileMetaForServe,
31790
- getFileForServe,
31791
- getDocument,
31792
- getDatabase,
31793
- getCurrentDatabase,
31794
- getBlob,
31795
- ftsAvailable,
31796
- formatHlc,
31797
- fileSizeOf,
31798
- fileIdFor,
31799
- fileCounts,
31800
- fileCount,
31801
- errorCode,
31802
- ensurePropIndex,
31803
- ensureDirs,
31804
- emitFields,
31805
- emit,
31806
- editDocumentBatch,
31807
- editDocument,
31808
- duplicateDocument,
31809
- duplicateDatabase,
31810
- documentVersion,
31811
- displayNodes,
31812
- deleteSite,
31813
- deleteRecord,
31814
- deleteFile,
31815
- deleteDocument,
31816
- deleteDatabase,
31817
- deleteBlob,
31818
- decodeFileRow,
31819
- dbPath,
31820
- createSite,
31821
- createRecordPrepared,
31822
- createRecord,
31823
- createDocument,
31824
- createDatabase,
31825
- coerce,
31826
- clearCurrentDatabase,
31827
- changesSince,
31828
- changesAfterSeq,
31829
- cacheDir,
31830
- bytesToBase64,
31831
- blobPath,
31832
- blobHash,
31833
- blobExists,
31834
- base64ToBytes,
31835
- backfillRecordOrderKeys,
31836
- backfillDocumentOrderKeys,
31837
- applyChange,
31838
- appendDocument,
31839
- advanceAckedPrefix,
31840
- addProperty,
31841
- SyncResponseSchema,
31842
- SyncRequestSchema,
31843
- SYNC_PATH,
31844
- SITE_FILE_SELECT,
31845
- SITE_FILE_COLS,
31846
- SITE_COLS,
31847
- RENEW_PATH,
31848
- RECORD_META,
31849
- PortInUseError,
31850
- PairResponseSchema,
31851
- PairRequestSchema,
31852
- PROP_TYPES,
31853
- PROPERTY_COLS,
31854
- PAIR_PATH,
31855
- OPLOG_ONLY_DATASETS,
31856
- NOT_NULL_ZERO_COLS,
31857
- MhError,
31858
- MAX_HLC_COUNTER,
31859
- INLINE_LIMIT,
31860
- HealthResponseSchema,
31861
- HEALTH_PATH,
31862
- DOMAIN,
31863
- DOCUMENT_COLS,
31864
- DATABASE_COLS,
31865
- ChangeSchema,
31866
- CHANGE_SELECT,
32590
+ })
32591
+ },
32592
+ {
32593
+ method: "GET",
32594
+ path: "/api/blob-cache",
32595
+ summary: "Local blob cache stats + clear policy + device/bucket roster (Settings storage panel). " + "A blob is clearable only once a presence verify confirmed a designated anchor holds it.",
32596
+ response: BlobCacheSchema,
32597
+ handler: handle3((_req, { db: db2 }) => blobCacheInfo(db2))
32598
+ },
32599
+ {
32600
+ method: "POST",
32601
+ path: "/api/blob-cache/verify",
32602
+ summary: "Verify NOW which cached blobs the designated anchors durably hold (bucket LIST / " + "device /api/blobs/has), recording the per-blob `anchored` flag that gates clearing. " + "Returns the refreshed cache info incl. any unreachable anchors. Run on panel open / refresh.",
32603
+ response: BlobCacheSchema,
32604
+ handler: handle3(async (_req, { db: db2 }) => {
32605
+ const r = await verifyAnchorPresence(db2);
32606
+ return blobCacheInfo(db2, r.unreachable);
32607
+ })
32608
+ },
32609
+ {
32610
+ method: "POST",
32611
+ path: "/api/blob-cache/clear",
32612
+ summary: "Drop locally-cached blob bytes a full blob device durably holds (the reference stays; bytes re-download on demand). Returns bytes freed.",
32613
+ response: ClearResultSchema,
32614
+ handler: handle3((_req, { db: db2 }) => clearCache(db2))
32615
+ },
32616
+ {
32617
+ method: "POST",
32618
+ path: "/api/blob-cache/pin",
32619
+ summary: "Pin/unpin a cached blob by hash (node-local; never synced). Pinned blobs are kept by both manual clear and automatic quota eviction.",
32620
+ request: PinReq,
32621
+ response: PinResSchema,
32622
+ handler: handle3(async (req, { db: db2 }) => {
32623
+ const body = await req.json();
32624
+ reconcileCache(db2);
32625
+ if (!setPinned(db2, body.hash, body.pinned))
32626
+ throw new MhError("not_found", `blob not in cache: ${body.hash}`);
32627
+ return { hash: body.hash, pinned: body.pinned };
32628
+ })
32629
+ },
32630
+ {
32631
+ method: "GET",
32632
+ path: "/api/blobs",
32633
+ summary: "Per-blob detail for the Settings blob manager: size, content type, last access, " + "and the pinned/pending/clearable/referenced flags the popup sorts, filters and acts on.",
32634
+ response: BlobListSchema,
32635
+ handler: handle3((_req, { db: db2 }) => blobList(db2))
32636
+ },
32637
+ {
32638
+ method: "POST",
32639
+ path: "/api/blobs/clear",
32640
+ summary: "Drop bytes for a chosen subset of clearable blobs (the reference stays; bytes re-download on demand). " + "Pinned / non-clearable hashes are skipped. Returns bytes freed and skipped count.",
32641
+ request: HashListReq,
32642
+ response: ClearResultSchema,
32643
+ handler: handle3(async (req, { db: db2 }) => {
32644
+ const body = await req.json();
32645
+ return clearBlobs(db2, body.hashes ?? []);
32646
+ })
32647
+ },
32648
+ {
32649
+ method: "POST",
32650
+ path: "/api/blobs/delete",
32651
+ summary: "Permanently delete a chosen subset of ORPHAN blobs (not referenced by any live document/site). " + "Still-referenced hashes are refused (skipped) so an in-use file is never removed. Returns bytes freed.",
32652
+ request: HashListReq,
32653
+ response: GcResultSchema,
32654
+ handler: handle3(async (req, { db: db2 }) => {
32655
+ const body = await req.json();
32656
+ return deleteOrphanBlobs(db2, body.hashes ?? []);
32657
+ })
32658
+ },
32659
+ {
32660
+ method: "POST",
32661
+ path: "/api/blob-policy",
32662
+ summary: "Set the full blob device(s) and/or redundancy (all|any). Anchor designation only \u2014 clearing is decided locally per device.",
32663
+ request: SetBlobPolicyReq,
32664
+ response: SetBlobPolicyResSchema,
32665
+ handler: handle3(async (req, { db: db2 }) => {
32666
+ const body = await req.json();
32667
+ if (body.full_nodes)
32668
+ setFullNodes(db2, body.full_nodes);
32669
+ if (body.redundancy)
32670
+ setRedundancy(db2, body.redundancy);
32671
+ return { policy: readPolicy(db2) };
32672
+ })
32673
+ },
32674
+ ...shareRoutes,
32675
+ ...siteHostingRoutes,
32676
+ ...edgeRoutes,
32677
+ ...changesRoutes
32678
+ ];
32679
+ export {
32680
+ ACTOR_TAG_RE,
32681
+ BLOB_HASH_HEX,
31867
32682
  CHANGE_COLS,
31868
- BLOB_HASH_HEX
32683
+ CHANGE_SELECT,
32684
+ ChangeSchema,
32685
+ DATABASE_COLS,
32686
+ DOCUMENT_COLS,
32687
+ DOMAIN,
32688
+ HEALTH_PATH,
32689
+ HealthResponseSchema,
32690
+ INLINE_LIMIT,
32691
+ MAX_HLC_COUNTER,
32692
+ MhError,
32693
+ NOT_NULL_ZERO_COLS,
32694
+ OPLOG_ONLY_DATASETS,
32695
+ PAIR_PATH,
32696
+ PROPERTY_COLS,
32697
+ PROP_TYPES,
32698
+ PairRequestSchema,
32699
+ PairResponseSchema,
32700
+ PortInUseError,
32701
+ RECORD_META,
32702
+ RENEW_PATH,
32703
+ SITE_COLS,
32704
+ SITE_FILE_COLS,
32705
+ SITE_FILE_SELECT,
32706
+ SYNC_PATH,
32707
+ SyncRequestSchema,
32708
+ SyncResponseSchema,
32709
+ actorTag,
32710
+ addProperty,
32711
+ advanceAckedPrefix,
32712
+ appendDocument,
32713
+ applyChange,
32714
+ backfillDocumentOrderKeys,
32715
+ backfillRecordOrderKeys,
32716
+ base64ToBytes,
32717
+ blobExists,
32718
+ blobHash,
32719
+ blobPath,
32720
+ bytesToBase64,
32721
+ cacheDir,
32722
+ changesAfterSeq,
32723
+ changesSince,
32724
+ clearCurrentDatabase,
32725
+ coerce,
32726
+ createDatabase,
32727
+ createDocument,
32728
+ createRecord,
32729
+ createRecordPrepared,
32730
+ createSite,
32731
+ dbPath,
32732
+ decodeFileRow,
32733
+ deleteBlob,
32734
+ deleteDatabase,
32735
+ deleteDocument,
32736
+ deleteFile,
32737
+ deleteRecord,
32738
+ deleteSite,
32739
+ displayNodes,
32740
+ documentTitleMap,
32741
+ documentVersion,
32742
+ duplicateDatabase,
32743
+ duplicateDocument,
32744
+ editDocument,
32745
+ editDocumentBatch,
32746
+ emit,
32747
+ emitFields,
32748
+ ensureDirs,
32749
+ ensurePropIndex,
32750
+ errorCode,
32751
+ fileCount,
32752
+ fileCounts,
32753
+ fileIdFor,
32754
+ fileSizeOf,
32755
+ formatHlc,
32756
+ ftsAvailable,
32757
+ getBlob,
32758
+ getCurrentDatabase,
32759
+ getDatabase,
32760
+ getDocument,
32761
+ getFileForServe,
32762
+ getFileMetaForServe,
32763
+ getFileRow,
32764
+ getNodeId,
32765
+ getNodeLabel,
32766
+ getProperty,
32767
+ getRecord,
32768
+ getSite,
32769
+ getSiteByName,
32770
+ grouped,
32771
+ hasIndex,
32772
+ idKind,
32773
+ inferContentType,
32774
+ ingest,
32775
+ initSchema,
32776
+ isImageType,
32777
+ isSitePublic,
32778
+ isTextType,
32779
+ keyBetween,
32780
+ keysBetween,
32781
+ listDatabases,
32782
+ listDocuments,
32783
+ listFiles,
32784
+ listProperties,
32785
+ listRecords,
32786
+ listSites,
32787
+ liveFileRowIfSame,
32788
+ loopbackUiRejection,
32789
+ makeId,
32790
+ maybeAutoIndex,
32791
+ metahubHome,
32792
+ migrateDocBlocks,
32793
+ migrateDocuments,
32794
+ migrateOplog,
32795
+ migratePeers,
32796
+ migrateRecords,
32797
+ migrateSiteChannels,
32798
+ moveDocument,
32799
+ moveRecord,
32800
+ newId,
32801
+ nextHlc,
32802
+ normalizeSiteName,
32803
+ normalizeSitePath,
32804
+ observeHlc,
32805
+ openMetahub,
32806
+ parseDocBlocks,
32807
+ parseHlc,
32808
+ prepareRecordCells,
32809
+ prependDocument,
32810
+ publishDirectory,
32811
+ putBlob,
32812
+ putBlobAt,
32813
+ putFile,
32814
+ putFileInline,
32815
+ randomSuffix,
32816
+ rebuildSearchIndex,
32817
+ reconcile,
32818
+ recordTitleMap,
32819
+ removeProperty,
32820
+ removeSelectOption,
32821
+ renameSelectOption,
32822
+ resolveCandidates,
32823
+ resolveData,
32824
+ resolveEntity,
32825
+ resolveRef,
32826
+ resolveSite,
32827
+ resolveSiteFileRow,
32828
+ runSchema,
32829
+ search,
32830
+ serializeDocBlocks,
32831
+ serveWebui,
32832
+ setActorTag,
32833
+ setCurrentDatabase,
32834
+ setNodeLabel,
32835
+ setPropertyWidth,
32836
+ setSitePublicGrants,
32837
+ setWebuiBundle,
32838
+ sha256Hex,
32839
+ siteCacheControl,
32840
+ siteLifecycle,
32841
+ slugify,
32842
+ startServer,
32843
+ syncWithPeer,
32844
+ titlePropId,
32845
+ toBytes,
32846
+ updateDatabase,
32847
+ updateDocument,
32848
+ updateProperty,
32849
+ updateRecord,
32850
+ updateRecordPrepared,
32851
+ updateSite,
32852
+ verifyBlobBytes,
32853
+ warmWebui,
32854
+ webuiRoutes,
32855
+ withChangeGroup,
32856
+ withNodeId,
32857
+ withTxnId,
32858
+ writeFileRow
31869
32859
  };
31870
32860
 
31871
- //# debugId=DA3A2F257B2F30C464756E2164756E21
32861
+ //# debugId=3750093FAAD260D064756E2164756E21