@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
@@ -0,0 +1,167 @@
1
+ import type { FieldIssue } from "@cosmicdrift/kumiko-framework/errors";
2
+ import { type JSONContent } from "@tiptap/core";
3
+ import * as z from "zod";
4
+ import type { DocumentHtmlKind } from "./constants.ts";
5
+ export declare const MAX_DOCUMENT_OPS = 50;
6
+ export type DocumentBlockType = "paragraph" | "heading" | "list" | "table" | "repeat" | "image" | "button" | "divider" | "pageBreak" | "steps";
7
+ export type DocumentBlock = {
8
+ readonly id: string;
9
+ readonly type: DocumentBlockType;
10
+ /** Inline content with `{{name}}` for placeholders; containers list one line per text block. */
11
+ readonly text?: string;
12
+ readonly level?: number;
13
+ readonly align?: string;
14
+ readonly showIf?: string;
15
+ readonly resource?: string;
16
+ readonly alt?: string;
17
+ readonly href?: string;
18
+ readonly each?: string;
19
+ };
20
+ export declare function documentBlockId(index: number): string;
21
+ export declare function documentBlocksOf(doc: JSONContent): DocumentBlock[];
22
+ declare const blockInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
23
+ type: z.ZodLiteral<"paragraph">;
24
+ text: z.ZodString;
25
+ align: z.ZodOptional<z.ZodEnum<{
26
+ center: "center";
27
+ justify: "justify";
28
+ left: "left";
29
+ right: "right";
30
+ }>>;
31
+ }, z.core.$strip>, z.ZodObject<{
32
+ type: z.ZodLiteral<"heading">;
33
+ level: z.ZodNumber;
34
+ text: z.ZodString;
35
+ }, z.core.$strip>, z.ZodObject<{
36
+ type: z.ZodLiteral<"image">;
37
+ resource: z.ZodString;
38
+ alt: z.ZodOptional<z.ZodString>;
39
+ }, z.core.$strip>, z.ZodObject<{
40
+ type: z.ZodLiteral<"button">;
41
+ text: z.ZodString;
42
+ href: z.ZodString;
43
+ }, z.core.$strip>, z.ZodObject<{
44
+ type: z.ZodLiteral<"divider">;
45
+ }, z.core.$strip>, z.ZodObject<{
46
+ type: z.ZodLiteral<"pageBreak">;
47
+ }, z.core.$strip>], "type">;
48
+ export type BlockInput = z.infer<typeof blockInputSchema>;
49
+ export declare const documentOpSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
50
+ op: z.ZodLiteral<"insertBlock">;
51
+ after: z.ZodNullable<z.ZodString>;
52
+ block: z.ZodDiscriminatedUnion<[z.ZodObject<{
53
+ type: z.ZodLiteral<"paragraph">;
54
+ text: z.ZodString;
55
+ align: z.ZodOptional<z.ZodEnum<{
56
+ center: "center";
57
+ justify: "justify";
58
+ left: "left";
59
+ right: "right";
60
+ }>>;
61
+ }, z.core.$strip>, z.ZodObject<{
62
+ type: z.ZodLiteral<"heading">;
63
+ level: z.ZodNumber;
64
+ text: z.ZodString;
65
+ }, z.core.$strip>, z.ZodObject<{
66
+ type: z.ZodLiteral<"image">;
67
+ resource: z.ZodString;
68
+ alt: z.ZodOptional<z.ZodString>;
69
+ }, z.core.$strip>, z.ZodObject<{
70
+ type: z.ZodLiteral<"button">;
71
+ text: z.ZodString;
72
+ href: z.ZodString;
73
+ }, z.core.$strip>, z.ZodObject<{
74
+ type: z.ZodLiteral<"divider">;
75
+ }, z.core.$strip>, z.ZodObject<{
76
+ type: z.ZodLiteral<"pageBreak">;
77
+ }, z.core.$strip>], "type">;
78
+ }, z.core.$strip>, z.ZodObject<{
79
+ op: z.ZodLiteral<"replaceText">;
80
+ blockId: z.ZodString;
81
+ find: z.ZodString;
82
+ replace: z.ZodString;
83
+ }, z.core.$strip>, z.ZodObject<{
84
+ op: z.ZodLiteral<"removeBlock">;
85
+ blockId: z.ZodString;
86
+ }, z.core.$strip>, z.ZodObject<{
87
+ op: z.ZodLiteral<"setResource">;
88
+ blockId: z.ZodString;
89
+ resource: z.ZodString;
90
+ alt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
91
+ }, z.core.$strip>, z.ZodObject<{
92
+ op: z.ZodLiteral<"setMeta">;
93
+ meta: z.ZodRecord<z.ZodString, z.ZodUnknown>;
94
+ }, z.core.$strip>, z.ZodObject<{
95
+ op: z.ZodLiteral<"setVariable">;
96
+ name: z.ZodString;
97
+ definition: z.ZodNullable<z.ZodUnknown>;
98
+ }, z.core.$strip>], "op">;
99
+ export declare const documentOpsSchema: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
100
+ op: z.ZodLiteral<"insertBlock">;
101
+ after: z.ZodNullable<z.ZodString>;
102
+ block: z.ZodDiscriminatedUnion<[z.ZodObject<{
103
+ type: z.ZodLiteral<"paragraph">;
104
+ text: z.ZodString;
105
+ align: z.ZodOptional<z.ZodEnum<{
106
+ center: "center";
107
+ justify: "justify";
108
+ left: "left";
109
+ right: "right";
110
+ }>>;
111
+ }, z.core.$strip>, z.ZodObject<{
112
+ type: z.ZodLiteral<"heading">;
113
+ level: z.ZodNumber;
114
+ text: z.ZodString;
115
+ }, z.core.$strip>, z.ZodObject<{
116
+ type: z.ZodLiteral<"image">;
117
+ resource: z.ZodString;
118
+ alt: z.ZodOptional<z.ZodString>;
119
+ }, z.core.$strip>, z.ZodObject<{
120
+ type: z.ZodLiteral<"button">;
121
+ text: z.ZodString;
122
+ href: z.ZodString;
123
+ }, z.core.$strip>, z.ZodObject<{
124
+ type: z.ZodLiteral<"divider">;
125
+ }, z.core.$strip>, z.ZodObject<{
126
+ type: z.ZodLiteral<"pageBreak">;
127
+ }, z.core.$strip>], "type">;
128
+ }, z.core.$strip>, z.ZodObject<{
129
+ op: z.ZodLiteral<"replaceText">;
130
+ blockId: z.ZodString;
131
+ find: z.ZodString;
132
+ replace: z.ZodString;
133
+ }, z.core.$strip>, z.ZodObject<{
134
+ op: z.ZodLiteral<"removeBlock">;
135
+ blockId: z.ZodString;
136
+ }, z.core.$strip>, z.ZodObject<{
137
+ op: z.ZodLiteral<"setResource">;
138
+ blockId: z.ZodString;
139
+ resource: z.ZodString;
140
+ alt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
141
+ }, z.core.$strip>, z.ZodObject<{
142
+ op: z.ZodLiteral<"setMeta">;
143
+ meta: z.ZodRecord<z.ZodString, z.ZodUnknown>;
144
+ }, z.core.$strip>, z.ZodObject<{
145
+ op: z.ZodLiteral<"setVariable">;
146
+ name: z.ZodString;
147
+ definition: z.ZodNullable<z.ZodUnknown>;
148
+ }, z.core.$strip>], "op">>;
149
+ export type DocumentOp = z.infer<typeof documentOpSchema>;
150
+ export type DocumentOpsInput = {
151
+ readonly doc: JSONContent;
152
+ readonly meta: Readonly<Record<string, unknown>>;
153
+ readonly variableSchema: Readonly<Record<string, unknown>>;
154
+ readonly kind: DocumentHtmlKind;
155
+ readonly ops: readonly DocumentOp[];
156
+ };
157
+ export type DocumentOpsResult = {
158
+ readonly ok: true;
159
+ readonly doc: JSONContent;
160
+ readonly meta: Record<string, unknown>;
161
+ readonly variableSchema: Record<string, unknown>;
162
+ } | {
163
+ readonly ok: false;
164
+ readonly issues: FieldIssue[];
165
+ };
166
+ export declare function applyDocumentOps(input: DocumentOpsInput): DocumentOpsResult;
167
+ export {};
@@ -0,0 +1,390 @@
1
+ import { getSchema } from "@tiptap/core";
2
+ import * as z from "zod";
3
+ import { documentBlocksForKind } from "./document-blocks.js";
4
+ import { DOCUMENT_TEXT_ALIGNMENTS, documentExtensions, isDocumentPlaceholderHref, isDocumentReferenceName, isDocumentResourceKey, } from "./document-schema.js";
5
+ import { contentToLine, lineToContent, singleLine } from "./placeholder-text.js";
6
+ import { toVariableDef } from "./template-validation.js";
7
+ export const MAX_DOCUMENT_OPS = 50;
8
+ // Assigning these keys would reach the prototype of the meta object.
9
+ const FORBIDDEN_META_KEYS = new Set(["__proto__", "prototype", "constructor"]);
10
+ const TEXT_BLOCK_TYPES = new Set(["paragraph", "heading", "button"]);
11
+ function blockTypeOf(node) {
12
+ switch (node.type) {
13
+ case "paragraph":
14
+ case "heading":
15
+ case "button":
16
+ case "divider":
17
+ case "pageBreak":
18
+ case "steps":
19
+ return node.type;
20
+ case "bulletList":
21
+ case "orderedList":
22
+ return "list";
23
+ case "table":
24
+ return eachOf(node) === undefined ? "table" : "repeat";
25
+ case "resource":
26
+ return "image";
27
+ default:
28
+ return null;
29
+ }
30
+ }
31
+ function stringAttr(node, name) {
32
+ const value = node.attrs?.[name];
33
+ return typeof value === "string" && value !== "" ? value : undefined;
34
+ }
35
+ function eachOf(table) {
36
+ for (const row of table.content ?? []) {
37
+ const each = stringAttr(row, "each");
38
+ if (each !== undefined)
39
+ return each;
40
+ }
41
+ return undefined;
42
+ }
43
+ function textLinesOf(node) {
44
+ if (TEXT_BLOCK_TYPES.has(node.type ?? ""))
45
+ return [contentToLine(node.content)];
46
+ return (node.content ?? []).flatMap(textLinesOf);
47
+ }
48
+ const NON_TEXT_BLOCK_TYPES = new Set([
49
+ "image",
50
+ "divider",
51
+ "pageBreak",
52
+ "steps",
53
+ ]);
54
+ function setOptionalAttrs(block, node) {
55
+ const align = stringAttr(node, "textAlign");
56
+ if (align !== undefined)
57
+ block.align = align;
58
+ const showIf = stringAttr(node, "showIf");
59
+ if (showIf !== undefined)
60
+ block.showIf = showIf;
61
+ }
62
+ function setTypeSpecificAttrs(block, node) {
63
+ const level = node.attrs?.["level"];
64
+ if (block.type === "heading" && typeof level === "number")
65
+ block.level = level;
66
+ const resource = stringAttr(node, "resource");
67
+ if (block.type === "image" && resource !== undefined)
68
+ block.resource = resource;
69
+ const alt = stringAttr(node, "alt");
70
+ if (block.type === "image" && alt !== undefined)
71
+ block.alt = alt;
72
+ const href = stringAttr(node, "href");
73
+ if (block.type === "button" && href !== undefined)
74
+ block.href = href;
75
+ const each = eachOf(node);
76
+ if (block.type === "repeat" && each !== undefined)
77
+ block.each = each;
78
+ }
79
+ function blockOf(node, id) {
80
+ const type = blockTypeOf(node);
81
+ if (type === null)
82
+ return null;
83
+ const block = { id, type };
84
+ if (!NON_TEXT_BLOCK_TYPES.has(type))
85
+ block.text = textLinesOf(node).join("\n");
86
+ setOptionalAttrs(block, node);
87
+ setTypeSpecificAttrs(block, node);
88
+ return block;
89
+ }
90
+ export function documentBlockId(index) {
91
+ return `b${index}`;
92
+ }
93
+ export function documentBlocksOf(doc) {
94
+ return (doc.content ?? []).flatMap((node, index) => blockOf(node, documentBlockId(index)) ?? []);
95
+ }
96
+ const blockIdSchema = z.string().min(1).max(20);
97
+ const singleLineText = z.string().max(2000);
98
+ const blockInputSchema = z.discriminatedUnion("type", [
99
+ z.object({
100
+ type: z.literal("paragraph"),
101
+ text: singleLineText,
102
+ align: z.enum(DOCUMENT_TEXT_ALIGNMENTS).optional(),
103
+ }),
104
+ z.object({
105
+ type: z.literal("heading"),
106
+ level: z.number().int().min(1).max(3),
107
+ text: singleLineText,
108
+ }),
109
+ z.object({
110
+ type: z.literal("image"),
111
+ resource: z.string().min(1).max(200),
112
+ alt: z.string().max(500).optional(),
113
+ }),
114
+ z.object({ type: z.literal("button"), text: singleLineText, href: z.string().max(300) }),
115
+ z.object({ type: z.literal("divider") }),
116
+ z.object({ type: z.literal("pageBreak") }),
117
+ ]);
118
+ export const documentOpSchema = z.discriminatedUnion("op", [
119
+ z.object({
120
+ op: z.literal("insertBlock"),
121
+ after: blockIdSchema.nullable(),
122
+ block: blockInputSchema,
123
+ }),
124
+ z.object({
125
+ op: z.literal("replaceText"),
126
+ blockId: blockIdSchema,
127
+ find: z.string().min(1).max(2000),
128
+ replace: z.string().max(2000),
129
+ }),
130
+ z.object({ op: z.literal("removeBlock"), blockId: blockIdSchema }),
131
+ z.object({
132
+ op: z.literal("setResource"),
133
+ blockId: blockIdSchema,
134
+ resource: z.string().min(1).max(200),
135
+ alt: z.string().max(500).nullable().optional(),
136
+ }),
137
+ z.object({ op: z.literal("setMeta"), meta: z.record(z.string(), z.unknown()) }),
138
+ z.object({
139
+ op: z.literal("setVariable"),
140
+ name: z.string().min(1).max(100),
141
+ definition: z.unknown().nullable(),
142
+ }),
143
+ ]);
144
+ export const documentOpsSchema = z.array(documentOpSchema).min(1).max(MAX_DOCUMENT_OPS);
145
+ function patchIssue(path, code, params) {
146
+ const camel = code.replace(/_([a-z])/g, (_match, letter) => letter.toUpperCase());
147
+ return {
148
+ path,
149
+ code,
150
+ i18nKey: `templateResolver.errors.patch.${camel}`,
151
+ ...(params === undefined ? {} : { params }),
152
+ };
153
+ }
154
+ function textNodesIn(nodes) {
155
+ return nodes.flatMap((node) => (node.type === "text" ? [node] : textNodesIn(node.content ?? [])));
156
+ }
157
+ function occurrencesOf(text, find) {
158
+ return text.split(find).length - 1;
159
+ }
160
+ function replacementNodes(textNode, find, replace) {
161
+ const text = textNode.text ?? "";
162
+ const at = text.indexOf(find);
163
+ const withMarks = (node) => node.type === "text" && textNode.marks !== undefined
164
+ ? { ...node, marks: textNode.marks }
165
+ : node;
166
+ const before = text.slice(0, at);
167
+ const after = text.slice(at + find.length);
168
+ return [
169
+ ...(before === "" ? [] : [{ ...textNode, text: before }]),
170
+ ...lineToContent(singleLine(replace)).map(withMarks),
171
+ ...(after === "" ? [] : [{ ...textNode, text: after }]),
172
+ ];
173
+ }
174
+ function replaceInContent(content, find, replace) {
175
+ return content.flatMap((node) => {
176
+ if (node.type === "text") {
177
+ return (node.text ?? "").includes(find) ? replacementNodes(node, find, replace) : [node];
178
+ }
179
+ return [
180
+ node.content === undefined
181
+ ? node
182
+ : { ...node, content: replaceInContent(node.content, find, replace) },
183
+ ];
184
+ });
185
+ }
186
+ function nodeOfInput(input) {
187
+ switch (input.type) {
188
+ case "paragraph":
189
+ return {
190
+ type: "paragraph",
191
+ ...(input.align === undefined ? {} : { attrs: { textAlign: input.align } }),
192
+ content: lineToContent(singleLine(input.text)),
193
+ };
194
+ case "heading":
195
+ return {
196
+ type: "heading",
197
+ attrs: { level: input.level },
198
+ content: lineToContent(singleLine(input.text)),
199
+ };
200
+ case "image":
201
+ return { type: "resource", attrs: { resource: input.resource, alt: input.alt ?? null } };
202
+ case "button":
203
+ return {
204
+ type: "button",
205
+ attrs: { href: input.href },
206
+ content: lineToContent(singleLine(input.text)),
207
+ };
208
+ case "divider":
209
+ case "pageBreak":
210
+ return { type: input.type };
211
+ }
212
+ }
213
+ const TOOLBAR_BLOCK_OF_INPUT = {
214
+ image: "image",
215
+ button: "button",
216
+ divider: "divider",
217
+ pageBreak: "pageBreak",
218
+ };
219
+ function isBlockAllowed(input, kind) {
220
+ if (input.type === "paragraph" || input.type === "heading")
221
+ return true;
222
+ return documentBlocksForKind(kind).includes(TOOLBAR_BLOCK_OF_INPUT[input.type]);
223
+ }
224
+ function inputIssue(input, path) {
225
+ if (input.type === "image" && !isDocumentResourceKey(input.resource)) {
226
+ return patchIssue(`${path}.block.resource`, "invalid_resource_key", {
227
+ resource: input.resource,
228
+ });
229
+ }
230
+ if (input.type === "button" && !isDocumentPlaceholderHref(input.href)) {
231
+ return patchIssue(`${path}.block.href`, "invalid_button_href", { href: input.href });
232
+ }
233
+ return null;
234
+ }
235
+ let cachedSchema = null;
236
+ function documentSchema() {
237
+ cachedSchema ??= getSchema(documentExtensions);
238
+ return cachedSchema;
239
+ }
240
+ function isValidDocument(doc) {
241
+ try {
242
+ documentSchema().nodeFromJSON(doc).check();
243
+ return true;
244
+ }
245
+ catch {
246
+ return false;
247
+ }
248
+ }
249
+ function lookupEntry(state, blockId, fieldPath) {
250
+ const entry = state.entries.get(blockId);
251
+ if (entry === undefined)
252
+ return { issue: patchIssue(fieldPath, "unknown_block", { blockId }) };
253
+ if (entry.removed)
254
+ return { issue: patchIssue(fieldPath, "block_removed", { blockId }) };
255
+ return { entry };
256
+ }
257
+ function blockInputIssue(op, path, kind) {
258
+ if (!isBlockAllowed(op.block, kind)) {
259
+ return patchIssue(`${path}.block.type`, "block_not_allowed", { type: op.block.type, kind });
260
+ }
261
+ if (op.block.type === "paragraph" &&
262
+ op.block.align !== undefined &&
263
+ !documentBlocksForKind(kind).includes("align")) {
264
+ return patchIssue(`${path}.block.align`, "block_not_allowed", { type: "align", kind });
265
+ }
266
+ return inputIssue(op.block, path);
267
+ }
268
+ function insertBlockOp(state, op, path) {
269
+ const anchor = op.after === null ? null : lookupEntry(state, op.after, `${path}.after`);
270
+ if (anchor !== null && "issue" in anchor)
271
+ return anchor.issue;
272
+ const invalid = blockInputIssue(op, path, state.kind);
273
+ if (invalid !== null)
274
+ return invalid;
275
+ const target = anchor === null ? state.insertedAtStart : anchor.entry.insertedAfter;
276
+ target.push(nodeOfInput(op.block));
277
+ return null;
278
+ }
279
+ function removeBlockOp(state, op, path) {
280
+ const found = lookupEntry(state, op.blockId, `${path}.blockId`);
281
+ if ("issue" in found)
282
+ return found.issue;
283
+ found.entry.removed = true;
284
+ return null;
285
+ }
286
+ function replaceTextOp(state, op, path) {
287
+ const found = lookupEntry(state, op.blockId, `${path}.blockId`);
288
+ if ("issue" in found)
289
+ return found.issue;
290
+ const { entry } = found;
291
+ const count = textNodesIn([entry.node]).reduce((sum, node) => sum + occurrencesOf(node.text ?? "", op.find), 0);
292
+ if (count === 0)
293
+ return patchIssue(`${path}.find`, "text_not_found", { find: op.find });
294
+ if (count > 1)
295
+ return patchIssue(`${path}.find`, "text_ambiguous", { find: op.find, count });
296
+ entry.node = replaceInContent([entry.node], op.find, op.replace)[0] ?? entry.node;
297
+ return null;
298
+ }
299
+ function setResourceOp(state, op, path) {
300
+ const found = lookupEntry(state, op.blockId, `${path}.blockId`);
301
+ if ("issue" in found)
302
+ return found.issue;
303
+ const { entry } = found;
304
+ if (entry.node.type !== "resource") {
305
+ return patchIssue(`${path}.blockId`, "block_type_mismatch", {
306
+ expected: "image",
307
+ actual: entry.node.type ?? "unknown",
308
+ });
309
+ }
310
+ if (!isDocumentResourceKey(op.resource)) {
311
+ return patchIssue(`${path}.resource`, "invalid_resource_key", { resource: op.resource });
312
+ }
313
+ const alt = op.alt === undefined ? (entry.node.attrs?.["alt"] ?? null) : op.alt;
314
+ entry.node = { ...entry.node, attrs: { resource: op.resource, alt } };
315
+ return null;
316
+ }
317
+ function setMetaOp(state, op, path) {
318
+ const forbidden = Object.keys(op.meta).find((key) => FORBIDDEN_META_KEYS.has(key));
319
+ if (forbidden !== undefined) {
320
+ return patchIssue(`${path}.meta`, "invalid_meta_key", { key: forbidden });
321
+ }
322
+ for (const [key, value] of Object.entries(op.meta)) {
323
+ if (value === null)
324
+ delete state.meta[key];
325
+ else
326
+ state.meta[key] = value;
327
+ }
328
+ return null;
329
+ }
330
+ function setVariableOp(state, op, path) {
331
+ if (!isDocumentReferenceName(op.name)) {
332
+ return patchIssue(`${path}.name`, "invalid_variable_name", { name: op.name });
333
+ }
334
+ if (op.definition === null) {
335
+ delete state.variableSchema[op.name];
336
+ return null;
337
+ }
338
+ const definition = toVariableDef(op.definition);
339
+ if (definition === null) {
340
+ return patchIssue(`${path}.definition`, "invalid_variable_definition", { name: op.name });
341
+ }
342
+ state.variableSchema[op.name] = definition;
343
+ return null;
344
+ }
345
+ function applyOp(state, op, path) {
346
+ switch (op.op) {
347
+ case "insertBlock":
348
+ return insertBlockOp(state, op, path);
349
+ case "removeBlock":
350
+ return removeBlockOp(state, op, path);
351
+ case "replaceText":
352
+ return replaceTextOp(state, op, path);
353
+ case "setResource":
354
+ return setResourceOp(state, op, path);
355
+ case "setMeta":
356
+ return setMetaOp(state, op, path);
357
+ case "setVariable":
358
+ return setVariableOp(state, op, path);
359
+ }
360
+ }
361
+ // Ops address blocks by the ids of the document as it was read, so inserted blocks are
362
+ // collected per anchor and the list is assembled once at the end.
363
+ export function applyDocumentOps(input) {
364
+ const entries = new Map();
365
+ (input.doc.content ?? []).forEach((node, index) => {
366
+ entries.set(documentBlockId(index), {
367
+ node: structuredClone(node),
368
+ removed: false,
369
+ insertedAfter: [],
370
+ });
371
+ });
372
+ const state = {
373
+ kind: input.kind,
374
+ entries,
375
+ insertedAtStart: [],
376
+ meta: { ...input.meta },
377
+ variableSchema: { ...input.variableSchema },
378
+ };
379
+ const issues = input.ops.flatMap((op, index) => applyOp(state, op, `ops.${index}`) ?? []);
380
+ if (issues.length > 0)
381
+ return { ok: false, issues };
382
+ const content = [
383
+ ...state.insertedAtStart,
384
+ ...[...entries.values()].flatMap((entry) => entry.removed ? entry.insertedAfter : [entry.node, ...entry.insertedAfter]),
385
+ ];
386
+ const doc = { ...input.doc, content };
387
+ if (!isValidDocument(doc))
388
+ return { ok: false, issues: [patchIssue("ops", "invalid_document")] };
389
+ return { ok: true, doc, meta: state.meta, variableSchema: state.variableSchema };
390
+ }
@@ -1,7 +1,8 @@
1
1
  import type { FieldIssue } from "@cosmicdrift/kumiko-framework/errors";
2
+ import type { JSONContent } from "@tiptap/core";
2
3
  import { type Element as ScanElement } from "happy-dom";
3
4
  import type { ContentFormat } from "./constants.ts";
4
- export type DocumentViolationCode = "script_element" | "event_handler_attribute" | "disallowed_link_href" | "external_image_source" | "image_without_resource" | "invalid_reference_name" | "embedded_content" | "unsafe_attribute_value" | "button_href_not_placeholder" | "document_requires_html_format" | "layout_requires_mjml_format" | "layout_invalid_structure" | "layout_missing_content_slot" | "layout_source_system_only";
5
+ export type DocumentViolationCode = "script_element" | "event_handler_attribute" | "disallowed_link_href" | "external_image_source" | "image_without_resource" | "invalid_reference_name" | "embedded_content" | "unsafe_attribute_value" | "images_block_pdf_only" | "button_href_not_placeholder" | "document_requires_html_format" | "layout_requires_mjml_format" | "layout_invalid_structure" | "layout_missing_content_slot" | "layout_source_system_only";
5
6
  export type DocumentViolation = {
6
7
  readonly code: DocumentViolationCode;
7
8
  readonly detail: string;
@@ -24,6 +25,8 @@ export type SanitizeBodyResult = {
24
25
  export declare function violation(code: DocumentViolationCode, detail: string, message: string): DocumentViolation;
25
26
  export declare function withParsedDocument<T>(html: string, read: (body: ScanElement) => T): T;
26
27
  export declare function sanitizeDocumentHtml(html: string): SanitizeHtmlResult;
28
+ export declare function parseDocumentJson(html: string): JSONContent;
29
+ export declare function serializeDocumentJson(doc: JSONContent): string;
27
30
  export declare function flattenParagraphsToLineBreaks(sanitizedHtml: string): string;
28
31
  export declare function sanitizeTemplateBody(input: {
29
32
  readonly kind: string;
@@ -59,6 +59,7 @@ const REFERENCE_ATTRIBUTES = [
59
59
  [DOCUMENT_CONDITION_ATTRIBUTE, isDocumentReferenceName],
60
60
  ["data-resource", isDocumentResourceKey],
61
61
  ["data-steps", isDocumentReferenceName],
62
+ ["data-images", isDocumentReferenceName],
62
63
  ["data-step", isDocumentStepKey],
63
64
  ];
64
65
  function scanReferences(tag, element, out) {
@@ -156,6 +157,12 @@ export function sanitizeDocumentHtml(html) {
156
157
  html: generateHTML(generateJSON(html, documentExtensions), documentExtensions),
157
158
  };
158
159
  }
160
+ export function parseDocumentJson(html) {
161
+ return generateJSON(html, documentExtensions);
162
+ }
163
+ export function serializeDocumentJson(doc) {
164
+ return generateHTML(doc, documentExtensions);
165
+ }
159
166
  // For a sanitized value placed inside a line of text: paragraphs become line
160
167
  // breaks. Other blocks (lists, headings) cannot be made inline and stay as they are.
161
168
  export function flattenParagraphsToLineBreaks(sanitizedHtml) {
@@ -176,10 +183,28 @@ function requiredFormatViolation(kind, contentFormat) {
176
183
  }
177
184
  return null;
178
185
  }
186
+ const IMAGES_BLOCK_KIND = "document-pdf";
187
+ // The node is part of the shared document model, so a mail body would keep it after the
188
+ // rebuild; only a PDF resolves the record's images.
189
+ function imagesBlockViolation(input) {
190
+ if (input.kind === IMAGES_BLOCK_KIND ||
191
+ !isSanitizedHtmlKind(input.kind) ||
192
+ input.contentFormat !== "html" ||
193
+ input.content === null) {
194
+ return null;
195
+ }
196
+ const hasImagesBlock = withParsedDocument(input.content, (body) => body.querySelector("div[data-images]") !== null);
197
+ return hasImagesBlock
198
+ ? violation("images_block_pdf_only", input.kind, `Record images blocks are only allowed in templates of kind ${IMAGES_BLOCK_KIND}`)
199
+ : null;
200
+ }
179
201
  export function sanitizeTemplateBody(input) {
180
202
  const formatViolation = requiredFormatViolation(input.kind, input.contentFormat);
181
203
  if (formatViolation !== null)
182
204
  return { ok: false, violations: [formatViolation] };
205
+ const imagesViolation = imagesBlockViolation(input);
206
+ if (imagesViolation !== null)
207
+ return { ok: false, violations: [imagesViolation] };
183
208
  if (!isSanitizedHtmlKind(input.kind) ||
184
209
  input.contentFormat !== "html" ||
185
210
  input.content === null) {
@@ -197,6 +222,7 @@ const VIOLATION_I18N_KEYS = {
197
222
  invalid_reference_name: "templateResolver.errors.document.invalidReferenceName",
198
223
  embedded_content: "templateResolver.errors.document.embeddedContent",
199
224
  unsafe_attribute_value: "templateResolver.errors.document.unsafeAttributeValue",
225
+ images_block_pdf_only: "templateResolver.errors.document.imagesBlockPdfOnly",
200
226
  button_href_not_placeholder: "templateResolver.errors.document.buttonHrefNotPlaceholder",
201
227
  document_requires_html_format: "templateResolver.errors.document.documentRequiresHtmlFormat",
202
228
  layout_requires_mjml_format: "templateResolver.errors.document.layoutRequiresMjmlFormat",
@@ -3,13 +3,14 @@ export declare function isDocumentPlaceholderHref(href: string): boolean;
3
3
  export declare function isAllowedDocumentLinkHref(href: string): boolean;
4
4
  export declare function isDocumentReferenceName(value: string): boolean;
5
5
  export declare function isDocumentResourceKey(value: string): boolean;
6
- export declare const DOCUMENT_NODE_NAMES: readonly ["variable", "resource", "button", "divider", "pageBreak", "steps"];
6
+ export declare const DOCUMENT_NODE_NAMES: readonly ["variable", "resource", "button", "divider", "pageBreak", "steps", "images"];
7
7
  export declare const DocumentVariable: Node<any, any>;
8
8
  export declare const DocumentResource: Node<any, any>;
9
9
  export declare const DocumentButton: Node<any, any>;
10
10
  export declare const DocumentDivider: Node<any, any>;
11
11
  export declare const DocumentPageBreak: Node<any, any>;
12
12
  export declare const DocumentSteps: Node<any, any>;
13
+ export declare const DocumentImages: Node<any, any>;
13
14
  export declare const DocumentTableRow: Node<import("@tiptap/extension-table").TableRowOptions, any>;
14
15
  export declare const DocumentTable: Node<import("@tiptap/extension-table").TableOptions, any>;
15
16
  export declare const DocumentTableCell: Node<import("@tiptap/extension-table").TableCellOptions, any>;
@@ -8,6 +8,7 @@ import { Extension, Node } from "@tiptap/core";
8
8
  import { Link } from "@tiptap/extension-link";
9
9
  import { Table, TableCell, TableHeader, TableRow } from "@tiptap/extension-table";
10
10
  import StarterKit from "@tiptap/starter-kit";
11
+ import { createDocumentImagesNode } from "./document-images.js";
11
12
  import { createDocumentStepsNode } from "./document-steps.js";
12
13
  const PLACEHOLDER_HREF = /^\{\{(.+)\}\}$/;
13
14
  const REFERENCE_NAME = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
@@ -65,6 +66,7 @@ export const DOCUMENT_NODE_NAMES = [
65
66
  "divider",
66
67
  "pageBreak",
67
68
  "steps",
69
+ "images",
68
70
  ];
69
71
  export const DocumentVariable = Node.create({
70
72
  name: "variable",
@@ -170,6 +172,7 @@ export const DocumentPageBreak = Node.create({
170
172
  },
171
173
  });
172
174
  export const DocumentSteps = createDocumentStepsNode(isDocumentReferenceName);
175
+ export const DocumentImages = createDocumentImagesNode(isDocumentReferenceName);
173
176
  // A repeat row is a table row carrying `each`: prosemirror-tables requires
174
177
  // the tableRow node type, so a separate node type is not an option.
175
178
  export const DocumentTableRow = TableRow.extend({
@@ -346,6 +349,7 @@ export const documentExtensions = [
346
349
  DocumentDivider,
347
350
  DocumentPageBreak,
348
351
  DocumentSteps,
352
+ DocumentImages,
349
353
  DocumentTextAlign,
350
354
  DocumentTextSize,
351
355
  DocumentCondition,