@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,401 @@
1
+ /**
2
+ * List types — the definition part of a list (epic #1107,
3
+ * `docs/lists.md` §3). A list type names the entry kinds (`nodes`), the
4
+ * fields each carries, what may hang under what, and which nodes are
5
+ * filled from a source instead of stored children. Every form of list
6
+ * is expressed with it: a flat link group, a three-level menu, a mega
7
+ * dropdown with columns, teasers and a "latest news" block, an unbounded
8
+ * category tree.
9
+ */
10
+ import { z } from "zod";
11
+ import { type ListIssue } from "./fields.js";
12
+ /** Hard ceiling for any tree, recursive or not. */
13
+ export declare const LIST_MAX_DEPTH = 8;
14
+ /** Entries per list (all levels together). */
15
+ export declare const LIST_MAX_ITEMS = 500;
16
+ /** Entries one query may return. */
17
+ export declare const LIST_QUERY_MAX_LIMIT = 50;
18
+ export declare const QUERY_KNOBS: readonly ["page_type", "terms", "terms_mode", "parent", "exclude_current", "order", "limit"];
19
+ export type QueryKnob = (typeof QUERY_KNOBS)[number];
20
+ export declare const SYSTEM_SOURCE_NAMES: readonly ["breadcrumbs", "children", "siblings", "page_terms", "term_pages"];
21
+ export type SystemSourceName = (typeof SYSTEM_SOURCE_NAMES)[number];
22
+ /** A query over pages. Resolved at render time; nothing is stored. */
23
+ export declare const pageQuerySchema: z.ZodObject<{
24
+ page_type: z.ZodOptional<z.ZodString>;
25
+ terms: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ terms_mode: z.ZodOptional<z.ZodEnum<{
27
+ any: "any";
28
+ all: "all";
29
+ }>>;
30
+ parent: z.ZodOptional<z.ZodString>;
31
+ exclude_current: z.ZodOptional<z.ZodBoolean>;
32
+ order: z.ZodUnion<readonly [z.ZodEnum<{
33
+ published_desc: "published_desc";
34
+ published_asc: "published_asc";
35
+ title_asc: "title_asc";
36
+ }>, z.ZodString]>;
37
+ limit: z.ZodNumber;
38
+ }, z.core.$strict>;
39
+ export type PageQuery = z.infer<typeof pageQuerySchema>;
40
+ /** Partial query: defaults on a node, or the knobs an entry overrides. */
41
+ export declare const pageQueryPartialSchema: z.ZodObject<{
42
+ page_type: z.ZodOptional<z.ZodOptional<z.ZodString>>;
43
+ terms: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
44
+ terms_mode: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
45
+ any: "any";
46
+ all: "all";
47
+ }>>>;
48
+ parent: z.ZodOptional<z.ZodOptional<z.ZodString>>;
49
+ exclude_current: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
50
+ order: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
51
+ published_desc: "published_desc";
52
+ published_asc: "published_asc";
53
+ title_asc: "title_asc";
54
+ }>, z.ZodString]>>;
55
+ limit: z.ZodOptional<z.ZodNumber>;
56
+ }, z.core.$strict>;
57
+ export declare const sourceDefSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
58
+ kind: z.ZodLiteral<"query">;
59
+ editable: z.ZodArray<z.ZodEnum<{
60
+ page_type: "page_type";
61
+ terms: "terms";
62
+ terms_mode: "terms_mode";
63
+ parent: "parent";
64
+ exclude_current: "exclude_current";
65
+ order: "order";
66
+ limit: "limit";
67
+ }>>;
68
+ defaults: z.ZodObject<{
69
+ page_type: z.ZodOptional<z.ZodOptional<z.ZodString>>;
70
+ terms: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
71
+ terms_mode: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
72
+ any: "any";
73
+ all: "all";
74
+ }>>>;
75
+ parent: z.ZodOptional<z.ZodOptional<z.ZodString>>;
76
+ exclude_current: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
77
+ order: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
78
+ published_desc: "published_desc";
79
+ published_asc: "published_asc";
80
+ title_asc: "title_asc";
81
+ }>, z.ZodString]>>;
82
+ limit: z.ZodOptional<z.ZodNumber>;
83
+ }, z.core.$strict>;
84
+ }, z.core.$strict>, z.ZodObject<{
85
+ kind: z.ZodLiteral<"system">;
86
+ name: z.ZodEnum<{
87
+ breadcrumbs: "breadcrumbs";
88
+ children: "children";
89
+ siblings: "siblings";
90
+ page_terms: "page_terms";
91
+ term_pages: "term_pages";
92
+ }>;
93
+ }, z.core.$strict>, z.ZodObject<{
94
+ kind: z.ZodLiteral<"plugin">;
95
+ name: z.ZodString;
96
+ }, z.core.$strict>], "kind">;
97
+ export type SourceDef = z.infer<typeof sourceDefSchema>;
98
+ export declare const nodeDefSchema: z.ZodObject<{
99
+ label: z.ZodString;
100
+ fields: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
101
+ type: z.ZodLiteral<"text">;
102
+ maxLength: z.ZodOptional<z.ZodNumber>;
103
+ name: z.ZodString;
104
+ label: z.ZodString;
105
+ required: z.ZodOptional<z.ZodBoolean>;
106
+ default: z.ZodOptional<z.ZodUnknown>;
107
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
108
+ }, z.core.$strict>, z.ZodObject<{
109
+ type: z.ZodLiteral<"richtext">;
110
+ maxLength: z.ZodOptional<z.ZodNumber>;
111
+ name: z.ZodString;
112
+ label: z.ZodString;
113
+ required: z.ZodOptional<z.ZodBoolean>;
114
+ default: z.ZodOptional<z.ZodUnknown>;
115
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
116
+ }, z.core.$strict>, z.ZodObject<{
117
+ type: z.ZodLiteral<"link">;
118
+ name: z.ZodString;
119
+ label: z.ZodString;
120
+ required: z.ZodOptional<z.ZodBoolean>;
121
+ default: z.ZodOptional<z.ZodUnknown>;
122
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
123
+ }, z.core.$strict>, z.ZodObject<{
124
+ type: z.ZodLiteral<"media">;
125
+ name: z.ZodString;
126
+ label: z.ZodString;
127
+ required: z.ZodOptional<z.ZodBoolean>;
128
+ default: z.ZodOptional<z.ZodUnknown>;
129
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
130
+ }, z.core.$strict>, z.ZodObject<{
131
+ type: z.ZodLiteral<"select">;
132
+ options: z.ZodArray<z.ZodString>;
133
+ name: z.ZodString;
134
+ label: z.ZodString;
135
+ required: z.ZodOptional<z.ZodBoolean>;
136
+ default: z.ZodOptional<z.ZodUnknown>;
137
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
138
+ }, z.core.$strict>, z.ZodObject<{
139
+ type: z.ZodLiteral<"boolean">;
140
+ name: z.ZodString;
141
+ label: z.ZodString;
142
+ required: z.ZodOptional<z.ZodBoolean>;
143
+ default: z.ZodOptional<z.ZodUnknown>;
144
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
145
+ }, z.core.$strict>, z.ZodObject<{
146
+ type: z.ZodLiteral<"number">;
147
+ min: z.ZodOptional<z.ZodNumber>;
148
+ max: z.ZodOptional<z.ZodNumber>;
149
+ name: z.ZodString;
150
+ label: z.ZodString;
151
+ required: z.ZodOptional<z.ZodBoolean>;
152
+ default: z.ZodOptional<z.ZodUnknown>;
153
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
154
+ }, z.core.$strict>, z.ZodObject<{
155
+ type: z.ZodLiteral<"date">;
156
+ name: z.ZodString;
157
+ label: z.ZodString;
158
+ required: z.ZodOptional<z.ZodBoolean>;
159
+ default: z.ZodOptional<z.ZodUnknown>;
160
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
161
+ }, z.core.$strict>, z.ZodObject<{
162
+ type: z.ZodLiteral<"icon">;
163
+ name: z.ZodString;
164
+ label: z.ZodString;
165
+ required: z.ZodOptional<z.ZodBoolean>;
166
+ default: z.ZodOptional<z.ZodUnknown>;
167
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
168
+ }, z.core.$strict>, z.ZodObject<{
169
+ type: z.ZodLiteral<"module">;
170
+ accepts: z.ZodOptional<z.ZodArray<z.ZodString>>;
171
+ name: z.ZodString;
172
+ label: z.ZodString;
173
+ required: z.ZodOptional<z.ZodBoolean>;
174
+ default: z.ZodOptional<z.ZodUnknown>;
175
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
176
+ }, z.core.$strict>, z.ZodObject<{
177
+ type: z.ZodLiteral<"term">;
178
+ list: z.ZodString;
179
+ multiple: z.ZodOptional<z.ZodBoolean>;
180
+ name: z.ZodString;
181
+ label: z.ZodString;
182
+ required: z.ZodOptional<z.ZodBoolean>;
183
+ default: z.ZodOptional<z.ZodUnknown>;
184
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
185
+ }, z.core.$strict>], "type">>;
186
+ children: z.ZodOptional<z.ZodObject<{
187
+ name: z.ZodString;
188
+ allow: z.ZodArray<z.ZodString>;
189
+ max: z.ZodOptional<z.ZodNumber>;
190
+ }, z.core.$strict>>;
191
+ current_from: z.ZodOptional<z.ZodString>;
192
+ source: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
193
+ kind: z.ZodLiteral<"query">;
194
+ editable: z.ZodArray<z.ZodEnum<{
195
+ page_type: "page_type";
196
+ terms: "terms";
197
+ terms_mode: "terms_mode";
198
+ parent: "parent";
199
+ exclude_current: "exclude_current";
200
+ order: "order";
201
+ limit: "limit";
202
+ }>>;
203
+ defaults: z.ZodObject<{
204
+ page_type: z.ZodOptional<z.ZodOptional<z.ZodString>>;
205
+ terms: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
206
+ terms_mode: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
207
+ any: "any";
208
+ all: "all";
209
+ }>>>;
210
+ parent: z.ZodOptional<z.ZodOptional<z.ZodString>>;
211
+ exclude_current: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
212
+ order: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
213
+ published_desc: "published_desc";
214
+ published_asc: "published_asc";
215
+ title_asc: "title_asc";
216
+ }>, z.ZodString]>>;
217
+ limit: z.ZodOptional<z.ZodNumber>;
218
+ }, z.core.$strict>;
219
+ }, z.core.$strict>, z.ZodObject<{
220
+ kind: z.ZodLiteral<"system">;
221
+ name: z.ZodEnum<{
222
+ breadcrumbs: "breadcrumbs";
223
+ children: "children";
224
+ siblings: "siblings";
225
+ page_terms: "page_terms";
226
+ term_pages: "term_pages";
227
+ }>;
228
+ }, z.core.$strict>, z.ZodObject<{
229
+ kind: z.ZodLiteral<"plugin">;
230
+ name: z.ZodString;
231
+ }, z.core.$strict>], "kind">>;
232
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
233
+ }, z.core.$strict>;
234
+ export type NodeDef = z.infer<typeof nodeDefSchema>;
235
+ export declare const LIST_TYPE_ROLES: readonly ["navigation", "vocabulary", "content"];
236
+ export type ListTypeRole = (typeof LIST_TYPE_ROLES)[number];
237
+ export declare const listTypeDefSchema: z.ZodObject<{
238
+ slug: z.ZodString;
239
+ name: z.ZodString;
240
+ purpose: z.ZodString;
241
+ role: z.ZodEnum<{
242
+ navigation: "navigation";
243
+ vocabulary: "vocabulary";
244
+ content: "content";
245
+ }>;
246
+ root: z.ZodObject<{
247
+ allow: z.ZodArray<z.ZodString>;
248
+ max: z.ZodOptional<z.ZodNumber>;
249
+ }, z.core.$strict>;
250
+ nodes: z.ZodRecord<z.ZodString, z.ZodObject<{
251
+ label: z.ZodString;
252
+ fields: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
253
+ type: z.ZodLiteral<"text">;
254
+ maxLength: z.ZodOptional<z.ZodNumber>;
255
+ name: z.ZodString;
256
+ label: z.ZodString;
257
+ required: z.ZodOptional<z.ZodBoolean>;
258
+ default: z.ZodOptional<z.ZodUnknown>;
259
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
260
+ }, z.core.$strict>, z.ZodObject<{
261
+ type: z.ZodLiteral<"richtext">;
262
+ maxLength: z.ZodOptional<z.ZodNumber>;
263
+ name: z.ZodString;
264
+ label: z.ZodString;
265
+ required: z.ZodOptional<z.ZodBoolean>;
266
+ default: z.ZodOptional<z.ZodUnknown>;
267
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
268
+ }, z.core.$strict>, z.ZodObject<{
269
+ type: z.ZodLiteral<"link">;
270
+ name: z.ZodString;
271
+ label: z.ZodString;
272
+ required: z.ZodOptional<z.ZodBoolean>;
273
+ default: z.ZodOptional<z.ZodUnknown>;
274
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
275
+ }, z.core.$strict>, z.ZodObject<{
276
+ type: z.ZodLiteral<"media">;
277
+ name: z.ZodString;
278
+ label: z.ZodString;
279
+ required: z.ZodOptional<z.ZodBoolean>;
280
+ default: z.ZodOptional<z.ZodUnknown>;
281
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
282
+ }, z.core.$strict>, z.ZodObject<{
283
+ type: z.ZodLiteral<"select">;
284
+ options: z.ZodArray<z.ZodString>;
285
+ name: z.ZodString;
286
+ label: z.ZodString;
287
+ required: z.ZodOptional<z.ZodBoolean>;
288
+ default: z.ZodOptional<z.ZodUnknown>;
289
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
290
+ }, z.core.$strict>, z.ZodObject<{
291
+ type: z.ZodLiteral<"boolean">;
292
+ name: z.ZodString;
293
+ label: z.ZodString;
294
+ required: z.ZodOptional<z.ZodBoolean>;
295
+ default: z.ZodOptional<z.ZodUnknown>;
296
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
297
+ }, z.core.$strict>, z.ZodObject<{
298
+ type: z.ZodLiteral<"number">;
299
+ min: z.ZodOptional<z.ZodNumber>;
300
+ max: z.ZodOptional<z.ZodNumber>;
301
+ name: z.ZodString;
302
+ label: z.ZodString;
303
+ required: z.ZodOptional<z.ZodBoolean>;
304
+ default: z.ZodOptional<z.ZodUnknown>;
305
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
306
+ }, z.core.$strict>, z.ZodObject<{
307
+ type: z.ZodLiteral<"date">;
308
+ name: z.ZodString;
309
+ label: z.ZodString;
310
+ required: z.ZodOptional<z.ZodBoolean>;
311
+ default: z.ZodOptional<z.ZodUnknown>;
312
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
313
+ }, z.core.$strict>, z.ZodObject<{
314
+ type: z.ZodLiteral<"icon">;
315
+ name: z.ZodString;
316
+ label: z.ZodString;
317
+ required: z.ZodOptional<z.ZodBoolean>;
318
+ default: z.ZodOptional<z.ZodUnknown>;
319
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
320
+ }, z.core.$strict>, z.ZodObject<{
321
+ type: z.ZodLiteral<"module">;
322
+ accepts: z.ZodOptional<z.ZodArray<z.ZodString>>;
323
+ name: z.ZodString;
324
+ label: z.ZodString;
325
+ required: z.ZodOptional<z.ZodBoolean>;
326
+ default: z.ZodOptional<z.ZodUnknown>;
327
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
328
+ }, z.core.$strict>, z.ZodObject<{
329
+ type: z.ZodLiteral<"term">;
330
+ list: z.ZodString;
331
+ multiple: z.ZodOptional<z.ZodBoolean>;
332
+ name: z.ZodString;
333
+ label: z.ZodString;
334
+ required: z.ZodOptional<z.ZodBoolean>;
335
+ default: z.ZodOptional<z.ZodUnknown>;
336
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
337
+ }, z.core.$strict>], "type">>;
338
+ children: z.ZodOptional<z.ZodObject<{
339
+ name: z.ZodString;
340
+ allow: z.ZodArray<z.ZodString>;
341
+ max: z.ZodOptional<z.ZodNumber>;
342
+ }, z.core.$strict>>;
343
+ current_from: z.ZodOptional<z.ZodString>;
344
+ source: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
345
+ kind: z.ZodLiteral<"query">;
346
+ editable: z.ZodArray<z.ZodEnum<{
347
+ page_type: "page_type";
348
+ terms: "terms";
349
+ terms_mode: "terms_mode";
350
+ parent: "parent";
351
+ exclude_current: "exclude_current";
352
+ order: "order";
353
+ limit: "limit";
354
+ }>>;
355
+ defaults: z.ZodObject<{
356
+ page_type: z.ZodOptional<z.ZodOptional<z.ZodString>>;
357
+ terms: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString>>>;
358
+ terms_mode: z.ZodOptional<z.ZodOptional<z.ZodEnum<{
359
+ any: "any";
360
+ all: "all";
361
+ }>>>;
362
+ parent: z.ZodOptional<z.ZodOptional<z.ZodString>>;
363
+ exclude_current: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
364
+ order: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
365
+ published_desc: "published_desc";
366
+ published_asc: "published_asc";
367
+ title_asc: "title_asc";
368
+ }>, z.ZodString]>>;
369
+ limit: z.ZodOptional<z.ZodNumber>;
370
+ }, z.core.$strict>;
371
+ }, z.core.$strict>, z.ZodObject<{
372
+ kind: z.ZodLiteral<"system">;
373
+ name: z.ZodEnum<{
374
+ breadcrumbs: "breadcrumbs";
375
+ children: "children";
376
+ siblings: "siblings";
377
+ page_terms: "page_terms";
378
+ term_pages: "term_pages";
379
+ }>;
380
+ }, z.core.$strict>, z.ZodObject<{
381
+ kind: z.ZodLiteral<"plugin">;
382
+ name: z.ZodString;
383
+ }, z.core.$strict>], "kind">>;
384
+ ext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
385
+ }, z.core.$strict>>;
386
+ max_depth: z.ZodOptional<z.ZodNumber>;
387
+ }, z.core.$strict>;
388
+ export type ListTypeDef = z.infer<typeof listTypeDefSchema>;
389
+ /**
390
+ * Static checks Zod cannot express. Returns every issue found so the AI
391
+ * fixes a definition in one round instead of one error per call.
392
+ */
393
+ export declare function checkListTypeDef(def: ListTypeDef): ListIssue[];
394
+ /** True when some node kind can (transitively) contain itself. */
395
+ export declare function hasRecursion(def: ListTypeDef): boolean;
396
+ /**
397
+ * Effective depth limit of a type: `max_depth` when set, else the
398
+ * longest non-recursive path (bounded by {@link LIST_MAX_DEPTH}).
399
+ */
400
+ export declare function effectiveMaxDepth(def: ListTypeDef): number;
401
+ //# sourceMappingURL=list-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-type.d.ts","sourceRoot":"","sources":["../../src/lists/list-type.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAML,KAAK,SAAS,EAEf,MAAM,aAAa,CAAC;AAErB,mDAAmD;AACnD,eAAO,MAAM,cAAc,IAAI,CAAC;AAChC,8CAA8C;AAC9C,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,oCAAoC;AACpC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,eAAO,MAAM,WAAW,8FAQd,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,eAAO,MAAM,mBAAmB,8EAMtB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAOpE,sEAAsE;AACtE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;kBAmBjB,CAAC;AACZ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,0EAA0E;AAC1E,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;kBAA4B,CAAC;AAEhE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BA2B1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAWxD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAWf,CAAC;AACZ,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,eAAO,MAAM,eAAe,kDAAmD,CAAC;AAChF,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAenB,CAAC;AACZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,EAAE,CA8G9D;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAetD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAY1D"}
@@ -0,0 +1,275 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * List types — the definition part of a list (epic #1107,
4
+ * `docs/lists.md` §3). A list type names the entry kinds (`nodes`), the
5
+ * fields each carries, what may hang under what, and which nodes are
6
+ * filled from a source instead of stored children. Every form of list
7
+ * is expressed with it: a flat link group, a three-level menu, a mega
8
+ * dropdown with columns, teasers and a "latest news" block, an unbounded
9
+ * category tree.
10
+ */
11
+ import { z } from "zod";
12
+ import { checkFieldDef, fieldDefSchema, fieldExtSchema, isReservedListName, listNameSchema, } from "./fields.js";
13
+ /** Hard ceiling for any tree, recursive or not. */
14
+ export const LIST_MAX_DEPTH = 8;
15
+ /** Entries per list (all levels together). */
16
+ export const LIST_MAX_ITEMS = 500;
17
+ /** Entries one query may return. */
18
+ export const LIST_QUERY_MAX_LIMIT = 50;
19
+ export const QUERY_KNOBS = [
20
+ "page_type",
21
+ "terms",
22
+ "terms_mode",
23
+ "parent",
24
+ "exclude_current",
25
+ "order",
26
+ "limit",
27
+ ];
28
+ export const SYSTEM_SOURCE_NAMES = [
29
+ "breadcrumbs",
30
+ "children",
31
+ "siblings",
32
+ "page_terms",
33
+ "term_pages",
34
+ ];
35
+ const queryOrderSchema = z.union([
36
+ z.enum(["published_desc", "published_asc", "title_asc"]),
37
+ z.string().regex(/^prop_(?:desc|asc):[a-z][a-z0-9_]{0,63}$/),
38
+ ]);
39
+ /** A query over pages. Resolved at render time; nothing is stored. */
40
+ export const pageQuerySchema = z
41
+ .object({
42
+ page_type: z
43
+ .string()
44
+ .regex(/^[a-z0-9-]+$/)
45
+ .optional(),
46
+ terms: z
47
+ .array(z.string().regex(/^caelo:term\/[0-9a-f-]{36}\/[0-9a-f-]{36}$/))
48
+ .max(20)
49
+ .optional(),
50
+ terms_mode: z.enum(["any", "all"]).optional(),
51
+ parent: z
52
+ .string()
53
+ .regex(/^caelo:page\/[0-9a-f-]{36}$/)
54
+ .optional(),
55
+ exclude_current: z.boolean().optional(),
56
+ order: queryOrderSchema,
57
+ limit: z.number().int().min(1).max(LIST_QUERY_MAX_LIMIT),
58
+ })
59
+ .strict();
60
+ /** Partial query: defaults on a node, or the knobs an entry overrides. */
61
+ export const pageQueryPartialSchema = pageQuerySchema.partial();
62
+ export const sourceDefSchema = z.discriminatedUnion("kind", [
63
+ z
64
+ .object({
65
+ kind: z.literal("query"),
66
+ /** Which query parts an editor (or the AI) may set per entry/placement. */
67
+ editable: z.array(z.enum(QUERY_KNOBS)).max(QUERY_KNOBS.length),
68
+ defaults: pageQueryPartialSchema,
69
+ })
70
+ .strict(),
71
+ z
72
+ .object({
73
+ kind: z.literal("system"),
74
+ // The AI reached for {kind:"system", name:"consent_categories"} in the
75
+ // PR #1121 e2e run: name the plugin form in the refusal itself.
76
+ name: z.enum(SYSTEM_SOURCE_NAMES, {
77
+ error: () => `system sources are ${SYSTEM_SOURCE_NAMES.join(", ")} — a plugin's list source (consent_categories, language_links, …) is {kind:"plugin", name:"<source>"}, and a module that only iterates it needs no field at all: {{#<source>}}…{{/<source>}}.`,
78
+ }),
79
+ })
80
+ .strict(),
81
+ z
82
+ .object({
83
+ kind: z.literal("plugin"),
84
+ /** The list-source name an active plugin declared. */
85
+ name: z.string().regex(/^[a-z][a-z0-9_]{0,63}$/),
86
+ })
87
+ .strict(),
88
+ ]);
89
+ const childrenSchema = z
90
+ .object({
91
+ /** Loop name in templates (`{{#columns}}`). Storage always uses `children`. */
92
+ name: listNameSchema,
93
+ allow: z.array(listNameSchema).min(1).max(32),
94
+ max: z.number().int().min(1).max(LIST_MAX_ITEMS).optional(),
95
+ })
96
+ .strict();
97
+ export const nodeDefSchema = z
98
+ .object({
99
+ label: z.string().min(1).max(128),
100
+ fields: z.array(fieldDefSchema).max(32),
101
+ children: childrenSchema.optional(),
102
+ /** Link field that decides `is_current` / `is_ancestor`. */
103
+ current_from: listNameSchema.optional(),
104
+ /** Generated children (`items`) instead of stored ones. */
105
+ source: sourceDefSchema.optional(),
106
+ ext: fieldExtSchema.optional(),
107
+ })
108
+ .strict();
109
+ export const LIST_TYPE_ROLES = ["navigation", "vocabulary", "content"];
110
+ export const listTypeDefSchema = z
111
+ .object({
112
+ slug: z.string().regex(/^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/),
113
+ name: z.string().min(1).max(200),
114
+ purpose: z.string().min(1).max(1000),
115
+ role: z.enum(LIST_TYPE_ROLES),
116
+ root: z
117
+ .object({
118
+ allow: z.array(listNameSchema).min(1).max(32),
119
+ max: z.number().int().min(1).max(LIST_MAX_ITEMS).optional(),
120
+ })
121
+ .strict(),
122
+ nodes: z.record(listNameSchema, nodeDefSchema),
123
+ max_depth: z.number().int().min(1).max(LIST_MAX_DEPTH).optional(),
124
+ })
125
+ .strict();
126
+ /**
127
+ * Static checks Zod cannot express. Returns every issue found so the AI
128
+ * fixes a definition in one round instead of one error per call.
129
+ */
130
+ export function checkListTypeDef(def) {
131
+ const issues = [];
132
+ const kinds = new Set(Object.keys(def.nodes));
133
+ if (kinds.size === 0) {
134
+ issues.push({ path: "nodes", message: "a list type needs at least one node kind." });
135
+ }
136
+ const checkAllow = (allow, path) => {
137
+ for (const k of allow) {
138
+ if (!kinds.has(k)) {
139
+ issues.push({
140
+ path,
141
+ message: `node kind "${k}" is not defined — add it under nodes or remove it from allow.`,
142
+ });
143
+ }
144
+ }
145
+ };
146
+ checkAllow(def.root.allow, "root.allow");
147
+ for (const [kind, node] of Object.entries(def.nodes)) {
148
+ const at = `nodes.${kind}`;
149
+ if (isReservedListName(kind)) {
150
+ issues.push({ path: at, message: `node kind "${kind}" is a reserved name — rename it.` });
151
+ }
152
+ const seen = new Set();
153
+ node.fields.forEach((f, i) => {
154
+ const fp = `${at}.fields[${i}]`;
155
+ if (seen.has(f.name))
156
+ issues.push({ path: fp, message: `duplicate field name "${f.name}".` });
157
+ seen.add(f.name);
158
+ issues.push(...checkFieldDef(f, fp));
159
+ });
160
+ if (node.children) {
161
+ if (isReservedListName(node.children.name)) {
162
+ issues.push({
163
+ path: `${at}.children.name`,
164
+ message: `children name "${node.children.name}" is reserved — pick another loop name.`,
165
+ });
166
+ }
167
+ if (seen.has(node.children.name)) {
168
+ issues.push({
169
+ path: `${at}.children.name`,
170
+ message: `children name "${node.children.name}" collides with a field of the same node.`,
171
+ });
172
+ }
173
+ checkAllow(node.children.allow, `${at}.children.allow`);
174
+ }
175
+ if (node.children && node.source) {
176
+ issues.push({
177
+ path: at,
178
+ message: "a node has either stored children or a source, not both — remove one.",
179
+ });
180
+ }
181
+ if (node.current_from !== undefined) {
182
+ const target = node.fields.find((f) => f.name === node.current_from);
183
+ if (target?.type !== "link") {
184
+ issues.push({
185
+ path: `${at}.current_from`,
186
+ message: `current_from must name a link field of this node ("${node.current_from}" is not one).`,
187
+ });
188
+ }
189
+ }
190
+ if (node.source?.kind === "query") {
191
+ const q = pageQueryPartialSchema.safeParse(node.source.defaults);
192
+ if (!q.success) {
193
+ issues.push({ path: `${at}.source.defaults`, message: "query defaults are invalid." });
194
+ }
195
+ else if (node.source.defaults.order === undefined &&
196
+ !node.source.editable.includes("order")) {
197
+ issues.push({
198
+ path: `${at}.source`,
199
+ message: 'a query source needs a default "order" or "order" in editable.',
200
+ });
201
+ }
202
+ else if (node.source.defaults.limit === undefined &&
203
+ !node.source.editable.includes("limit")) {
204
+ issues.push({
205
+ path: `${at}.source`,
206
+ message: 'a query source needs a default "limit" or "limit" in editable.',
207
+ });
208
+ }
209
+ }
210
+ }
211
+ if (hasRecursion(def) && def.max_depth === undefined) {
212
+ issues.push({
213
+ path: "max_depth",
214
+ message: "this type nests a node kind inside itself — set max_depth (1–8).",
215
+ });
216
+ }
217
+ if (def.role === "vocabulary") {
218
+ const rootKinds = def.root.allow;
219
+ for (const k of rootKinds) {
220
+ const node = def.nodes[k];
221
+ if (!node)
222
+ continue;
223
+ const hasText = (n) => node.fields.some((f) => f.name === n && f.type === "text");
224
+ if (!hasText("name") || !hasText("slug")) {
225
+ issues.push({
226
+ path: `nodes.${k}`,
227
+ message: 'vocabulary entries need a text field "name" and a text field "slug".',
228
+ });
229
+ }
230
+ if (node.source) {
231
+ issues.push({ path: `nodes.${k}`, message: "vocabulary entries cannot have a source." });
232
+ }
233
+ }
234
+ }
235
+ return issues;
236
+ }
237
+ /** True when some node kind can (transitively) contain itself. */
238
+ export function hasRecursion(def) {
239
+ const edges = new Map();
240
+ for (const [k, n] of Object.entries(def.nodes))
241
+ edges.set(k, n.children?.allow ?? []);
242
+ const visiting = new Set();
243
+ const done = new Set();
244
+ const visit = (k) => {
245
+ if (visiting.has(k))
246
+ return true;
247
+ if (done.has(k))
248
+ return false;
249
+ visiting.add(k);
250
+ for (const c of edges.get(k) ?? [])
251
+ if (visit(c))
252
+ return true;
253
+ visiting.delete(k);
254
+ done.add(k);
255
+ return false;
256
+ };
257
+ return [...edges.keys()].some(visit);
258
+ }
259
+ /**
260
+ * Effective depth limit of a type: `max_depth` when set, else the
261
+ * longest non-recursive path (bounded by {@link LIST_MAX_DEPTH}).
262
+ */
263
+ export function effectiveMaxDepth(def) {
264
+ if (def.max_depth !== undefined)
265
+ return def.max_depth;
266
+ const longest = (k, seen) => {
267
+ if (seen.has(k))
268
+ return LIST_MAX_DEPTH;
269
+ const next = new Set(seen).add(k);
270
+ const kids = def.nodes[k]?.children?.allow ?? [];
271
+ return 1 + kids.reduce((m, c) => Math.max(m, longest(c, next)), 0);
272
+ };
273
+ return Math.min(LIST_MAX_DEPTH, def.root.allow.reduce((m, k) => Math.max(m, longest(k, new Set())), 0));
274
+ }
275
+ //# sourceMappingURL=list-type.js.map