@caelo-cms/shared 0.10.22 → 0.10.23

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 (241) hide show
  1. package/dist/ai-tools.d.ts +290 -214
  2. package/dist/ai-tools.d.ts.map +1 -1
  3. package/dist/ai-tools.js +341 -264
  4. package/dist/ai-tools.js.map +1 -1
  5. package/dist/auth-forms.d.ts.map +1 -1
  6. package/dist/auth-forms.js +4 -1
  7. package/dist/auth-forms.js.map +1 -1
  8. package/dist/base-css.d.ts +24 -0
  9. package/dist/base-css.d.ts.map +1 -0
  10. package/dist/base-css.js +28 -0
  11. package/dist/base-css.js.map +1 -0
  12. package/dist/build-page.d.ts +330 -0
  13. package/dist/build-page.d.ts.map +1 -0
  14. package/dist/build-page.js +282 -0
  15. package/dist/build-page.js.map +1 -0
  16. package/dist/content.d.ts +322 -9
  17. package/dist/content.d.ts.map +1 -1
  18. package/dist/content.js +354 -11
  19. package/dist/content.js.map +1 -1
  20. package/dist/css-gradient-scan.d.ts +14 -0
  21. package/dist/css-gradient-scan.d.ts.map +1 -0
  22. package/dist/css-gradient-scan.js +81 -0
  23. package/dist/css-gradient-scan.js.map +1 -0
  24. package/dist/css-var-scan.d.ts +56 -0
  25. package/dist/css-var-scan.d.ts.map +1 -0
  26. package/dist/css-var-scan.js +97 -0
  27. package/dist/css-var-scan.js.map +1 -0
  28. package/dist/design-manifest.d.ts +36 -0
  29. package/dist/design-manifest.d.ts.map +1 -0
  30. package/dist/design-manifest.js +90 -0
  31. package/dist/design-manifest.js.map +1 -0
  32. package/dist/fonts.d.ts +89 -0
  33. package/dist/fonts.d.ts.map +1 -0
  34. package/dist/fonts.js +241 -0
  35. package/dist/fonts.js.map +1 -0
  36. package/dist/genesis-inventory.d.ts +32 -0
  37. package/dist/genesis-inventory.d.ts.map +1 -0
  38. package/dist/genesis-inventory.js +186 -0
  39. package/dist/genesis-inventory.js.map +1 -0
  40. package/dist/genesis.d.ts +62 -0
  41. package/dist/genesis.d.ts.map +1 -0
  42. package/dist/genesis.js +78 -0
  43. package/dist/genesis.js.map +1 -0
  44. package/dist/i18n.d.ts +44 -1
  45. package/dist/i18n.d.ts.map +1 -1
  46. package/dist/i18n.js +72 -6
  47. package/dist/i18n.js.map +1 -1
  48. package/dist/index.d.ts +27 -0
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +27 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/interactions.d.ts +23 -0
  53. package/dist/interactions.d.ts.map +1 -0
  54. package/dist/interactions.js +44 -0
  55. package/dist/interactions.js.map +1 -0
  56. package/dist/media.d.ts +101 -16
  57. package/dist/media.d.ts.map +1 -1
  58. package/dist/media.js +126 -15
  59. package/dist/media.js.map +1 -1
  60. package/dist/page-log.d.ts +94 -0
  61. package/dist/page-log.d.ts.map +1 -0
  62. package/dist/page-log.js +111 -0
  63. package/dist/page-log.js.map +1 -0
  64. package/dist/preview-compose.d.ts +79 -0
  65. package/dist/preview-compose.d.ts.map +1 -1
  66. package/dist/preview-compose.js +155 -25
  67. package/dist/preview-compose.js.map +1 -1
  68. package/dist/proposal-status.d.ts +40 -0
  69. package/dist/proposal-status.d.ts.map +1 -0
  70. package/dist/proposal-status.js +34 -0
  71. package/dist/proposal-status.js.map +1 -0
  72. package/dist/responsive-images.d.ts +64 -0
  73. package/dist/responsive-images.d.ts.map +1 -0
  74. package/dist/responsive-images.js +98 -0
  75. package/dist/responsive-images.js.map +1 -0
  76. package/dist/safe-keys.d.ts +9 -0
  77. package/dist/safe-keys.d.ts.map +1 -0
  78. package/dist/safe-keys.js +20 -0
  79. package/dist/safe-keys.js.map +1 -0
  80. package/dist/seo.d.ts +8 -0
  81. package/dist/seo.d.ts.map +1 -1
  82. package/dist/seo.js +3 -1
  83. package/dist/seo.js.map +1 -1
  84. package/dist/skills.d.ts +14 -68
  85. package/dist/skills.d.ts.map +1 -1
  86. package/dist/skills.js +19 -113
  87. package/dist/skills.js.map +1 -1
  88. package/dist/strip-cdata.d.ts +7 -0
  89. package/dist/strip-cdata.d.ts.map +1 -0
  90. package/dist/strip-cdata.js +48 -0
  91. package/dist/strip-cdata.js.map +1 -0
  92. package/dist/structured-sets.d.ts +6 -16
  93. package/dist/structured-sets.d.ts.map +1 -1
  94. package/dist/structured-sets.js +5 -16
  95. package/dist/structured-sets.js.map +1 -1
  96. package/dist/subagents.d.ts +105 -3
  97. package/dist/subagents.d.ts.map +1 -1
  98. package/dist/subagents.js +224 -41
  99. package/dist/subagents.js.map +1 -1
  100. package/dist/template-engine.d.ts +85 -0
  101. package/dist/template-engine.d.ts.map +1 -0
  102. package/dist/template-engine.js +403 -0
  103. package/dist/template-engine.js.map +1 -0
  104. package/dist/theme-importers/auto-detect.d.ts +26 -0
  105. package/dist/theme-importers/auto-detect.d.ts.map +1 -0
  106. package/dist/theme-importers/auto-detect.js +42 -0
  107. package/dist/theme-importers/auto-detect.js.map +1 -0
  108. package/dist/theme-importers/css-comments.d.ts +12 -0
  109. package/dist/theme-importers/css-comments.d.ts.map +1 -0
  110. package/dist/theme-importers/css-comments.js +15 -0
  111. package/dist/theme-importers/css-comments.js.map +1 -0
  112. package/dist/theme-importers/dtcg.d.ts +46 -0
  113. package/dist/theme-importers/dtcg.d.ts.map +1 -0
  114. package/dist/theme-importers/dtcg.js +111 -0
  115. package/dist/theme-importers/dtcg.js.map +1 -0
  116. package/dist/theme-importers/loose.d.ts +3 -0
  117. package/dist/theme-importers/loose.d.ts.map +1 -0
  118. package/dist/theme-importers/loose.js +76 -0
  119. package/dist/theme-importers/loose.js.map +1 -0
  120. package/dist/theme-importers/shadcn.d.ts +24 -0
  121. package/dist/theme-importers/shadcn.d.ts.map +1 -0
  122. package/dist/theme-importers/shadcn.js +135 -0
  123. package/dist/theme-importers/shadcn.js.map +1 -0
  124. package/dist/theme-importers/style-dictionary.d.ts +17 -0
  125. package/dist/theme-importers/style-dictionary.d.ts.map +1 -0
  126. package/dist/theme-importers/style-dictionary.js +125 -0
  127. package/dist/theme-importers/style-dictionary.js.map +1 -0
  128. package/dist/theme-importers/tailwind.d.ts +3 -0
  129. package/dist/theme-importers/tailwind.d.ts.map +1 -0
  130. package/dist/theme-importers/tailwind.js +218 -0
  131. package/dist/theme-importers/tailwind.js.map +1 -0
  132. package/dist/theme-literal-binding.d.ts +37 -0
  133. package/dist/theme-literal-binding.d.ts.map +1 -0
  134. package/dist/theme-literal-binding.js +138 -0
  135. package/dist/theme-literal-binding.js.map +1 -0
  136. package/dist/theme-normalize.d.ts +31 -0
  137. package/dist/theme-normalize.d.ts.map +1 -0
  138. package/dist/theme-normalize.js +587 -0
  139. package/dist/theme-normalize.js.map +1 -0
  140. package/dist/theme-ramp.d.ts +55 -0
  141. package/dist/theme-ramp.d.ts.map +1 -0
  142. package/dist/theme-ramp.js +149 -0
  143. package/dist/theme-ramp.js.map +1 -0
  144. package/dist/theme-render.d.ts +105 -0
  145. package/dist/theme-render.d.ts.map +1 -0
  146. package/dist/theme-render.js +441 -0
  147. package/dist/theme-render.js.map +1 -0
  148. package/dist/themes-errors.d.ts +109 -0
  149. package/dist/themes-errors.d.ts.map +1 -0
  150. package/dist/themes-errors.js +170 -0
  151. package/dist/themes-errors.js.map +1 -0
  152. package/dist/themes.d.ts +343 -0
  153. package/dist/themes.d.ts.map +1 -0
  154. package/dist/themes.js +697 -0
  155. package/dist/themes.js.map +1 -0
  156. package/dist/version.d.ts +7 -4
  157. package/dist/version.d.ts.map +1 -1
  158. package/dist/version.js +6 -3
  159. package/dist/version.js.map +1 -1
  160. package/package.json +10 -2
  161. package/src/__tests__/redos-hardening.test.ts +160 -0
  162. package/src/ai-tools-add-module-modes.test.ts +106 -0
  163. package/src/ai-tools-position.test.ts +134 -0
  164. package/src/ai-tools.test.ts +81 -0
  165. package/src/ai-tools.ts +1179 -0
  166. package/src/auth-forms.ts +36 -0
  167. package/src/base-css.ts +30 -0
  168. package/src/build-page.test.ts +228 -0
  169. package/src/build-page.ts +319 -0
  170. package/src/cap-failures.ts +67 -0
  171. package/src/content.test.ts +170 -0
  172. package/src/content.ts +620 -0
  173. package/src/context.ts +43 -0
  174. package/src/css-gradient-scan.ts +88 -0
  175. package/src/css-var-scan.test.ts +96 -0
  176. package/src/css-var-scan.ts +144 -0
  177. package/src/derive-module-type.test.ts +80 -0
  178. package/src/design-manifest.ts +93 -0
  179. package/src/fonts.test.ts +157 -0
  180. package/src/fonts.ts +296 -0
  181. package/src/genesis-inventory.test.ts +86 -0
  182. package/src/genesis-inventory.ts +215 -0
  183. package/src/genesis-sanitize.test.ts +35 -0
  184. package/src/genesis.ts +87 -0
  185. package/src/i18n.test.ts +274 -0
  186. package/src/i18n.ts +269 -0
  187. package/src/index.test.ts +10 -0
  188. package/src/index.ts +59 -0
  189. package/src/interactions.ts +48 -0
  190. package/src/logger.ts +147 -0
  191. package/src/media.test.ts +160 -0
  192. package/src/media.ts +355 -0
  193. package/src/page-log.test.ts +163 -0
  194. package/src/page-log.ts +124 -0
  195. package/src/preview-compose.test.ts +602 -0
  196. package/src/preview-compose.ts +709 -0
  197. package/src/preview-scanner.test.ts +96 -0
  198. package/src/preview-scanner.ts +214 -0
  199. package/src/proposal-status.test.ts +69 -0
  200. package/src/proposal-status.ts +40 -0
  201. package/src/responsive-images.test.ts +104 -0
  202. package/src/responsive-images.ts +151 -0
  203. package/src/result.ts +29 -0
  204. package/src/safe-keys.ts +21 -0
  205. package/src/seo.test.ts +234 -0
  206. package/src/seo.ts +261 -0
  207. package/src/skills.ts +48 -0
  208. package/src/snapshots.test.ts +80 -0
  209. package/src/snapshots.ts +81 -0
  210. package/src/strip-cdata.test.ts +41 -0
  211. package/src/strip-cdata.ts +50 -0
  212. package/src/structured-sets.ts +180 -0
  213. package/src/subagents.test.ts +262 -0
  214. package/src/subagents.ts +432 -0
  215. package/src/template-engine.test.ts +379 -0
  216. package/src/template-engine.ts +520 -0
  217. package/src/theme-gradient.test.ts +92 -0
  218. package/src/theme-importers/__tests__/proto-pollution.test.ts +54 -0
  219. package/src/theme-importers/auto-detect.ts +84 -0
  220. package/src/theme-importers/css-comments.ts +15 -0
  221. package/src/theme-importers/dtcg.ts +106 -0
  222. package/src/theme-importers/loose.ts +76 -0
  223. package/src/theme-importers/shadcn.ts +133 -0
  224. package/src/theme-importers/style-dictionary.ts +125 -0
  225. package/src/theme-importers/tailwind.ts +217 -0
  226. package/src/theme-literal-binding.test.ts +71 -0
  227. package/src/theme-literal-binding.ts +159 -0
  228. package/src/theme-motion.test.ts +115 -0
  229. package/src/theme-normalize-envelope.test.ts +43 -0
  230. package/src/theme-normalize-gradient.test.ts +135 -0
  231. package/src/theme-normalize.ts +661 -0
  232. package/src/theme-ramp.ts +187 -0
  233. package/src/theme-render-sanitize.test.ts +45 -0
  234. package/src/theme-render.test.ts +119 -0
  235. package/src/theme-render.ts +487 -0
  236. package/src/theme-shadow.test.ts +56 -0
  237. package/src/themes-errors.ts +199 -0
  238. package/src/themes.ts +842 -0
  239. package/src/translation.test.ts +160 -0
  240. package/src/translation.ts +295 -0
  241. package/src/version.ts +66 -0
@@ -0,0 +1,282 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * Issue #299 — bulk build-path schemas (CLAUDE.md §11 bulk-first).
4
+ *
5
+ * Run #15 telemetry showed the AI assembling ~14 pages through ~100
6
+ * singular round-trips (36× add_module_to_page, 29× set_page_module_content,
7
+ * 9× create_content_instance, 8× create_page) at 110K–556K input tokens
8
+ * per call. These schemas back the three ops that collapse that chain:
9
+ *
10
+ * - `pages.build_page` — ONE call: page (new or existing)
11
+ * + ordered modules + content instances + placements, one transaction.
12
+ * - `content_instances.create_many` — batch instance minting.
13
+ * - `page_module_content.set_many` — batch content fill on existing
14
+ * placements.
15
+ *
16
+ * All three are all-or-nothing: any validation error aborts the whole
17
+ * call with a message naming the failing element index (and field where
18
+ * one is involved), so partial failure is impossible (§11).
19
+ */
20
+ import { z } from "zod";
21
+ import { contentInstanceCreateSchema, localeSchema, MODULE_CSS_MAX, MODULE_HTML_MAX, MODULE_JS_MAX, moduleFieldSchema, moduleKindSchema, pageStatusSchema, slugSchema, syncModeSchema, } from "./content.js";
22
+ /** Content values keyed by the module's declared field names. */
23
+ const contentValuesSchema = z.record(z.string(), z.unknown());
24
+ /**
25
+ * Per-module content payload — a discriminated union mirroring the three
26
+ * existing content paths so build_page adds NO new semantics, only batching:
27
+ *
28
+ * - `inline` → mint a private (unsynced) content_instance carrying
29
+ * `values`, exactly what `set_page_module_content` produces for a
30
+ * fresh placement.
31
+ * - `shared` → mint a reusable content_instance (purpose required —
32
+ * same decision-support contract as `create_content_instance`) and
33
+ * bind this placement to it, `synced` by default.
34
+ * - `existing` → bind an already-minted content_instance (reuse-first
35
+ * per CLAUDE.md §1A) — the batched form of `set_placement_content`.
36
+ *
37
+ * Omitting `content` mints an empty unsynced instance, matching what
38
+ * `pages.set_modules` does for a net-new placement today.
39
+ */
40
+ export const buildPageContentSchema = z.discriminatedUnion("source", [
41
+ z
42
+ .object({
43
+ source: z.literal("inline"),
44
+ values: contentValuesSchema,
45
+ })
46
+ .strict(),
47
+ z
48
+ .object({
49
+ source: z.literal("shared"),
50
+ values: contentValuesSchema.default({}),
51
+ /** Why this row exists as a shared instance — see CLAUDE.md §1A. */
52
+ purpose: z.string().min(1).max(1000),
53
+ slug: slugSchema.optional(),
54
+ displayName: z.string().min(1).max(128).optional(),
55
+ syncMode: syncModeSchema.default("synced"),
56
+ })
57
+ .strict(),
58
+ z
59
+ .object({
60
+ source: z.literal("existing"),
61
+ contentInstanceId: z.string().uuid(),
62
+ syncMode: syncModeSchema.default("synced"),
63
+ })
64
+ .strict(),
65
+ ]);
66
+ /**
67
+ * One module entry in a build_page call. Two modes per entry, identical
68
+ * to `add_module_to_page` (issue #159):
69
+ *
70
+ * - **Mint mode** — `displayName` + `html` (+ `fields`, `description`,
71
+ * `kind`, `type`, `css`, `js`). The op creates the module through the
72
+ * same `modules.create` path (extractor fallback, type derivation,
73
+ * snapshot) the singular tool uses.
74
+ * - **Place mode** — `moduleId` of an existing module. Placement-only:
75
+ * extra authoring keys are TOLERATED (§1A/§11 — a placement that can
76
+ * succeed must not fail over an extra field) but NOT applied; the op
77
+ * surfaces an info naming any carried field whose value differs from the
78
+ * module's stored one, pointing at edit_module (§2 — no silent drop).
79
+ *
80
+ * The element-level superRefine reports issues WITH the element's array
81
+ * index in the Zod path, so a mode error fails as `modules[3]: …`.
82
+ */
83
+ export const buildPageModuleSchema = z
84
+ .object({
85
+ /**
86
+ * Template block to place into — must exist on the page's template.
87
+ * OMIT for a DETACHED entry: the module + its content_instance are
88
+ * created but NOT placed on the page — used for nested-only modules
89
+ * that later entries embed via `{"$ref": "<ref>"}` in a
90
+ * module / module-list field value. A detached entry requires `ref`.
91
+ */
92
+ blockName: slugSchema.optional(),
93
+ /**
94
+ * Local handle other entries in the SAME call can reference: a
95
+ * module/module-list field value of `{"$ref": "<ref>"}` resolves to
96
+ * this entry's `{moduleId, contentInstanceId}`. Entries resolve in
97
+ * array order, so referenced entries must come FIRST.
98
+ */
99
+ ref: z
100
+ .string()
101
+ .regex(/^[a-z][a-z0-9_-]{0,31}$/, "ref must be a short lowercase handle")
102
+ .optional(),
103
+ /**
104
+ * Place mode: an existing module from `## Modules` (UUID), or a
105
+ * module minted EARLIER IN THIS CALL via `{"$ref": "<handle>"}` —
106
+ * the second-placement case (e.g. three feature cards reusing one
107
+ * card module). Live-edit run A showed the model writing
108
+ * `moduleId: "$feat1"` unprompted; the union makes that intent
109
+ * expressible instead of a validation dead-end.
110
+ */
111
+ moduleId: z
112
+ .union([
113
+ z
114
+ .string()
115
+ .uuid('moduleId must be a UUID from ## Modules — to re-place a module minted earlier in THIS call, pass {"$ref": "<its ref>"} instead'),
116
+ z.object({ $ref: z.string() }).strict(),
117
+ ])
118
+ .optional(),
119
+ /** Mint mode: authoring surface, mirrors add_module_to_page. */
120
+ displayName: z.string().min(1).max(128).optional(),
121
+ description: z.string().max(1000).optional(),
122
+ kind: moduleKindSchema.optional(),
123
+ type: slugSchema.optional(),
124
+ html: z.string().min(1).max(MODULE_HTML_MAX).optional(),
125
+ css: z.string().max(MODULE_CSS_MAX).optional(),
126
+ js: z.string().max(MODULE_JS_MAX).optional(),
127
+ fields: z.array(moduleFieldSchema).max(64).optional(),
128
+ /** issue #164 slice 2 — opt-in mechanical token binding (tool layer). */
129
+ bindThemeLiterals: z.boolean().optional(),
130
+ content: buildPageContentSchema.optional(),
131
+ })
132
+ .strict()
133
+ .superRefine((entry, ctx) => {
134
+ if (entry.blockName === undefined && entry.ref === undefined) {
135
+ ctx.addIssue({
136
+ code: z.ZodIssueCode.custom,
137
+ message: "An entry without `blockName` is a DETACHED (nested-only) module and requires `ref` " +
138
+ 'so a later entry can embed it via {"$ref": "<ref>"} — otherwise it would be unreachable. ' +
139
+ "Pass `blockName` to place it on the page instead.",
140
+ });
141
+ }
142
+ // `moduleId` is PLACEMENT-ONLY: a placement that CAN succeed must never
143
+ // fail over an extra field (§1A/§11), so we do NOT reject a moduleId entry
144
+ // that also carries authoring fields. But those fields are NOT applied here
145
+ // (build_page places; it does not re-author a shared module). To avoid a
146
+ // SILENT dropped change (§2), the HANDLER surfaces an INFO in the result
147
+ // naming any ignored authoring field whose value DIFFERS from the module's
148
+ // stored one, and points at edit_module. The schema can't do that check (no
149
+ // DB), so it just allows the entry through.
150
+ if (entry.moduleId !== undefined)
151
+ return;
152
+ if (entry.displayName === undefined || entry.html === undefined) {
153
+ ctx.addIssue({
154
+ code: z.ZodIssueCode.custom,
155
+ message: "Pass either `moduleId` (place an existing module from ## Modules) " +
156
+ "or `displayName` + `html` (mint a new module).",
157
+ });
158
+ }
159
+ });
160
+ /**
161
+ * Target page — exactly one of two shapes:
162
+ *
163
+ * - `{ pageId }` → build onto an existing page
164
+ * (modules are APPENDED to the named blocks in listed order).
165
+ * - `{ slug, title, … }` → create the page first (same
166
+ * resolution rules as `pages.create`: templateId optional when
167
+ * site_defaults carries a default).
168
+ */
169
+ export const buildPageTargetSchema = z
170
+ .object({
171
+ pageId: z.string().uuid().optional(),
172
+ slug: slugSchema.optional(),
173
+ title: z.string().min(1).max(256).optional(),
174
+ name: z.string().min(1).max(256).optional(),
175
+ locale: localeSchema.optional(),
176
+ templateId: z.string().uuid().optional(),
177
+ status: pageStatusSchema.optional(),
178
+ /**
179
+ * Migration linkage (issue #278 flow): the `import_pages` row this
180
+ * page rebuilds. The op stamps `import_pages.accepted_page_id` with
181
+ * the built page's id so fidelity / inventory / media-migration reads
182
+ * resolve via that pointer regardless of slug. It ALSO makes the
183
+ * build idempotent — a second build_page for the same importPageId
184
+ * REBUILDS the already-linked page instead of minting a duplicate.
185
+ * Compatible with either target shape (create OR existing pageId).
186
+ */
187
+ importPageId: z.string().uuid().optional(),
188
+ })
189
+ .strict()
190
+ .superRefine((page, ctx) => {
191
+ const createKeys = ["slug", "title", "name", "locale", "templateId", "status"].filter((k) => page[k] !== undefined);
192
+ if (page.pageId !== undefined) {
193
+ if (createKeys.length > 0) {
194
+ ctx.addIssue({
195
+ code: z.ZodIssueCode.custom,
196
+ message: `pageId targets an EXISTING page — drop ${createKeys.join(", ")}. ` +
197
+ "To create a new page instead, omit pageId and pass slug + title.",
198
+ });
199
+ }
200
+ return;
201
+ }
202
+ if (page.slug === undefined || page.title === undefined) {
203
+ ctx.addIssue({
204
+ code: z.ZodIssueCode.custom,
205
+ message: "Pass either `pageId` (build onto an existing page) or `slug` + `title` (create the page in the same call).",
206
+ });
207
+ }
208
+ });
209
+ /** `pages.build_page` op input. */
210
+ export const buildPageInputSchema = z
211
+ .object({
212
+ page: buildPageTargetSchema,
213
+ // min 0: build_page is the SINGLE page-creation tool. An empty modules
214
+ // array creates an intentionally empty page shell (the case that used to
215
+ // need the now-removed create_page); a populated array builds the whole
216
+ // page in one transaction (the common case).
217
+ modules: z.array(buildPageModuleSchema).max(40),
218
+ })
219
+ .strict()
220
+ .superRefine((input, ctx) => {
221
+ // `ref` handles must be unique — a duplicate would silently shadow
222
+ // the earlier entry when a later {"$ref"} resolves.
223
+ const seen = new Set();
224
+ for (const [i, entry] of input.modules.entries()) {
225
+ if (entry.ref === undefined)
226
+ continue;
227
+ if (seen.has(entry.ref)) {
228
+ ctx.addIssue({
229
+ code: z.ZodIssueCode.custom,
230
+ path: ["modules", i, "ref"],
231
+ message: `duplicate ref "${entry.ref}" — each ref handle must be unique within the call`,
232
+ });
233
+ }
234
+ seen.add(entry.ref);
235
+ }
236
+ });
237
+ /** `pages.build_page` op output — one row per placed module, in input order. */
238
+ export const buildPagePlacementResultSchema = z.object({
239
+ blockName: z.string(),
240
+ position: z.number().int().nonnegative(),
241
+ moduleId: z.string(),
242
+ contentInstanceId: z.string(),
243
+ syncMode: syncModeSchema,
244
+ /** True when this call minted the module (mint mode). */
245
+ minted: z.boolean(),
246
+ });
247
+ // ─── content_instances.create_many ───────────────────────────────────
248
+ /**
249
+ * Batch form of `content_instances.create`. Each item is the exact
250
+ * singular input; the handler runs the singular path per item inside
251
+ * ONE transaction (all-or-nothing — a failure at index i rolls back
252
+ * items 0..i-1 and the error names `instances[i]`).
253
+ */
254
+ export const contentInstancesCreateManySchema = z
255
+ .object({
256
+ instances: z.array(contentInstanceCreateSchema).min(1).max(100),
257
+ })
258
+ .strict();
259
+ // ─── page_module_content.set_many ────────────────────────────────────
260
+ /**
261
+ * Batch form of `page_module_content.set` — a content-only pass over N
262
+ * existing placements (typically one page's worth, but cross-page items
263
+ * are fine). All-or-nothing in one transaction; failures name `items[i]`
264
+ * plus the placement coordinates and, for value-shape errors, the field.
265
+ */
266
+ export const pageModuleContentSetManySchema = z
267
+ .object({
268
+ items: z
269
+ .array(z
270
+ .object({
271
+ pageId: z.string().uuid(),
272
+ blockName: z.string().min(1).max(80),
273
+ position: z.number().int().nonnegative(),
274
+ /** Keyed by module field name. Fully replaces existing values. */
275
+ contentValues: contentValuesSchema,
276
+ })
277
+ .strict())
278
+ .min(1)
279
+ .max(100),
280
+ })
281
+ .strict();
282
+ //# sourceMappingURL=build-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-page.js","sourceRoot":"","sources":["../src/build-page.ts"],"names":[],"mappings":"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"}