@cosmicdrift/kumiko-bundled-features 0.374.0 → 0.378.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 (260) hide show
  1. package/dist/account-security/constants.d.ts +1 -0
  2. package/dist/account-security/constants.js +1 -0
  3. package/dist/account-security/index.d.ts +1 -1
  4. package/dist/account-security/index.js +1 -1
  5. package/dist/admin-shell/web/client-plugin.d.ts +1 -1
  6. package/dist/audit/web/client-plugin.d.ts +1 -1
  7. package/dist/auth-email-password/mail-notifications.js +1 -1
  8. package/dist/auth-email-password/web/auth-client.js +1 -1
  9. package/dist/auth-email-password/web/auth-form-primitives.js +1 -1
  10. package/dist/auth-email-password/web/default-topbar-actions.js +1 -1
  11. package/dist/auth-email-password/web/index.js +1 -1
  12. package/dist/auth-email-password/web/session.js +1 -1
  13. package/dist/auth-email-password/web/tenant-menu-items.js +1 -1
  14. package/dist/auth-email-password/web/tenant-switcher.js +1 -1
  15. package/dist/auth-email-password/web/user-menu.js +1 -1
  16. package/dist/auth-foundation/env.d.ts +9 -0
  17. package/dist/auth-foundation/env.js +21 -0
  18. package/dist/auth-foundation/index.d.ts +1 -0
  19. package/dist/auth-foundation/index.js +1 -0
  20. package/dist/auth-mfa/schema/user-mfa.d.ts +6 -6
  21. package/dist/billing-foundation/consumer-protection/confirmation-mail.js +1 -1
  22. package/dist/billing-foundation/consumer-protection/termination-pages.js +1 -1
  23. package/dist/billing-foundation/contact-card.d.ts +2 -0
  24. package/dist/billing-foundation/contact-card.js +16 -0
  25. package/dist/billing-foundation/entities.d.ts +8 -8
  26. package/dist/billing-foundation/handlers/billing-plans.query.js +1 -1
  27. package/dist/billing-foundation/index.d.ts +1 -1
  28. package/dist/billing-foundation/plan-catalog.js +1 -0
  29. package/dist/billing-foundation/projection.d.ts +8 -8
  30. package/dist/billing-foundation/types.d.ts +11 -0
  31. package/dist/billing-foundation/validate-options.js +13 -0
  32. package/dist/billing-foundation/web/billing-contact-plan.d.ts +5 -0
  33. package/dist/billing-foundation/web/billing-contact-plan.js +17 -0
  34. package/dist/billing-foundation/web/billing-plans-panel.js +5 -13
  35. package/dist/billing-foundation/web/cancel-contract-dialog.js +2 -2
  36. package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +1 -1
  37. package/dist/billing-foundation/web/checkout-consent-dialog.js +1 -0
  38. package/dist/billing-foundation/web/client-plugin.d.ts +1 -1
  39. package/dist/billing-foundation/web/localized-params.d.ts +1 -0
  40. package/dist/billing-foundation/web/localized-params.js +11 -0
  41. package/dist/cap-counter/entity.d.ts +1 -1
  42. package/dist/cap-counter/stock-cap-guard.js +8 -0
  43. package/dist/cap-overview/web/cap-cards-panel.js +3 -3
  44. package/dist/cap-overview/web/client-plugin.d.ts +1 -1
  45. package/dist/channel-email/email-channel.d.ts +2 -1
  46. package/dist/compliance-profiles/web/client-plugin.d.ts +1 -1
  47. package/dist/config/feature.js +2 -2
  48. package/dist/config/table.d.ts +6 -6
  49. package/dist/config/web/i18n.js +1 -0
  50. package/dist/custom-fields/entity.d.ts +4 -4
  51. package/dist/custom-fields/web/client-plugin.d.ts +1 -1
  52. package/dist/data-retention/schema/tenant-retention-override.d.ts +4 -4
  53. package/dist/delivery/tables.d.ts +6 -6
  54. package/dist/delivery/unsubscribe-page.js +1 -1
  55. package/dist/delivery/web/client-plugin.d.ts +1 -1
  56. package/dist/delivery/web/delivery-status-cell.js +1 -1
  57. package/dist/document-ingest-foundation/entity.d.ts +4 -4
  58. package/dist/feature-toggles/web/client-plugin.d.ts +1 -1
  59. package/dist/file-provider-s3/env-named-feature.d.ts +17 -0
  60. package/dist/file-provider-s3/env-named-feature.js +23 -0
  61. package/dist/file-provider-s3/env-schema.d.ts +7 -0
  62. package/dist/file-provider-s3/env-schema.js +15 -10
  63. package/dist/file-provider-s3/index.d.ts +1 -0
  64. package/dist/file-provider-s3/index.js +1 -0
  65. package/dist/folders/entity.d.ts +8 -8
  66. package/dist/folders/web/client-plugin.d.ts +1 -1
  67. package/dist/form-draft/entity.d.ts +2 -2
  68. package/dist/host-routing/constants.d.ts +2 -0
  69. package/dist/host-routing/constants.js +3 -0
  70. package/dist/host-routing/dispatch.d.ts +1 -1
  71. package/dist/host-routing/dispatch.js +35 -25
  72. package/dist/host-routing/feature.js +100 -27
  73. package/dist/host-routing/host.d.ts +9 -0
  74. package/dist/host-routing/host.js +24 -2
  75. package/dist/host-routing/index.d.ts +2 -1
  76. package/dist/host-routing/index.js +1 -0
  77. package/dist/host-routing/options.d.ts +14 -0
  78. package/dist/host-routing/redirects.d.ts +6 -0
  79. package/dist/host-routing/redirects.js +27 -0
  80. package/dist/host-routing/tenant-lookup.d.ts +7 -0
  81. package/dist/host-routing/tenant-lookup.js +39 -0
  82. package/dist/host-routing/validate-options.js +34 -1
  83. package/dist/inbound-mail-foundation/entities.d.ts +25 -25
  84. package/dist/inbound-mail-foundation/feature.js +7 -0
  85. package/dist/inbound-mail-foundation/handlers/list-accounts.query.d.ts +1 -1
  86. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +11 -3
  87. package/dist/inbound-mail-foundation/i18n.d.ts +3 -0
  88. package/dist/inbound-mail-foundation/i18n.js +35 -0
  89. package/dist/inbound-mail-foundation/index.d.ts +1 -0
  90. package/dist/inbound-mail-foundation/index.js +1 -0
  91. package/dist/inbound-mail-foundation/projection.d.ts +20 -20
  92. package/dist/inbound-mail-foundation/screens.d.ts +7 -0
  93. package/dist/inbound-mail-foundation/screens.js +86 -0
  94. package/dist/inbound-mail-foundation/types.d.ts +2 -2
  95. package/dist/jobs/job-run-table.d.ts +6 -6
  96. package/dist/jobs/web/client-plugin.d.ts +1 -1
  97. package/dist/ledger/entity.d.ts +13 -13
  98. package/dist/legal-pages/feature.js +11 -1
  99. package/dist/legal-pages/layout.d.ts +2 -2
  100. package/dist/legal-pages/layout.js +4 -4
  101. package/dist/legal-pages/web/client-plugin.d.ts +1 -1
  102. package/dist/mail-foundation/feature.d.ts +20 -21
  103. package/dist/mail-foundation/feature.js +1 -1
  104. package/dist/mail-foundation/i18n.d.ts +5 -2
  105. package/dist/mail-foundation/i18n.js +3 -2
  106. package/dist/mail-transport-smtp/i18n.d.ts +1 -1
  107. package/dist/mail-transport-smtp/i18n.js +1 -1
  108. package/dist/managed-pages/table.d.ts +12 -12
  109. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  110. package/dist/notes-history/entity.d.ts +12 -12
  111. package/dist/notes-history/web/client-plugin.d.ts +1 -1
  112. package/dist/page-render/branding.js +1 -1
  113. package/dist/page-render/layout.d.ts +1 -1
  114. package/dist/page-render/layout.js +2 -2
  115. package/dist/page-render/markdown.js +1 -1
  116. package/dist/personal-access-tokens/i18n.js +1 -1
  117. package/dist/personal-access-tokens/schema/api-token.d.ts +6 -6
  118. package/dist/personal-access-tokens/screens.js +1 -1
  119. package/dist/secrets/feature.d.ts +1 -1
  120. package/dist/secrets/feature.js +3 -3
  121. package/dist/secrets/table.d.ts +1 -1
  122. package/dist/seo/sitemap.js +1 -1
  123. package/dist/sessions/schema/user-session.d.ts +4 -4
  124. package/dist/shared/mail-template-body.js +1 -1
  125. package/dist/shared/purge-files-reaching-subject.js +98 -3
  126. package/dist/tags/entity.d.ts +9 -9
  127. package/dist/tags/web/client-plugin.d.ts +1 -1
  128. package/dist/template-resolver/compile-document-body.d.ts +3 -0
  129. package/dist/template-resolver/compile-document-body.js +50 -3
  130. package/dist/template-resolver/constants.d.ts +3 -0
  131. package/dist/template-resolver/constants.js +2 -0
  132. package/dist/template-resolver/document-blocks.d.ts +5 -0
  133. package/dist/template-resolver/document-blocks.js +22 -0
  134. package/dist/template-resolver/document-images.d.ts +2 -0
  135. package/dist/template-resolver/document-images.js +28 -0
  136. package/dist/template-resolver/document-ops.d.ts +167 -0
  137. package/dist/template-resolver/document-ops.js +390 -0
  138. package/dist/template-resolver/document-sanitizer.d.ts +4 -1
  139. package/dist/template-resolver/document-sanitizer.js +26 -0
  140. package/dist/template-resolver/document-schema.d.ts +2 -1
  141. package/dist/template-resolver/document-schema.js +4 -0
  142. package/dist/template-resolver/feature.d.ts +11 -0
  143. package/dist/template-resolver/feature.js +60 -31
  144. package/dist/template-resolver/handlers/bundle-import.js +1 -0
  145. package/dist/template-resolver/handlers/collection-item.query.js +2 -1
  146. package/dist/template-resolver/handlers/collection-list.query.js +2 -1
  147. package/dist/template-resolver/handlers/collection-set.write.js +2 -2
  148. package/dist/template-resolver/handlers/collection-shared.d.ts +1 -2
  149. package/dist/template-resolver/handlers/collection-shared.js +0 -4
  150. package/dist/template-resolver/handlers/copy-locale.write.d.ts +2 -1
  151. package/dist/template-resolver/handlers/copy-locale.write.js +67 -63
  152. package/dist/template-resolver/handlers/discard-draft.write.d.ts +3 -2
  153. package/dist/template-resolver/handlers/discard-draft.write.js +18 -6
  154. package/dist/template-resolver/handlers/document-base.d.ts +23 -0
  155. package/dist/template-resolver/handlers/document-base.js +55 -0
  156. package/dist/template-resolver/handlers/document-blocks.query.d.ts +22 -0
  157. package/dist/template-resolver/handlers/document-blocks.query.js +46 -0
  158. package/dist/template-resolver/handlers/export-bundle.query.d.ts +1 -0
  159. package/dist/template-resolver/handlers/export-bundle.query.js +9 -2
  160. package/dist/template-resolver/handlers/import-bundle-system.write.d.ts +1 -0
  161. package/dist/template-resolver/handlers/import-bundle.write.d.ts +3 -1
  162. package/dist/template-resolver/handlers/import-bundle.write.js +30 -25
  163. package/dist/template-resolver/handlers/overview.query.d.ts +2 -1
  164. package/dist/template-resolver/handlers/overview.query.js +46 -42
  165. package/dist/template-resolver/handlers/patch-draft.write.d.ts +67 -0
  166. package/dist/template-resolver/handlers/patch-draft.write.js +111 -0
  167. package/dist/template-resolver/handlers/preview.query.d.ts +1 -0
  168. package/dist/template-resolver/handlers/preview.query.js +2 -1
  169. package/dist/template-resolver/handlers/reset-to-system.write.d.ts +2 -1
  170. package/dist/template-resolver/handlers/reset-to-system.write.js +51 -44
  171. package/dist/template-resolver/handlers/resource-link-pdf.write.d.ts +2 -1
  172. package/dist/template-resolver/handlers/resource-link-pdf.write.js +34 -28
  173. package/dist/template-resolver/handlers/resource-remove.write.d.ts +2 -1
  174. package/dist/template-resolver/handlers/resource-remove.write.js +39 -33
  175. package/dist/template-resolver/handlers/resource-upload.write.d.ts +2 -1
  176. package/dist/template-resolver/handlers/resource-upload.write.js +104 -96
  177. package/dist/template-resolver/handlers/send-test-shared.d.ts +5 -0
  178. package/dist/template-resolver/handlers/send-test-shared.js +19 -0
  179. package/dist/template-resolver/handlers/send-test-status.query.d.ts +9 -0
  180. package/dist/template-resolver/handlers/send-test-status.query.js +18 -0
  181. package/dist/template-resolver/handlers/send-test.write.d.ts +3 -1
  182. package/dist/template-resolver/handlers/send-test.write.js +87 -88
  183. package/dist/template-resolver/handlers/set.write.d.ts +2 -1
  184. package/dist/template-resolver/handlers/set.write.js +94 -90
  185. package/dist/template-resolver/handlers/template-write.d.ts +2 -0
  186. package/dist/template-resolver/handlers/template-write.js +14 -2
  187. package/dist/template-resolver/handlers/toggle-status.write.d.ts +6 -7
  188. package/dist/template-resolver/handlers/toggle-status.write.js +28 -10
  189. package/dist/template-resolver/handlers/upsert-tenant.write.d.ts +2 -1
  190. package/dist/template-resolver/handlers/upsert-tenant.write.js +30 -24
  191. package/dist/template-resolver/handlers/validate.query.d.ts +10 -4
  192. package/dist/template-resolver/handlers/validate.query.js +12 -7
  193. package/dist/template-resolver/index.d.ts +4 -2
  194. package/dist/template-resolver/index.js +3 -1
  195. package/dist/template-resolver/{web/placeholder-text.js → placeholder-text.js} +1 -1
  196. package/dist/template-resolver/qualified-names.d.ts +4 -0
  197. package/dist/template-resolver/qualified-names.js +4 -0
  198. package/dist/template-resolver/seeding.d.ts +1 -0
  199. package/dist/template-resolver/seeding.js +2 -1
  200. package/dist/template-resolver/table.d.ts +10 -10
  201. package/dist/template-resolver/template-bundle.d.ts +1 -0
  202. package/dist/template-resolver/template-bundle.js +6 -1
  203. package/dist/template-resolver/template-edit-policy.d.ts +22 -0
  204. package/dist/template-resolver/template-edit-policy.js +45 -0
  205. package/dist/template-resolver/template-preview.d.ts +4 -1
  206. package/dist/template-resolver/template-preview.js +23 -5
  207. package/dist/template-resolver/template-validation.d.ts +2 -1
  208. package/dist/template-resolver/template-validation.js +34 -14
  209. package/dist/template-resolver/user-content-table.d.ts +10 -10
  210. package/dist/template-resolver/web/client-plugin.d.ts +1 -1
  211. package/dist/template-resolver/web/client-plugin.js +3 -3
  212. package/dist/template-resolver/web/document-editor-extensions.d.ts +1 -0
  213. package/dist/template-resolver/web/document-editor-extensions.js +21 -1
  214. package/dist/template-resolver/web/document-tiptap-editor.d.ts +1 -1
  215. package/dist/template-resolver/web/document-tiptap-editor.js +23 -7
  216. package/dist/template-resolver/web/document-toolbar-blocks.d.ts +4 -5
  217. package/dist/template-resolver/web/document-toolbar-blocks.js +1 -21
  218. package/dist/template-resolver/web/i18n.js +18 -0
  219. package/dist/template-resolver/web/placeholder-line-editor.js +2 -2
  220. package/dist/tenant/invitation-table.d.ts +6 -6
  221. package/dist/tenant/membership-table.d.ts +4 -4
  222. package/dist/tenant/schema/tenant.d.ts +6 -6
  223. package/dist/tenant/web/client-plugin.d.ts +1 -1
  224. package/dist/tenant/web/member-status-cell.js +1 -1
  225. package/dist/tier-engine/entity.d.ts +1 -1
  226. package/dist/tier-engine/tier-resolver.d.ts +1 -1
  227. package/dist/tier-engine/web/client-plugin.d.ts +1 -1
  228. package/dist/user/schema/user.d.ts +12 -12
  229. package/dist/user-data-rights/env.d.ts +5 -0
  230. package/dist/user-data-rights/env.js +11 -0
  231. package/dist/user-data-rights/feature.js +4 -2
  232. package/dist/user-data-rights/index.d.ts +1 -0
  233. package/dist/user-data-rights/index.js +1 -0
  234. package/dist/user-data-rights/lib/mail-transport-resolver.js +1 -1
  235. package/dist/user-data-rights/lib/storage-provider-resolver.js +1 -1
  236. package/dist/user-data-rights/mail-notifications.js +1 -1
  237. package/dist/user-data-rights/schema/download-attempt.d.ts +14 -14
  238. package/dist/user-data-rights/schema/download-token.d.ts +8 -8
  239. package/dist/user-data-rights/schema/export-job.d.ts +6 -6
  240. package/dist/user-data-rights/web/client-plugin.d.ts +1 -1
  241. package/dist/user-data-rights/web/privacy-center-screen.js +2 -2
  242. package/dist/waitlist/entity.d.ts +14 -14
  243. package/dist/waitlist/legacy-migrate.d.ts +2 -0
  244. package/dist/waitlist/legacy-migrate.js +38 -3
  245. package/package.json +16 -11
  246. package/src/account-security/changes.json +6 -0
  247. package/src/auth-foundation/changes.json +6 -0
  248. package/src/billing-foundation/changes.json +6 -0
  249. package/src/cap-counter/changes.json +12 -0
  250. package/src/channel-email/changes.json +6 -0
  251. package/src/crypto-shredding/changes.json +6 -0
  252. package/src/file-provider-s3/changes.json +6 -0
  253. package/src/host-routing/changes.json +6 -0
  254. package/src/inbound-mail-foundation/changes.json +13 -0
  255. package/src/legal-pages/changes.json +6 -0
  256. package/src/mail-foundation/changes.json +6 -0
  257. package/src/template-resolver/changes.json +38 -0
  258. package/src/user-data-rights/changes.json +6 -0
  259. package/src/waitlist/changes.json +6 -0
  260. /package/dist/template-resolver/{web/placeholder-text.d.ts → placeholder-text.d.ts} +0 -0
@@ -14,7 +14,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
14
14
  readonly sensitive?: boolean;
15
15
  readonly writeOnly?: boolean;
16
16
  readonly readAsInstruction?: boolean;
17
- readonly format?: "email" | "url" | "phone" | "password";
17
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
18
18
  readonly default?: string;
19
19
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
20
20
  readonly multiline?: boolean | {
@@ -37,7 +37,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
37
37
  readonly sensitive?: boolean;
38
38
  readonly writeOnly?: boolean;
39
39
  readonly readAsInstruction?: boolean;
40
- readonly format?: "email" | "url" | "phone" | "password";
40
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
41
41
  readonly default?: string;
42
42
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
43
43
  readonly multiline?: boolean | {
@@ -89,7 +89,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
89
89
  readonly sensitive?: boolean;
90
90
  readonly writeOnly?: boolean;
91
91
  readonly readAsInstruction?: boolean;
92
- readonly format?: "email" | "url" | "phone" | "password";
92
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
93
93
  readonly default?: string;
94
94
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
95
95
  readonly multiline?: boolean | {
@@ -112,7 +112,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
112
112
  readonly sensitive?: boolean;
113
113
  readonly writeOnly?: boolean;
114
114
  readonly readAsInstruction?: boolean;
115
- readonly format?: "email" | "url" | "phone" | "password";
115
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
116
116
  readonly default?: string;
117
117
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
118
118
  readonly multiline?: boolean | {
@@ -135,7 +135,7 @@ export declare const userContentEntryEntity: import("@cosmicdrift/kumiko-types/f
135
135
  readonly sensitive?: boolean;
136
136
  readonly writeOnly?: boolean;
137
137
  readonly readAsInstruction?: boolean;
138
- readonly format?: "email" | "url" | "phone" | "password";
138
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
139
139
  readonly default?: string;
140
140
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
141
141
  readonly multiline?: boolean | {
@@ -200,7 +200,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
200
200
  readonly sensitive?: boolean;
201
201
  readonly writeOnly?: boolean;
202
202
  readonly readAsInstruction?: boolean;
203
- readonly format?: "email" | "url" | "phone" | "password";
203
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
204
204
  readonly default?: string;
205
205
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
206
206
  readonly multiline?: boolean | {
@@ -223,7 +223,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
223
223
  readonly sensitive?: boolean;
224
224
  readonly writeOnly?: boolean;
225
225
  readonly readAsInstruction?: boolean;
226
- readonly format?: "email" | "url" | "phone" | "password";
226
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
227
227
  readonly default?: string;
228
228
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
229
229
  readonly multiline?: boolean | {
@@ -275,7 +275,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
275
275
  readonly sensitive?: boolean;
276
276
  readonly writeOnly?: boolean;
277
277
  readonly readAsInstruction?: boolean;
278
- readonly format?: "email" | "url" | "phone" | "password";
278
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
279
279
  readonly default?: string;
280
280
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
281
281
  readonly multiline?: boolean | {
@@ -298,7 +298,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
298
298
  readonly sensitive?: boolean;
299
299
  readonly writeOnly?: boolean;
300
300
  readonly readAsInstruction?: boolean;
301
- readonly format?: "email" | "url" | "phone" | "password";
301
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
302
302
  readonly default?: string;
303
303
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
304
304
  readonly multiline?: boolean | {
@@ -321,7 +321,7 @@ export declare const userContentEntriesTable: import("@cosmicdrift/kumiko-framew
321
321
  readonly sensitive?: boolean;
322
322
  readonly writeOnly?: boolean;
323
323
  readonly readAsInstruction?: boolean;
324
- readonly format?: "email" | "url" | "phone" | "password";
324
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
325
325
  readonly default?: string;
326
326
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
327
327
  readonly multiline?: boolean | {
@@ -1,5 +1,5 @@
1
1
  import type { TreeNode } from "@cosmicdrift/kumiko-framework/engine";
2
- import { type ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer-web";
2
+ import { type ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer/web";
3
3
  export type BlockSummary = {
4
4
  readonly slug: string;
5
5
  readonly locale: string;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { EMPTY_VALUE_PLACEHOLDER } from "@cosmicdrift/kumiko-headless";
2
+ import { EMPTY_VALUE_PLACEHOLDER } from "@cosmicdrift/kumiko-renderer/headless";
3
3
  // @runtime client
4
4
  // Client feature factory for the text-block content tree. Apps mount it via
5
5
  // createKumikoApp({ clientFeatures: [textBlocksClient()] }); it loads the
@@ -12,9 +12,9 @@ import { EMPTY_VALUE_PLACEHOLDER } from "@cosmicdrift/kumiko-headless";
12
12
  // **State**: TreeNode.state = "filled" when content is set, otherwise "stub"
13
13
  // (a hint that the slug exists but is empty).
14
14
  import { useShellUser } from "@cosmicdrift/kumiko-bundled-features/auth-email-password/web";
15
- import { CSRF_HEADER_NAME, readCsrfToken } from "@cosmicdrift/kumiko-dispatcher-live";
16
15
  import { ContentPreview, useAppFeatures, useContentEditor, useDispatcher, usePrimitives, useQuery, useTranslation, } from "@cosmicdrift/kumiko-renderer";
17
- import { PlainContentEditor, RichContentEditor, } from "@cosmicdrift/kumiko-renderer-web";
16
+ import { CSRF_HEADER_NAME, readCsrfToken } from "@cosmicdrift/kumiko-renderer/live";
17
+ import { PlainContentEditor, RichContentEditor, } from "@cosmicdrift/kumiko-renderer/web";
18
18
  import { useEffect, useId, useState } from "react";
19
19
  import { collectionHandlerName, collectionQueryName, TemplateResolverHandlers, TemplateResolverQueries, } from "../qualified-names.js";
20
20
  import { DocumentBlocksContext, DocumentContentEditor } from "./document-editor.js";
@@ -7,6 +7,7 @@ export type DocumentEditorLabels = {
7
7
  readonly pageBreak: string;
8
8
  readonly button?: string;
9
9
  readonly steps?: string;
10
+ readonly images?: string;
10
11
  /** Canvas block label of an image, e.g. "Image · inline". */
11
12
  readonly imageBlock?: string;
12
13
  readonly variableLabels?: Readonly<Record<string, string>>;
@@ -1,6 +1,6 @@
1
1
  import { ListKeymap } from "@tiptap/extension-list";
2
2
  import { Dropcursor, Gapcursor, Placeholder, UndoRedo } from "@tiptap/extensions";
3
- import { DocumentButton, DocumentPageBreak, DocumentResource, DocumentSteps, DocumentVariable, documentExtensions, } from "../document-schema.js";
3
+ import { DocumentButton, DocumentImages, DocumentPageBreak, DocumentResource, DocumentSteps, DocumentVariable, documentExtensions, } from "../document-schema.js";
4
4
  import { readDocumentStepsAttribute } from "../document-steps.js";
5
5
  const DOCUMENT_RESOURCE_SIZE_TOKEN = "{size}";
6
6
  export const DOCUMENT_BLOCK_ATTRIBUTE = "data-document-block";
@@ -134,6 +134,24 @@ function createStepsView(labels) {
134
134
  return { dom };
135
135
  };
136
136
  }
137
+ // A sketch only: the photos are record data, known at render time.
138
+ function createImagesView(labels) {
139
+ return ({ node }) => {
140
+ const dom = createElementWithClass("div", "relative my-3 rounded border border-dashed border-input px-3 pb-3 pt-4");
141
+ dom.setAttribute(DOCUMENT_BLOCK_ATTRIBUTE, "");
142
+ dom.contentEditable = "false";
143
+ const variable = String(node.attrs["variable"]);
144
+ const variableLabels = labels.variableLabels ?? {};
145
+ const variableLabel = Object.hasOwn(variableLabels, variable)
146
+ ? variableLabels[variable]
147
+ : undefined;
148
+ dom.append(createBlockLabel(`${labels.images ?? "Photos"} · ${variableLabel ?? variable}`));
149
+ const grid = createElementWithClass("div", "grid grid-cols-2 gap-1.5");
150
+ grid.append(createElementWithClass("div", "h-12 rounded bg-muted"), createElementWithClass("div", "h-12 rounded bg-muted"));
151
+ dom.append(grid);
152
+ return { dom };
153
+ };
154
+ }
137
155
  // Replaced by name, not appended: the schema must keep exactly one node per
138
156
  // name, and only the editor view differs from the shared document schema.
139
157
  export function createDocumentEditorExtensions(labels) {
@@ -151,6 +169,8 @@ export function createDocumentEditorExtensions(labels) {
151
169
  : extension;
152
170
  case DocumentSteps.name:
153
171
  return DocumentSteps.extend({ addNodeView: () => createStepsView(labels) });
172
+ case DocumentImages.name:
173
+ return DocumentImages.extend({ addNodeView: () => createImagesView(labels) });
154
174
  case DocumentPageBreak.name:
155
175
  return DocumentPageBreak.extend({
156
176
  addNodeView: () => createPageBreakView(labels.pageBreak),
@@ -1,3 +1,3 @@
1
1
  import { type ReactNode } from "react";
2
2
  import { type DocumentEditorProps } from "./document-toolbar-blocks.ts";
3
- export default function DocumentTiptapEditor({ id, value, onChange, variables, readOnly, blocks, variableLabels, systemVariables, resourcePreviews, chrome, toolbar, renderPaper, toolbarHost, onEditorReady, }: DocumentEditorProps): ReactNode;
3
+ export default function DocumentTiptapEditor({ id, value, onChange, variables, readOnly, blocks: configuredBlocks, imageVariables, variableLabels, systemVariables, resourcePreviews, chrome, toolbar, renderPaper, toolbarHost, onEditorReady, }: DocumentEditorProps): ReactNode;
@@ -6,11 +6,11 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
6
6
  // collection is rendered. Variables are inserted as `variable` nodes only,
7
7
  // never as `{{name}}` text, so the sanitizer's schema keeps them.
8
8
  import { TextareaContentEditor, usePrimitives, useTranslation, VariableChips, } from "@cosmicdrift/kumiko-renderer";
9
- import { cn } from "@cosmicdrift/kumiko-renderer-web";
9
+ import { cn } from "@cosmicdrift/kumiko-renderer/web";
10
10
  import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
11
11
  import { EditorContent, useEditor, useEditorState } from "@tiptap/react";
12
12
  import { BubbleMenu } from "@tiptap/react/menus";
13
- import { AlignCenter, AlignJustify, AlignLeft, AlignRight, Bold as BoldIcon, Braces, ChevronDown, Image as ImageIcon, Italic as ItalicIcon, Link as LinkIcon, List, ListChecks, ListOrdered, Minus, MousePointerClick, Repeat, Scissors, Table as TableIcon, Underline as UnderlineIcon, } from "lucide-react";
13
+ import { AlignCenter, AlignJustify, AlignLeft, AlignRight, Bold as BoldIcon, Braces, ChevronDown, GalleryThumbnails, Image as ImageIcon, Italic as ItalicIcon, Link as LinkIcon, List, ListChecks, ListOrdered, Minus, MousePointerClick, Repeat, Scissors, Table as TableIcon, Underline as UnderlineIcon, } from "lucide-react";
14
14
  import { Fragment, useEffect, useMemo, useState } from "react";
15
15
  import { createPortal } from "react-dom";
16
16
  import { DOCUMENT_TEXT_ALIGNMENTS, isAllowedDocumentLinkHref, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "../document-schema.js";
@@ -35,6 +35,7 @@ const BLOCK_PANEL = {
35
35
  repeat: "repeat",
36
36
  align: "align",
37
37
  steps: "steps",
38
+ images: "images",
38
39
  };
39
40
  const ALIGNMENT_ICONS = {
40
41
  left: _jsx(AlignLeft, { size: 16 }),
@@ -243,7 +244,11 @@ function InsertPanel({ editor, editorId, kind, variables, variableLabels, onClos
243
244
  }
244
245
  insertAndClose({ type: "steps", attrs: { variable: selectedName, steps } });
245
246
  };
246
- const needsVariables = kind === "button" || kind === "repeat" || kind === "placeholder" || kind === "steps";
247
+ const needsVariables = kind === "button" ||
248
+ kind === "repeat" ||
249
+ kind === "placeholder" ||
250
+ kind === "steps" ||
251
+ kind === "images";
247
252
  const noVariables = needsVariables && selectable.length === 0;
248
253
  const idPrefix = `${editorId}-panel`;
249
254
  return (_jsxs("div", { className: "flex flex-col gap-2 border-b border-input bg-muted/40 p-2", children: [noVariables && (_jsx("p", { className: "text-sm text-muted-foreground", children: t("template-resolver.documentEditor.noVariables") })), kind === "link" && (_jsx(Field, { id: `${idPrefix}-href`, label: t("template-resolver.documentEditor.linkHref"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-href`, name: "href", value: href, onChange: setHref, placeholder: t("template-resolver.documentEditor.linkHrefPlaceholder") }) })), kind === "placeholder" && !noVariables && (_jsx("div", { className: "flex flex-wrap gap-1", children: _jsx(VariableChips, { variables: selectable, labels: variableLabels, onInsert: (name) => insertAndClose({ type: "variable", attrs: { name } }) }) })), kind === "align" && (_jsx("div", { className: "flex flex-wrap gap-1", children: DOCUMENT_TEXT_ALIGNMENTS.map((alignment) => (_jsxs(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => {
@@ -254,7 +259,7 @@ function InsertPanel({ editor, editorId, kind, variables, variableLabels, onClos
254
259
  .updateAttributes("heading", { textAlign: alignment })
255
260
  .run();
256
261
  onClose();
257
- }, children: [ALIGNMENT_ICONS[alignment], t(ALIGNMENT_LABEL_KEYS[alignment])] }, alignment))) })), kind === "image" && (_jsxs(_Fragment, { children: [_jsx(Field, { id: `${idPrefix}-resource`, label: t("template-resolver.documentEditor.resourceKey"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-resource`, name: "resource", value: resource, onChange: setResource }) }), _jsx(Field, { id: `${idPrefix}-alt`, label: t("template-resolver.documentEditor.imageAlt"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-alt`, name: "alt", value: alt, onChange: setAlt }) })] })), kind === "button" && !noVariables && (_jsxs(_Fragment, { children: [_jsx(NameSelect, { id: `${idPrefix}-target`, label: t("template-resolver.documentEditor.buttonTarget"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName }), _jsx(Field, { id: `${idPrefix}-text`, label: t("template-resolver.documentEditor.buttonText"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-text`, name: "text", value: buttonText, onChange: setButtonText }) })] })), kind === "repeat" && !noVariables && (_jsx(NameSelect, { id: `${idPrefix}-list`, label: t("template-resolver.documentEditor.repeatList"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName })), kind === "steps" && !noVariables && (_jsxs(_Fragment, { children: [_jsx(NameSelect, { id: `${idPrefix}-steps-variable`, label: t("template-resolver.documentEditor.stepsVariable"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName }), _jsx(Field, { id: `${idPrefix}-steps-list`, label: t("template-resolver.documentEditor.stepsList"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-steps-list`, name: "steps", value: stepsText, onChange: setStepsText }) })] })), error !== null && (_jsx("p", { role: "alert", className: "text-sm text-destructive", children: error })), _jsx("div", { className: "flex flex-wrap gap-2", children: _jsx(PanelActions, { onCancel: onClose, ...(kind === "link" && { onInsert: submitLink }), ...(kind === "link" &&
262
+ }, children: [ALIGNMENT_ICONS[alignment], t(ALIGNMENT_LABEL_KEYS[alignment])] }, alignment))) })), kind === "image" && (_jsxs(_Fragment, { children: [_jsx(Field, { id: `${idPrefix}-resource`, label: t("template-resolver.documentEditor.resourceKey"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-resource`, name: "resource", value: resource, onChange: setResource }) }), _jsx(Field, { id: `${idPrefix}-alt`, label: t("template-resolver.documentEditor.imageAlt"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-alt`, name: "alt", value: alt, onChange: setAlt }) })] })), kind === "button" && !noVariables && (_jsxs(_Fragment, { children: [_jsx(NameSelect, { id: `${idPrefix}-target`, label: t("template-resolver.documentEditor.buttonTarget"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName }), _jsx(Field, { id: `${idPrefix}-text`, label: t("template-resolver.documentEditor.buttonText"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-text`, name: "text", value: buttonText, onChange: setButtonText }) })] })), kind === "repeat" && !noVariables && (_jsx(NameSelect, { id: `${idPrefix}-list`, label: t("template-resolver.documentEditor.repeatList"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName })), kind === "images" && !noVariables && (_jsx(NameSelect, { id: `${idPrefix}-images-variable`, label: t("template-resolver.documentEditor.imagesVariable"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName })), kind === "steps" && !noVariables && (_jsxs(_Fragment, { children: [_jsx(NameSelect, { id: `${idPrefix}-steps-variable`, label: t("template-resolver.documentEditor.stepsVariable"), names: selectable, labels: variableLabels, value: selectedName, onChange: setChosenName }), _jsx(Field, { id: `${idPrefix}-steps-list`, label: t("template-resolver.documentEditor.stepsList"), children: _jsx(Input, { kind: "text", id: `${idPrefix}-steps-list`, name: "steps", value: stepsText, onChange: setStepsText }) })] })), error !== null && (_jsx("p", { role: "alert", className: "text-sm text-destructive", children: error })), _jsx("div", { className: "flex flex-wrap gap-2", children: _jsx(PanelActions, { onCancel: onClose, ...(kind === "link" && { onInsert: submitLink }), ...(kind === "link" &&
258
263
  editor.isActive("link") && {
259
264
  onRemoveLink: () => {
260
265
  editor.chain().focus().extendMarkRange("link").unsetLink().run();
@@ -268,9 +273,12 @@ function InsertPanel({ editor, editorId, kind, variables, variableLabels, onClos
268
273
  content: buttonText ? [{ type: "text", text: buttonText }] : [],
269
274
  }),
270
275
  }), ...(kind === "repeat" &&
271
- !noVariables && { onInsert: () => insertAndClose(repeatTableContent(selectedName)) }), ...(kind === "steps" && !noVariables && { onInsert: submitSteps }) }) })] }));
276
+ !noVariables && { onInsert: () => insertAndClose(repeatTableContent(selectedName)) }), ...(kind === "steps" && !noVariables && { onInsert: submitSteps }), ...(kind === "images" &&
277
+ !noVariables && {
278
+ onInsert: () => insertAndClose({ type: "images", attrs: { variable: selectedName } }),
279
+ }) }) })] }));
272
280
  }
273
- export default function DocumentTiptapEditor({ id, value, onChange, variables, readOnly, blocks = MAIL_DOCUMENT_BLOCKS, variableLabels = NO_LABELS, systemVariables = NO_NAMES, resourcePreviews = NO_PREVIEWS, chrome = "default", toolbar = "full", renderPaper, toolbarHost, onEditorReady, }) {
281
+ export default function DocumentTiptapEditor({ id, value, onChange, variables, readOnly, blocks: configuredBlocks = MAIL_DOCUMENT_BLOCKS, imageVariables = NO_NAMES, variableLabels = NO_LABELS, systemVariables = NO_NAMES, resourcePreviews = NO_PREVIEWS, chrome = "default", toolbar = "full", renderPaper, toolbarHost, onEditorReady, }) {
274
282
  const t = useTranslation();
275
283
  const { ActionOverflowMenu, Button, Field, Input } = usePrimitives();
276
284
  const [openPanel, setOpenPanel] = useState(null);
@@ -279,12 +287,17 @@ export default function DocumentTiptapEditor({ id, value, onChange, variables, r
279
287
  const canvas = chrome === "canvas";
280
288
  const compact = toolbar === "compact" && !canvas;
281
289
  const hosted = toolbarHost !== undefined;
290
+ // A photo block needs an images variable to bind to; without one the button would open an empty panel.
291
+ const blocks = imageVariables.length === 0
292
+ ? configuredBlocks.filter((block) => block !== "images")
293
+ : configuredBlocks;
282
294
  const placeholderLabel = t("template-resolver.documentEditor.placeholder");
283
295
  const imageLabel = t("template-resolver.documentEditor.image");
284
296
  const imageBlockLabel = t("template-resolver.documentEditor.imageBlock");
285
297
  const pageBreakLabel = t("template-resolver.documentEditor.pageBreak");
286
298
  const buttonLabel = t("template-resolver.documentEditor.button");
287
299
  const stepsLabel = t("template-resolver.documentEditor.steps");
300
+ const imagesLabel = t("template-resolver.documentEditor.images");
288
301
  const stableLabels = useStableByKey(variableLabels, JSON.stringify(variableLabels));
289
302
  const stableSystem = useStableByKey(systemVariables, systemVariables.join("\n"));
290
303
  const stablePreviews = useStableByKey(resourcePreviews, previewsKey(resourcePreviews));
@@ -294,6 +307,7 @@ export default function DocumentTiptapEditor({ id, value, onChange, variables, r
294
307
  pageBreak: pageBreakLabel,
295
308
  button: buttonLabel,
296
309
  steps: stepsLabel,
310
+ images: imagesLabel,
297
311
  imageBlock: imageBlockLabel,
298
312
  variableLabels: stableLabels,
299
313
  systemVariables: stableSystem,
@@ -306,6 +320,7 @@ export default function DocumentTiptapEditor({ id, value, onChange, variables, r
306
320
  pageBreakLabel,
307
321
  buttonLabel,
308
322
  stepsLabel,
323
+ imagesLabel,
309
324
  stableLabels,
310
325
  stableSystem,
311
326
  stablePreviews,
@@ -415,6 +430,7 @@ export default function DocumentTiptapEditor({ id, value, onChange, variables, r
415
430
  pageBreak: { label: pageBreakLabel, icon: _jsx(Scissors, { size: 16 }) },
416
431
  align: { label: t("template-resolver.documentEditor.align"), icon: _jsx(AlignLeft, { size: 16 }) },
417
432
  steps: { label: stepsLabel, icon: _jsx(ListChecks, { size: 16 }) },
433
+ images: { label: imagesLabel, icon: _jsx(GalleryThumbnails, { size: 16 }) },
418
434
  };
419
435
  const repeatTable = activeState?.repeatTable ?? null;
420
436
  const repeatListLabel = repeatTable !== null && repeatTable.lists.length === 1
@@ -507,7 +523,7 @@ export default function DocumentTiptapEditor({ id, value, onChange, variables, r
507
523
  : t("template-resolver.documentEditor.buttonTarget"), ": ", selectedBlock.type === "button" ? (_jsx("strong", { children: buttonTargetLabel(selectedBlock.detail, variableLabels) })) : (_jsx("code", { children: selectedBlock.detail }))] }), _jsx(Button, { type: "button", size: "sm", variant: "danger-ghost", onClick: () => {
508
524
  editor.chain().focus().deleteNode(selectedBlock.type).run();
509
525
  }, children: t("template-resolver.documentEditor.removeBlock") })] })) : (repeatTable !== null && (_jsxs("div", { "data-testid": "document-repeat-bar", className: BUBBLE_BAR_CLASS, children: [_jsx("span", { className: "px-1.5 text-[10px] uppercase tracking-wide text-muted-foreground", children: repeatBarLabel }), _jsx(Button, { type: "button", variant: "secondary", size: "sm", pressed: repeatTable.headerRepeats, onClick: () => toggleRepeatHeader(editor), children: t("template-resolver.documentEditor.repeatHeader") })] }))) }, mountKeyOf(editor)));
510
- const insertPanel = openPanel !== null && !readOnly && (_jsx(InsertPanel, { editor: editor, editorId: id, kind: openPanel, variables: variables, variableLabels: stableLabels, onClose: () => setOpenPanel(null) }, openPanel));
526
+ const insertPanel = openPanel !== null && !readOnly && (_jsx(InsertPanel, { editor: editor, editorId: id, kind: openPanel, variables: openPanel === "images" ? imageVariables : variables, variableLabels: stableLabels, onClose: () => setOpenPanel(null) }, openPanel));
511
527
  if (hosted) {
512
528
  return (_jsxs(_Fragment, { children: [toolbarHost !== null &&
513
529
  createPortal(_jsxs(_Fragment, { children: [toolbarBar, insertPanel] }), toolbarHost), !readOnly && bubbleMenu, editorContent] }));
@@ -1,6 +1,6 @@
1
1
  import type { ContentEditorProps } from "@cosmicdrift/kumiko-renderer";
2
2
  import type { ReactNode } from "react";
3
- export type DocumentToolbarBlock = "image" | "table" | "button" | "divider" | "repeat" | "pageBreak" | "align" | "steps";
3
+ import type { DocumentToolbarBlock } from "../document-blocks.ts";
4
4
  /** Imperative access for an outside panel (placeholder list, resource list). */
5
5
  export type DocumentEditorHandle = {
6
6
  readonly insertPlaceholder: (name: string) => void;
@@ -17,6 +17,8 @@ export type DocumentResourcePreview = {
17
17
  export type DocumentEditorChrome = "default" | "canvas";
18
18
  export type DocumentEditorProps = ContentEditorProps & {
19
19
  readonly blocks?: readonly DocumentToolbarBlock[];
20
+ /** Names of the template's images variables; the photo block offers exactly these and is hidden without any. */
21
+ readonly imageVariables?: readonly string[];
20
22
  /** Display label per variable name, as inserted (list item fields use the
21
23
  * dotted form, e.g. "lines.description"). A chip shows label and name. */
22
24
  readonly variableLabels?: Readonly<Record<string, string>>;
@@ -35,7 +37,4 @@ export type DocumentEditorProps = ContentEditorProps & {
35
37
  /** Called with the handle once the editor exists and with null when it is destroyed (unmount or rebuild), so a held handle never outlives its editor. */
36
38
  readonly onEditorReady?: (handle: DocumentEditorHandle | null) => void;
37
39
  };
38
- export declare const MAIL_DOCUMENT_BLOCKS: readonly ["image", "table", "button", "divider", "repeat", "steps"];
39
- export declare const PDF_DOCUMENT_BLOCKS: readonly ["align", "image", "table", "divider", "repeat", "steps", "pageBreak"];
40
- /** Block set for a template-resource kind; every kind except "document-pdf" gets the mail set. */
41
- export declare function documentBlocksForKind(kind: string | undefined): readonly DocumentToolbarBlock[];
40
+ export { type DocumentToolbarBlock, documentBlocksForKind, MAIL_DOCUMENT_BLOCKS, PDF_DOCUMENT_BLOCKS, } from "../document-blocks.ts";
@@ -1,21 +1 @@
1
- export const MAIL_DOCUMENT_BLOCKS = [
2
- "image",
3
- "table",
4
- "button",
5
- "divider",
6
- "repeat",
7
- "steps",
8
- ];
9
- export const PDF_DOCUMENT_BLOCKS = [
10
- "align",
11
- "image",
12
- "table",
13
- "divider",
14
- "repeat",
15
- "steps",
16
- "pageBreak",
17
- ];
18
- /** Block set for a template-resource kind; every kind except "document-pdf" gets the mail set. */
19
- export function documentBlocksForKind(kind) {
20
- return kind === "document-pdf" ? PDF_DOCUMENT_BLOCKS : MAIL_DOCUMENT_BLOCKS;
21
- }
1
+ export { documentBlocksForKind, MAIL_DOCUMENT_BLOCKS, PDF_DOCUMENT_BLOCKS, } from "../document-blocks.js";
@@ -39,6 +39,8 @@ export const defaultTranslations = {
39
39
  "template-resolver.documentEditor.removeLink": "Remove link",
40
40
  "template-resolver.documentEditor.repeat": "Repeat",
41
41
  "template-resolver.documentEditor.repeatList": "List to repeat",
42
+ "template-resolver.documentEditor.images": "Photos",
43
+ "template-resolver.documentEditor.imagesVariable": "Photos from",
42
44
  "template-resolver.documentEditor.steps": "Steps",
43
45
  "template-resolver.documentEditor.stepsVariable": "Current step from",
44
46
  "template-resolver.documentEditor.stepsList": "Steps, separated by commas (value=label)",
@@ -52,6 +54,7 @@ export const defaultTranslations = {
52
54
  "template-resolver.editor.saving": "Saving…",
53
55
  "template-resolver.editor.created": "Created.",
54
56
  "template-resolver.editor.saved": "Saved.",
57
+ "templateResolver.errors.document.imagesBlockPdfOnly": "Photo blocks are only allowed in PDF documents.",
55
58
  "templateResolver.errors.document.buttonHrefNotPlaceholder": "The button target “{detail}” must be a placeholder.",
56
59
  "templateResolver.errors.document.disallowedLinkHref": "Link target “{detail}” is not allowed; use https, http, mailto, tel or a placeholder.",
57
60
  "templateResolver.errors.document.documentRequiresHtmlFormat": "This template kind requires the html format, got “{detail}”.",
@@ -66,6 +69,20 @@ export const defaultTranslations = {
66
69
  "templateResolver.checks.sizeUnderCap": "The mail is within the 10 MiB size limit",
67
70
  "templateResolver.checks.requiredPlaceholders": "All required placeholders are used",
68
71
  "templateResolver.errors.preview.renderFailed": "The preview could not be rendered.",
72
+ "templateResolver.errors.patch.unknownBlock": "The block {blockId} does not exist in the template.",
73
+ "templateResolver.errors.patch.blockRemoved": "The block {blockId} was already removed by an earlier step.",
74
+ "templateResolver.errors.patch.textNotFound": "The text {find} was not found in the block.",
75
+ "templateResolver.errors.patch.textAmbiguous": "The text {find} occurs {count} times in the block; use a longer text.",
76
+ "templateResolver.errors.patch.blockNotAllowed": "The block type {type} is not available in {kind} templates.",
77
+ "templateResolver.errors.patch.blockTypeMismatch": "This step needs a {expected} block, but the block is a {actual}.",
78
+ "templateResolver.errors.patch.invalidResourceKey": "The image key {resource} is not valid.",
79
+ "templateResolver.errors.patch.invalidButtonHref": "A button target must be a placeholder in double curly braces.",
80
+ "templateResolver.errors.patch.invalidVariableName": "The variable name {name} is not valid.",
81
+ "templateResolver.errors.patch.invalidVariableDefinition": "The definition of the variable {name} is not valid.",
82
+ "templateResolver.errors.patch.invalidDocument": "The change would produce an invalid document.",
83
+ "templateResolver.errors.patch.invalidMetaKey": "The meta key {key} is not allowed.",
84
+ "templateResolver.errors.patch.variablesDeclaredByFeature": "The variables of {slug} are fixed by the application and cannot be changed.",
85
+ "templateResolver.errors.patch.requiredPlaceholderRemoved": "The change removes required placeholders: {names}",
69
86
  "templateResolver.errors.testMail.noChannel": "No email channel is set up, so no test mail can be sent.",
70
87
  "templateResolver.errors.testMail.noAddress": "Your account has no email address to send the test mail to.",
71
88
  "templateResolver.errors.testMail.failed": "The test mail could not be sent.",
@@ -77,6 +94,7 @@ export const defaultTranslations = {
77
94
  "templateResolver.errors.noSystemTemplate": "There is no active system template to reset to.",
78
95
  "templateResolver.errors.noDraft": "There is no draft to discard.",
79
96
  "templateResolver.errors.systemOnlyTemplate": "Only the platform maintains this template; it cannot be overridden per tenant.",
97
+ "templateResolver.errors.templateNotTenantEditable": "Only the platform may edit this template.",
80
98
  "templateResolver.errors.template.invalidMeta": "The template settings are invalid.",
81
99
  "templateResolver.errors.template.meta.subject.required": "The subject is missing.",
82
100
  "templateResolver.errors.template.meta.subject.invalid": "The subject is invalid (at most 200 characters, no line breaks).",
@@ -4,16 +4,16 @@ import { jsx as _jsx } from "react/jsx-runtime";
4
4
  // Single-line editor for plain-text fields that carry {{placeholders}}
5
5
  // (subject, preheader). The stored value stays plain text; placeholders show
6
6
  // as chips while editing. Lives in the same lazy chunk as the document editor.
7
- import { cn } from "@cosmicdrift/kumiko-renderer-web";
7
+ import { cn } from "@cosmicdrift/kumiko-renderer/web";
8
8
  import { Extension, Node } from "@tiptap/core";
9
9
  import { Placeholder, UndoRedo } from "@tiptap/extensions";
10
10
  import { EditorContent, useEditor } from "@tiptap/react";
11
11
  import StarterKit from "@tiptap/starter-kit";
12
12
  import { useMemo, useState } from "react";
13
13
  import { DocumentVariable } from "../document-schema.js";
14
+ import { contentToLine, lineToContent, singleLine } from "../placeholder-text.js";
14
15
  import { createVariableView } from "./document-editor-extensions.js";
15
16
  import { createEditorHandle } from "./editor-handle.js";
16
- import { contentToLine, lineToContent, singleLine } from "./placeholder-text.js";
17
17
  import { useStableByKey } from "./use-stable-by-key.js";
18
18
  const LineDocument = Node.create({ name: "doc", topNode: true, content: "paragraph" });
19
19
  // One line only: Enter must not split the paragraph.
@@ -21,7 +21,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
21
21
  readonly sensitive?: boolean;
22
22
  readonly writeOnly?: boolean;
23
23
  readonly readAsInstruction?: boolean;
24
- readonly format?: "email" | "url" | "phone" | "password";
24
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
25
25
  readonly default?: string;
26
26
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
27
27
  readonly multiline?: boolean | {
@@ -44,7 +44,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
44
44
  readonly sensitive?: boolean;
45
45
  readonly writeOnly?: boolean;
46
46
  readonly readAsInstruction?: boolean;
47
- readonly format?: "email" | "url" | "phone" | "password";
47
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
48
48
  readonly default?: string;
49
49
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
50
50
  readonly multiline?: boolean | {
@@ -92,7 +92,7 @@ export declare const tenantInvitationEntity: import("@cosmicdrift/kumiko-types/f
92
92
  readonly sensitive?: boolean;
93
93
  readonly writeOnly?: boolean;
94
94
  readonly readAsInstruction?: boolean;
95
- readonly format?: "email" | "url" | "phone" | "password";
95
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
96
96
  readonly default?: string;
97
97
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
98
98
  readonly multiline?: boolean | {
@@ -151,7 +151,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
151
151
  readonly sensitive?: boolean;
152
152
  readonly writeOnly?: boolean;
153
153
  readonly readAsInstruction?: boolean;
154
- readonly format?: "email" | "url" | "phone" | "password";
154
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
155
155
  readonly default?: string;
156
156
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
157
157
  readonly multiline?: boolean | {
@@ -174,7 +174,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
174
174
  readonly sensitive?: boolean;
175
175
  readonly writeOnly?: boolean;
176
176
  readonly readAsInstruction?: boolean;
177
- readonly format?: "email" | "url" | "phone" | "password";
177
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
178
178
  readonly default?: string;
179
179
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
180
180
  readonly multiline?: boolean | {
@@ -222,7 +222,7 @@ export declare const tenantInvitationsTable: import("@cosmicdrift/kumiko-framewo
222
222
  readonly sensitive?: boolean;
223
223
  readonly writeOnly?: boolean;
224
224
  readonly readAsInstruction?: boolean;
225
- readonly format?: "email" | "url" | "phone" | "password";
225
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
226
226
  readonly default?: string;
227
227
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
228
228
  readonly multiline?: boolean | {
@@ -13,7 +13,7 @@ export declare const tenantMembershipEntity: import("@cosmicdrift/kumiko-types/f
13
13
  readonly sensitive?: boolean;
14
14
  readonly writeOnly?: boolean;
15
15
  readonly readAsInstruction?: boolean;
16
- readonly format?: "email" | "url" | "phone" | "password";
16
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
17
17
  readonly default?: string;
18
18
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
19
19
  readonly multiline?: boolean | {
@@ -36,7 +36,7 @@ export declare const tenantMembershipEntity: import("@cosmicdrift/kumiko-types/f
36
36
  readonly sensitive?: boolean;
37
37
  readonly writeOnly?: boolean;
38
38
  readonly readAsInstruction?: boolean;
39
- readonly format?: "email" | "url" | "phone" | "password";
39
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
40
40
  readonly default?: string;
41
41
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
42
42
  readonly multiline?: boolean | {
@@ -61,7 +61,7 @@ export declare const tenantMembershipsTable: import("@cosmicdrift/kumiko-framewo
61
61
  readonly sensitive?: boolean;
62
62
  readonly writeOnly?: boolean;
63
63
  readonly readAsInstruction?: boolean;
64
- readonly format?: "email" | "url" | "phone" | "password";
64
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
65
65
  readonly default?: string;
66
66
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
67
67
  readonly multiline?: boolean | {
@@ -84,7 +84,7 @@ export declare const tenantMembershipsTable: import("@cosmicdrift/kumiko-framewo
84
84
  readonly sensitive?: boolean;
85
85
  readonly writeOnly?: boolean;
86
86
  readonly readAsInstruction?: boolean;
87
- readonly format?: "email" | "url" | "phone" | "password";
87
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
88
88
  readonly default?: string;
89
89
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
90
90
  readonly multiline?: boolean | {
@@ -15,7 +15,7 @@ export declare const tenantEntity: import("@cosmicdrift/kumiko-types/fields").En
15
15
  readonly sensitive?: boolean;
16
16
  readonly writeOnly?: boolean;
17
17
  readonly readAsInstruction?: boolean;
18
- readonly format?: "email" | "url" | "phone" | "password";
18
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
19
19
  readonly default?: string;
20
20
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
21
21
  readonly multiline?: boolean | {
@@ -38,7 +38,7 @@ export declare const tenantEntity: import("@cosmicdrift/kumiko-types/fields").En
38
38
  readonly sensitive?: boolean;
39
39
  readonly writeOnly?: boolean;
40
40
  readonly readAsInstruction?: boolean;
41
- readonly format?: "email" | "url" | "phone" | "password";
41
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
42
42
  readonly default?: string;
43
43
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
44
44
  readonly multiline?: boolean | {
@@ -105,7 +105,7 @@ export declare const tenantEntity: import("@cosmicdrift/kumiko-types/fields").En
105
105
  readonly sensitive?: boolean;
106
106
  readonly writeOnly?: boolean;
107
107
  readonly readAsInstruction?: boolean;
108
- readonly format?: "email" | "url" | "phone" | "password";
108
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
109
109
  readonly default?: string;
110
110
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
111
111
  readonly multiline?: boolean | {
@@ -175,7 +175,7 @@ export declare const tenantTable: import("@cosmicdrift/kumiko-framework/db").Ent
175
175
  readonly sensitive?: boolean;
176
176
  readonly writeOnly?: boolean;
177
177
  readonly readAsInstruction?: boolean;
178
- readonly format?: "email" | "url" | "phone" | "password";
178
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
179
179
  readonly default?: string;
180
180
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
181
181
  readonly multiline?: boolean | {
@@ -198,7 +198,7 @@ export declare const tenantTable: import("@cosmicdrift/kumiko-framework/db").Ent
198
198
  readonly sensitive?: boolean;
199
199
  readonly writeOnly?: boolean;
200
200
  readonly readAsInstruction?: boolean;
201
- readonly format?: "email" | "url" | "phone" | "password";
201
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
202
202
  readonly default?: string;
203
203
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
204
204
  readonly multiline?: boolean | {
@@ -265,7 +265,7 @@ export declare const tenantTable: import("@cosmicdrift/kumiko-framework/db").Ent
265
265
  readonly sensitive?: boolean;
266
266
  readonly writeOnly?: boolean;
267
267
  readonly readAsInstruction?: boolean;
268
- readonly format?: "email" | "url" | "phone" | "password";
268
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
269
269
  readonly default?: string;
270
270
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
271
271
  readonly multiline?: boolean | {
@@ -1,5 +1,5 @@
1
1
  import { type TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
2
- import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer-web";
2
+ import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer/web";
3
3
  export type TenantClientOptions = {
4
4
  readonly translations?: TranslationsByLocale;
5
5
  };
@@ -5,7 +5,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
5
5
  // screens.ts). The list frame itself is the generic declarative
6
6
  // projectionList renderer — only this one cell stays TSX.
7
7
  import { useTranslation } from "@cosmicdrift/kumiko-renderer";
8
- import { StatusBadge } from "@cosmicdrift/kumiko-renderer-web";
8
+ import { StatusBadge } from "@cosmicdrift/kumiko-renderer/web";
9
9
  import { translateOrRaw } from "../../shared/web/translate-or-raw.js";
10
10
  const STATUS_TONE = {
11
11
  active: "ok",
@@ -14,7 +14,7 @@ export declare const tierAssignmentEntity: import("@cosmicdrift/kumiko-types/fie
14
14
  readonly sensitive?: boolean;
15
15
  readonly writeOnly?: boolean;
16
16
  readonly readAsInstruction?: boolean;
17
- readonly format?: "email" | "url" | "phone" | "password";
17
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
18
18
  readonly default?: string;
19
19
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
20
20
  readonly multiline?: boolean | {
@@ -21,7 +21,7 @@ export declare function createTierResolver<TTier extends string, TCaps>(deps: Ti
21
21
  readonly sensitive?: boolean;
22
22
  readonly writeOnly?: boolean;
23
23
  readonly readAsInstruction?: boolean;
24
- readonly format?: "email" | "url" | "phone" | "password";
24
+ readonly format?: "email" | "url" | "phone" | "password" | "month";
25
25
  readonly default?: string;
26
26
  readonly access?: import("@cosmicdrift/kumiko-types/fields").FieldAccess;
27
27
  readonly multiline?: boolean | {
@@ -1,5 +1,5 @@
1
1
  import { type TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
2
- import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer-web";
2
+ import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer/web";
3
3
  export type TierEngineClientOptions = {
4
4
  /** Per-key overrides over the default bundles (de/en). */
5
5
  readonly translations?: TranslationsByLocale;