@caelo-cms/shared 0.10.71 → 0.11.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 (202) hide show
  1. package/dist/ai-tools.d.ts +125 -50
  2. package/dist/ai-tools.d.ts.map +1 -1
  3. package/dist/ai-tools.js +50 -38
  4. package/dist/ai-tools.js.map +1 -1
  5. package/dist/build-page.d.ts +110 -30
  6. package/dist/build-page.d.ts.map +1 -1
  7. package/dist/build-page.js +26 -7
  8. package/dist/build-page.js.map +1 -1
  9. package/dist/content.d.ts +203 -102
  10. package/dist/content.d.ts.map +1 -1
  11. package/dist/content.js +178 -76
  12. package/dist/content.js.map +1 -1
  13. package/dist/css-var-aliases.d.ts +20 -0
  14. package/dist/css-var-aliases.d.ts.map +1 -0
  15. package/dist/css-var-aliases.js +95 -0
  16. package/dist/css-var-aliases.js.map +1 -0
  17. package/dist/css-var-scan.d.ts +0 -16
  18. package/dist/css-var-scan.d.ts.map +1 -1
  19. package/dist/css-var-scan.js +24 -0
  20. package/dist/css-var-scan.js.map +1 -1
  21. package/dist/edit-markers.d.ts +41 -5
  22. package/dist/edit-markers.d.ts.map +1 -1
  23. package/dist/edit-markers.js +47 -50
  24. package/dist/edit-markers.js.map +1 -1
  25. package/dist/id-safe-truncate.d.ts +15 -0
  26. package/dist/id-safe-truncate.d.ts.map +1 -0
  27. package/dist/id-safe-truncate.js +47 -0
  28. package/dist/id-safe-truncate.js.map +1 -0
  29. package/dist/index.d.ts +5 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +5 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/interactions.js +2 -2
  34. package/dist/interactions.js.map +1 -1
  35. package/dist/link-canonicalise.d.ts.map +1 -1
  36. package/dist/link-canonicalise.js +7 -1
  37. package/dist/link-canonicalise.js.map +1 -1
  38. package/dist/link-refs.d.ts +1 -1
  39. package/dist/link-refs.js +3 -3
  40. package/dist/lists/address.d.ts +34 -0
  41. package/dist/lists/address.d.ts.map +1 -0
  42. package/dist/lists/address.js +43 -0
  43. package/dist/lists/address.js.map +1 -0
  44. package/dist/lists/default-types.d.ts +10 -0
  45. package/dist/lists/default-types.d.ts.map +1 -0
  46. package/dist/lists/default-types.js +91 -0
  47. package/dist/lists/default-types.js.map +1 -0
  48. package/dist/lists/fields.d.ts +152 -0
  49. package/dist/lists/fields.d.ts.map +1 -0
  50. package/dist/lists/fields.js +258 -0
  51. package/dist/lists/fields.js.map +1 -0
  52. package/dist/lists/index.d.ts +14 -0
  53. package/dist/lists/index.d.ts.map +1 -0
  54. package/dist/lists/index.js +15 -0
  55. package/dist/lists/index.js.map +1 -0
  56. package/dist/lists/item-attr.d.ts +26 -0
  57. package/dist/lists/item-attr.d.ts.map +1 -0
  58. package/dist/lists/item-attr.js +31 -0
  59. package/dist/lists/item-attr.js.map +1 -0
  60. package/dist/lists/items.d.ts +105 -0
  61. package/dist/lists/items.d.ts.map +1 -0
  62. package/dist/lists/items.js +304 -0
  63. package/dist/lists/items.js.map +1 -0
  64. package/dist/lists/list-type.d.ts +401 -0
  65. package/dist/lists/list-type.d.ts.map +1 -0
  66. package/dist/lists/list-type.js +275 -0
  67. package/dist/lists/list-type.js.map +1 -0
  68. package/dist/lists/model.d.ts +14 -0
  69. package/dist/lists/model.d.ts.map +1 -0
  70. package/dist/lists/model.js +15 -0
  71. package/dist/lists/model.js.map +1 -0
  72. package/dist/lists/page-type.d.ts +115 -0
  73. package/dist/lists/page-type.d.ts.map +1 -0
  74. package/dist/lists/page-type.js +66 -0
  75. package/dist/lists/page-type.js.map +1 -0
  76. package/dist/lists/refs.d.ts +13 -0
  77. package/dist/lists/refs.d.ts.map +1 -0
  78. package/dist/lists/refs.js +18 -0
  79. package/dist/lists/refs.js.map +1 -0
  80. package/dist/lists/render-data.d.ts +114 -0
  81. package/dist/lists/render-data.d.ts.map +1 -0
  82. package/dist/lists/render-data.js +3 -0
  83. package/dist/lists/render-data.js.map +1 -0
  84. package/dist/lists/render-deps.d.ts +68 -0
  85. package/dist/lists/render-deps.d.ts.map +1 -0
  86. package/dist/lists/render-deps.js +91 -0
  87. package/dist/lists/render-deps.js.map +1 -0
  88. package/dist/lists/resolve-values.d.ts +63 -0
  89. package/dist/lists/resolve-values.d.ts.map +1 -0
  90. package/dist/lists/resolve-values.js +181 -0
  91. package/dist/lists/resolve-values.js.map +1 -0
  92. package/dist/lists/resolve.d.ts +106 -0
  93. package/dist/lists/resolve.d.ts.map +1 -0
  94. package/dist/lists/resolve.js +878 -0
  95. package/dist/lists/resolve.js.map +1 -0
  96. package/dist/lists/scope.d.ts +81 -0
  97. package/dist/lists/scope.d.ts.map +1 -0
  98. package/dist/lists/scope.js +3 -0
  99. package/dist/lists/scope.js.map +1 -0
  100. package/dist/markup-structure.d.ts +8 -0
  101. package/dist/markup-structure.d.ts.map +1 -1
  102. package/dist/markup-structure.js +2 -0
  103. package/dist/markup-structure.js.map +1 -1
  104. package/dist/media.d.ts +1 -1
  105. package/dist/nested-module-render.d.ts +25 -20
  106. package/dist/nested-module-render.d.ts.map +1 -1
  107. package/dist/nested-module-render.js +122 -31
  108. package/dist/nested-module-render.js.map +1 -1
  109. package/dist/page-log.d.ts +1 -1
  110. package/dist/preview-compose.d.ts +24 -21
  111. package/dist/preview-compose.d.ts.map +1 -1
  112. package/dist/preview-compose.js +34 -118
  113. package/dist/preview-compose.js.map +1 -1
  114. package/dist/preview-scanner.d.ts +5 -2
  115. package/dist/preview-scanner.d.ts.map +1 -1
  116. package/dist/preview-scanner.js +5 -3
  117. package/dist/preview-scanner.js.map +1 -1
  118. package/dist/source-text-transport.d.ts +17 -0
  119. package/dist/source-text-transport.d.ts.map +1 -0
  120. package/dist/source-text-transport.js +71 -0
  121. package/dist/source-text-transport.js.map +1 -0
  122. package/dist/template-engine.d.ts +44 -31
  123. package/dist/template-engine.d.ts.map +1 -1
  124. package/dist/template-engine.js +75 -174
  125. package/dist/template-engine.js.map +1 -1
  126. package/dist/template-sections.d.ts +69 -0
  127. package/dist/template-sections.d.ts.map +1 -0
  128. package/dist/template-sections.js +423 -0
  129. package/dist/template-sections.js.map +1 -0
  130. package/dist/uuid-diagnose.d.ts +9 -0
  131. package/dist/uuid-diagnose.d.ts.map +1 -0
  132. package/dist/uuid-diagnose.js +47 -0
  133. package/dist/uuid-diagnose.js.map +1 -0
  134. package/dist/version.d.ts +2 -2
  135. package/dist/version.d.ts.map +1 -1
  136. package/dist/version.js +1 -1
  137. package/dist/version.js.map +1 -1
  138. package/package.json +8 -1
  139. package/src/__tests__/redos-hardening.test.ts +50 -16
  140. package/src/ai-tools-add-module-modes.test.ts +50 -0
  141. package/src/ai-tools.test.ts +10 -0
  142. package/src/ai-tools.ts +53 -39
  143. package/src/build-page.test.ts +34 -3
  144. package/src/build-page.ts +29 -6
  145. package/src/content.test.ts +111 -3
  146. package/src/content.ts +188 -77
  147. package/src/css-var-aliases.test.ts +61 -0
  148. package/src/css-var-aliases.ts +109 -0
  149. package/src/css-var-scan.ts +9 -0
  150. package/src/edit-markers.test.ts +37 -21
  151. package/src/edit-markers.ts +52 -20
  152. package/src/id-safe-truncate.test.ts +35 -0
  153. package/src/id-safe-truncate.ts +46 -0
  154. package/src/index.ts +5 -1
  155. package/src/interactions.ts +2 -2
  156. package/src/link-canonicalise.test.ts +36 -6
  157. package/src/link-canonicalise.ts +6 -1
  158. package/src/link-refs.test.ts +66 -42
  159. package/src/link-refs.ts +3 -3
  160. package/src/lists/address.ts +75 -0
  161. package/src/lists/default-types.ts +102 -0
  162. package/src/lists/fields.ts +285 -0
  163. package/src/lists/index.ts +16 -0
  164. package/src/lists/item-attr.test.ts +36 -0
  165. package/src/lists/item-attr.ts +49 -0
  166. package/src/lists/items.ts +402 -0
  167. package/src/lists/list-fixtures.test.ts +302 -0
  168. package/src/lists/list-type.ts +306 -0
  169. package/src/lists/lists.test.ts +328 -0
  170. package/src/lists/model.ts +16 -0
  171. package/src/lists/page-type.ts +71 -0
  172. package/src/lists/refs.ts +21 -0
  173. package/src/lists/render-data.ts +125 -0
  174. package/src/lists/render-deps.test.ts +132 -0
  175. package/src/lists/render-deps.ts +144 -0
  176. package/src/lists/resolve-values.ts +224 -0
  177. package/src/lists/resolve.test.ts +295 -0
  178. package/src/lists/resolve.ts +1148 -0
  179. package/src/lists/scope.ts +69 -0
  180. package/src/lists-compose-parity.test.ts +262 -0
  181. package/src/markup-structure.ts +10 -0
  182. package/src/nested-module-render.test.ts +111 -77
  183. package/src/nested-module-render.ts +85 -48
  184. package/src/preview-compose.test.ts +74 -19
  185. package/src/preview-compose.ts +59 -154
  186. package/src/preview-scanner.test.ts +8 -4
  187. package/src/preview-scanner.ts +5 -3
  188. package/src/source-text-transport.test.ts +63 -0
  189. package/src/source-text-transport.ts +70 -0
  190. package/src/template-engine-lists.test.ts +553 -0
  191. package/src/template-engine.test.ts +62 -80
  192. package/src/template-engine.ts +102 -245
  193. package/src/template-sections.ts +500 -0
  194. package/src/uuid-diagnose.test.ts +28 -0
  195. package/src/uuid-diagnose.ts +50 -0
  196. package/src/version.ts +1 -1
  197. package/dist/structured-sets.d.ts +0 -70
  198. package/dist/structured-sets.d.ts.map +0 -1
  199. package/dist/structured-sets.js +0 -92
  200. package/dist/structured-sets.js.map +0 -1
  201. package/src/structured-sets.ts +0 -114
  202. package/src/template-engine-data-lists.test.ts +0 -90
@@ -0,0 +1,258 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * The field system shared by list types (entry fields) and page types
4
+ * (page properties) — epic #1107, `docs/lists.md` §2.
5
+ *
6
+ * A list imposes no shape of its own: no entry must have a label or a
7
+ * link. The list type declares fields once, and every stored value is
8
+ * checked against that declaration at write time. One set of field types
9
+ * keeps list entries, page properties and future definitions speaking the
10
+ * same language, so the editor generates every form from the same code
11
+ * and the template engine renders every value the same way.
12
+ *
13
+ * `ext` carries attributes a plugin declared for fields (translation is
14
+ * the canonical case). Core stores and validates them against the
15
+ * plugin's schema but never interprets them — core has no locale concept
16
+ * (epic #380).
17
+ */
18
+ import { z } from "zod";
19
+ /** Every field type a definition may declare. */
20
+ export const LIST_FIELD_TYPES = [
21
+ "text",
22
+ "richtext",
23
+ "link",
24
+ "media",
25
+ "select",
26
+ "boolean",
27
+ "number",
28
+ "date",
29
+ "icon",
30
+ "module",
31
+ "term",
32
+ ];
33
+ /**
34
+ * Names the template engine binds itself inside a list entry, so a field
35
+ * or children list may not take them. Prefixes `is_`, `has_`, `count_`
36
+ * are reserved as a family (`is_<node>`, `has_<children>`,
37
+ * `count_<children>`).
38
+ */
39
+ export const LIST_RESERVED_NAMES = new Set([
40
+ "id",
41
+ "node",
42
+ "index",
43
+ "depth",
44
+ "first",
45
+ "last",
46
+ "items",
47
+ "page",
48
+ "recurse",
49
+ ]);
50
+ const RESERVED_PREFIXES = ["is_", "has_", "count_"];
51
+ /** True when `name` is taken by the engine (see {@link LIST_RESERVED_NAMES}). */
52
+ export function isReservedListName(name) {
53
+ return LIST_RESERVED_NAMES.has(name) || RESERVED_PREFIXES.some((p) => name.startsWith(p));
54
+ }
55
+ export const listNameSchema = z
56
+ .string()
57
+ .regex(/^[a-z][a-z0-9_]{0,63}$/, "must be snake_case (lowercase letters, digits, underscores)");
58
+ const fieldLabel = z.string().min(1).max(128);
59
+ /** Plugin-declared attributes keyed by plugin slug; validated by the host. */
60
+ export const fieldExtSchema = z.record(z.string().regex(/^[a-z0-9-]+$/), z.unknown());
61
+ const base = {
62
+ name: listNameSchema,
63
+ label: fieldLabel,
64
+ required: z.boolean().optional(),
65
+ default: z.unknown().optional(),
66
+ ext: fieldExtSchema.optional(),
67
+ };
68
+ const textField = z
69
+ .object({
70
+ ...base,
71
+ type: z.literal("text"),
72
+ maxLength: z.number().int().min(1).max(2000).optional(),
73
+ })
74
+ .strict();
75
+ const richtextField = z
76
+ .object({
77
+ ...base,
78
+ type: z.literal("richtext"),
79
+ maxLength: z.number().int().min(1).max(20000).optional(),
80
+ })
81
+ .strict();
82
+ const linkField = z.object({ ...base, type: z.literal("link") }).strict();
83
+ const mediaField = z.object({ ...base, type: z.literal("media") }).strict();
84
+ const selectField = z
85
+ .object({
86
+ ...base,
87
+ type: z.literal("select"),
88
+ options: z.array(listNameSchema).min(1).max(64),
89
+ })
90
+ .strict();
91
+ const booleanField = z.object({ ...base, type: z.literal("boolean") }).strict();
92
+ const numberField = z
93
+ .object({
94
+ ...base,
95
+ type: z.literal("number"),
96
+ min: z.number().optional(),
97
+ max: z.number().optional(),
98
+ })
99
+ .strict();
100
+ const dateField = z.object({ ...base, type: z.literal("date") }).strict();
101
+ const iconField = z.object({ ...base, type: z.literal("icon") }).strict();
102
+ const moduleField = z
103
+ .object({
104
+ ...base,
105
+ type: z.literal("module"),
106
+ /** Stable module `type`s that may fill the slot; absent = any module. */
107
+ accepts: z
108
+ .array(z.string().regex(/^[a-z0-9-]+$/))
109
+ .max(32)
110
+ .optional(),
111
+ })
112
+ .strict();
113
+ const termField = z
114
+ .object({
115
+ ...base,
116
+ type: z.literal("term"),
117
+ /** Slug of the vocabulary list the terms come from. */
118
+ list: z.string().regex(/^[a-z0-9-]+$/),
119
+ multiple: z.boolean().optional(),
120
+ })
121
+ .strict();
122
+ /** One field declaration. See `docs/lists.md` §2 for the value shapes. */
123
+ export const fieldDefSchema = z.discriminatedUnion("type", [
124
+ textField,
125
+ richtextField,
126
+ linkField,
127
+ mediaField,
128
+ selectField,
129
+ booleanField,
130
+ numberField,
131
+ dateField,
132
+ iconField,
133
+ moduleField,
134
+ termField,
135
+ ]);
136
+ /** Stored value of a `link` field. `href` may be an internal reference. */
137
+ export const linkValueSchema = z
138
+ .object({
139
+ href: z.string().min(1).max(2000),
140
+ target: z.enum(["_self", "_blank"]).optional(),
141
+ })
142
+ .strict();
143
+ /** Stored value of a `module` field — the same ref shape as module fields. */
144
+ export const embeddedModuleValueSchema = z
145
+ .object({ moduleId: z.string().uuid(), contentInstanceId: z.string().uuid() })
146
+ .strict();
147
+ const MEDIA_REF_RE = /^caelo:media\/[0-9a-f-]{36}(?:\/[a-z0-9-]+)?$/;
148
+ /** `caelo:term/<listId>/<itemId>` */
149
+ export const TERM_REF_RE = /^caelo:term\/([0-9a-f-]{36})\/([0-9a-f-]{36})$/;
150
+ const ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
151
+ const ICON_RE = /^[a-z0-9-]{1,64}$/;
152
+ const DEFAULT_TEXT_MAX = 500;
153
+ const DEFAULT_RICHTEXT_MAX = 5000;
154
+ /**
155
+ * Validate one stored value against its field. Returns the issues found
156
+ * (empty = valid). `undefined` is "not set" and only an issue when the
157
+ * field is required.
158
+ */
159
+ export function validateFieldValue(field, value, path) {
160
+ if (value === undefined || value === null) {
161
+ return field.required
162
+ ? [{ path, message: `"${field.name}" is required (${field.type}) — set a value.` }]
163
+ : [];
164
+ }
165
+ const bad = (expected) => [
166
+ { path, message: `"${field.name}" must be ${expected}, got ${describe(value)}.` },
167
+ ];
168
+ switch (field.type) {
169
+ case "text":
170
+ case "richtext": {
171
+ if (typeof value !== "string")
172
+ return bad("a string");
173
+ const max = field.maxLength ?? (field.type === "text" ? DEFAULT_TEXT_MAX : DEFAULT_RICHTEXT_MAX);
174
+ if (value.length > max)
175
+ return bad(`at most ${max} characters`);
176
+ if (field.required && value.trim().length === 0)
177
+ return bad("non-empty text");
178
+ return [];
179
+ }
180
+ case "link": {
181
+ const r = linkValueSchema.safeParse(value);
182
+ return r.success ? [] : bad('{ href, target? } (href like "/about" or "https://…")');
183
+ }
184
+ case "media":
185
+ return typeof value === "string" && MEDIA_REF_RE.test(value)
186
+ ? []
187
+ : bad("a media reference (caelo:media/<id>) — pick an asset from find_media");
188
+ case "select":
189
+ return typeof value === "string" && field.options.includes(value)
190
+ ? []
191
+ : bad(`one of ${field.options.map((o) => `"${o}"`).join(", ")}`);
192
+ case "boolean":
193
+ return typeof value === "boolean" ? [] : bad("true or false");
194
+ case "number": {
195
+ if (typeof value !== "number" || !Number.isFinite(value))
196
+ return bad("a number");
197
+ if (field.min !== undefined && value < field.min)
198
+ return bad(`≥ ${field.min}`);
199
+ if (field.max !== undefined && value > field.max)
200
+ return bad(`≤ ${field.max}`);
201
+ return [];
202
+ }
203
+ case "date":
204
+ return typeof value === "string" &&
205
+ ISO_DATE_RE.test(value) &&
206
+ !Number.isNaN(Date.parse(value))
207
+ ? []
208
+ : bad("an ISO date YYYY-MM-DD");
209
+ case "icon":
210
+ return typeof value === "string" && ICON_RE.test(value) ? [] : bad("an icon name");
211
+ case "module":
212
+ return embeddedModuleValueSchema.safeParse(value).success
213
+ ? []
214
+ : bad("{ moduleId, contentInstanceId }");
215
+ case "term": {
216
+ if (!Array.isArray(value) ||
217
+ value.some((v) => typeof v !== "string" || !TERM_REF_RE.test(v))) {
218
+ return bad("an array of term references (caelo:term/<listId>/<itemId>)");
219
+ }
220
+ if (!field.multiple && value.length > 1)
221
+ return bad("at most one term (multiple is off)");
222
+ if (field.required && value.length === 0)
223
+ return bad("at least one term");
224
+ return [];
225
+ }
226
+ }
227
+ }
228
+ /** Checks on one field declaration that Zod cannot express. */
229
+ export function checkFieldDef(field, path) {
230
+ const issues = [];
231
+ if (isReservedListName(field.name)) {
232
+ issues.push({
233
+ path,
234
+ message: `field name "${field.name}" is reserved by the template engine — pick another name.`,
235
+ });
236
+ }
237
+ if (field.default !== undefined) {
238
+ for (const i of validateFieldValue({ ...field, required: false }, field.default, `${path}.default`)) {
239
+ issues.push(i);
240
+ }
241
+ }
242
+ if (field.type === "number" &&
243
+ field.min !== undefined &&
244
+ field.max !== undefined &&
245
+ field.min > field.max) {
246
+ issues.push({ path, message: "min is greater than max." });
247
+ }
248
+ return issues;
249
+ }
250
+ function describe(value) {
251
+ if (Array.isArray(value))
252
+ return "an array";
253
+ if (value === null)
254
+ return "null";
255
+ const s = typeof value === "string" ? JSON.stringify(value.slice(0, 40)) : typeof value;
256
+ return s;
257
+ }
258
+ //# sourceMappingURL=fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields.js","sourceRoot":"","sources":["../../src/lists/fields.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /** Lists, list types, page types — epic #1107, see `docs/lists.md`. */
2
+ export * from "./address.js";
3
+ export * from "./default-types.js";
4
+ export * from "./fields.js";
5
+ export * from "./item-attr.js";
6
+ export * from "./items.js";
7
+ export * from "./list-type.js";
8
+ export * from "./page-type.js";
9
+ export * from "./refs.js";
10
+ export * from "./render-data.js";
11
+ export * from "./render-deps.js";
12
+ export * from "./resolve.js";
13
+ export * from "./scope.js";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lists/index.ts"],"names":[],"mappings":"AAEA,uEAAuE;AAEvE,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,15 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /** Lists, list types, page types — epic #1107, see `docs/lists.md`. */
3
+ export * from "./address.js";
4
+ export * from "./default-types.js";
5
+ export * from "./fields.js";
6
+ export * from "./item-attr.js";
7
+ export * from "./items.js";
8
+ export * from "./list-type.js";
9
+ export * from "./page-type.js";
10
+ export * from "./refs.js";
11
+ export * from "./render-data.js";
12
+ export * from "./render-deps.js";
13
+ export * from "./resolve.js";
14
+ export * from "./scope.js";
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lists/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,uEAAuE;AAEvE,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,26 @@
1
+ /** Every form a `data-caelo-list-item` value takes. */
2
+ export declare const LIST_ITEM_ATTR_RE: RegExp;
3
+ /** A parsed `data-caelo-list-item` value. */
4
+ export type ListItemAttr =
5
+ /** An entry of a shared list. */
6
+ {
7
+ readonly kind: "shared";
8
+ readonly listId: string;
9
+ readonly itemId: string;
10
+ }
11
+ /** An entry of a module's own list, stored in a content instance. */
12
+ | {
13
+ readonly kind: "instance";
14
+ readonly contentInstanceId: string;
15
+ readonly field: string;
16
+ readonly itemId: string;
17
+ }
18
+ /** An entry of a module field's default list (site chrome without stored content). */
19
+ | {
20
+ readonly kind: "local";
21
+ readonly field: string;
22
+ readonly itemId: string;
23
+ };
24
+ /** Parse a `data-caelo-list-item` value; null when it is not one. */
25
+ export declare function parseListItemAttr(value: string): ListItemAttr | null;
26
+ //# sourceMappingURL=item-attr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item-attr.d.ts","sourceRoot":"","sources":["../../src/lists/item-attr.ts"],"names":[],"mappings":"AAaA,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,QAE7B,CAAC;AAEF,6CAA6C;AAC7C,MAAM,MAAM,YAAY;AACtB,iCAAiC;AAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC/E,qEAAqE;GACnE;IACE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AACH,sFAAsF;GACpF;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAepE"}
@@ -0,0 +1,31 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * The `data-caelo-list-item` value the engine stamps on a rendered stored
4
+ * list entry (epic #1107, `docs/lists.md` §13), parsed. Live Edit sends it
5
+ * with a click-to-chat reference so the chip names the list entry, not the
6
+ * whole module, and the AI edits that entry with the list tools (shared
7
+ * list) or the content tools (a module's own list).
8
+ */
9
+ const UUID = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
10
+ const NAME = "[a-z][a-z0-9_]{0,63}";
11
+ /** Every form a `data-caelo-list-item` value takes. */
12
+ export const LIST_ITEM_ATTR_RE = new RegExp(`^(?:${UUID}/${UUID}|instance/${UUID}/${NAME}/${UUID}|local/${NAME}/${UUID})$`);
13
+ /** Parse a `data-caelo-list-item` value; null when it is not one. */
14
+ export function parseListItemAttr(value) {
15
+ if (!LIST_ITEM_ATTR_RE.test(value))
16
+ return null;
17
+ const parts = value.split("/");
18
+ if (parts[0] === "instance") {
19
+ return {
20
+ kind: "instance",
21
+ contentInstanceId: parts[1],
22
+ field: parts[2],
23
+ itemId: parts[3],
24
+ };
25
+ }
26
+ if (parts[0] === "local") {
27
+ return { kind: "local", field: parts[1], itemId: parts[2] };
28
+ }
29
+ return { kind: "shared", listId: parts[0], itemId: parts[1] };
30
+ }
31
+ //# sourceMappingURL=item-attr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item-attr.js","sourceRoot":"","sources":["../../src/lists/item-attr.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;GAMG;AAEH,MAAM,IAAI,GAAG,8DAA8D,CAAC;AAC5E,MAAM,IAAI,GAAG,sBAAsB,CAAC;AAEpC,uDAAuD;AACvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,MAAM,CACzC,OAAO,IAAI,IAAI,IAAI,aAAa,IAAI,IAAI,IAAI,IAAI,IAAI,UAAU,IAAI,IAAI,IAAI,IAAI,CAC/E,CAAC;AAgBF,qEAAqE;AACrE,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;QAC5B,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAW;YACrC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAW;YACzB,MAAM,EAAE,KAAK,CAAC,CAAC,CAAW;SAC3B,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAW,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAW,EAAE,CAAC;IAClF,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAW,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAW,EAAE,CAAC;AACpF,CAAC"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * List entries — storage shape, validation against a list type, and the
3
+ * pure item-level patch operations (epic #1107, `docs/lists.md` §4).
4
+ *
5
+ * A shared list and a local list (a module field value) store the same
6
+ * array. Children always live under `children` in storage; the loop name
7
+ * a template uses (`children.name` on the node) is a rendering concern,
8
+ * so renaming a loop never rewrites stored data.
9
+ *
10
+ * Every entry carries a UUID that never changes, also not on a move.
11
+ * Diffs, translations (by address, `address.ts`) and page terms
12
+ * (`caelo:term/<listId>/<itemId>`) hang off it.
13
+ */
14
+ import { z } from "zod";
15
+ import { type ListIssue } from "./fields.js";
16
+ import { type ListTypeDef } from "./list-type.js";
17
+ export interface ListItem {
18
+ readonly id: string;
19
+ readonly node: string;
20
+ readonly values: Readonly<Record<string, unknown>>;
21
+ readonly children?: readonly ListItem[];
22
+ readonly query?: Readonly<Record<string, unknown>>;
23
+ }
24
+ /** Input shape: `id` optional (assigned on write). Recursive. */
25
+ export declare const listItemInputSchema: z.ZodType<ListItemInput>;
26
+ export interface ListItemInput {
27
+ id?: string;
28
+ node: string;
29
+ values: Record<string, unknown>;
30
+ children?: ListItemInput[];
31
+ query?: Record<string, unknown>;
32
+ }
33
+ export interface ValidateItemsOptions {
34
+ /** Mints ids for new entries; injectable for deterministic tests. */
35
+ readonly newId?: () => string;
36
+ /** Path prefix for issues (`items` by default). */
37
+ readonly path?: string;
38
+ }
39
+ export interface ValidatedItems {
40
+ readonly items: ListItem[];
41
+ readonly issues: ListIssue[];
42
+ }
43
+ /**
44
+ * Validate entries against `type`, assigning ids to entries without one.
45
+ * Checks node placement, required fields and value shapes, depth, per-level
46
+ * `max`, the total count, duplicate ids, and query overrides (only the
47
+ * source's `editable` knobs). Values for fields a node does not declare
48
+ * are an issue — data the type does not know about would be invisible in
49
+ * the editor and silently dropped by the next full replace.
50
+ */
51
+ export declare function validateListItems(type: ListTypeDef, input: unknown, opts?: ValidateItemsOptions): ValidatedItems;
52
+ /** Depth-first visit of every entry with its parent id and depth (1-based). */
53
+ export declare function walkListItems(items: readonly ListItem[], visit: (item: ListItem, parentId: string | null, depth: number, index: number) => void): void;
54
+ /** Find an entry by id anywhere in the tree. */
55
+ export declare function findListItem(items: readonly ListItem[], id: string): ListItem | null;
56
+ export type ListItemPatch = {
57
+ readonly op: "add";
58
+ readonly parentId?: string | null;
59
+ readonly position?: number;
60
+ readonly item: ListItemInput;
61
+ } | {
62
+ readonly op: "update";
63
+ readonly itemId: string;
64
+ /** Merged into the entry's values; `null` removes a value. */
65
+ readonly values?: Readonly<Record<string, unknown>>;
66
+ readonly query?: Readonly<Record<string, unknown>> | null;
67
+ } | {
68
+ readonly op: "move";
69
+ readonly itemId: string;
70
+ readonly parentId?: string | null;
71
+ readonly position: number;
72
+ } | {
73
+ readonly op: "remove";
74
+ readonly itemId: string;
75
+ };
76
+ /**
77
+ * Apply item-level patches to a tree. Pure; the result still needs
78
+ * {@link validateListItems}. Throws {@link ListPatchError} when a patch
79
+ * names an entry that does not exist (or moves an entry into itself).
80
+ */
81
+ export declare function applyListItemPatches(items: readonly ListItem[], patches: readonly ListItemPatch[]): ListItemInput[];
82
+ /** A patch that cannot apply (unknown id, move into itself). */
83
+ export declare class ListPatchError extends Error {
84
+ readonly path: string;
85
+ constructor(path: string, message: string);
86
+ }
87
+ /** Per-entry change between two versions of a tree (domain events, `docs/lists.md` §9). */
88
+ export type ListItemChange = {
89
+ readonly kind: "added";
90
+ readonly itemId: string;
91
+ } | {
92
+ readonly kind: "updated";
93
+ readonly itemId: string;
94
+ readonly fields: readonly string[];
95
+ readonly before: Readonly<Record<string, unknown>>;
96
+ } | {
97
+ readonly kind: "moved";
98
+ readonly itemId: string;
99
+ } | {
100
+ readonly kind: "removed";
101
+ readonly itemId: string;
102
+ };
103
+ /** Diff two trees by entry id. Deterministic order: removed, added, updated, moved. */
104
+ export declare function diffListItems(before: readonly ListItem[], after: readonly ListItem[]): ListItemChange[];
105
+ //# sourceMappingURL=items.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"items.d.ts","sourceRoot":"","sources":["../../src/lists/items.ts"],"names":[],"mappings":"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"}