@tensorix/metahub 0.4.1 → 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 +2311 -1633
  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 +1 -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 +74 -26
  29. package/dist/index.js +2267 -1423
  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 +178 -174
  47. package/package.json +1 -1
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;
@@ -975,6 +985,7 @@ var init_properties = __esm(() => {
975
985
  "multi_select",
976
986
  "date",
977
987
  "relation",
988
+ "doc",
978
989
  "url"
979
990
  ]);
980
991
  PROPERTY_COLS = ["id", "database_id", "name", "type", "config", "position"];
@@ -992,7 +1003,7 @@ var init_properties = __esm(() => {
992
1003
  emit(db, "properties", id, "type", opts.type);
993
1004
  emit(db, "properties", id, "config", config);
994
1005
  emit(db, "properties", id, "position", opts.position ?? nextPosition(db, databaseId));
995
- if (opts.type === "relation" || opts.indexed === true)
1006
+ if (opts.type === "relation" || opts.type === "doc" || opts.indexed === true)
996
1007
  ensurePropIndex(db, databaseId, id);
997
1008
  return getProperty(db, id);
998
1009
  });
@@ -1166,19 +1177,38 @@ var init_databases = __esm(() => {
1166
1177
  emit(db, "databases", dup.id, "meta", meta);
1167
1178
  }
1168
1179
  const propIdMap = new Map;
1180
+ const selfRelNew = new Set;
1169
1181
  for (const p of listProperties(db, id)) {
1170
- 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;
1171
1184
  const np = addProperty(db, dup.id, { name: p.name, type: p.type, config, position: p.position });
1172
1185
  propIdMap.set(p.id, np.id);
1186
+ if (self)
1187
+ selfRelNew.add(np.id);
1173
1188
  }
1174
- for (const r of listRecords(db, id)) {
1189
+ const srcRecords = listRecords(db, id);
1190
+ const recIdMap = new Map;
1191
+ for (const r of srcRecords) {
1175
1192
  const data = {};
1176
1193
  for (const [pid, v] of Object.entries(r.cells)) {
1177
1194
  const nid = propIdMap.get(pid);
1178
- if (nid)
1179
- 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);
1180
1209
  }
1181
- createRecord(db, dup.id, data);
1210
+ if (Object.keys(patch).length)
1211
+ updateRecord(db, recIdMap.get(r.id), patch);
1182
1212
  }
1183
1213
  return getDatabase(db, dup.id);
1184
1214
  });
@@ -1365,6 +1395,20 @@ function resolveRelation(db, prop, value) {
1365
1395
  }
1366
1396
  throw new MhError("ambiguous", `${prop.name}: ambiguous relation "${value}" (${cands.length} matches); use a full id`);
1367
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
+ }
1368
1412
  function coerce(db, prop, value) {
1369
1413
  switch (prop.type) {
1370
1414
  case "text":
@@ -1413,6 +1457,10 @@ function coerce(db, prop, value) {
1413
1457
  const arr = value === null ? [] : Array.isArray(value) ? value : [value];
1414
1458
  return arr.map((v) => resolveRelation(db, prop, String(v)));
1415
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
+ }
1416
1464
  }
1417
1465
  }
1418
1466
  function propsByName(props) {
@@ -1564,6 +1612,17 @@ function listRecords(db, databaseId, opts = {}) {
1564
1612
  }
1565
1613
  return rows;
1566
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
+ }
1567
1626
  var backfillRecordOrderKeys, createRecordPrepared, createRecord, moveRecord, updateRecordPrepared, updateRecord, deleteRecord;
1568
1627
  var init_records = __esm(() => {
1569
1628
  init_ids();
@@ -1634,11 +1693,16 @@ var init_records = __esm(() => {
1634
1693
  return getRecord(db, id);
1635
1694
  });
1636
1695
  updateRecordPrepared = grouped(function updateRecordPrepared2(db, id, cells) {
1637
- 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);
1638
1697
  if (!rec)
1639
1698
  throw new MhError("not_found", `no such record: ${id}`);
1640
- for (const { prop, value } of cells)
1641
- 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
+ }
1642
1706
  return getRecord(db, id);
1643
1707
  });
1644
1708
  updateRecord = grouped(function updateRecord2(db, id, data) {
@@ -1728,6 +1792,14 @@ function listDocuments(db, opts = {}) {
1728
1792
  return db.query(`${cols} AND database_id = ? ${ORDER_BY}`).all(opts.database_id);
1729
1793
  return db.query(`${cols} ${ORDER_BY}`).all();
1730
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
+ }
1731
1803
  function siblingWhere(parentId) {
1732
1804
  return parentId === null ? { clause: "parent_id IS NULL", args: [] } : { clause: "parent_id = ?", args: [parentId] };
1733
1805
  }
@@ -2603,29 +2675,33 @@ function liveRowCount(db, databaseId) {
2603
2675
  }
2604
2676
  function assertRelationAllowed(set, principalKind, prop) {
2605
2677
  if (principalKind === "public")
2606
- 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)`);
2607
2681
  const target = prop.config?.database;
2608
2682
  if (!target || !grantFor(set, target))
2609
2683
  throw new MhError("invalid_input", `${prop.name}: relation target database is not in this share's grants`);
2610
2684
  }
2685
+ function isLiveRefValue(prop, value) {
2686
+ return (prop.type === "relation" || prop.type === "doc") && value != null && !(Array.isArray(value) && value.length === 0);
2687
+ }
2611
2688
  function assertGuestPayload(db, set, principal, database, values, opts = {}) {
2612
2689
  const limits = opts.limits ?? GUEST_LIMITS;
2613
2690
  const entries = Object.entries(values);
2614
2691
  if (entries.length > limits.maxCells)
2615
2692
  throw new MhError("invalid_input", `too many cells (max ${limits.maxCells})`);
2616
2693
  const props = listProperties(db, database.id);
2617
- const resolved = resolveData(props, values).map(({ prop, value }) => ({
2618
- prop,
2619
- value: coerce(db, prop, value)
2620
- }));
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
+ });
2621
2699
  let total = 0;
2622
2700
  for (const { prop, value } of resolved) {
2623
2701
  const size = utf8Len(JSON.stringify(value ?? null));
2624
2702
  if (size > limits.maxValueBytes)
2625
2703
  throw new MhError("invalid_input", `${prop.name}: value too large (max ${limits.maxValueBytes} bytes)`);
2626
2704
  total += size;
2627
- if (prop.type === "relation" && value != null && !(Array.isArray(value) && value.length === 0))
2628
- assertRelationAllowed(set, principal.kind, prop);
2629
2705
  }
2630
2706
  if (total > limits.maxBodyBytes)
2631
2707
  throw new MhError("invalid_input", `payload too large (max ${limits.maxBodyBytes} bytes)`);
@@ -2695,7 +2771,7 @@ function checkGuestChanges(db, set, guestNode, changes, principalKind = "public"
2695
2771
  if (utf8Len(c.value ?? "") > limits.maxValueBytes)
2696
2772
  throw new MhError("invalid_input", `${prop.name}: value too large (max ${limits.maxValueBytes} bytes)`);
2697
2773
  const value = c.value == null ? null : JSON.parse(c.value);
2698
- if (prop.type === "relation" && value != null && !(Array.isArray(value) && value.length === 0))
2774
+ if (isLiveRefValue(prop, value))
2699
2775
  assertRelationAllowed(set, principalKind, prop);
2700
2776
  coerce(db, prop, value);
2701
2777
  }
@@ -3131,69 +3207,69 @@ var init_core = __esm(() => {
3131
3207
  // node_modules/zod/v4/core/util.js
3132
3208
  var exports_util = {};
3133
3209
  __export(exports_util, {
3134
- unwrapMessage: () => unwrapMessage,
3135
- uint8ArrayToHex: () => uint8ArrayToHex,
3136
- uint8ArrayToBase64url: () => uint8ArrayToBase64url,
3137
- uint8ArrayToBase64: () => uint8ArrayToBase64,
3138
- stringifyPrimitive: () => stringifyPrimitive,
3139
- slugify: () => slugify2,
3140
- shallowClone: () => shallowClone,
3141
- safeExtend: () => safeExtend,
3142
- required: () => required,
3143
- randomString: () => randomString,
3144
- propertyKeyTypes: () => propertyKeyTypes,
3145
- promiseAllObject: () => promiseAllObject,
3146
- primitiveTypes: () => primitiveTypes,
3147
- prefixIssues: () => prefixIssues,
3148
- pick: () => pick,
3149
- partial: () => partial,
3150
- parsedType: () => parsedType,
3151
- optionalKeys: () => optionalKeys,
3152
- omit: () => omit,
3153
- objectClone: () => objectClone,
3154
- numKeys: () => numKeys,
3155
- nullish: () => nullish,
3156
- normalizeParams: () => normalizeParams,
3157
- mergeDefs: () => mergeDefs,
3158
- merge: () => merge,
3159
- jsonStringifyReplacer: () => jsonStringifyReplacer,
3160
- joinValues: () => joinValues,
3161
- issue: () => issue,
3162
- isPlainObject: () => isPlainObject,
3163
- isObject: () => isObject,
3164
- hexToUint8Array: () => hexToUint8Array,
3165
- getSizableOrigin: () => getSizableOrigin,
3166
- getParsedType: () => getParsedType,
3167
- getLengthableOrigin: () => getLengthableOrigin,
3168
- getEnumValues: () => getEnumValues,
3169
- getElementAtPath: () => getElementAtPath,
3170
- floatSafeRemainder: () => floatSafeRemainder,
3171
- finalizeIssue: () => finalizeIssue,
3172
- extend: () => extend,
3173
- explicitlyAborted: () => explicitlyAborted,
3174
- escapeRegex: () => escapeRegex,
3175
- esc: () => esc,
3176
- defineLazy: () => defineLazy,
3177
- createTransparentProxy: () => createTransparentProxy,
3178
- cloneDef: () => cloneDef,
3179
- clone: () => clone,
3180
- cleanRegex: () => cleanRegex,
3181
- cleanEnum: () => cleanEnum,
3182
- captureStackTrace: () => captureStackTrace,
3183
- cached: () => cached,
3184
- base64urlToUint8Array: () => base64urlToUint8Array,
3185
- base64ToUint8Array: () => base64ToUint8Array,
3186
- assignProp: () => assignProp,
3187
- assertNotEqual: () => assertNotEqual,
3188
- assertNever: () => assertNever,
3189
- assertIs: () => assertIs,
3190
- assertEqual: () => assertEqual,
3191
- assert: () => assert,
3192
- allowsEval: () => allowsEval,
3193
- aborted: () => aborted,
3194
- NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES,
3210
+ BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
3195
3211
  Class: () => Class,
3196
- 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
3197
3273
  });
3198
3274
  function assertEqual(val) {
3199
3275
  return val;
@@ -4052,109 +4128,109 @@ var init_parse = __esm(() => {
4052
4128
  // node_modules/zod/v4/core/regexes.js
4053
4129
  var exports_regexes = {};
4054
4130
  __export(exports_regexes, {
4055
- xid: () => xid,
4056
- uuid7: () => uuid7,
4057
- uuid6: () => uuid6,
4058
- uuid4: () => uuid4,
4059
- uuid: () => uuid,
4060
- uppercase: () => uppercase,
4061
- unicodeEmail: () => unicodeEmail,
4062
- undefined: () => _undefined,
4063
- ulid: () => ulid,
4064
- time: () => time,
4065
- string: () => string,
4066
- sha512_hex: () => sha512_hex,
4067
- sha512_base64url: () => sha512_base64url,
4068
- sha512_base64: () => sha512_base64,
4069
- sha384_hex: () => sha384_hex,
4070
- sha384_base64url: () => sha384_base64url,
4071
- sha384_base64: () => sha384_base64,
4072
- sha256_hex: () => sha256_hex,
4073
- sha256_base64url: () => sha256_base64url,
4074
- sha256_base64: () => sha256_base64,
4075
- sha1_hex: () => sha1_hex,
4076
- sha1_base64url: () => sha1_base64url,
4077
- sha1_base64: () => sha1_base64,
4078
- rfc5322Email: () => rfc5322Email,
4079
- number: () => number,
4080
- null: () => _null,
4081
- nanoid: () => nanoid,
4082
- md5_hex: () => md5_hex,
4083
- md5_base64url: () => md5_base64url,
4084
- md5_base64: () => md5_base64,
4085
- mac: () => mac,
4086
- lowercase: () => lowercase,
4087
- ksuid: () => ksuid,
4088
- ipv6: () => ipv6,
4089
- ipv4: () => ipv4,
4090
- integer: () => integer,
4091
- idnEmail: () => idnEmail,
4092
- httpProtocol: () => httpProtocol,
4093
- html5Email: () => html5Email,
4094
- hostname: () => hostname,
4095
- hex: () => hex,
4096
- guid: () => guid,
4097
- extendedDuration: () => extendedDuration,
4098
- emoji: () => emoji,
4099
- email: () => email,
4100
- e164: () => e164,
4101
- duration: () => duration,
4102
- domain: () => domain,
4103
- datetime: () => datetime,
4104
- date: () => date,
4105
- cuid2: () => cuid2,
4106
- cuid: () => cuid,
4107
- cidrv6: () => cidrv6,
4108
- cidrv4: () => cidrv4,
4109
- browserEmail: () => browserEmail,
4110
- boolean: () => boolean,
4111
- bigint: () => bigint,
4131
+ base64: () => base64,
4112
4132
  base64url: () => base64url,
4113
- base64: () => base64
4114
- });
4115
- function emoji() {
4116
- return new RegExp(_emoji, "u");
4117
- }
4118
- function timeSource(args) {
4119
- const hhmm = `(?:[01]\\d|2[0-3]):[0-5]\\d`;
4120
- 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+)?)?`;
4121
- return regex;
4122
- }
4123
- function time(args) {
4124
- return new RegExp(`^${timeSource(args)}$`);
4125
- }
4126
- function datetime(args) {
4127
- const time2 = timeSource({ precision: args.precision });
4128
- const opts = ["Z"];
4129
- if (args.local)
4130
- opts.push("");
4131
- if (args.offset)
4132
- opts.push(`([+-](?:[01]\\d|2[0-3]):[0-5]\\d)`);
4133
- const timeRegex = `${time2}(?:${opts.join("|")})`;
4134
- return new RegExp(`^${dateSource}T(?:${timeRegex})$`);
4135
- }
4136
- function fixedBase64(bodyLength, padding) {
4137
- return new RegExp(`^[A-Za-z0-9+/]{${bodyLength}}${padding}$`);
4138
- }
4139
- function fixedBase64url(length) {
4140
- return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);
4141
- }
4142
- var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, extendedDuration, guid, uuid = (version) => {
4143
- if (!version)
4144
- return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
4145
- return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
4146
- }, uuid4, uuid6, uuid7, email, html5Email, rfc5322Email, unicodeEmail, idnEmail, browserEmail, _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`, ipv4, ipv6, mac = (delimiter) => {
4147
- const escapedDelim = escapeRegex(delimiter ?? ":");
4148
- return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
4149
- }, cidrv4, cidrv6, base64, base64url, hostname, domain, httpProtocol, e164, dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`, date, string = (params) => {
4150
- const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
4151
- return new RegExp(`^${regex}$`);
4152
- }, bigint, integer, number, boolean, _null, _undefined, lowercase, uppercase, hex, md5_hex, md5_base64, md5_base64url, sha1_hex, sha1_base64, sha1_base64url, sha256_hex, sha256_base64, sha256_base64url, sha384_hex, sha384_base64, sha384_base64url, sha512_hex, sha512_base64, sha512_base64url;
4153
- var init_regexes = __esm(() => {
4154
- init_util();
4155
- cuid = /^[cC][0-9a-z]{6,}$/;
4156
- cuid2 = /^[0-9a-z]+$/;
4157
- ulid = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/;
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
+ }
4215
+ function fixedBase64url(length) {
4216
+ return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);
4217
+ }
4218
+ var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, extendedDuration, guid, uuid = (version) => {
4219
+ if (!version)
4220
+ return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
4221
+ return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
4222
+ }, uuid4, uuid6, uuid7, email, html5Email, rfc5322Email, unicodeEmail, idnEmail, browserEmail, _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`, ipv4, ipv6, mac = (delimiter) => {
4223
+ const escapedDelim = escapeRegex(delimiter ?? ":");
4224
+ return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
4225
+ }, cidrv4, cidrv6, base64, base64url, hostname, domain, httpProtocol, e164, dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`, date, string = (params) => {
4226
+ const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
4227
+ return new RegExp(`^${regex}$`);
4228
+ }, bigint, integer, number, boolean, _null, _undefined, lowercase, uppercase, hex, md5_hex, md5_base64, md5_base64url, sha1_hex, sha1_base64, sha1_base64url, sha256_hex, sha256_base64, sha256_base64url, sha384_hex, sha384_base64, sha384_base64url, sha512_hex, sha512_base64, sha512_base64url;
4229
+ var init_regexes = __esm(() => {
4230
+ init_util();
4231
+ cuid = /^[cC][0-9a-z]{6,}$/;
4232
+ cuid2 = /^[0-9a-z]+$/;
4233
+ ulid = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/;
4158
4234
  xid = /^[0-9a-vA-V]{20}$/;
4159
4235
  ksuid = /^[A-Za-z0-9]{27}$/;
4160
4236
  nanoid = /^[a-zA-Z0-9_-]{21}$/;
@@ -12955,58 +13031,58 @@ var init_yo = __esm(() => {
12955
13031
  // node_modules/zod/v4/locales/index.js
12956
13032
  var exports_locales = {};
12957
13033
  __export(exports_locales, {
12958
- zhTW: () => zh_TW_default,
12959
- zhCN: () => zh_CN_default,
12960
- yo: () => yo_default,
12961
- vi: () => vi_default,
12962
- uz: () => uz_default,
12963
- ur: () => ur_default,
12964
- uk: () => uk_default,
12965
- ua: () => ua_default,
12966
- tr: () => tr_default,
12967
- th: () => th_default,
12968
- ta: () => ta_default,
12969
- sv: () => sv_default,
12970
- sl: () => sl_default,
12971
- ru: () => ru_default,
12972
- ro: () => ro_default,
12973
- pt: () => pt_default,
12974
- ps: () => ps_default,
12975
- pl: () => pl_default,
12976
- ota: () => ota_default,
12977
- no: () => no_default,
12978
- nl: () => nl_default,
12979
- ms: () => ms_default,
12980
- mk: () => mk_default,
12981
- lt: () => lt_default,
12982
- ko: () => ko_default,
12983
- km: () => km_default,
12984
- kh: () => kh_default,
12985
- ka: () => ka_default,
12986
- ja: () => ja_default,
12987
- it: () => it_default,
12988
- is: () => is_default,
12989
- id: () => id_default,
12990
- hy: () => hy_default,
12991
- hu: () => hu_default,
12992
- hr: () => hr_default,
12993
- he: () => he_default,
12994
- frCA: () => fr_CA_default,
12995
- fr: () => fr_default,
12996
- fi: () => fi_default,
12997
- fa: () => fa_default,
12998
- es: () => es_default,
12999
- eo: () => eo_default,
13000
- en: () => en_default,
13001
- el: () => el_default,
13002
- de: () => de_default,
13003
- da: () => da_default,
13004
- cs: () => cs_default,
13005
- ca: () => ca_default,
13006
- bg: () => bg_default,
13007
- be: () => be_default,
13034
+ ar: () => ar_default,
13008
13035
  az: () => az_default,
13009
- 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
13010
13086
  });
13011
13087
  var init_locales = __esm(() => {
13012
13088
  init_ar();
@@ -14974,331 +15050,331 @@ var init_json_schema = () => {};
14974
15050
  // node_modules/zod/v4/core/index.js
14975
15051
  var exports_core2 = {};
14976
15052
  __export(exports_core2, {
14977
- version: () => version,
14978
- util: () => exports_util,
14979
- treeifyError: () => treeifyError,
14980
- toJSONSchema: () => toJSONSchema,
14981
- toDotPath: () => toDotPath,
14982
- safeParseAsync: () => safeParseAsync,
14983
- safeParse: () => safeParse,
14984
- safeEncodeAsync: () => safeEncodeAsync,
14985
- safeEncode: () => safeEncode,
14986
- safeDecodeAsync: () => safeDecodeAsync,
14987
- safeDecode: () => safeDecode,
14988
- registry: () => registry,
14989
- regexes: () => exports_regexes,
14990
- process: () => process2,
14991
- prettifyError: () => prettifyError,
14992
- parseAsync: () => parseAsync,
14993
- parse: () => parse,
14994
- meta: () => meta,
14995
- locales: () => exports_locales,
14996
- isValidJWT: () => isValidJWT,
14997
- isValidBase64URL: () => isValidBase64URL,
14998
- isValidBase64: () => isValidBase64,
14999
- initializeContext: () => initializeContext,
15000
- globalRegistry: () => globalRegistry,
15001
- globalConfig: () => globalConfig,
15002
- formatError: () => formatError,
15003
- flattenError: () => flattenError,
15004
- finalize: () => finalize,
15005
- extractDefs: () => extractDefs,
15006
- encodeAsync: () => encodeAsync,
15007
- encode: () => encode,
15008
- describe: () => describe,
15009
- decodeAsync: () => decodeAsync,
15010
- decode: () => decode,
15011
- createToJSONSchemaMethod: () => createToJSONSchemaMethod,
15012
- createStandardJSONSchemaMethod: () => createStandardJSONSchemaMethod,
15013
- config: () => config,
15014
- clone: () => clone,
15015
- _xor: () => _xor,
15016
- _xid: () => _xid,
15017
- _void: () => _void,
15018
- _uuidv7: () => _uuidv7,
15019
- _uuidv6: () => _uuidv6,
15020
- _uuidv4: () => _uuidv4,
15021
- _uuid: () => _uuid,
15022
- _url: () => _url,
15023
- _uppercase: () => _uppercase,
15024
- _unknown: () => _unknown,
15025
- _union: () => _union,
15026
- _undefined: () => _undefined2,
15027
- _ulid: () => _ulid,
15028
- _uint64: () => _uint64,
15029
- _uint32: () => _uint32,
15030
- _tuple: () => _tuple,
15031
- _trim: () => _trim,
15032
- _transform: () => _transform,
15033
- _toUpperCase: () => _toUpperCase,
15034
- _toLowerCase: () => _toLowerCase,
15035
- _templateLiteral: () => _templateLiteral,
15036
- _symbol: () => _symbol,
15037
- _superRefine: () => _superRefine,
15038
- _success: () => _success,
15039
- _stringbool: () => _stringbool,
15040
- _stringFormat: () => _stringFormat,
15041
- _string: () => _string,
15042
- _startsWith: () => _startsWith,
15043
- _slugify: () => _slugify,
15044
- _size: () => _size,
15045
- _set: () => _set,
15046
- _safeParseAsync: () => _safeParseAsync,
15047
- _safeParse: () => _safeParse,
15048
- _safeEncodeAsync: () => _safeEncodeAsync,
15049
- _safeEncode: () => _safeEncode,
15050
- _safeDecodeAsync: () => _safeDecodeAsync,
15051
- _safeDecode: () => _safeDecode,
15052
- _regex: () => _regex,
15053
- _refine: () => _refine,
15054
- _record: () => _record,
15055
- _readonly: () => _readonly,
15056
- _property: () => _property,
15057
- _promise: () => _promise,
15058
- _positive: () => _positive,
15059
- _pipe: () => _pipe,
15060
- _parseAsync: () => _parseAsync,
15061
- _parse: () => _parse,
15062
- _overwrite: () => _overwrite,
15063
- _optional: () => _optional,
15064
- _number: () => _number,
15065
- _nullable: () => _nullable,
15066
- _null: () => _null2,
15067
- _normalize: () => _normalize,
15068
- _nonpositive: () => _nonpositive,
15069
- _nonoptional: () => _nonoptional,
15070
- _nonnegative: () => _nonnegative,
15071
- _never: () => _never,
15072
- _negative: () => _negative,
15073
- _nativeEnum: () => _nativeEnum,
15074
- _nanoid: () => _nanoid,
15075
- _nan: () => _nan,
15076
- _multipleOf: () => _multipleOf,
15077
- _minSize: () => _minSize,
15078
- _minLength: () => _minLength,
15079
- _min: () => _gte,
15080
- _mime: () => _mime,
15081
- _maxSize: () => _maxSize,
15082
- _maxLength: () => _maxLength,
15083
- _max: () => _lte,
15084
- _map: () => _map,
15085
- _mac: () => _mac,
15086
- _lte: () => _lte,
15087
- _lt: () => _lt,
15088
- _lowercase: () => _lowercase,
15089
- _literal: () => _literal,
15090
- _length: () => _length,
15091
- _lazy: () => _lazy,
15092
- _ksuid: () => _ksuid,
15093
- _jwt: () => _jwt,
15094
- _isoTime: () => _isoTime,
15095
- _isoDuration: () => _isoDuration,
15096
- _isoDateTime: () => _isoDateTime,
15097
- _isoDate: () => _isoDate,
15098
- _ipv6: () => _ipv6,
15099
- _ipv4: () => _ipv4,
15100
- _intersection: () => _intersection,
15101
- _int64: () => _int64,
15102
- _int32: () => _int32,
15103
- _int: () => _int,
15104
- _includes: () => _includes,
15105
- _guid: () => _guid,
15106
- _gte: () => _gte,
15107
- _gt: () => _gt,
15108
- _float64: () => _float64,
15109
- _float32: () => _float32,
15110
- _file: () => _file,
15111
- _enum: () => _enum,
15112
- _endsWith: () => _endsWith,
15113
- _encodeAsync: () => _encodeAsync,
15114
- _encode: () => _encode,
15115
- _emoji: () => _emoji2,
15116
- _email: () => _email,
15117
- _e164: () => _e164,
15118
- _discriminatedUnion: () => _discriminatedUnion,
15119
- _default: () => _default,
15120
- _decodeAsync: () => _decodeAsync,
15121
- _decode: () => _decode,
15122
- _date: () => _date,
15123
- _custom: () => _custom,
15124
- _cuid2: () => _cuid2,
15125
- _cuid: () => _cuid,
15126
- _coercedString: () => _coercedString,
15127
- _coercedNumber: () => _coercedNumber,
15128
- _coercedDate: () => _coercedDate,
15129
- _coercedBoolean: () => _coercedBoolean,
15130
- _coercedBigint: () => _coercedBigint,
15131
- _cidrv6: () => _cidrv6,
15132
- _cidrv4: () => _cidrv4,
15133
- _check: () => _check,
15134
- _catch: () => _catch,
15135
- _boolean: () => _boolean,
15136
- _bigint: () => _bigint,
15137
- _base64url: () => _base64url,
15138
- _base64: () => _base64,
15139
- _array: () => _array,
15140
- _any: () => _any,
15141
- TimePrecision: () => TimePrecision,
15142
- NEVER: () => NEVER,
15143
- JSONSchemaGenerator: () => JSONSchemaGenerator,
15144
- JSONSchema: () => exports_json_schema,
15145
- Doc: () => Doc,
15146
- $output: () => $output,
15147
- $input: () => $input,
15148
- $constructor: () => $constructor,
15149
- $brand: () => $brand,
15150
- $ZodXor: () => $ZodXor,
15151
- $ZodXID: () => $ZodXID,
15152
- $ZodVoid: () => $ZodVoid,
15153
- $ZodUnknown: () => $ZodUnknown,
15154
- $ZodUnion: () => $ZodUnion,
15155
- $ZodUndefined: () => $ZodUndefined,
15156
- $ZodUUID: () => $ZodUUID,
15157
- $ZodURL: () => $ZodURL,
15158
- $ZodULID: () => $ZodULID,
15159
- $ZodType: () => $ZodType,
15160
- $ZodTuple: () => $ZodTuple,
15161
- $ZodTransform: () => $ZodTransform,
15162
- $ZodTemplateLiteral: () => $ZodTemplateLiteral,
15163
- $ZodSymbol: () => $ZodSymbol,
15164
- $ZodSuccess: () => $ZodSuccess,
15165
- $ZodStringFormat: () => $ZodStringFormat,
15166
- $ZodString: () => $ZodString,
15167
- $ZodSet: () => $ZodSet,
15168
- $ZodRegistry: () => $ZodRegistry,
15169
- $ZodRecord: () => $ZodRecord,
15170
- $ZodRealError: () => $ZodRealError,
15171
- $ZodReadonly: () => $ZodReadonly,
15172
- $ZodPromise: () => $ZodPromise,
15173
- $ZodPreprocess: () => $ZodPreprocess,
15174
- $ZodPrefault: () => $ZodPrefault,
15175
- $ZodPipe: () => $ZodPipe,
15176
- $ZodOptional: () => $ZodOptional,
15177
- $ZodObjectJIT: () => $ZodObjectJIT,
15178
- $ZodObject: () => $ZodObject,
15179
- $ZodNumberFormat: () => $ZodNumberFormat,
15180
- $ZodNumber: () => $ZodNumber,
15181
- $ZodNullable: () => $ZodNullable,
15182
- $ZodNull: () => $ZodNull,
15183
- $ZodNonOptional: () => $ZodNonOptional,
15184
- $ZodNever: () => $ZodNever,
15185
- $ZodNanoID: () => $ZodNanoID,
15186
- $ZodNaN: () => $ZodNaN,
15187
- $ZodMap: () => $ZodMap,
15188
- $ZodMAC: () => $ZodMAC,
15189
- $ZodLiteral: () => $ZodLiteral,
15190
- $ZodLazy: () => $ZodLazy,
15191
- $ZodKSUID: () => $ZodKSUID,
15192
- $ZodJWT: () => $ZodJWT,
15193
- $ZodIntersection: () => $ZodIntersection,
15194
- $ZodISOTime: () => $ZodISOTime,
15195
- $ZodISODuration: () => $ZodISODuration,
15196
- $ZodISODateTime: () => $ZodISODateTime,
15197
- $ZodISODate: () => $ZodISODate,
15198
- $ZodIPv6: () => $ZodIPv6,
15199
- $ZodIPv4: () => $ZodIPv4,
15200
- $ZodGUID: () => $ZodGUID,
15201
- $ZodFunction: () => $ZodFunction,
15202
- $ZodFile: () => $ZodFile,
15203
- $ZodExactOptional: () => $ZodExactOptional,
15204
- $ZodError: () => $ZodError,
15205
- $ZodEnum: () => $ZodEnum,
15206
- $ZodEncodeError: () => $ZodEncodeError,
15207
- $ZodEmoji: () => $ZodEmoji,
15208
- $ZodEmail: () => $ZodEmail,
15209
- $ZodE164: () => $ZodE164,
15210
- $ZodDiscriminatedUnion: () => $ZodDiscriminatedUnion,
15211
- $ZodDefault: () => $ZodDefault,
15212
- $ZodDate: () => $ZodDate,
15213
- $ZodCustomStringFormat: () => $ZodCustomStringFormat,
15214
- $ZodCustom: () => $ZodCustom,
15215
- $ZodCodec: () => $ZodCodec,
15216
- $ZodCheckUpperCase: () => $ZodCheckUpperCase,
15217
- $ZodCheckStringFormat: () => $ZodCheckStringFormat,
15218
- $ZodCheckStartsWith: () => $ZodCheckStartsWith,
15219
- $ZodCheckSizeEquals: () => $ZodCheckSizeEquals,
15220
- $ZodCheckRegex: () => $ZodCheckRegex,
15221
- $ZodCheckProperty: () => $ZodCheckProperty,
15222
- $ZodCheckOverwrite: () => $ZodCheckOverwrite,
15223
- $ZodCheckNumberFormat: () => $ZodCheckNumberFormat,
15224
- $ZodCheckMultipleOf: () => $ZodCheckMultipleOf,
15225
- $ZodCheckMinSize: () => $ZodCheckMinSize,
15226
- $ZodCheckMinLength: () => $ZodCheckMinLength,
15227
- $ZodCheckMimeType: () => $ZodCheckMimeType,
15228
- $ZodCheckMaxSize: () => $ZodCheckMaxSize,
15229
- $ZodCheckMaxLength: () => $ZodCheckMaxLength,
15230
- $ZodCheckLowerCase: () => $ZodCheckLowerCase,
15231
- $ZodCheckLessThan: () => $ZodCheckLessThan,
15232
- $ZodCheckLengthEquals: () => $ZodCheckLengthEquals,
15233
- $ZodCheckIncludes: () => $ZodCheckIncludes,
15234
- $ZodCheckGreaterThan: () => $ZodCheckGreaterThan,
15235
- $ZodCheckEndsWith: () => $ZodCheckEndsWith,
15236
- $ZodCheckBigIntFormat: () => $ZodCheckBigIntFormat,
15237
- $ZodCheck: () => $ZodCheck,
15238
- $ZodCatch: () => $ZodCatch,
15239
- $ZodCUID2: () => $ZodCUID2,
15240
- $ZodCUID: () => $ZodCUID,
15241
- $ZodCIDRv6: () => $ZodCIDRv6,
15242
- $ZodCIDRv4: () => $ZodCIDRv4,
15243
- $ZodBoolean: () => $ZodBoolean,
15244
- $ZodBigIntFormat: () => $ZodBigIntFormat,
15245
- $ZodBigInt: () => $ZodBigInt,
15246
- $ZodBase64URL: () => $ZodBase64URL,
15247
- $ZodBase64: () => $ZodBase64,
15248
- $ZodAsyncError: () => $ZodAsyncError,
15053
+ $ZodAny: () => $ZodAny,
15249
15054
  $ZodArray: () => $ZodArray,
15250
- $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
15251
15327
  });
15252
15328
  var init_core2 = __esm(() => {
15253
15329
  init_util();
15254
- init_regexes();
15255
- init_locales();
15256
- init_json_schema_processors();
15257
- init_json_schema_generator();
15258
- init_json_schema();
15259
- init_core();
15260
- init_parse();
15261
- init_errors2();
15262
- init_schemas();
15263
- init_checks();
15264
- init_versions();
15265
- init_registries();
15266
- init_api();
15267
- init_to_json_schema();
15268
- });
15269
-
15270
- // node_modules/zod/v4/classic/checks.js
15271
- var exports_checks2 = {};
15272
- __export(exports_checks2, {
15273
- uppercase: () => _uppercase,
15274
- trim: () => _trim,
15275
- toUpperCase: () => _toUpperCase,
15276
- toLowerCase: () => _toLowerCase,
15277
- startsWith: () => _startsWith,
15278
- slugify: () => _slugify,
15279
- size: () => _size,
15280
- regex: () => _regex,
15281
- property: () => _property,
15282
- positive: () => _positive,
15283
- overwrite: () => _overwrite,
15284
- normalize: () => _normalize,
15285
- nonpositive: () => _nonpositive,
15286
- nonnegative: () => _nonnegative,
15287
- negative: () => _negative,
15288
- multipleOf: () => _multipleOf,
15289
- minSize: () => _minSize,
15290
- minLength: () => _minLength,
15291
- mime: () => _mime,
15292
- maxSize: () => _maxSize,
15293
- maxLength: () => _maxLength,
15294
- lte: () => _lte,
15295
- lt: () => _lt,
15296
- lowercase: () => _lowercase,
15297
- length: () => _length,
15298
- includes: () => _includes,
15299
- gte: () => _gte,
15330
+ init_regexes();
15331
+ init_locales();
15332
+ init_json_schema_processors();
15333
+ init_json_schema_generator();
15334
+ init_json_schema();
15335
+ init_core();
15336
+ init_parse();
15337
+ init_errors2();
15338
+ init_schemas();
15339
+ init_checks();
15340
+ init_versions();
15341
+ init_registries();
15342
+ init_api();
15343
+ init_to_json_schema();
15344
+ });
15345
+
15346
+ // node_modules/zod/v4/classic/checks.js
15347
+ var exports_checks2 = {};
15348
+ __export(exports_checks2, {
15349
+ endsWith: () => _endsWith,
15300
15350
  gt: () => _gt,
15301
- 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
15302
15378
  });
15303
15379
  var init_checks2 = __esm(() => {
15304
15380
  init_core2();
@@ -15307,14 +15383,14 @@ var init_checks2 = __esm(() => {
15307
15383
  // node_modules/zod/v4/classic/iso.js
15308
15384
  var exports_iso = {};
15309
15385
  __export(exports_iso, {
15310
- time: () => time2,
15311
- duration: () => duration2,
15312
- datetime: () => datetime2,
15313
- date: () => date2,
15314
- ZodISOTime: () => ZodISOTime,
15315
- ZodISODuration: () => ZodISODuration,
15386
+ ZodISODate: () => ZodISODate,
15316
15387
  ZodISODateTime: () => ZodISODateTime,
15317
- ZodISODate: () => ZodISODate
15388
+ ZodISODuration: () => ZodISODuration,
15389
+ ZodISOTime: () => ZodISOTime,
15390
+ date: () => date2,
15391
+ datetime: () => datetime2,
15392
+ duration: () => duration2,
15393
+ time: () => time2
15318
15394
  });
15319
15395
  function datetime2(params) {
15320
15396
  return _isoDateTime(ZodISODateTime, params);
@@ -15412,172 +15488,172 @@ var init_parse2 = __esm(() => {
15412
15488
  // node_modules/zod/v4/classic/schemas.js
15413
15489
  var exports_schemas2 = {};
15414
15490
  __export(exports_schemas2, {
15415
- xor: () => xor,
15416
- xid: () => xid2,
15417
- void: () => _void2,
15418
- uuidv7: () => uuidv7,
15419
- uuidv6: () => uuidv6,
15420
- uuidv4: () => uuidv4,
15421
- uuid: () => uuid2,
15422
- url: () => url,
15423
- unknown: () => unknown,
15424
- union: () => union,
15425
- undefined: () => _undefined3,
15426
- ulid: () => ulid2,
15427
- uint64: () => uint64,
15428
- uint32: () => uint32,
15429
- tuple: () => tuple,
15430
- transform: () => transform,
15431
- templateLiteral: () => templateLiteral,
15432
- symbol: () => symbol,
15433
- superRefine: () => superRefine,
15434
- success: () => success,
15435
- stringbool: () => stringbool,
15436
- stringFormat: () => stringFormat,
15437
- string: () => string2,
15438
- strictObject: () => strictObject,
15439
- set: () => set,
15440
- refine: () => refine,
15441
- record: () => record,
15442
- readonly: () => readonly,
15443
- promise: () => promise,
15444
- preprocess: () => preprocess,
15445
- prefault: () => prefault,
15446
- pipe: () => pipe,
15447
- partialRecord: () => partialRecord,
15448
- optional: () => optional,
15449
- object: () => object,
15450
- number: () => number2,
15451
- nullish: () => nullish2,
15452
- nullable: () => nullable,
15453
- null: () => _null3,
15454
- nonoptional: () => nonoptional,
15455
- never: () => never,
15456
- nativeEnum: () => nativeEnum,
15457
- nanoid: () => nanoid2,
15458
- nan: () => nan,
15459
- meta: () => meta2,
15460
- map: () => map,
15461
- mac: () => mac2,
15462
- looseRecord: () => looseRecord,
15463
- looseObject: () => looseObject,
15464
- literal: () => literal,
15465
- lazy: () => lazy,
15466
- ksuid: () => ksuid2,
15467
- keyof: () => keyof,
15468
- jwt: () => jwt,
15469
- json: () => json,
15470
- ipv6: () => ipv62,
15471
- ipv4: () => ipv42,
15472
- invertCodec: () => invertCodec,
15473
- intersection: () => intersection,
15474
- int64: () => int64,
15475
- int32: () => int32,
15476
- int: () => int,
15477
- instanceof: () => _instanceof,
15478
- httpUrl: () => httpUrl,
15479
- hostname: () => hostname2,
15480
- hex: () => hex2,
15481
- hash: () => hash,
15482
- guid: () => guid2,
15483
- function: () => _function,
15484
- float64: () => float64,
15485
- float32: () => float32,
15486
- file: () => file,
15487
- exactOptional: () => exactOptional,
15488
- enum: () => _enum2,
15489
- emoji: () => emoji2,
15490
- email: () => email2,
15491
- e164: () => e1642,
15492
- discriminatedUnion: () => discriminatedUnion,
15493
- describe: () => describe2,
15494
- date: () => date3,
15495
- custom: () => custom,
15496
- cuid2: () => cuid22,
15497
- cuid: () => cuid3,
15498
- codec: () => codec,
15499
- cidrv6: () => cidrv62,
15500
- cidrv4: () => cidrv42,
15501
- check: () => check,
15502
- catch: () => _catch2,
15503
- boolean: () => boolean2,
15504
- bigint: () => bigint2,
15505
- base64url: () => base64url2,
15506
- base64: () => base642,
15507
- array: () => array,
15508
- any: () => any,
15509
- _function: () => _function,
15510
- _default: () => _default2,
15511
- _ZodString: () => _ZodString,
15512
- ZodXor: () => ZodXor,
15513
- ZodXID: () => ZodXID,
15514
- ZodVoid: () => ZodVoid,
15515
- ZodUnknown: () => ZodUnknown,
15516
- ZodUnion: () => ZodUnion,
15517
- ZodUndefined: () => ZodUndefined,
15518
- ZodUUID: () => ZodUUID,
15519
- ZodURL: () => ZodURL,
15520
- ZodULID: () => ZodULID,
15521
- ZodType: () => ZodType,
15522
- ZodTuple: () => ZodTuple,
15523
- ZodTransform: () => ZodTransform,
15524
- ZodTemplateLiteral: () => ZodTemplateLiteral,
15525
- ZodSymbol: () => ZodSymbol,
15526
- ZodSuccess: () => ZodSuccess,
15527
- ZodStringFormat: () => ZodStringFormat,
15528
- ZodString: () => ZodString,
15529
- ZodSet: () => ZodSet,
15530
- ZodRecord: () => ZodRecord,
15531
- ZodReadonly: () => ZodReadonly,
15532
- ZodPromise: () => ZodPromise,
15533
- ZodPreprocess: () => ZodPreprocess,
15534
- ZodPrefault: () => ZodPrefault,
15535
- ZodPipe: () => ZodPipe,
15536
- ZodOptional: () => ZodOptional,
15537
- ZodObject: () => ZodObject,
15538
- ZodNumberFormat: () => ZodNumberFormat,
15539
- ZodNumber: () => ZodNumber,
15540
- ZodNullable: () => ZodNullable,
15541
- ZodNull: () => ZodNull,
15542
- ZodNonOptional: () => ZodNonOptional,
15543
- ZodNever: () => ZodNever,
15544
- ZodNanoID: () => ZodNanoID,
15545
- ZodNaN: () => ZodNaN,
15546
- ZodMap: () => ZodMap,
15547
- ZodMAC: () => ZodMAC,
15548
- ZodLiteral: () => ZodLiteral,
15549
- ZodLazy: () => ZodLazy,
15550
- ZodKSUID: () => ZodKSUID,
15551
- ZodJWT: () => ZodJWT,
15552
- ZodIntersection: () => ZodIntersection,
15553
- ZodIPv6: () => ZodIPv6,
15554
- ZodIPv4: () => ZodIPv4,
15555
- ZodGUID: () => ZodGUID,
15556
- ZodFunction: () => ZodFunction,
15557
- ZodFile: () => ZodFile,
15558
- ZodExactOptional: () => ZodExactOptional,
15559
- ZodEnum: () => ZodEnum,
15560
- ZodEmoji: () => ZodEmoji,
15561
- ZodEmail: () => ZodEmail,
15562
- ZodE164: () => ZodE164,
15563
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
15564
- ZodDefault: () => ZodDefault,
15565
- ZodDate: () => ZodDate,
15566
- ZodCustomStringFormat: () => ZodCustomStringFormat,
15567
- ZodCustom: () => ZodCustom,
15568
- ZodCodec: () => ZodCodec,
15569
- ZodCatch: () => ZodCatch,
15570
- ZodCUID2: () => ZodCUID2,
15571
- ZodCUID: () => ZodCUID,
15572
- ZodCIDRv6: () => ZodCIDRv6,
15573
- ZodCIDRv4: () => ZodCIDRv4,
15574
- ZodBoolean: () => ZodBoolean,
15575
- ZodBigIntFormat: () => ZodBigIntFormat,
15576
- ZodBigInt: () => ZodBigInt,
15577
- ZodBase64URL: () => ZodBase64URL,
15578
- ZodBase64: () => ZodBase64,
15491
+ ZodAny: () => ZodAny,
15579
15492
  ZodArray: () => ZodArray,
15580
- 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
15581
15657
  });
15582
15658
  function _installLazyMethods(inst, group, methods) {
15583
15659
  const proto = Object.getPrototypeOf(inst);
@@ -17271,383 +17347,383 @@ function convertSchema(schema, ctx) {
17271
17347
  extraMeta[key] = schema[key];
17272
17348
  }
17273
17349
  }
17274
- for (const key of Object.keys(schema)) {
17275
- if (!RECOGNIZED_KEYS.has(key)) {
17276
- extraMeta[key] = schema[key];
17277
- }
17278
- }
17279
- if (Object.keys(extraMeta).length > 0) {
17280
- ctx.registry.add(baseSchema, extraMeta);
17281
- }
17282
- if (schema.description) {
17283
- baseSchema = baseSchema.describe(schema.description);
17284
- }
17285
- return baseSchema;
17286
- }
17287
- function fromJSONSchema(schema, params) {
17288
- if (typeof schema === "boolean") {
17289
- return schema ? z.any() : z.never();
17290
- }
17291
- let normalized;
17292
- try {
17293
- normalized = JSON.parse(JSON.stringify(schema));
17294
- } catch {
17295
- throw new Error("fromJSONSchema input is not valid JSON (possibly cyclic); use $defs/$ref for recursive schemas");
17296
- }
17297
- const version2 = detectVersion(normalized, params?.defaultTarget);
17298
- const defs = normalized.$defs || normalized.definitions || {};
17299
- const ctx = {
17300
- version: version2,
17301
- defs,
17302
- refs: new Map,
17303
- processing: new Set,
17304
- rootSchema: normalized,
17305
- registry: params?.registry ?? globalRegistry
17306
- };
17307
- return convertSchema(normalized, ctx);
17308
- }
17309
- var z, RECOGNIZED_KEYS;
17310
- var init_from_json_schema = __esm(() => {
17311
- init_registries();
17312
- init_checks2();
17313
- init_iso();
17314
- init_schemas2();
17315
- z = {
17316
- ...exports_schemas2,
17317
- ...exports_checks2,
17318
- iso: exports_iso
17319
- };
17320
- RECOGNIZED_KEYS = /* @__PURE__ */ new Set([
17321
- "$schema",
17322
- "$ref",
17323
- "$defs",
17324
- "definitions",
17325
- "$id",
17326
- "id",
17327
- "$comment",
17328
- "$anchor",
17329
- "$vocabulary",
17330
- "$dynamicRef",
17331
- "$dynamicAnchor",
17332
- "type",
17333
- "enum",
17334
- "const",
17335
- "anyOf",
17336
- "oneOf",
17337
- "allOf",
17338
- "not",
17339
- "properties",
17340
- "required",
17341
- "additionalProperties",
17342
- "patternProperties",
17343
- "propertyNames",
17344
- "minProperties",
17345
- "maxProperties",
17346
- "items",
17347
- "prefixItems",
17348
- "additionalItems",
17349
- "minItems",
17350
- "maxItems",
17351
- "uniqueItems",
17352
- "contains",
17353
- "minContains",
17354
- "maxContains",
17355
- "minLength",
17356
- "maxLength",
17357
- "pattern",
17358
- "format",
17359
- "minimum",
17360
- "maximum",
17361
- "exclusiveMinimum",
17362
- "exclusiveMaximum",
17363
- "multipleOf",
17364
- "description",
17365
- "default",
17366
- "contentEncoding",
17367
- "contentMediaType",
17368
- "contentSchema",
17369
- "unevaluatedItems",
17370
- "unevaluatedProperties",
17371
- "if",
17372
- "then",
17373
- "else",
17374
- "dependentSchemas",
17375
- "dependentRequired",
17376
- "nullable",
17377
- "readOnly"
17378
- ]);
17379
- });
17380
-
17381
- // node_modules/zod/v4/classic/coerce.js
17382
- var exports_coerce = {};
17383
- __export(exports_coerce, {
17384
- string: () => string3,
17385
- number: () => number3,
17386
- date: () => date4,
17387
- boolean: () => boolean3,
17388
- bigint: () => bigint3
17389
- });
17390
- function string3(params) {
17391
- return _coercedString(ZodString, params);
17392
- }
17393
- function number3(params) {
17394
- return _coercedNumber(ZodNumber, params);
17395
- }
17396
- function boolean3(params) {
17397
- return _coercedBoolean(ZodBoolean, params);
17398
- }
17399
- function bigint3(params) {
17400
- return _coercedBigint(ZodBigInt, params);
17401
- }
17402
- function date4(params) {
17403
- return _coercedDate(ZodDate, params);
17350
+ for (const key of Object.keys(schema)) {
17351
+ if (!RECOGNIZED_KEYS.has(key)) {
17352
+ extraMeta[key] = schema[key];
17353
+ }
17354
+ }
17355
+ if (Object.keys(extraMeta).length > 0) {
17356
+ ctx.registry.add(baseSchema, extraMeta);
17357
+ }
17358
+ if (schema.description) {
17359
+ baseSchema = baseSchema.describe(schema.description);
17360
+ }
17361
+ return baseSchema;
17404
17362
  }
17405
- var init_coerce = __esm(() => {
17406
- init_core2();
17407
- init_schemas2();
17408
- });
17409
-
17410
- // node_modules/zod/v4/classic/external.js
17411
- var exports_external = {};
17412
- __export(exports_external, {
17413
- xor: () => xor,
17414
- xid: () => xid2,
17415
- void: () => _void2,
17416
- uuidv7: () => uuidv7,
17417
- uuidv6: () => uuidv6,
17418
- uuidv4: () => uuidv4,
17419
- uuid: () => uuid2,
17420
- util: () => exports_util,
17421
- url: () => url,
17422
- uppercase: () => _uppercase,
17423
- unknown: () => unknown,
17424
- union: () => union,
17425
- undefined: () => _undefined3,
17426
- ulid: () => ulid2,
17427
- uint64: () => uint64,
17428
- uint32: () => uint32,
17429
- tuple: () => tuple,
17430
- trim: () => _trim,
17431
- treeifyError: () => treeifyError,
17432
- transform: () => transform,
17433
- toUpperCase: () => _toUpperCase,
17434
- toLowerCase: () => _toLowerCase,
17435
- toJSONSchema: () => toJSONSchema,
17436
- templateLiteral: () => templateLiteral,
17437
- symbol: () => symbol,
17438
- superRefine: () => superRefine,
17439
- success: () => success,
17440
- stringbool: () => stringbool,
17441
- stringFormat: () => stringFormat,
17442
- string: () => string2,
17443
- strictObject: () => strictObject,
17444
- startsWith: () => _startsWith,
17445
- slugify: () => _slugify,
17446
- size: () => _size,
17447
- setErrorMap: () => setErrorMap,
17448
- set: () => set,
17449
- safeParseAsync: () => safeParseAsync2,
17450
- safeParse: () => safeParse2,
17451
- safeEncodeAsync: () => safeEncodeAsync2,
17452
- safeEncode: () => safeEncode2,
17453
- safeDecodeAsync: () => safeDecodeAsync2,
17454
- safeDecode: () => safeDecode2,
17455
- registry: () => registry,
17456
- regexes: () => exports_regexes,
17457
- regex: () => _regex,
17458
- refine: () => refine,
17459
- record: () => record,
17460
- readonly: () => readonly,
17461
- property: () => _property,
17462
- promise: () => promise,
17463
- prettifyError: () => prettifyError,
17464
- preprocess: () => preprocess,
17465
- prefault: () => prefault,
17466
- positive: () => _positive,
17467
- pipe: () => pipe,
17468
- partialRecord: () => partialRecord,
17469
- parseAsync: () => parseAsync2,
17470
- parse: () => parse3,
17471
- overwrite: () => _overwrite,
17472
- optional: () => optional,
17473
- object: () => object,
17474
- number: () => number2,
17475
- nullish: () => nullish2,
17476
- nullable: () => nullable,
17477
- null: () => _null3,
17478
- normalize: () => _normalize,
17479
- nonpositive: () => _nonpositive,
17480
- nonoptional: () => nonoptional,
17481
- nonnegative: () => _nonnegative,
17482
- never: () => never,
17483
- negative: () => _negative,
17484
- nativeEnum: () => nativeEnum,
17485
- nanoid: () => nanoid2,
17486
- nan: () => nan,
17487
- multipleOf: () => _multipleOf,
17488
- minSize: () => _minSize,
17489
- minLength: () => _minLength,
17490
- mime: () => _mime,
17491
- meta: () => meta2,
17492
- maxSize: () => _maxSize,
17493
- maxLength: () => _maxLength,
17494
- map: () => map,
17495
- mac: () => mac2,
17496
- lte: () => _lte,
17497
- lt: () => _lt,
17498
- lowercase: () => _lowercase,
17499
- looseRecord: () => looseRecord,
17500
- looseObject: () => looseObject,
17501
- locales: () => exports_locales,
17502
- literal: () => literal,
17503
- length: () => _length,
17504
- lazy: () => lazy,
17505
- ksuid: () => ksuid2,
17506
- keyof: () => keyof,
17507
- jwt: () => jwt,
17508
- json: () => json,
17509
- iso: () => exports_iso,
17510
- ipv6: () => ipv62,
17511
- ipv4: () => ipv42,
17512
- invertCodec: () => invertCodec,
17513
- intersection: () => intersection,
17514
- int64: () => int64,
17515
- int32: () => int32,
17516
- int: () => int,
17517
- instanceof: () => _instanceof,
17518
- includes: () => _includes,
17519
- httpUrl: () => httpUrl,
17520
- hostname: () => hostname2,
17521
- hex: () => hex2,
17522
- hash: () => hash,
17523
- guid: () => guid2,
17524
- gte: () => _gte,
17525
- gt: () => _gt,
17526
- globalRegistry: () => globalRegistry,
17527
- getErrorMap: () => getErrorMap,
17528
- function: () => _function,
17529
- fromJSONSchema: () => fromJSONSchema,
17530
- formatError: () => formatError,
17531
- float64: () => float64,
17532
- float32: () => float32,
17533
- flattenError: () => flattenError,
17534
- file: () => file,
17535
- exactOptional: () => exactOptional,
17536
- enum: () => _enum2,
17537
- endsWith: () => _endsWith,
17538
- encodeAsync: () => encodeAsync2,
17539
- encode: () => encode2,
17540
- emoji: () => emoji2,
17541
- email: () => email2,
17542
- e164: () => e1642,
17543
- discriminatedUnion: () => discriminatedUnion,
17544
- describe: () => describe2,
17545
- decodeAsync: () => decodeAsync2,
17546
- decode: () => decode2,
17547
- date: () => date3,
17548
- custom: () => custom,
17549
- cuid2: () => cuid22,
17550
- cuid: () => cuid3,
17551
- core: () => exports_core2,
17552
- config: () => config,
17553
- coerce: () => exports_coerce,
17554
- codec: () => codec,
17555
- clone: () => clone,
17556
- cidrv6: () => cidrv62,
17557
- cidrv4: () => cidrv42,
17558
- check: () => check,
17559
- catch: () => _catch2,
17560
- boolean: () => boolean2,
17561
- bigint: () => bigint2,
17562
- base64url: () => base64url2,
17563
- base64: () => base642,
17564
- array: () => array,
17565
- any: () => any,
17566
- _function: () => _function,
17567
- _default: () => _default2,
17568
- _ZodString: () => _ZodString,
17569
- ZodXor: () => ZodXor,
17570
- ZodXID: () => ZodXID,
17571
- ZodVoid: () => ZodVoid,
17572
- ZodUnknown: () => ZodUnknown,
17573
- ZodUnion: () => ZodUnion,
17574
- ZodUndefined: () => ZodUndefined,
17575
- ZodUUID: () => ZodUUID,
17576
- ZodURL: () => ZodURL,
17577
- ZodULID: () => ZodULID,
17578
- ZodType: () => ZodType,
17579
- ZodTuple: () => ZodTuple,
17580
- ZodTransform: () => ZodTransform,
17581
- ZodTemplateLiteral: () => ZodTemplateLiteral,
17582
- ZodSymbol: () => ZodSymbol,
17583
- ZodSuccess: () => ZodSuccess,
17584
- ZodStringFormat: () => ZodStringFormat,
17585
- ZodString: () => ZodString,
17586
- ZodSet: () => ZodSet,
17587
- ZodRecord: () => ZodRecord,
17588
- ZodRealError: () => ZodRealError,
17589
- ZodReadonly: () => ZodReadonly,
17590
- ZodPromise: () => ZodPromise,
17591
- ZodPreprocess: () => ZodPreprocess,
17592
- ZodPrefault: () => ZodPrefault,
17593
- ZodPipe: () => ZodPipe,
17594
- ZodOptional: () => ZodOptional,
17595
- ZodObject: () => ZodObject,
17596
- ZodNumberFormat: () => ZodNumberFormat,
17597
- ZodNumber: () => ZodNumber,
17598
- ZodNullable: () => ZodNullable,
17599
- ZodNull: () => ZodNull,
17600
- ZodNonOptional: () => ZodNonOptional,
17601
- ZodNever: () => ZodNever,
17602
- ZodNanoID: () => ZodNanoID,
17603
- ZodNaN: () => ZodNaN,
17604
- ZodMap: () => ZodMap,
17605
- ZodMAC: () => ZodMAC,
17606
- ZodLiteral: () => ZodLiteral,
17607
- ZodLazy: () => ZodLazy,
17608
- ZodKSUID: () => ZodKSUID,
17609
- ZodJWT: () => ZodJWT,
17610
- ZodIssueCode: () => ZodIssueCode,
17611
- ZodIntersection: () => ZodIntersection,
17612
- ZodISOTime: () => ZodISOTime,
17613
- ZodISODuration: () => ZodISODuration,
17614
- ZodISODateTime: () => ZodISODateTime,
17615
- ZodISODate: () => ZodISODate,
17616
- ZodIPv6: () => ZodIPv6,
17617
- ZodIPv4: () => ZodIPv4,
17618
- ZodGUID: () => ZodGUID,
17619
- ZodFunction: () => ZodFunction,
17620
- ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
17621
- ZodFile: () => ZodFile,
17622
- ZodExactOptional: () => ZodExactOptional,
17623
- ZodError: () => ZodError,
17624
- ZodEnum: () => ZodEnum,
17625
- ZodEmoji: () => ZodEmoji,
17626
- ZodEmail: () => ZodEmail,
17627
- ZodE164: () => ZodE164,
17628
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
17629
- ZodDefault: () => ZodDefault,
17630
- ZodDate: () => ZodDate,
17631
- ZodCustomStringFormat: () => ZodCustomStringFormat,
17632
- ZodCustom: () => ZodCustom,
17633
- ZodCodec: () => ZodCodec,
17634
- ZodCatch: () => ZodCatch,
17635
- ZodCUID2: () => ZodCUID2,
17636
- ZodCUID: () => ZodCUID,
17637
- ZodCIDRv6: () => ZodCIDRv6,
17638
- ZodCIDRv4: () => ZodCIDRv4,
17639
- ZodBoolean: () => ZodBoolean,
17640
- ZodBigIntFormat: () => ZodBigIntFormat,
17641
- ZodBigInt: () => ZodBigInt,
17642
- ZodBase64URL: () => ZodBase64URL,
17643
- ZodBase64: () => ZodBase64,
17644
- ZodArray: () => ZodArray,
17645
- ZodAny: () => ZodAny,
17646
- TimePrecision: () => TimePrecision,
17647
- NEVER: () => NEVER,
17648
- $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,
17649
17490
  $input: () => $input,
17650
- $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
17651
17727
  });
17652
17728
  var init_external = __esm(() => {
17653
17729
  init_core2();
@@ -18566,7 +18642,7 @@ var package_default;
18566
18642
  var init_package = __esm(() => {
18567
18643
  package_default = {
18568
18644
  name: "@tensorix/metahub",
18569
- version: "0.4.1",
18645
+ version: "0.5.0",
18570
18646
  description: "Metahub core library and CLI",
18571
18647
  license: "AGPL-3.0-only",
18572
18648
  type: "module",
@@ -19372,15 +19448,15 @@ function roomUrlOf(config2) {
19372
19448
  // src/core/sync/room-peer.ts
19373
19449
  var exports_room_peer = {};
19374
19450
  __export(exports_room_peer, {
19375
- teardownRoomForShare: () => teardownRoomForShare,
19376
- syncRoomPeer: () => syncRoomPeer,
19377
- roomUrlOf: () => roomUrlOf,
19378
- roomTransport: () => roomTransport,
19379
- roomPeerKey: () => roomPeerKey,
19380
- registerRoomBlobResolver: () => registerRoomBlobResolver,
19381
- pushRoomBlobs: () => pushRoomBlobs,
19451
+ destroyRoom: () => destroyRoom,
19382
19452
  provisionRoomForShare: () => provisionRoomForShare,
19383
- destroyRoom: () => destroyRoom
19453
+ pushRoomBlobs: () => pushRoomBlobs,
19454
+ registerRoomBlobResolver: () => registerRoomBlobResolver,
19455
+ roomPeerKey: () => roomPeerKey,
19456
+ roomTransport: () => roomTransport,
19457
+ roomUrlOf: () => roomUrlOf,
19458
+ syncRoomPeer: () => syncRoomPeer,
19459
+ teardownRoomForShare: () => teardownRoomForShare
19384
19460
  });
19385
19461
  function registerRoomBlobResolver(resolve) {
19386
19462
  defaultBlobResolver = resolve;
@@ -19921,9 +19997,9 @@ var init_site_channel_store = __esm(() => {
19921
19997
  // src/core/sync/site-channel-reconcile.ts
19922
19998
  var exports_site_channel_reconcile = {};
19923
19999
  __export(exports_site_channel_reconcile, {
19924
- reconcileSiteChannelsQuietly: () => reconcileSiteChannelsQuietly,
20000
+ CONTROLLER_STATE_MISSING: () => CONTROLLER_STATE_MISSING,
19925
20001
  reconcileSiteChannels: () => reconcileSiteChannels,
19926
- CONTROLLER_STATE_MISSING: () => CONTROLLER_STATE_MISSING
20002
+ reconcileSiteChannelsQuietly: () => reconcileSiteChannelsQuietly
19927
20003
  });
19928
20004
  async function reconcileSiteChannelsQuietly(db) {
19929
20005
  try {
@@ -22275,8 +22351,8 @@ function safeDecode3(s) {
22275
22351
  // src/core/sync/blob-routes.ts
22276
22352
  var exports_blob_routes = {};
22277
22353
  __export(exports_blob_routes, {
22278
- serveBlob: () => serveBlob,
22279
- blobRoutes: () => blobRoutes
22354
+ blobRoutes: () => blobRoutes,
22355
+ serveBlob: () => serveBlob
22280
22356
  });
22281
22357
  function ext(ct) {
22282
22358
  const t = ct.toLowerCase().split(";")[0].trim();
@@ -23671,8 +23747,8 @@ var init_share_render = __esm(() => {
23671
23747
  // src/core/sync/sites-serve.ts
23672
23748
  var exports_sites_serve = {};
23673
23749
  __export(exports_sites_serve, {
23674
- serveSiteFile: () => serveSiteFile,
23675
- serveSite: () => serveSite
23750
+ serveSite: () => serveSite,
23751
+ serveSiteFile: () => serveSiteFile
23676
23752
  });
23677
23753
  async function serveSite(req, ctx, auth, opts = {}) {
23678
23754
  const url2 = new URL(req.url);
@@ -23967,16 +24043,16 @@ function docEditScript(slug, version2, body) {
23967
24043
  }
23968
24044
  });`;
23969
24045
  }
23970
- function cellText(prop, value) {
24046
+ function cellText(prop, value, titles) {
23971
24047
  if (value === null || value === undefined)
23972
24048
  return "";
23973
24049
  if (prop.type === "checkbox")
23974
24050
  return value ? "\u2713" : "";
23975
24051
  if (Array.isArray(value))
23976
- return value.map((v) => String(v)).join(", ");
24052
+ return value.map((v) => titles?.get(String(v)) ?? String(v)).join(", ");
23977
24053
  return String(value);
23978
24054
  }
23979
- function cellHtml(prop, value) {
24055
+ function cellHtml(prop, value, titles) {
23980
24056
  if (value === null || value === undefined)
23981
24057
  return "";
23982
24058
  if (prop.type === "checkbox")
@@ -23986,7 +24062,7 @@ function cellHtml(prop, value) {
23986
24062
  return `<a href="${escapeHtml(s)}" target="_blank" rel="noreferrer noopener">${escapeHtml(s)}</a>`;
23987
24063
  }
23988
24064
  if (Array.isArray(value))
23989
- 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(" ");
23990
24066
  return escapeHtml(String(value));
23991
24067
  }
23992
24068
  function editableType(t) {
@@ -24020,6 +24096,16 @@ async function serveTable(ctx, req, share, sub) {
24020
24096
  if (sub !== "")
24021
24097
  return notFound();
24022
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;
24023
24109
  const editable = share.permission === "edit";
24024
24110
  const head = props.map((p) => `<th>${escapeHtml(p.name)}</th>`).join("");
24025
24111
  const rows = records.map((r) => {
@@ -24028,7 +24114,7 @@ async function serveTable(ctx, req, share, sub) {
24028
24114
  if (editable && editableType(p.type)) {
24029
24115
  return `<td contenteditable data-rec="${escapeHtml(r.id)}" data-prop="${escapeHtml(p.id)}" data-type="${p.type}">${escapeHtml(cellText(p, v))}</td>`;
24030
24116
  }
24031
- return `<td>${cellHtml(p, v)}</td>`;
24117
+ return `<td>${cellHtml(p, v, titlesFor(p))}</td>`;
24032
24118
  }).join("");
24033
24119
  return `<tr>${tds}</tr>`;
24034
24120
  }).join("");
@@ -24309,6 +24395,7 @@ var init_share_serve = __esm(() => {
24309
24395
  init_databases();
24310
24396
  init_properties();
24311
24397
  init_records();
24398
+ init_grants_core();
24312
24399
  init_sites();
24313
24400
  init_sites_serve();
24314
24401
  init_blobs();
@@ -24705,9 +24792,9 @@ var init_drop_protocol = __esm(() => {
24705
24792
  // src/core/sync/drop-pull.ts
24706
24793
  var exports_drop_pull = {};
24707
24794
  __export(exports_drop_pull, {
24708
- pullDropsOnce: () => pullDropsOnce,
24795
+ changesMaxSeq: () => changesMaxSeq,
24709
24796
  dropWiredSites: () => dropWiredSites,
24710
- changesMaxSeq: () => changesMaxSeq
24797
+ pullDropsOnce: () => pullDropsOnce
24711
24798
  });
24712
24799
  function dropWiredSites(db) {
24713
24800
  return listSites(db).filter((s) => parseGrantSet(s.public_grants).tables.some((t) => t.ops.includes("create")));
@@ -25245,7 +25332,9 @@ function scalarHtml(specUrl) {
25245
25332
  }
25246
25333
  function startServer(opts = {}) {
25247
25334
  registerRoomBlobResolver(resolveBlob);
25335
+ const tDb = Date.now();
25248
25336
  const db = openMetahub();
25337
+ const dbMs = Date.now() - tDb;
25249
25338
  const node = getNodeId(db);
25250
25339
  const ctx = {
25251
25340
  db,
@@ -25271,6 +25360,7 @@ function startServer(opts = {}) {
25271
25360
  graceMs: DEFAULT_GRACE_MS
25272
25361
  };
25273
25362
  let server;
25363
+ const tServe = Date.now();
25274
25364
  try {
25275
25365
  server = Bun.serve({
25276
25366
  port,
@@ -25352,6 +25442,9 @@ function startServer(opts = {}) {
25352
25442
  }
25353
25443
  throw e;
25354
25444
  }
25445
+ if (opts.debug) {
25446
+ console.log(`[perf] openMetahub ${dbMs}ms, Bun.serve ${Date.now() - tServe}ms`);
25447
+ }
25355
25448
  let timer = null;
25356
25449
  if (autoSync && syncIntervalMs > 0) {
25357
25450
  const IDLE_BACKOFF_MAX_MS = 150000;
@@ -25766,6 +25859,43 @@ var styles_default = ` :root {
25766
25859
  color:var(--danger); margin:0 0 4px 2px; }
25767
25860
  .set-callout { padding:9px 11px; border-radius:var(--radius-sm); background:var(--surface);
25768
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; } }
25769
25899
  .set-callout.warn { border-color:color-mix(in srgb,var(--warning,#9a6700) 32%,var(--line)); }
25770
25900
  /* two-fact meta line under a block title (who publishes \xB7 where creds live) \u2014
25771
25901
  answers the questions hiding under "is this bucket for server or browser?" */
@@ -25956,6 +26086,10 @@ var styles_default = ` :root {
25956
26086
  .crumb-sep { flex:none; color:var(--muted); font-weight:400; }
25957
26087
  .iconbtn { width:30px; height:30px; display:grid; place-items:center; border-radius:var(--radius-sm); color:var(--fg-soft); transition:background .12s; }
25958
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; }
25959
26093
  /* Reserve the classic-scrollbar gutter up front: view width never changes
25960
26094
  when content grows past one screen \u2014 no jump / rewrap flicker. stable
25961
26095
  ONLY (never both-edges): a left-edge gutter desyncs Chromium's composited
@@ -26035,6 +26169,11 @@ var styles_default = ` :root {
26035
26169
  /* wide mode (\u22EF menu): lift the column cap; the 60px side padding stays as the
26036
26170
  reading gutter and keeps the fixed .doc-toc ticks off the text. */
26037
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; }
26038
26177
  /* floating table of contents: a column of indented tick marks in the right
26039
26178
  gutter that expands to a labelled list on hover (Notion / Vercel-docs style).
26040
26179
  Fixed to the viewport so it never disturbs the centred .doc column. */
@@ -26511,6 +26650,21 @@ var styles_default = ` :root {
26511
26650
  border-bottom:2px solid transparent; margin-bottom:-1px; transition:color .12s; }
26512
26651
  .view-tab.active { color:var(--fg); border-bottom-color:var(--accent); }
26513
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); }
26514
26668
  .toolbar { display:flex; align-items:center; gap:2px; padding:10px 0; }
26515
26669
  .toolbar .spacer { flex:1; }
26516
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; }
@@ -26605,6 +26759,12 @@ var styles_default = ` :root {
26605
26759
  background:color-mix(in srgb,var(--c) 15%,transparent); color:var(--c); }
26606
26760
  /* data-resolved (not prefers-color-scheme): tracks a manual dark choice too. */
26607
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; }
26608
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); }
26609
26769
  .addrow:hover { background:var(--hover); color:var(--fg-soft); }
26610
26770
  .gridfoot { display:flex; gap:18px; color:var(--muted); font-size:12px; padding:8px 2px; }
@@ -26816,6 +26976,14 @@ var styles_default = ` :root {
26816
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; }
26817
26977
  .proprow .v:hover { background:var(--hover); }
26818
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; }
26819
26987
 
26820
26988
  /* version history (doc drawer + record peek view) */
26821
26989
  .hist-peek { width:760px; }
@@ -26976,11 +27144,19 @@ var styles_default = ` :root {
26976
27144
  .pop input.field:focus { border-color:var(--accent); }
26977
27145
  /* select-cell picker: search/create input at the top of the popover */
26978
27146
  .pop .selsearch { display:flex; align-items:center; gap:7px; margin:2px 2px 6px; padding:6px 9px;
26979
- border:1px solid var(--line-strong); border-radius:var(--radius-sm); background:var(--surface); color:var(--muted); }
26980
- .pop .selsearch:focus-within { border-color:var(--accent); }
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); }
26981
27151
  .pop .selsearch input { flex:1; width:0; min-width:0; border:0; background:transparent; outline:none;
26982
27152
  font:inherit; font-size:var(--fs-ui); color:var(--fg); }
26983
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; }
26984
27160
  .optrow { display:flex; align-items:center; gap:6px; padding:3px 4px; }
26985
27161
  .optrow .chip { flex:1; }
26986
27162
  .optrow .grip { width:18px; height:22px; display:grid; place-items:center; color:var(--muted); cursor:grab; touch-action:none; flex:none; }
@@ -27189,9 +27365,17 @@ var styles_default = ` :root {
27189
27365
  .board-count { color:var(--muted); font-size:12px; font-weight:600; }
27190
27366
  .board-col-head .iconbtn.sm { width:24px; height:24px; }
27191
27367
  .board-col-body { display:flex; flex-direction:column; gap:7px; padding:0 8px 8px; overflow-y:auto; }
27192
- .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);
27193
27369
  cursor:grab; display:flex; flex-direction:column; gap:5px; touch-action:none; transition:border-color .1s,box-shadow .1s; }
27194
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; }
27195
27379
  .kcard.drag-source { opacity:.4; }
27196
27380
  .kcard.dragging-ghost { position:fixed; left:0; top:0; z-index:120; pointer-events:none; cursor:grabbing;
27197
27381
  box-shadow:var(--shadow-lg); opacity:.95; transform:translate3d(-9999px,0,0); }
@@ -27426,6 +27610,7 @@ var styles_default = ` :root {
27426
27610
  @media (hover: none) {
27427
27611
  .code-tools { opacity:1; transform:none; pointer-events:auto; }
27428
27612
  .rowactions { opacity:1; pointer-events:auto; }
27613
+ .kcard-actions { opacity:1; pointer-events:auto; }
27429
27614
  .cal-add, .filerow .facts,
27430
27615
  .navitem .acts { opacity:1; }
27431
27616
  /* the pill handles survive on touch (focus-driven, not hover-driven), but
@@ -27500,25 +27685,137 @@ var styles_default = ` :root {
27500
27685
  border-color:var(--accent);
27501
27686
  background:var(--accent) center/10px no-repeat
27502
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"); }
27503
- /* Compact menus inside the quick-note window only (dropdown + slash command
27504
- share .pop/.item/.lico with the main app; scope under body.quicknote so the
27505
- main app keeps its roomier density). */
27506
- body.quicknote .pop { padding:5px; border-radius:9px; }
27507
- body.quicknote .pop .lbl { padding:4px 8px 2px; font-size:10px; }
27508
- body.quicknote .pop .item { padding:5px 9px; gap:8px; font-size:var(--fs-sm); }
27509
- body.quicknote .pop .item .t { font-size:var(--fs-sm); }
27510
- body.quicknote .pop .item .d { font-size:10.5px; }
27511
- body.quicknote .pop .item .lico { width:22px; height:22px; }
27512
- body.quicknote .pop .item .lico.plain { width:20px; height:20px; }
27513
- body.quicknote .pop .sep { margin:4px 4px; }
27514
-
27515
- /* 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). */
27516
27793
  .qn-shortcut { min-width:140px; justify-content:center; font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC",sans-serif; }
27517
27794
  .qn-shortcut.capturing { outline:2px solid var(--accent); color:var(--accent); }
27518
27795
  .qn-keys { display:inline-flex; align-items:center; gap:6px; }
27519
27796
  .qn-key { line-height:1; }
27520
27797
  .qn-key.sym { font-size:1.15em; line-height:1; } /* \u2318 \u21E7 glyphs render smaller \u2014 bump to match letters */
27521
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
+
27522
27819
  /* No-origin bootstrap: enroll screen + hydration splash (data-blind shell). */
27523
27820
  .enroll-splash { min-height:100dvh; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px; padding:24px; }
27524
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; }
@@ -27837,6 +28134,7 @@ var injected = {
27837
28134
  sdk: null
27838
28135
  };
27839
28136
  var injectedWasm = null;
28137
+ var injectedWasmLoader = null;
27840
28138
  var injectedFmtWasm = {};
27841
28139
  function toArrayBuffer(w) {
27842
28140
  return w.byteOffset === 0 && w.byteLength === w.buffer.byteLength ? w.buffer : w.slice().buffer;
@@ -27847,7 +28145,13 @@ function setWebuiBundle(bundle) {
27847
28145
  injected.dbWorker = bundle.dbWorker;
27848
28146
  injected.runtime = bundle.runtime;
27849
28147
  injected.sdk = bundle.sdk;
27850
- 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
+ }
27851
28155
  for (const p of FMT_PROVIDERS) {
27852
28156
  const js = bundle.fmt?.[p.js];
27853
28157
  if (js != null)
@@ -27873,6 +28177,7 @@ function newestSourceMtime(dir) {
27873
28177
  function bundleGetter(opts) {
27874
28178
  let cached2 = null;
27875
28179
  let cachedMtime = 0;
28180
+ let building = null;
27876
28181
  return async () => {
27877
28182
  const fromBinary = injected[opts.key];
27878
28183
  if (fromBinary != null)
@@ -27883,15 +28188,24 @@ function bundleGetter(opts) {
27883
28188
  for (const extra of opts.extraDirs ?? []) {
27884
28189
  newest = Math.max(newest, newestSourceMtime(fileURLToPath(new URL(extra, import.meta.url))));
27885
28190
  }
27886
- if (cached2 == null || newest > cachedMtime) {
27887
- const entry = fileURLToPath(new URL(opts.entry, import.meta.url));
27888
- const res = await Bun.build({ entrypoints: [entry], target: "browser" });
27889
- if (!res.success)
27890
- throw new AggregateError(res.logs, `${opts.dist} build failed`);
27891
- cached2 = await res.outputs[0].text();
27892
- 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
+ });
27893
28207
  }
27894
- return cached2;
28208
+ return building;
27895
28209
  }
27896
28210
  if (cached2 == null) {
27897
28211
  const prebuilt = Bun.file(fileURLToPath(new URL(`./${opts.dist}`, import.meta.url)));
@@ -27943,6 +28257,10 @@ async function getSw() {
27943
28257
  async function getWasm() {
27944
28258
  if (injectedWasm != null)
27945
28259
  return injectedWasm;
28260
+ if (injectedWasmLoader != null) {
28261
+ injectedWasm = toArrayBuffer(await injectedWasmLoader());
28262
+ return injectedWasm;
28263
+ }
27946
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));
27947
28265
  const f = Bun.file(path);
27948
28266
  if (!await f.exists()) {
@@ -27973,21 +28291,34 @@ async function warmWebui() {
27973
28291
  await getJs();
27974
28292
  } catch {}
27975
28293
  }
27976
- function asset(body, contentType) {
27977
- return new Response(body, {
27978
- headers: { "content-type": contentType, "cache-control": "no-store" }
27979
- });
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 });
27980
28311
  }
27981
28312
  async function serveWebui(req) {
27982
28313
  if (req.method !== "GET")
27983
28314
  return null;
27984
28315
  const { pathname } = new URL(req.url);
27985
28316
  if (pathname === "/")
27986
- return asset(HTML2, "text/html; charset=utf-8");
28317
+ return asset(req, HTML2, "text/html; charset=utf-8");
27987
28318
  if (pathname === "/webui.css")
27988
- return asset(await getCss(), "text/css; charset=utf-8");
28319
+ return asset(req, await getCss(), "text/css; charset=utf-8");
27989
28320
  if (pathname === "/manifest.webmanifest")
27990
- return asset(MANIFEST, "application/manifest+json");
28321
+ return asset(req, MANIFEST, "application/manifest+json");
27991
28322
  const icon = ICONS[pathname];
27992
28323
  if (icon) {
27993
28324
  return new Response(Buffer.from(icon, "base64"), {
@@ -28026,7 +28357,7 @@ async function serveWebui(req) {
28026
28357
  const getter = script[pathname];
28027
28358
  if (getter) {
28028
28359
  try {
28029
- return asset(await getter(), "text/javascript; charset=utf-8");
28360
+ return asset(req, await getter(), "text/javascript; charset=utf-8");
28030
28361
  } catch (e) {
28031
28362
  console.error(`[webui] failed to serve ${pathname} \u2014`, e);
28032
28363
  return new Response(`webui build failed: ${e}`, { status: 500 });
@@ -28055,12 +28386,19 @@ function hlcMillis(hlc2) {
28055
28386
  function hlcIso(hlc2) {
28056
28387
  return new Date(hlcMillis(hlc2)).toISOString();
28057
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
+ }
28058
28400
  function revisionKind(txn) {
28059
- if (txn?.startsWith("repair:"))
28060
- return "repair";
28061
- if (txn?.startsWith("revert:"))
28062
- return "revert";
28063
- return "user";
28401
+ return parseTxn(txn).kind;
28064
28402
  }
28065
28403
  function clusterRevisions(changes) {
28066
28404
  const groups = [];
@@ -28153,6 +28491,7 @@ function listDocumentRevisions(db2, id) {
28153
28491
  at: hlcIso(last.hlc),
28154
28492
  node_id: last.node_id,
28155
28493
  kind: revisionKind(last.txn),
28494
+ actor: parseTxn(last.txn).actor,
28156
28495
  changes: group.length,
28157
28496
  created,
28158
28497
  deleted,
@@ -28271,6 +28610,7 @@ function recordRevisionOf(group) {
28271
28610
  at: hlcIso(last.hlc),
28272
28611
  node_id: last.node_id,
28273
28612
  kind: revisionKind(last.txn),
28613
+ actor: parseTxn(last.txn).actor,
28274
28614
  changes: group.length,
28275
28615
  created,
28276
28616
  deleted,
@@ -28410,6 +28750,7 @@ function listPropertyRevisions(db2, id) {
28410
28750
  at: hlcIso(last.hlc),
28411
28751
  node_id: last.node_id,
28412
28752
  kind: revisionKind(last.txn),
28753
+ actor: parseTxn(last.txn).actor,
28413
28754
  changes: group.length,
28414
28755
  created,
28415
28756
  deleted,
@@ -28471,7 +28812,7 @@ var revertProperty = grouped(function revertProperty2(db2, id, to) {
28471
28812
  emit(db2, "properties", id, "__deleted", 0);
28472
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));
28473
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);
28474
- const isCascade = (txn) => txn !== null && (schemaTxns.has(txn) || txn.startsWith("repair:"));
28815
+ const isCascade = (txn) => txn !== null && (schemaTxns.has(txn) || parseTxn(txn).kind === "repair");
28475
28816
  let restored = 0;
28476
28817
  let skipped = 0;
28477
28818
  let i = 0;
@@ -28517,6 +28858,302 @@ function recordFieldHistory(db2, id, propId) {
28517
28858
  }));
28518
28859
  }
28519
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
+
28520
29157
  // src/webui/server/routes.ts
28521
29158
  init_node();
28522
29159
  init_blobs();
@@ -29517,6 +30154,132 @@ function isPeer(db2, url2) {
29517
30154
  return listShareServers(db2).some((s) => s.url === url2);
29518
30155
  }
29519
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
+
29520
30283
  // src/webui/server/site-hosting-routes.ts
29521
30284
  init_zod();
29522
30285
  init_errors();
@@ -31168,10 +31931,56 @@ var RevisionBase = exports_external.object({
31168
31931
  at: exports_external.string().describe("Wall-clock time of the revision (ISO 8601)"),
31169
31932
  node_id: exports_external.string(),
31170
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)'),
31171
31935
  changes: exports_external.number(),
31172
31936
  created: exports_external.boolean(),
31173
31937
  deleted: exports_external.boolean()
31174
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
+ });
31175
31984
  var DocRevisionSchema = RevisionBase.extend({
31176
31985
  title_changed: exports_external.boolean(),
31177
31986
  blocks_changed: exports_external.number(),
@@ -31436,6 +32245,34 @@ var webuiRoutes = [
31436
32245
  });
31437
32246
  })
31438
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
+ },
31439
32276
  {
31440
32277
  method: "GET",
31441
32278
  path: "/api/properties",
@@ -31752,266 +32589,273 @@ var webuiRoutes = [
31752
32589
  return search(db2, need3(req, "q"), { limit: limit ? Number(limit) : undefined });
31753
32590
  })
31754
32591
  },
31755
- {
31756
- method: "GET",
31757
- path: "/api/blob-cache",
31758
- 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.",
31759
- response: BlobCacheSchema,
31760
- handler: handle3((_req, { db: db2 }) => blobCacheInfo(db2))
31761
- },
31762
- {
31763
- method: "POST",
31764
- path: "/api/blob-cache/verify",
31765
- 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.",
31766
- response: BlobCacheSchema,
31767
- handler: handle3(async (_req, { db: db2 }) => {
31768
- const r = await verifyAnchorPresence(db2);
31769
- return blobCacheInfo(db2, r.unreachable);
31770
- })
31771
- },
31772
- {
31773
- method: "POST",
31774
- path: "/api/blob-cache/clear",
31775
- summary: "Drop locally-cached blob bytes a full blob device durably holds (the reference stays; bytes re-download on demand). Returns bytes freed.",
31776
- response: ClearResultSchema,
31777
- handler: handle3((_req, { db: db2 }) => clearCache(db2))
31778
- },
31779
- {
31780
- method: "POST",
31781
- path: "/api/blob-cache/pin",
31782
- summary: "Pin/unpin a cached blob by hash (node-local; never synced). Pinned blobs are kept by both manual clear and automatic quota eviction.",
31783
- request: PinReq,
31784
- response: PinResSchema,
31785
- handler: handle3(async (req, { db: db2 }) => {
31786
- const body = await req.json();
31787
- reconcileCache(db2);
31788
- if (!setPinned(db2, body.hash, body.pinned))
31789
- throw new MhError("not_found", `blob not in cache: ${body.hash}`);
31790
- return { hash: body.hash, pinned: body.pinned };
31791
- })
31792
- },
31793
- {
31794
- method: "GET",
31795
- path: "/api/blobs",
31796
- 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.",
31797
- response: BlobListSchema,
31798
- handler: handle3((_req, { db: db2 }) => blobList(db2))
31799
- },
31800
- {
31801
- method: "POST",
31802
- path: "/api/blobs/clear",
31803
- 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.",
31804
- request: HashListReq,
31805
- response: ClearResultSchema,
31806
- handler: handle3(async (req, { db: db2 }) => {
31807
- const body = await req.json();
31808
- return clearBlobs(db2, body.hashes ?? []);
31809
- })
31810
- },
31811
- {
31812
- method: "POST",
31813
- path: "/api/blobs/delete",
31814
- 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.",
31815
- request: HashListReq,
31816
- response: GcResultSchema,
31817
- handler: handle3(async (req, { db: db2 }) => {
31818
- const body = await req.json();
31819
- return deleteOrphanBlobs(db2, body.hashes ?? []);
31820
- })
31821
- },
31822
- {
31823
- method: "POST",
31824
- path: "/api/blob-policy",
31825
- summary: "Set the full blob device(s) and/or redundancy (all|any). Anchor designation only \u2014 clearing is decided locally per device.",
31826
- request: SetBlobPolicyReq,
31827
- response: SetBlobPolicyResSchema,
31828
- handler: handle3(async (req, { db: db2 }) => {
31829
- const body = await req.json();
31830
- if (body.full_nodes)
31831
- setFullNodes(db2, body.full_nodes);
31832
- if (body.redundancy)
31833
- setRedundancy(db2, body.redundancy);
31834
- return { policy: readPolicy(db2) };
31835
- })
31836
- },
31837
- ...shareRoutes,
31838
- ...siteHostingRoutes,
31839
- ...edgeRoutes
31840
- ];
31841
- export {
31842
- writeFileRow,
31843
- withTxnId,
31844
- withNodeId,
31845
- withChangeGroup,
31846
- webuiRoutes,
31847
- warmWebui,
31848
- verifyBlobBytes,
31849
- updateSite,
31850
- updateRecordPrepared,
31851
- updateRecord,
31852
- updateProperty,
31853
- updateDocument,
31854
- updateDatabase,
31855
- toBytes,
31856
- syncWithPeer,
31857
- startServer,
31858
- slugify,
31859
- siteLifecycle,
31860
- siteCacheControl,
31861
- sha256Hex,
31862
- setWebuiBundle,
31863
- setSitePublicGrants,
31864
- setPropertyWidth,
31865
- setNodeLabel,
31866
- setCurrentDatabase,
31867
- serveWebui,
31868
- serializeDocBlocks,
31869
- search,
31870
- runSchema,
31871
- resolveSiteFileRow,
31872
- resolveSite,
31873
- resolveRef,
31874
- resolveEntity,
31875
- resolveData,
31876
- resolveCandidates,
31877
- renameSelectOption,
31878
- removeSelectOption,
31879
- removeProperty,
31880
- reconcile,
31881
- rebuildSearchIndex,
31882
- randomSuffix,
31883
- putFileInline,
31884
- putFile,
31885
- putBlobAt,
31886
- putBlob,
31887
- publishDirectory,
31888
- prependDocument,
31889
- prepareRecordCells,
31890
- parseHlc,
31891
- parseDocBlocks,
31892
- openMetahub,
31893
- observeHlc,
31894
- normalizeSitePath,
31895
- normalizeSiteName,
31896
- nextHlc,
31897
- newId,
31898
- moveRecord,
31899
- moveDocument,
31900
- migrateSiteChannels,
31901
- migrateRecords,
31902
- migratePeers,
31903
- migrateOplog,
31904
- migrateDocuments,
31905
- migrateDocBlocks,
31906
- metahubHome,
31907
- maybeAutoIndex,
31908
- makeId,
31909
- loopbackUiRejection,
31910
- liveFileRowIfSame,
31911
- listSites,
31912
- listRecords,
31913
- listProperties,
31914
- listFiles,
31915
- listDocuments,
31916
- listDatabases,
31917
- keysBetween,
31918
- keyBetween,
31919
- isTextType,
31920
- isSitePublic,
31921
- isImageType,
31922
- initSchema,
31923
- ingest,
31924
- inferContentType,
31925
- idKind,
31926
- hasIndex,
31927
- grouped,
31928
- getSiteByName,
31929
- getSite,
31930
- getRecord,
31931
- getProperty,
31932
- getNodeLabel,
31933
- getNodeId,
31934
- getFileRow,
31935
- getFileMetaForServe,
31936
- getFileForServe,
31937
- getDocument,
31938
- getDatabase,
31939
- getCurrentDatabase,
31940
- getBlob,
31941
- ftsAvailable,
31942
- formatHlc,
31943
- fileSizeOf,
31944
- fileIdFor,
31945
- fileCounts,
31946
- fileCount,
31947
- errorCode,
31948
- ensurePropIndex,
31949
- ensureDirs,
31950
- emitFields,
31951
- emit,
31952
- editDocumentBatch,
31953
- editDocument,
31954
- duplicateDocument,
31955
- duplicateDatabase,
31956
- documentVersion,
31957
- displayNodes,
31958
- deleteSite,
31959
- deleteRecord,
31960
- deleteFile,
31961
- deleteDocument,
31962
- deleteDatabase,
31963
- deleteBlob,
31964
- decodeFileRow,
31965
- dbPath,
31966
- createSite,
31967
- createRecordPrepared,
31968
- createRecord,
31969
- createDocument,
31970
- createDatabase,
31971
- coerce,
31972
- clearCurrentDatabase,
31973
- changesSince,
31974
- changesAfterSeq,
31975
- cacheDir,
31976
- bytesToBase64,
31977
- blobPath,
31978
- blobHash,
31979
- blobExists,
31980
- base64ToBytes,
31981
- backfillRecordOrderKeys,
31982
- backfillDocumentOrderKeys,
31983
- applyChange,
31984
- appendDocument,
31985
- advanceAckedPrefix,
31986
- addProperty,
31987
- SyncResponseSchema,
31988
- SyncRequestSchema,
31989
- SYNC_PATH,
31990
- SITE_FILE_SELECT,
31991
- SITE_FILE_COLS,
31992
- SITE_COLS,
31993
- RENEW_PATH,
31994
- RECORD_META,
31995
- PortInUseError,
31996
- PairResponseSchema,
31997
- PairRequestSchema,
31998
- PROP_TYPES,
31999
- PROPERTY_COLS,
32000
- PAIR_PATH,
32001
- OPLOG_ONLY_DATASETS,
32002
- NOT_NULL_ZERO_COLS,
32003
- MhError,
32004
- MAX_HLC_COUNTER,
32005
- INLINE_LIMIT,
32006
- HealthResponseSchema,
32007
- HEALTH_PATH,
32008
- DOMAIN,
32009
- DOCUMENT_COLS,
32010
- DATABASE_COLS,
32011
- ChangeSchema,
32012
- CHANGE_SELECT,
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,
32013
32682
  CHANGE_COLS,
32014
- 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
32015
32859
  };
32016
32860
 
32017
- //# debugId=9052D340AA681E6D64756E2164756E21
32861
+ //# debugId=3750093FAAD260D064756E2164756E21