@mulmoclaude/core 0.13.0 → 0.14.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 (56) hide show
  1. package/assets/helps/billing-clients-worklog.md +15 -12
  2. package/assets/helps/collection-skills.md +42 -19
  3. package/assets/helps/gemini.md +5 -3
  4. package/assets/helps/todo-collection.md +13 -7
  5. package/dist/{deriveAll-CMFXDQ_G.js → calendarGrid-C1rfCXJ3.cjs} +468 -3
  6. package/dist/calendarGrid-C1rfCXJ3.cjs.map +1 -0
  7. package/dist/{deriveAll-BQ_p5HSB.cjs → calendarGrid-kO6rGfm0.js} +289 -74
  8. package/dist/calendarGrid-kO6rGfm0.js.map +1 -0
  9. package/dist/collection/core/ids.d.ts +12 -0
  10. package/dist/collection/core/recordZ.d.ts +25 -0
  11. package/dist/collection/core/schema.d.ts +65 -418
  12. package/dist/collection/core/schemaZ.d.ts +846 -0
  13. package/dist/collection/core/templatePath.d.ts +34 -0
  14. package/dist/collection/core/where.d.ts +9 -15
  15. package/dist/collection/index.cjs +34 -295
  16. package/dist/collection/index.cjs.map +1 -1
  17. package/dist/collection/index.d.ts +1 -0
  18. package/dist/collection/index.js +5 -270
  19. package/dist/collection/index.js.map +1 -1
  20. package/dist/collection/paths.cjs +1 -1
  21. package/dist/collection/paths.cjs.map +1 -1
  22. package/dist/collection/paths.js +1 -1
  23. package/dist/collection/paths.js.map +1 -1
  24. package/dist/collection/registry/server/index.cjs +1 -1
  25. package/dist/collection/registry/server/index.js +1 -1
  26. package/dist/collection/server/discovery.d.ts +2 -244
  27. package/dist/collection/server/index.cjs +3 -1
  28. package/dist/collection/server/index.js +2 -2
  29. package/dist/collection/server/templatePath.d.ts +1 -34
  30. package/dist/collection/server/validate.d.ts +11 -7
  31. package/dist/collection-watchers/clock.d.ts +1 -0
  32. package/dist/collection-watchers/index.cjs +13 -4
  33. package/dist/collection-watchers/index.cjs.map +1 -1
  34. package/dist/collection-watchers/index.d.ts +1 -0
  35. package/dist/collection-watchers/index.js +13 -5
  36. package/dist/collection-watchers/index.js.map +1 -1
  37. package/dist/feeds/index.cjs +4 -4
  38. package/dist/feeds/index.js +2 -2
  39. package/dist/feeds/ingestTypes.d.ts +15 -40
  40. package/dist/feeds/server/index.cjs +5 -5
  41. package/dist/feeds/server/index.js +3 -3
  42. package/dist/{ingestTypes-C7EheYZX.cjs → ingestTypes-BIFXlw7M.cjs} +3 -3
  43. package/dist/ingestTypes-BIFXlw7M.cjs.map +1 -0
  44. package/dist/{ingestTypes-CmJeOUJc.js → ingestTypes-KuYPX9Ea.js} +2 -2
  45. package/dist/ingestTypes-KuYPX9Ea.js.map +1 -0
  46. package/dist/{server-DKXXFTbw.js → server-Cc6XcyOA.js} +417 -187
  47. package/dist/server-Cc6XcyOA.js.map +1 -0
  48. package/dist/{server-G6GtOdaW.cjs → server-Cd5WdM8a.cjs} +440 -198
  49. package/dist/server-Cd5WdM8a.cjs.map +1 -0
  50. package/package.json +2 -2
  51. package/dist/deriveAll-BQ_p5HSB.cjs.map +0 -1
  52. package/dist/deriveAll-CMFXDQ_G.js.map +0 -1
  53. package/dist/ingestTypes-C7EheYZX.cjs.map +0 -1
  54. package/dist/ingestTypes-CmJeOUJc.js.map +0 -1
  55. package/dist/server-DKXXFTbw.js.map +0 -1
  56. package/dist/server-G6GtOdaW.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { a as resolveIcon, c as AGENT_INGEST_KIND, d as embedTargetId, f as isFieldDrivenEvery, i as firstDateField, l as FEED_SCHEDULES, o as selectDynamicRecord, t as deriveAll, u as INGEST_KINDS } from "./deriveAll-CMFXDQ_G.js";
1
+ import { A as isFieldDrivenEvery, C as SAFE_SLUG_PATTERN, D as FEED_SCHEDULES, E as AGENT_INGEST_KIND, O as INGEST_KINDS, S as SAFE_RECORD_ID_PATTERN, T as isSafeSlug, b as selectDynamicRecord, h as deriveAll, k as embedTargetId, l as parseIsoDate, u as parseIsoDateTime, v as firstDateField, w as isSafeRecordId, y as resolveIcon } from "./calendarGrid-kO6rGfm0.js";
2
2
  import { isSafeActionTemplatePath, isSafeCustomViewI18nPath, isSafeCustomViewPath } from "./collection/paths.js";
3
3
  import path from "node:path";
4
4
  import { promises, realpathSync } from "node:fs";
@@ -78,7 +78,6 @@ var log = {
78
78
  //#endregion
79
79
  //#region src/collection/server/paths.ts
80
80
  var SCHEMA_FILE = "schema.json";
81
- var SAFE_SLUG_PATTERN = /^[a-zA-Z0-9](?:[a-zA-Z0-9_-]*[a-zA-Z0-9])?$/;
82
81
  /** Sanitise a user-supplied slug into a safe directory-name leaf.
83
82
  * Returns null for anything that fails the slug whitelist OR isn't a
84
83
  * basename (i.e. survives `path.basename` round-trip unchanged).
@@ -91,7 +90,6 @@ function safeSlugName(slug) {
91
90
  if (basename !== slug) return null;
92
91
  return basename;
93
92
  }
94
- var SAFE_RECORD_ID_PATTERN = /^[a-zA-Z0-9](?:[a-zA-Z0-9_.-]*[a-zA-Z0-9])?$/;
95
93
  /** Sanitise a user-supplied record id into a safe filename stem. Like
96
94
  * `safeSlugName` but tolerates interior dots (so natural keys work),
97
95
  * while still rejecting any `..` substring, path separators, and
@@ -634,13 +632,119 @@ ${dataJson}
634
632
  ${templateText}`;
635
633
  }
636
634
  //#endregion
637
- //#region src/collection/server/validate.ts
638
- var MAX_ISSUES = 25;
635
+ //#region src/collection/core/recordZ.ts
636
+ /** derived/embed/toggle are host-computed or projected — never written to
637
+ * the record JSON, so required / value checks must not apply to them. */
639
638
  var COMPUTED_TYPES = /* @__PURE__ */ new Set([
640
639
  "derived",
641
640
  "embed",
642
641
  "toggle"
643
642
  ]);
643
+ /** The emptiness rule shared by `required` and the "only check present
644
+ * values" gate. NOT a truthiness check — `0` and `false` are filled. */
645
+ var isEmptyValue = (value) => value === void 0 || value === null || value === "";
646
+ /** The historical write-gate checks, verbatim: required non-empty, enum
647
+ * membership (compared as strings, so a numeric `5` satisfies `"5"`). */
648
+ function enforcedProblem(key, spec, value) {
649
+ const empty = isEmptyValue(value);
650
+ if (spec.required && empty) return `missing required field '${key}'`;
651
+ if (!empty && spec.type === "enum" && !spec.values.includes(String(value))) return `'${key}' = '${String(value)}' is not one of [${spec.values.join(", ")}]`;
652
+ return null;
653
+ }
654
+ /** Numeric coercion for the strict `number`/`money` check: a plain number,
655
+ * or a non-blank numeric string (renderers coerce those via `Number(...)`,
656
+ * so they display fine). Anything else — arrays (`[]` stringifies to `""`
657
+ * = 0, `[42]` to `"42"`), booleans, objects — is NaN and gets flagged. */
658
+ function coerceNumeric(value) {
659
+ if (typeof value === "number") return value;
660
+ if (typeof value === "string" && value.trim() !== "") return Number(value);
661
+ return NaN;
662
+ }
663
+ /** Report-only per-type checks on a PRESENT value. Date / datetime reuse the
664
+ * calendar's STRICT civil parsers (`parseIsoDate` / `parseIsoDateTime`), so
665
+ * the lint flags exactly the values the calendar / trigger / spawn code
666
+ * would silently drop — impossible days like `2026-02-30`, and datetimes
667
+ * outside the canonical `YYYY-MM-DDTHH:MM[:SS]` shape (e.g. a `Z` suffix,
668
+ * which the day view can't place). `string`-backed types accept anything
669
+ * stringifiable; `ref` existence is out of scope. */
670
+ function strictTypeProblem(key, spec, value) {
671
+ switch (spec.type) {
672
+ case "number":
673
+ case "money": return Number.isFinite(coerceNumeric(value)) ? null : `'${key}' = '${String(value)}' is not numeric (a '${spec.type}' field stores a plain number)`;
674
+ case "boolean": return value === true || value === false ? null : `'${key}' = '${String(value)}' is not a boolean (store true or false, unquoted)`;
675
+ case "date": return parseIsoDate(value) !== null ? null : `'${key}' = '${String(value)}' is not a real YYYY-MM-DD date`;
676
+ case "datetime": return parseIsoDateTime(value) !== null ? null : `'${key}' = '${String(value)}' is not a YYYY-MM-DDTHH:MM datetime (seconds optional, no timezone suffix — the shape the calendar parses)`;
677
+ default: return null;
678
+ }
679
+ }
680
+ /** Strict check for a PRESENT `table` value: an array of row objects, each
681
+ * row conforming to the sub-schema (required / enum / typed sub-values).
682
+ * First row problem wins, prefixed with the row number so the fix is
683
+ * locatable. */
684
+ function strictTableProblem(key, spec, value) {
685
+ if (!Array.isArray(value)) return `'${key}' = '${String(value)}' is not an array of rows (a 'table' field stores an array of row objects)`;
686
+ for (let index = 0; index < value.length; index++) {
687
+ const row = value[index];
688
+ if (!row || typeof row !== "object" || Array.isArray(row)) return `'${key}' row ${index + 1} is not an object`;
689
+ for (const [subKey, subSpec] of Object.entries(spec.of)) {
690
+ const subValue = row[subKey];
691
+ const problem = enforcedProblem(subKey, subSpec, subValue) ?? (isEmptyValue(subValue) ? null : strictTypeProblem(subKey, subSpec, subValue));
692
+ if (problem) return `'${key}' row ${index + 1}: ${problem}`;
693
+ }
694
+ }
695
+ return null;
696
+ }
697
+ /** First problem for one field's stored value under `tier`, or null.
698
+ * Enforced checks always run (and their messages never vary by tier — the
699
+ * scan and the write gate must agree on them); strict adds the per-type
700
+ * layer on present values only. */
701
+ function recordFieldProblem(key, spec, value, tier) {
702
+ const enforced = enforcedProblem(key, spec, value);
703
+ if (enforced || tier === "enforced") return enforced;
704
+ if (isEmptyValue(value)) return null;
705
+ if (spec.type === "table") return strictTableProblem(key, spec, value);
706
+ return strictTypeProblem(key, spec, value);
707
+ }
708
+ var compiled = /* @__PURE__ */ new WeakMap();
709
+ /** Compile `schema.fields` into a zod validator for a stored record.
710
+ * Loose object: unknown keys are allowed and any declared key may be
711
+ * absent (records are user files, not parse-and-rewrite targets —
712
+ * callers validate, they never persist the parse output). The checks run
713
+ * as ONE object-level refine iterating fields in declaration order —
714
+ * per-key shape schemas can't express "key may be absent BUT its absence
715
+ * must still reach the required check", and the single loop keeps the
716
+ * first reported issue identical to the historical first-problem-wins
717
+ * contract. */
718
+ function compileRecordZ(schema, tier) {
719
+ const cached = compiled.get(schema)?.[tier];
720
+ if (cached) return cached;
721
+ const stored = Object.entries(schema.fields).filter(([, spec]) => !COMPUTED_TYPES.has(spec.type));
722
+ const validator = z.looseObject({}).superRefine((record, ctx) => {
723
+ for (const [key, spec] of stored) {
724
+ const problem = recordFieldProblem(key, spec, record[key], tier);
725
+ if (problem) ctx.addIssue({
726
+ code: "custom",
727
+ message: problem,
728
+ path: [key]
729
+ });
730
+ }
731
+ });
732
+ const entry = compiled.get(schema) ?? {};
733
+ entry[tier] = validator;
734
+ compiled.set(schema, entry);
735
+ return validator;
736
+ }
737
+ /** First schema problem on an in-memory record under `tier`, or null. One
738
+ * issue per record keeps the report short and the fix obvious (the
739
+ * historical contract of `validateRecordObject`). */
740
+ function firstRecordProblem(record, schema, tier) {
741
+ const result = compileRecordZ(schema, tier).safeParse(record);
742
+ if (result.success) return null;
743
+ return result.error.issues[0]?.message ?? "record failed schema validation";
744
+ }
745
+ //#endregion
746
+ //#region src/collection/server/validate.ts
747
+ var MAX_ISSUES = 25;
644
748
  /** Read every `<id>.json` under the collection's dataDir and report the
645
749
  * ones that won't load or violate the schema. An empty list means every
646
750
  * record is fine. */
@@ -703,72 +807,70 @@ async function inspectRecord(fullPath, name, schema) {
703
807
  file: name,
704
808
  problem: "not a JSON object — skipped, won't appear"
705
809
  };
706
- const problem = validateRecordObject(parsed, name.replace(/\.json$/, ""), schema);
810
+ const problem = validateRecordObject(parsed, name.replace(/\.json$/, ""), schema, "strict");
707
811
  return problem ? {
708
812
  file: name,
709
813
  problem
710
814
  } : null;
711
815
  }
712
816
  /** First schema problem on an in-memory record (primaryKey↔id mismatch,
713
- * missing required, bad enum value), or null when it's fine. One issue
714
- * per record keeps the report short and the fix obvious. Pure +
715
- * exported so write paths (manageCollection putItems) can gate on the
716
- * SAME rules the post-hoc file scan reports `itemId` is the id the
717
- * record is (or would be) stored under. */
718
- function validateRecordObject(record, itemId, schema) {
817
+ * then the compiled per-field checks see `../core/recordZ` for the two
818
+ * tiers), or null when it's fine. One issue per record keeps the report
819
+ * short and the fix obvious. Pure + exported so write paths
820
+ * (manageCollection putItems) can gate on the SAME enforced rules the
821
+ * post-hoc file scan reports — `itemId` is the id the record is (or
822
+ * would be) stored under. The default `"enforced"` tier keeps every
823
+ * write gate on the historical three checks; only pass `"strict"` from
824
+ * report-only surfaces. */
825
+ function validateRecordObject(record, itemId, schema, tier = "enforced") {
719
826
  const idValue = record[schema.primaryKey];
720
827
  if (typeof idValue !== "string" || idValue !== itemId) return `'${schema.primaryKey}' is '${String(idValue ?? "")}' but must equal the filename ('${itemId}'), or the record can't be opened`;
721
- for (const [field, spec] of Object.entries(schema.fields)) {
722
- if (COMPUTED_TYPES.has(spec.type)) continue;
723
- const value = record[field];
724
- const empty = value === void 0 || value === null || value === "";
725
- if (spec.required && empty) return `missing required field '${field}'`;
726
- if (!empty && spec.type === "enum" && spec.values && !spec.values.includes(String(value))) return `'${field}' = '${String(value)}' is not one of [${spec.values.join(", ")}]`;
727
- }
728
- return null;
828
+ return firstRecordProblem(record, schema, tier);
729
829
  }
730
830
  //#endregion
731
- //#region src/collection/server/discovery.ts
732
- var refRefine = (spec) => {
733
- if (spec.type !== "ref") return true;
734
- if (typeof spec.to !== "string") return false;
735
- return safeSlugName(spec.to) !== null;
736
- };
737
- var refMessage = {
738
- message: "fields with type 'ref' must declare a `to` that is a valid collection slug (alphanumeric / hyphen / underscore, no path separators)",
739
- path: ["to"]
740
- };
741
- var isDateLike = (type) => type === "date" || type === "datetime";
742
- var isTimeStringField = (type) => type === "string" || type === "text";
743
- var embedRefine = (spec) => {
744
- if (spec.type !== "embed") return true;
745
- if (typeof spec.to !== "string" || safeSlugName(spec.to) === null) return false;
746
- return (typeof spec.id === "string" && spec.id.trim().length > 0) !== (typeof spec.idField === "string" && spec.idField.trim().length > 0);
747
- };
748
- var embedMessage = {
749
- message: "fields with type 'embed' must declare a `to` (valid collection slug) and exactly one of `id` (a fixed record's primary key) or `idField` (a sibling field naming the per-record target)",
750
- path: ["id"]
751
- };
752
- var enumRefine = (spec) => spec.type !== "enum" || Array.isArray(spec.values) && spec.values.length > 0 && spec.values.every((value) => typeof value === "string" && value.length > 0);
753
- var enumMessage = {
754
- message: "fields with type 'enum' must declare a non-empty `values` array of non-empty strings",
755
- path: ["values"]
831
+ //#region src/collection/core/schemaZ.ts
832
+ /** Optional visibility predicate shared by actions and fields: the target
833
+ * shows only when the open record's `field` (stringified) is one of `in`.
834
+ * Domain-free `field` is any non-empty key, `in` a non-empty array of
835
+ * non-empty values; the host never interprets the meaning.
836
+ *
837
+ * `trim().min(1)` rather than bare `min(1)` so a whitespace-only string
838
+ * (" ") fails validation otherwise the cell formatter / dropdown would
839
+ * render visual blanks that look like missing data. Applied consistently to
840
+ * every "non-empty string" slot in this file (CodeRabbit PR #1497). */
841
+ var WhenZ = z.object({
842
+ field: z.string().trim().min(1),
843
+ in: z.array(z.string().trim().min(1)).min(1)
844
+ });
845
+ var fieldBase = {
846
+ label: z.string().min(1),
847
+ primary: z.boolean().optional(),
848
+ required: z.boolean().optional(),
849
+ when: WhenZ.optional()
756
850
  };
757
- var currencyRefine = (spec) => {
758
- if (!(spec.type === "money" || spec.type === "derived" && spec.display === "money")) return true;
759
- const hasLiteral = typeof spec.currency === "string" && spec.currency.trim().length > 0;
760
- const hasPointer = typeof spec.currencyField === "string" && spec.currencyField.trim().length > 0;
761
- return hasLiteral || hasPointer;
851
+ var currencyKeys = {
852
+ currency: z.string().trim().min(1).optional(),
853
+ currencyField: z.string().trim().min(1).optional()
762
854
  };
855
+ var hasCurrencySource = (spec) => spec.currency !== void 0 || spec.currencyField !== void 0;
763
856
  var currencyMessage = {
764
857
  message: "fields that render as money (type 'money', or 'derived' with display 'money') must declare either a literal `currency` (ISO 4217 code, e.g. 'USD', 'JPY') or a `currencyField` naming the record field that holds the code",
765
858
  path: ["currency"]
766
859
  };
767
- var WhenSchema = z.object({
768
- field: z.string().trim().min(1),
769
- in: z.array(z.string().trim().min(1)).min(1)
860
+ var slugMessage = (key) => ({
861
+ message: `\`${key}\` must be a valid collection slug (alphanumeric / hyphen / underscore, no path separators)`,
862
+ path: [key]
770
863
  });
771
- var SubFieldSpecSchema = z.object({
864
+ /** The plain scalar field types. Stored and edited as primitive values; no
865
+ * variant-specific keys.
866
+ * - `image`: a workspace-relative image path (e.g. a `data/attachments/...`
867
+ * upload); rendered as an <img> in the detail view (not the list table —
868
+ * a per-row fetch is too expensive at scale). Stored as a plain string.
869
+ * - `file`: a workspace-relative file path as a plain string (e.g. an
870
+ * `artifacts/html/<name>.html` app). Rendered as a clickable link in both
871
+ * the list table and the detail view: HTML / SVG artifacts open their
872
+ * rendered form in a new tab; any other path opens in the File Explorer. */
873
+ var ScalarFieldZ = z.object({
772
874
  type: z.enum([
773
875
  "string",
774
876
  "text",
@@ -778,18 +880,39 @@ var SubFieldSpecSchema = z.object({
778
880
  "datetime",
779
881
  "boolean",
780
882
  "markdown",
781
- "ref",
782
- "money",
783
- "enum"
883
+ "image",
884
+ "file"
784
885
  ]),
886
+ ...fieldBase
887
+ });
888
+ /** A link to another collection: the record stores the target item's
889
+ * primary-key slug and the host renders a clickable link + dropdown picker.
890
+ * `to` must be a real slug (not `../foo`, not `mc-clients/extra` — see
891
+ * Codex P2 on PR #1495); whether the target collection exists resolves
892
+ * fail-soft at render time, never here. */
893
+ var RefFieldZ = z.object({
894
+ type: z.literal("ref"),
895
+ ...fieldBase,
896
+ to: z.string().min(1)
897
+ }).refine((spec) => isSafeSlug(spec.to), slugMessage("to"));
898
+ /** A money amount. See `currencyKeys` for the currency-source contract. */
899
+ var MoneyFieldZ = z.object({
900
+ type: z.literal("money"),
901
+ ...fieldBase,
902
+ ...currencyKeys
903
+ }).refine(hasCurrencySource, currencyMessage);
904
+ /** A closed set of allowed string values. The form renders a `<select>`
905
+ * populated from `values`; storage is a plain string. */
906
+ var EnumFieldZ = z.object({
907
+ type: z.literal("enum"),
908
+ ...fieldBase,
909
+ values: z.array(z.string().trim().min(1)).min(1)
910
+ });
911
+ var subFieldBase = {
785
912
  label: z.string().min(1),
786
- required: z.boolean().optional(),
787
- to: z.string().min(1).optional(),
788
- currency: z.string().trim().min(1).optional(),
789
- currencyField: z.string().trim().min(1).optional(),
790
- values: z.array(z.string().trim().min(1)).min(1).optional()
791
- }).refine(refRefine, refMessage).refine(enumRefine, enumMessage).refine(currencyRefine, currencyMessage);
792
- var FieldSpecSchema = z.object({
913
+ required: z.boolean().optional()
914
+ };
915
+ var SubScalarFieldZ = z.object({
793
916
  type: z.enum([
794
917
  "string",
795
918
  "text",
@@ -798,62 +921,126 @@ var FieldSpecSchema = z.object({
798
921
  "date",
799
922
  "datetime",
800
923
  "boolean",
801
- "markdown",
802
- "ref",
803
- "money",
804
- "enum",
805
- "table",
806
- "derived",
807
- "embed",
808
- "image",
809
- "file",
810
- "toggle"
924
+ "markdown"
811
925
  ]),
812
- label: z.string().min(1),
813
- primary: z.boolean().optional(),
814
- required: z.boolean().optional(),
815
- to: z.string().min(1).optional(),
816
- id: z.string().trim().min(1).optional(),
817
- idField: z.string().trim().min(1).optional(),
818
- currency: z.string().trim().min(1).optional(),
819
- currencyField: z.string().trim().min(1).optional(),
820
- values: z.array(z.string().trim().min(1)).min(1).optional(),
821
- field: z.string().trim().min(1).optional(),
822
- onValue: z.string().trim().min(1).optional(),
823
- offValue: z.string().trim().min(1).optional(),
824
- of: z.record(z.string(), SubFieldSpecSchema).optional(),
825
- formula: z.string().trim().min(1).optional(),
826
- /** Inner type to render a derived value as (e.g. `"money"`).
827
- * Restricted to the non-composite display targets — derived
828
- * values are scalars, so rendering them via `table` or another
829
- * `derived` would be meaningless. */
926
+ ...subFieldBase
927
+ });
928
+ var SubRefFieldZ = z.object({
929
+ type: z.literal("ref"),
930
+ ...subFieldBase,
931
+ to: z.string().min(1)
932
+ }).refine((spec) => isSafeSlug(spec.to), slugMessage("to"));
933
+ var SubMoneyFieldZ = z.object({
934
+ type: z.literal("money"),
935
+ ...subFieldBase,
936
+ ...currencyKeys
937
+ }).refine(hasCurrencySource, currencyMessage);
938
+ var SubEnumFieldZ = z.object({
939
+ type: z.literal("enum"),
940
+ ...subFieldBase,
941
+ values: z.array(z.string().trim().min(1)).min(1)
942
+ });
943
+ var SubFieldSpecZ = z.discriminatedUnion("type", [
944
+ SubScalarFieldZ,
945
+ SubRefFieldZ,
946
+ SubMoneyFieldZ,
947
+ SubEnumFieldZ
948
+ ]);
949
+ /** A flat sub-table: each row is a record of `of`'s sub-schema (insertion
950
+ * order = column order). v0 disallows nested tables and derived columns to
951
+ * keep the editor + evaluator simple. */
952
+ var TableFieldZ = z.object({
953
+ type: z.literal("table"),
954
+ ...fieldBase,
955
+ of: z.record(z.string(), SubFieldSpecZ)
956
+ }).refine((spec) => Object.keys(spec.of).length > 0, {
957
+ message: "fields with type 'table' must declare a non-empty `of` (sub-schema for each row)",
958
+ path: ["of"]
959
+ });
960
+ /** A computed scalar: `formula` is a tiny expression evaluated against the
961
+ * record — `+ - * /`, parens, identifier refs to top-level fields,
962
+ * `sum(tableField[].col)`, and `sum(tableField[].col * tableField[].col)`
963
+ * (see `./derivedFormula`). `display` picks the inner type the value renders
964
+ * as (default `"number"`) — restricted to the non-composite display targets,
965
+ * since a derived value is a scalar. Never stored; computed by `deriveAll`
966
+ * on both server and client. */
967
+ var DerivedFieldZ = z.object({
968
+ type: z.literal("derived"),
969
+ ...fieldBase,
970
+ formula: z.string().trim().min(1),
830
971
  display: z.enum([
831
972
  "string",
832
973
  "number",
833
974
  "money",
834
975
  "date"
835
976
  ]).optional(),
836
- when: WhenSchema.optional()
837
- }).refine(refRefine, refMessage).refine(enumRefine, enumMessage).refine(embedRefine, embedMessage).refine(currencyRefine, currencyMessage).refine((spec) => spec.type !== "table" || spec.of !== void 0 && Object.keys(spec.of).length > 0, {
838
- message: "fields with type 'table' must declare a non-empty `of` (sub-schema for each row)",
839
- path: ["of"]
840
- }).refine((spec) => spec.type !== "derived" || typeof spec.formula === "string" && spec.formula.length > 0, {
841
- message: "fields with type 'derived' must declare a non-empty `formula` (see src/utils/collections/derivedFormula.ts)",
842
- path: ["formula"]
843
- }).refine((spec) => spec.type !== "toggle" || typeof spec.field === "string" && spec.field.length > 0 && typeof spec.onValue === "string" && typeof spec.offValue === "string", {
844
- message: "fields with type 'toggle' must declare `field` (the enum field to project), `onValue`, and `offValue`",
845
- path: ["field"]
977
+ ...currencyKeys
978
+ }).refine((spec) => spec.display !== "money" || hasCurrencySource(spec), currencyMessage);
979
+ /** Pulls a record from another collection into the read-only detail view.
980
+ * Display-only — nothing is stored on this record, so it never appears in
981
+ * the list table or the edit form. Must declare a valid `to` slug (same
982
+ * path-traversal guard as `ref`) AND exactly one of `id` (a fixed target
983
+ * record, e.g. `me` for the singleton profile — same for every record) or
984
+ * `idField` (a sibling top-level field naming the per-record target, e.g.
985
+ * an invoice's `issuerId` selecting which profile to embed as the bill-from
986
+ * block; an absent/empty value resolves fail-soft to "no record"). The
987
+ * `idField` target is validated to be a real `ref`/`string` field by a
988
+ * schema-level refine below. */
989
+ var EmbedFieldZ = z.object({
990
+ type: z.literal("embed"),
991
+ ...fieldBase,
992
+ to: z.string().min(1),
993
+ id: z.string().trim().min(1).optional(),
994
+ idField: z.string().trim().min(1).optional()
995
+ }).refine((spec) => isSafeSlug(spec.to) && spec.id !== void 0 !== (spec.idField !== void 0), {
996
+ message: "fields with type 'embed' must declare a `to` (valid collection slug) and exactly one of `id` (a fixed record's primary key) or `idField` (a sibling field naming the per-record target)",
997
+ path: ["id"]
998
+ });
999
+ /** A checkbox that is a pure PROJECTION of an `enum` field — it stores
1000
+ * nothing of its own. Checked when the enum named by `field` equals
1001
+ * `onValue`; toggling writes `onValue` / `offValue` back to that enum
1002
+ * field. Lets a "done" checkbox front a kanban `status` field with the enum
1003
+ * as the single source of truth (no separate stored boolean to keep in
1004
+ * sync). `field` / `onValue` / `offValue` are validated against the target
1005
+ * enum's `values` by a schema-level refine below. */
1006
+ var ToggleFieldZ = z.object({
1007
+ type: z.literal("toggle"),
1008
+ ...fieldBase,
1009
+ field: z.string().trim().min(1),
1010
+ onValue: z.string().trim().min(1),
1011
+ offValue: z.string().trim().min(1)
846
1012
  });
847
- var ActionSpecSchema = z.object({
1013
+ var FieldSpecZ = z.discriminatedUnion("type", [
1014
+ ScalarFieldZ,
1015
+ RefFieldZ,
1016
+ MoneyFieldZ,
1017
+ EnumFieldZ,
1018
+ TableFieldZ,
1019
+ DerivedFieldZ,
1020
+ EmbedFieldZ,
1021
+ ToggleFieldZ
1022
+ ]);
1023
+ /** A schema-declared record action, rendered as a button in the read-only
1024
+ * detail view. Domain-free: the host validates the shape; the meaning
1025
+ * (which role, which template) is data. v1 ships only `kind: "chat"` —
1026
+ * start a new chat in `role` with a templated seed prompt; the enum
1027
+ * reserves room for a future `"mutate"` (status transitions) without
1028
+ * another schema-shape change. */
1029
+ var ActionSpecZ = z.object({
848
1030
  id: z.string().trim().min(1),
849
1031
  label: z.string().trim().min(1),
850
1032
  icon: z.string().trim().min(1).optional(),
851
1033
  kind: z.enum(["chat"]),
852
1034
  role: z.string().trim().min(1),
853
1035
  template: z.string().trim().min(1).refine(isSafeActionTemplatePath, "must be a safe path under `templates/` (e.g. `templates/invoice.md`; no `..`, no leading `/`, no backslash)"),
854
- when: WhenSchema.optional()
1036
+ when: WhenZ.optional()
855
1037
  });
856
- var CustomViewSchema = z.object({
1038
+ /** A custom (LLM-authored) HTML view registration. Domain-free: the host
1039
+ * validates the shape; the view's behaviour lives in the HTML file. `file`
1040
+ * is constrained to `views/*.html` (path-safe) so the view-file reader can
1041
+ * never reach the data folder or the schema/template files. `id` is
1042
+ * validated to be a real slug + unique by schema-level refines below. */
1043
+ var CustomViewZ = z.object({
857
1044
  id: z.string().trim().min(1),
858
1045
  label: z.string().trim().min(1),
859
1046
  icon: z.string().trim().min(1).optional(),
@@ -866,7 +1053,14 @@ var CustomViewSchema = z.object({
866
1053
  imageFields: z.array(z.string().trim().min(1)).optional(),
867
1054
  imageMaxEdge: z.number().int().min(1).optional()
868
1055
  });
869
- var EveryLiteralSchema = z.object({
1056
+ /** Recurrence advance for `spawn.every`. `interval` is a positive integer
1057
+ * count of `unit`s (`interval: 3` + `unit: "month"` = quarterly);
1058
+ * `dayOfMonth` (month/year only) is the CANONICAL day-of-month anchor
1059
+ * (1-31, read from the rule and clamped per-month at compute time so "31st
1060
+ * of every month" never drifts) or the `"last"` sentinel for end-of-month.
1061
+ * `.strict()` so the union below cleanly rejects an object carrying BOTH
1062
+ * `unit` and `fromField` (it fails this arm on the unknown `fromField`). */
1063
+ var EveryLiteralZ = z.object({
870
1064
  unit: z.enum([
871
1065
  "day",
872
1066
  "week",
@@ -876,17 +1070,114 @@ var EveryLiteralSchema = z.object({
876
1070
  interval: z.number().int().min(1),
877
1071
  dayOfMonth: z.union([z.number().int().min(1).max(31), z.literal("last")]).optional()
878
1072
  }).strict();
879
- var EveryFieldDrivenSchema = z.object({
1073
+ /** Field-driven recurrence: pick the interval per-record by an `enum`
1074
+ * field's value — one collection can mix daily / weekly / monthly
1075
+ * obligations in a single list. `map` keys are validated to exactly cover
1076
+ * that field's `values` by a `CollectionSchemaZ` refine (which can see the
1077
+ * sibling `fields`); here each map value just has to be a well-formed
1078
+ * literal `every`. `.strict()` mirrors the literal arm so a both-keys
1079
+ * object fails this arm too. */
1080
+ var EveryFieldDrivenZ = z.object({
880
1081
  fromField: z.string().trim().min(1),
881
- map: z.record(z.string(), EveryLiteralSchema)
1082
+ map: z.record(z.string(), EveryLiteralZ)
882
1083
  }).strict();
883
- var EverySchema = z.union([EveryLiteralSchema, EveryFieldDrivenSchema]);
884
- var SpawnSchema = z.object({
885
- when: WhenSchema.optional(),
886
- every: EverySchema,
1084
+ /** Either a single literal interval (applied to every record) or the
1085
+ * field-driven map. Two `.strict()` arms mean "both keys" and "neither
1086
+ * key" both fail validation, with no extra refine. */
1087
+ var EveryZ = z.union([EveryLiteralZ, EveryFieldDrivenZ]);
1088
+ /** Host-driven recurrence: when a record satisfies `when` (default:
1089
+ * "`completionField` value ∈ `completionDoneValues`"), the host creates the
1090
+ * next record with a forward-advanced `triggerField` date. `carry` copies
1091
+ * record fields verbatim onto the successor; `set` forces fixed values
1092
+ * (typically resetting the status field to its pending value). The
1093
+ * successor's id and contents are a pure function of (source record, this
1094
+ * rule); creation is create-if-absent, so the mechanism stays convergent. */
1095
+ var SpawnZ = z.object({
1096
+ when: WhenZ.optional(),
1097
+ every: EveryZ,
887
1098
  carry: z.array(z.string().trim().min(1)).optional(),
888
1099
  set: z.record(z.string(), z.unknown()).optional()
889
1100
  });
1101
+ /** Declarative retrieval config for a Feed (a collection that refills itself
1102
+ * from the internet). `http-json` needs `itemsAt` (a path to the items
1103
+ * array) only when the response body isn't itself the array; rss/atom yield
1104
+ * items natively and ignore it — so no kind-specific requirement here. */
1105
+ var DeclarativeIngestZ = z.object({
1106
+ kind: z.enum(INGEST_KINDS),
1107
+ url: z.string().url(),
1108
+ schedule: z.enum(FEED_SCHEDULES),
1109
+ atHour: z.number().int().min(0).max(23).optional(),
1110
+ itemsAt: z.string().trim().min(1).optional(),
1111
+ map: z.record(z.string().trim().min(1), z.string().trim().min(1)),
1112
+ idFrom: z.string().trim().min(1).optional(),
1113
+ maxItems: z.number().int().min(0).optional()
1114
+ });
1115
+ /** Agent-performed retrieval. Valid on any collection (the primary consumer
1116
+ * is skill-backed collections — feeds keep their declarative kinds). No
1117
+ * `url`/`map`: the worker owns retrieval and record shape, seeded by
1118
+ * `template` + a summary of every record, run in `role`. `template` is
1119
+ * validated the SAME way an action's template is (safe path under
1120
+ * `templates/`), so the skill-bridge mirrors it identically. */
1121
+ var AgentIngestZ = z.object({
1122
+ kind: z.literal(AGENT_INGEST_KIND),
1123
+ schedule: z.enum(FEED_SCHEDULES),
1124
+ atHour: z.number().int().min(0).max(23).optional(),
1125
+ role: z.string().trim().min(1),
1126
+ template: z.string().trim().min(1).refine(isSafeActionTemplatePath, "must be a safe path under `templates/` (e.g. `templates/refresh.md`; no `..`, no leading `/`, no backslash)")
1127
+ });
1128
+ /** `ingest` is a discriminated union on `kind`: the three declarative
1129
+ * retrievers fetch-and-map; `agent` dispatches a hidden worker. Optional on
1130
+ * every schema — skill-backed collections usually omit it; only feeds
1131
+ * discovered from `<workspace>/feeds/` are REQUIRED to carry it (gated by
1132
+ * `acceptParsedSchema`). */
1133
+ var IngestZ = z.discriminatedUnion("kind", [DeclarativeIngestZ, AgentIngestZ]);
1134
+ var ValueRefZ = z.object({
1135
+ record: z.string().trim().min(1).optional(),
1136
+ field: z.string().trim().min(1)
1137
+ });
1138
+ var WhereCondZ = z.object({
1139
+ field: z.string().trim().min(1),
1140
+ op: z.enum([
1141
+ "eq",
1142
+ "ne",
1143
+ "in",
1144
+ "gt",
1145
+ "gte",
1146
+ "lt",
1147
+ "lte",
1148
+ "contains"
1149
+ ]),
1150
+ value: z.union([z.string(), z.array(z.string())]).optional(),
1151
+ valueFrom: ValueRefZ.optional()
1152
+ }).refine((cond) => cond.value !== void 0 !== (cond.valueFrom !== void 0), {
1153
+ message: "a where condition must declare exactly one of `value` (a literal) or `valueFrom` (a reference to another record's field), never both or neither",
1154
+ path: ["value"]
1155
+ }).refine((cond) => cond.value === void 0 || cond.op === "in" === Array.isArray(cond.value), {
1156
+ message: "`in` requires an array `value` (the allowed set); every other op requires a single string `value`",
1157
+ path: ["value"]
1158
+ });
1159
+ var WhereZ = z.array(WhereCondZ);
1160
+ var DynamicIconSourceZ = z.object({
1161
+ collection: z.string().trim().min(1),
1162
+ from: z.enum([
1163
+ "latest",
1164
+ "first",
1165
+ "when"
1166
+ ]).optional(),
1167
+ orderBy: z.string().trim().min(1).optional(),
1168
+ where: WhereZ.optional()
1169
+ });
1170
+ var DynamicIconRuleZ = z.object({
1171
+ where: WhereZ,
1172
+ icon: z.string().trim().min(1)
1173
+ });
1174
+ var DynamicIconSpecZ = z.object({
1175
+ source: DynamicIconSourceZ,
1176
+ rules: z.array(DynamicIconRuleZ),
1177
+ fallback: z.string().trim().min(1).optional()
1178
+ });
1179
+ var isDateLike = (type) => type === "date" || type === "datetime";
1180
+ var isTimeStringField = (type) => type === "string" || type === "text";
890
1181
  var CODE_FIELD_TYPES = /* @__PURE__ */ new Set([
891
1182
  "string",
892
1183
  "text",
@@ -924,7 +1215,7 @@ function spawnSuccessorStartsInert(schema) {
924
1215
  }
925
1216
  function fieldDrivenSpawnEvery(schema) {
926
1217
  const every = schema.spawn?.every;
927
- if (!every || !isFieldDrivenEvery(every)) return null;
1218
+ if (!every || !("fromField" in every)) return null;
928
1219
  return every;
929
1220
  }
930
1221
  function fieldDrivenFromFieldIsEnum(schema) {
@@ -952,93 +1243,30 @@ function fieldDrivenFromFieldCarried(schema) {
952
1243
  }
953
1244
  return (carry ?? []).includes(driven.fromField);
954
1245
  }
955
- var DeclarativeIngestZ = z.object({
956
- kind: z.enum(INGEST_KINDS),
957
- url: z.string().url(),
958
- schedule: z.enum(FEED_SCHEDULES),
959
- atHour: z.number().int().min(0).max(23).optional(),
960
- itemsAt: z.string().trim().min(1).optional(),
961
- map: z.record(z.string().trim().min(1), z.string().trim().min(1)),
962
- idFrom: z.string().trim().min(1).optional(),
963
- maxItems: z.number().int().min(0).optional()
964
- });
965
- var AgentIngestZ = z.object({
966
- kind: z.literal(AGENT_INGEST_KIND),
967
- schedule: z.enum(FEED_SCHEDULES),
968
- atHour: z.number().int().min(0).max(23).optional(),
969
- role: z.string().trim().min(1),
970
- template: z.string().trim().min(1).refine(isSafeActionTemplatePath, "must be a safe path under `templates/` (e.g. `templates/refresh.md`; no `..`, no leading `/`, no backslash)")
971
- });
972
- var IngestSchemaZ = z.discriminatedUnion("kind", [DeclarativeIngestZ, AgentIngestZ]);
973
- var ValueRefZ = z.object({
974
- record: z.string().trim().min(1).optional(),
975
- field: z.string().trim().min(1)
976
- });
977
- var WhereCondZ = z.object({
978
- field: z.string().trim().min(1),
979
- op: z.enum([
980
- "eq",
981
- "ne",
982
- "in",
983
- "gt",
984
- "gte",
985
- "lt",
986
- "lte",
987
- "contains"
988
- ]),
989
- value: z.union([z.string(), z.array(z.string())]).optional(),
990
- valueFrom: ValueRefZ.optional()
991
- }).refine((cond) => cond.value !== void 0 !== (cond.valueFrom !== void 0), {
992
- message: "a where condition must declare exactly one of `value` (a literal) or `valueFrom` (a reference to another record's field), never both or neither",
993
- path: ["value"]
994
- }).refine((cond) => cond.value === void 0 || cond.op === "in" === Array.isArray(cond.value), {
995
- message: "`in` requires an array `value` (the allowed set); every other op requires a single string `value`",
996
- path: ["value"]
997
- });
998
- var WhereZ = z.array(WhereCondZ);
999
- var DynamicIconSourceZ = z.object({
1000
- collection: z.string().trim().min(1),
1001
- from: z.enum([
1002
- "latest",
1003
- "first",
1004
- "when"
1005
- ]).optional(),
1006
- orderBy: z.string().trim().min(1).optional(),
1007
- where: WhereZ.optional()
1008
- });
1009
- var DynamicIconRuleZ = z.object({
1010
- where: WhereZ,
1011
- icon: z.string().trim().min(1)
1012
- });
1013
- var DynamicIconSpecZ = z.object({
1014
- source: DynamicIconSourceZ,
1015
- rules: z.array(DynamicIconRuleZ),
1016
- fallback: z.string().trim().min(1).optional()
1017
- });
1018
1246
  var CollectionSchemaZ = z.object({
1019
1247
  title: z.string().min(1),
1020
1248
  icon: z.string().min(1),
1021
1249
  dataPath: z.string().min(1),
1022
1250
  primaryKey: z.string().min(1),
1023
1251
  singleton: z.string().trim().min(1).optional(),
1024
- fields: z.record(z.string(), FieldSpecSchema),
1025
- actions: z.array(ActionSpecSchema).optional(),
1026
- collectionActions: z.array(ActionSpecSchema).optional(),
1252
+ fields: z.record(z.string(), FieldSpecZ),
1253
+ actions: z.array(ActionSpecZ).optional(),
1254
+ collectionActions: z.array(ActionSpecZ).optional(),
1027
1255
  completionField: z.string().trim().min(1).optional(),
1028
1256
  completionDoneValues: z.array(z.string().trim().min(1)).min(1).optional(),
1029
1257
  displayField: z.string().trim().min(1).optional(),
1030
1258
  triggerField: z.string().trim().min(1).optional(),
1031
1259
  triggerLeadDays: z.number().int().min(0).optional(),
1032
- spawn: SpawnSchema.optional(),
1260
+ spawn: SpawnZ.optional(),
1033
1261
  calendarField: z.string().trim().min(1).optional(),
1034
1262
  calendarEndField: z.string().trim().min(1).optional(),
1035
1263
  calendarTimeField: z.string().trim().min(1).optional(),
1036
1264
  kanbanField: z.string().trim().min(1).optional(),
1037
- views: z.array(CustomViewSchema).optional(),
1038
- notifyWhen: WhenSchema.optional(),
1039
- ingest: IngestSchemaZ.optional(),
1265
+ views: z.array(CustomViewZ).optional(),
1266
+ notifyWhen: WhenZ.optional(),
1267
+ ingest: IngestZ.optional(),
1040
1268
  dynamicIcon: DynamicIconSpecZ.optional()
1041
- }).refine((schema) => schema.singleton === void 0 || safeRecordId(schema.singleton) !== null, {
1269
+ }).refine((schema) => schema.singleton === void 0 || isSafeRecordId(schema.singleton), {
1042
1270
  message: "schema `singleton` must be a valid item id (alphanumeric / hyphen / underscore / interior dot, no `..` or path separators)",
1043
1271
  path: ["singleton"]
1044
1272
  }).refine((schema) => schema.actions === void 0 || new Set(schema.actions.map((action) => action.id)).size === schema.actions.length, {
@@ -1129,13 +1357,15 @@ var CollectionSchemaZ = z.object({
1129
1357
  }).refine((schema) => schema.notifyWhen === void 0 || schema.fields[schema.notifyWhen.field] !== void 0, {
1130
1358
  message: "schema `notifyWhen.field` must name a top-level field declared in `fields`",
1131
1359
  path: ["notifyWhen"]
1132
- }).refine((schema) => schema.views === void 0 || schema.views.every((view) => safeSlugName(view.id) !== null), {
1360
+ }).refine((schema) => schema.views === void 0 || schema.views.every((view) => isSafeSlug(view.id)), {
1133
1361
  message: "every `views[].id` must be a valid slug (alphanumeric / hyphen / underscore, no path separators)",
1134
1362
  path: ["views"]
1135
1363
  }).refine((schema) => schema.views === void 0 || new Set(schema.views.map((view) => view.id)).size === schema.views.length, {
1136
1364
  message: "schema `views` must have unique `id`s",
1137
1365
  path: ["views"]
1138
1366
  });
1367
+ //#endregion
1368
+ //#region src/collection/server/discovery.ts
1139
1369
  function applyFeedSchemaDefaults(parsed, slug) {
1140
1370
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return parsed;
1141
1371
  const obj = parsed;
@@ -1915,6 +2145,6 @@ async function deleteCustomView(collection, viewId, opts = {}) {
1915
2145
  };
1916
2146
  }
1917
2147
  //#endregion
1918
- export { listItems as A, isContainedInRoot as B, COMPUTED_TYPES as C, buildCollectionActionSeedPrompt as D, buildActionSeedPrompt as E, readSkillTemplate as F, safeRecordId as G, itemFilePath as H, resolveCreateItemId as I, configureCollectionHost as J, safeSlugName as K, writeItem as L, readCustomViewHtml as M, readCustomViewI18n as N, deleteItem as O, readItem as P, setCollectionChangePublisher as Q, writeFileAtomic as R, toSummary as S, validateRecordObject as T, resolveDataDir as U, isContainedInWorkspace as V, resolveTemplatePath as W, log as X, getWorkspaceRoot as Y, publishCollectionChange as Z, CollectionSchemaZ as _, computeSuccessor as a, loadCollection as b, isTriggerDue as c, resolveEvery as d, successorId as f, enrichItems as g, computeCollectionIcon as h, advanceTriggerDate as i, promptPathsFor as j, generateItemId as k, maybeSpawnSuccessor as l, errorMessage as m, deleteCollection as n, daysInMonth as o, ONE_SECOND_MS as p, collectionsRegistriesConfigPath as q, deleteCollectionRefusalMessage as r, formatCivil as s, deleteCustomView as t, parseCivil as u, acceptParsedSchema as v, validateCollectionRecords as w, toDetail as x, discoverCollections as y, SCHEMA_FILE as z };
2148
+ export { publishCollectionChange as $, deleteItem as A, writeFileAtomic as B, validateCollectionRecords as C, recordFieldProblem as D, compileRecordZ as E, readCustomViewI18n as F, resolveDataDir as G, isContainedInRoot as H, readItem as I, safeSlugName as J, resolveTemplatePath as K, readSkillTemplate as L, listItems as M, promptPathsFor as N, buildActionSeedPrompt as O, readCustomViewHtml as P, log as Q, resolveCreateItemId as R, CollectionSchemaZ as S, COMPUTED_TYPES as T, isContainedInWorkspace as U, SCHEMA_FILE as V, itemFilePath as W, configureCollectionHost as X, collectionsRegistriesConfigPath as Y, getWorkspaceRoot as Z, acceptParsedSchema as _, computeSuccessor as a, toDetail as b, isTriggerDue as c, resolveEvery as d, setCollectionChangePublisher as et, successorId as f, enrichItems as g, computeCollectionIcon as h, advanceTriggerDate as i, generateItemId as j, buildCollectionActionSeedPrompt as k, maybeSpawnSuccessor as l, errorMessage as m, deleteCollection as n, daysInMonth as o, ONE_SECOND_MS as p, safeRecordId as q, deleteCollectionRefusalMessage as r, formatCivil as s, deleteCustomView as t, parseCivil as u, discoverCollections as v, validateRecordObject as w, toSummary as x, loadCollection as y, writeItem as z };
1919
2149
 
1920
- //# sourceMappingURL=server-DKXXFTbw.js.map
2150
+ //# sourceMappingURL=server-Cc6XcyOA.js.map