@samva/markup 0.8.0 → 0.10.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 (172) hide show
  1. package/AGENTS.md +107 -46
  2. package/CHANGELOG.md +345 -0
  3. package/README.md +188 -52
  4. package/dist/{brand-DcoVkh_S.d.ts → assets-BIsyMQ92.d.ts} +41 -11
  5. package/dist/{email/brand.js → brand-C0MKTwmX.js} +64 -4
  6. package/dist/{theme-css.d.ts → brand.d.ts} +12 -3
  7. package/dist/brand.js +4 -0
  8. package/dist/channel-specs-C2feJwuP.d.ts +13 -0
  9. package/dist/compiler.d.ts +88 -115
  10. package/dist/compiler.js +750 -171
  11. package/dist/components-BZCqegS8.js +1864 -0
  12. package/dist/diagnostic-model-DJtqbETd.js +38 -0
  13. package/dist/{diagnostics-OcQKQYSY.d.ts → diagnostic-model-DxthUZBT.d.ts} +3 -21
  14. package/dist/{diagnostics-BMYtBCQk.d.ts → diagnostics-B-Gym34R.d.ts} +8 -4
  15. package/dist/{email/diagnostics.js → diagnostics-CnKFefKz.js} +4 -3
  16. package/dist/diagnostics.d.ts +410 -2
  17. package/dist/diagnostics.js +402 -52
  18. package/dist/edit.d.ts +234 -0
  19. package/dist/edit.js +947 -0
  20. package/dist/email/jsx-dev-runtime.d.ts +2 -2
  21. package/dist/email/jsx-dev-runtime.js +1 -2
  22. package/dist/email/jsx-runtime.d.ts +1 -1
  23. package/dist/email/jsx-runtime.js +1 -85
  24. package/dist/{email/components.d.ts → email.d.ts} +22 -11
  25. package/dist/email.js +2 -0
  26. package/dist/fmt.d.ts +32 -0
  27. package/dist/fmt.js +174 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.js +2 -0
  30. package/dist/{render-vAv_4r9v.js → ir-CLhlklKV.js} +96 -279
  31. package/dist/jsx-runtime-CBlexoeR.js +98 -0
  32. package/dist/{elements-BzjjnoCS.d.ts → jsx-runtime-ylIOnaSf.d.ts} +76 -76
  33. package/dist/profile-pWGtWZXF.js +3803 -0
  34. package/dist/render-BPonDpCl.d.ts +539 -0
  35. package/dist/render-BQmfh94k.js +257 -0
  36. package/dist/render.d.ts +35 -0
  37. package/dist/render.js +49 -0
  38. package/dist/sms.d.ts +16 -0
  39. package/dist/sms.js +12 -0
  40. package/dist/source-locations-C8wCsiAy.d.ts +23 -0
  41. package/dist/template-DMPwxMSq.d.ts +65 -0
  42. package/dist/template-zLUjcwfF.js +42 -0
  43. package/dist/{theme-css-hFqcPSar.js → theme-css-JtRCm1fb.js} +2 -2
  44. package/dist/whatsapp.d.ts +57 -0
  45. package/dist/whatsapp.js +22 -0
  46. package/generated/contract.json +1788 -0
  47. package/generated/reference.md +360 -0
  48. package/package.json +46 -239
  49. package/samva-brand.d.ts +4 -4
  50. package/skills/sml/SKILL.md +123 -0
  51. package/dist/ast-BrDtApwS.d.ts +0 -107
  52. package/dist/ast.d.ts +0 -2
  53. package/dist/ast.js +0 -124
  54. package/dist/candidate.d.ts +0 -29
  55. package/dist/candidate.js +0 -88
  56. package/dist/catalog-CKuOooB8.d.ts +0 -354
  57. package/dist/checks-D73Xizbw.js +0 -59366
  58. package/dist/checks.d.ts +0 -33
  59. package/dist/checks.js +0 -2
  60. package/dist/classes.d.ts +0 -26
  61. package/dist/classes.js +0 -184
  62. package/dist/compile-sms.d.ts +0 -28
  63. package/dist/compile-sms.js +0 -44
  64. package/dist/compile-whatsapp.d.ts +0 -56
  65. package/dist/compile-whatsapp.js +0 -186
  66. package/dist/compile.d.ts +0 -18
  67. package/dist/compile.js +0 -29
  68. package/dist/components.d.ts +0 -289
  69. package/dist/components.js +0 -106
  70. package/dist/conditionals.d.ts +0 -10
  71. package/dist/conditionals.js +0 -74
  72. package/dist/corpus-CPPfgAHN.d.ts +0 -106
  73. package/dist/css-CS2jLID6.d.ts +0 -109
  74. package/dist/email/assets.d.ts +0 -40
  75. package/dist/email/assets.js +0 -63
  76. package/dist/email/brand-footer.d.ts +0 -34
  77. package/dist/email/brand-footer.js +0 -62
  78. package/dist/email/brand.d.ts +0 -2
  79. package/dist/email/components.js +0 -240
  80. package/dist/email/diagnostics.d.ts +0 -2
  81. package/dist/email/elements.d.ts +0 -2
  82. package/dist/email/elements.js +0 -299
  83. package/dist/email/html.d.ts +0 -2
  84. package/dist/email/html.js +0 -278
  85. package/dist/email/render.d.ts +0 -50
  86. package/dist/email/render.js +0 -3
  87. package/dist/email/selection.d.ts +0 -2
  88. package/dist/email/selection.js +0 -91
  89. package/dist/email/source-edit.d.ts +0 -67
  90. package/dist/email/source-edit.js +0 -185
  91. package/dist/email/stylesheets.d.ts +0 -15
  92. package/dist/email/stylesheets.js +0 -48
  93. package/dist/email/text.d.ts +0 -7
  94. package/dist/email/text.js +0 -100
  95. package/dist/emit.d.ts +0 -51
  96. package/dist/emit.js +0 -151
  97. package/dist/html-Bl9BAdqc.d.ts +0 -42
  98. package/dist/interpolate.d.ts +0 -24
  99. package/dist/interpolate.js +0 -43
  100. package/dist/jsx-dev-runtime.d.ts +0 -11
  101. package/dist/jsx-dev-runtime.js +0 -15
  102. package/dist/jsx-runtime-I-1nCtl2.d.ts +0 -57
  103. package/dist/jsx-runtime.d.ts +0 -2
  104. package/dist/jsx-runtime.js +0 -121
  105. package/dist/lexer.d.ts +0 -60
  106. package/dist/lexer.js +0 -281
  107. package/dist/model.d.ts +0 -24
  108. package/dist/model.js +0 -77
  109. package/dist/ops-BvwqHl7V.js +0 -630
  110. package/dist/ops.d.ts +0 -114
  111. package/dist/ops.js +0 -2
  112. package/dist/parser-t29cHLVL.d.ts +0 -396
  113. package/dist/parser.d.ts +0 -2
  114. package/dist/parser.js +0 -859
  115. package/dist/predicate-BI6uRRM-.js +0 -549
  116. package/dist/predicate-M-05Nd7R.d.ts +0 -56
  117. package/dist/predicate.d.ts +0 -2
  118. package/dist/predicate.js +0 -2
  119. package/dist/printer.d.ts +0 -6
  120. package/dist/printer.js +0 -122
  121. package/dist/registry-Dcp6QEK_.d.ts +0 -73
  122. package/dist/registry.d.ts +0 -2
  123. package/dist/registry.js +0 -646
  124. package/dist/render-template.d.ts +0 -45
  125. package/dist/render-template.js +0 -76
  126. package/dist/selection-CCArx9lU.d.ts +0 -91
  127. package/dist/showcase-egkusQBf.d.ts +0 -415
  128. package/dist/sms-segments-y4FpPilJ.d.ts +0 -13
  129. package/dist/sms-segments.d.ts +0 -2
  130. package/dist/sms-segments.js +0 -46
  131. package/dist/source-locations-DrCM82Ym.d.ts +0 -67
  132. package/dist/source-locations.d.ts +0 -2
  133. package/dist/source-locations.js +0 -102
  134. package/dist/starters/category-mapping.d.ts +0 -13
  135. package/dist/starters/category-mapping.js +0 -49
  136. package/dist/starters/corpus.d.ts +0 -2
  137. package/dist/starters/corpus.js +0 -194
  138. package/dist/starters/library.d.ts +0 -18
  139. package/dist/starters/library.js +0 -692
  140. package/dist/starters/public-gallery.d.ts +0 -266
  141. package/dist/starters/public-gallery.js +0 -916
  142. package/dist/starters/public-handoff.d.ts +0 -164
  143. package/dist/starters/public-handoff.js +0 -361
  144. package/dist/starters/public-preview-artifacts.d.ts +0 -43
  145. package/dist/starters/public-preview-artifacts.js +0 -104
  146. package/dist/starters/public-preview.d.ts +0 -61
  147. package/dist/starters/public-preview.js +0 -83
  148. package/dist/starters/showcase.d.ts +0 -2
  149. package/dist/starters/showcase.js +0 -335
  150. package/dist/starters/sources.d.ts +0 -45
  151. package/dist/starters/sources.js +0 -7762
  152. package/dist/starters/theme.d.ts +0 -45
  153. package/dist/starters/theme.js +0 -77
  154. package/dist/starters.d.ts +0 -2
  155. package/dist/starters.js +0 -874
  156. package/dist/tailwind-BYq7Lo6u.js +0 -727
  157. package/dist/template-DWftqh4x.d.ts +0 -60
  158. package/dist/template.d.ts +0 -2
  159. package/dist/template.js +0 -37
  160. package/dist/theme-css.js +0 -2
  161. package/dist/tsx-source-instrumentation.d.ts +0 -30
  162. package/dist/tsx-source-instrumentation.js +0 -115
  163. package/dist/tsx-tracer.d.ts +0 -112
  164. package/dist/tsx-tracer.js +0 -985
  165. package/dist/variables-J_L3qxRa.d.ts +0 -77
  166. package/dist/variables.d.ts +0 -2
  167. package/dist/variables.js +0 -141
  168. package/dist/version-BITr58kk.js +0 -96
  169. package/generated/sml-agent-contract.json +0 -709
  170. package/generated/sml-email-agent-contract.json +0 -615
  171. package/generated/sml-email-language-reference.md +0 -94
  172. package/generated/sml-language-reference.md +0 -195
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samva/markup",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "Type-safe authoring and compilation primitives for Samva templates",
5
5
  "keywords": [
6
6
  "email",
@@ -28,183 +28,23 @@
28
28
  "!dist/**/*.map",
29
29
  "samva-brand.d.ts",
30
30
  "generated",
31
+ "skills",
31
32
  "package.json",
32
33
  "README.md",
34
+ "CHANGELOG.md",
33
35
  "AGENTS.md",
34
36
  "LICENSE"
35
37
  ],
36
38
  "type": "module",
37
39
  "sideEffects": false,
38
40
  "exports": {
39
- "./package.json": "./package.json",
40
- "./ast": {
41
- "types": "./dist/ast.d.ts",
42
- "import": "./dist/ast.js"
41
+ ".": {
42
+ "types": "./dist/index.d.ts",
43
+ "import": "./dist/index.js"
43
44
  },
44
- "./candidate": {
45
- "types": "./dist/candidate.d.ts",
46
- "import": "./dist/candidate.js"
47
- },
48
- "./classes": {
49
- "types": "./dist/classes.d.ts",
50
- "import": "./dist/classes.js"
51
- },
52
- "./components": {
53
- "types": "./dist/components.d.ts",
54
- "import": "./dist/components.js"
55
- },
56
- "./compiler": {
57
- "types": "./dist/compiler.d.ts",
58
- "import": "./dist/compiler.js"
59
- },
60
- "./compile": {
61
- "types": "./dist/compile.d.ts",
62
- "import": "./dist/compile.js"
63
- },
64
- "./compile-sms": {
65
- "types": "./dist/compile-sms.d.ts",
66
- "import": "./dist/compile-sms.js"
67
- },
68
- "./compile-whatsapp": {
69
- "types": "./dist/compile-whatsapp.d.ts",
70
- "import": "./dist/compile-whatsapp.js"
71
- },
72
- "./interpolate": {
73
- "types": "./dist/interpolate.d.ts",
74
- "import": "./dist/interpolate.js"
75
- },
76
- "./model": {
77
- "types": "./dist/model.d.ts",
78
- "import": "./dist/model.js"
79
- },
80
- "./ops": {
81
- "types": "./dist/ops.d.ts",
82
- "import": "./dist/ops.js"
83
- },
84
- "./sms-segments": {
85
- "types": "./dist/sms-segments.d.ts",
86
- "import": "./dist/sms-segments.js"
87
- },
88
- "./checks": {
89
- "types": "./dist/checks.d.ts",
90
- "import": "./dist/checks.js"
91
- },
92
- "./conditionals": {
93
- "types": "./dist/conditionals.d.ts",
94
- "import": "./dist/conditionals.js"
95
- },
96
- "./diagnostics": {
97
- "types": "./dist/diagnostics.d.ts",
98
- "import": "./dist/diagnostics.js"
99
- },
100
- "./emit": {
101
- "types": "./dist/emit.d.ts",
102
- "import": "./dist/emit.js"
103
- },
104
- "./jsx-runtime": {
105
- "types": "./dist/jsx-runtime.d.ts",
106
- "import": "./dist/jsx-runtime.js"
107
- },
108
- "./jsx-dev-runtime": {
109
- "types": "./dist/jsx-dev-runtime.d.ts",
110
- "import": "./dist/jsx-dev-runtime.js"
111
- },
112
- "./lexer": {
113
- "types": "./dist/lexer.d.ts",
114
- "import": "./dist/lexer.js"
115
- },
116
- "./parser": {
117
- "types": "./dist/parser.d.ts",
118
- "import": "./dist/parser.js"
119
- },
120
- "./predicate": {
121
- "types": "./dist/predicate.d.ts",
122
- "import": "./dist/predicate.js"
123
- },
124
- "./starters": {
125
- "types": "./dist/starters.d.ts",
126
- "import": "./dist/starters.js"
127
- },
128
- "./starters/category-mapping": {
129
- "types": "./dist/starters/category-mapping.d.ts",
130
- "import": "./dist/starters/category-mapping.js"
131
- },
132
- "./starters/corpus": {
133
- "types": "./dist/starters/corpus.d.ts",
134
- "import": "./dist/starters/corpus.js"
135
- },
136
- "./starters/library": {
137
- "types": "./dist/starters/library.d.ts",
138
- "import": "./dist/starters/library.js"
139
- },
140
- "./starters/public-gallery": {
141
- "types": "./dist/starters/public-gallery.d.ts",
142
- "import": "./dist/starters/public-gallery.js"
143
- },
144
- "./starters/public-handoff": {
145
- "types": "./dist/starters/public-handoff.d.ts",
146
- "import": "./dist/starters/public-handoff.js"
147
- },
148
- "./starters/public-preview": {
149
- "types": "./dist/starters/public-preview.d.ts",
150
- "import": "./dist/starters/public-preview.js"
151
- },
152
- "./starters/public-preview-artifacts": {
153
- "types": "./dist/starters/public-preview-artifacts.d.ts",
154
- "import": "./dist/starters/public-preview-artifacts.js"
155
- },
156
- "./starters/showcase": {
157
- "types": "./dist/starters/showcase.d.ts",
158
- "import": "./dist/starters/showcase.js"
159
- },
160
- "./starters/sources": {
161
- "types": "./dist/starters/sources.d.ts",
162
- "import": "./dist/starters/sources.js"
163
- },
164
- "./starters/theme": {
165
- "types": "./dist/starters/theme.d.ts",
166
- "import": "./dist/starters/theme.js"
167
- },
168
- "./printer": {
169
- "types": "./dist/printer.d.ts",
170
- "import": "./dist/printer.js"
171
- },
172
- "./registry": {
173
- "types": "./dist/registry.d.ts",
174
- "import": "./dist/registry.js"
175
- },
176
- "./render-template": {
177
- "types": "./dist/render-template.d.ts",
178
- "import": "./dist/render-template.js"
179
- },
180
- "./source-locations": {
181
- "types": "./dist/source-locations.d.ts",
182
- "import": "./dist/source-locations.js"
183
- },
184
- "./theme-css": {
185
- "types": "./dist/theme-css.d.ts",
186
- "import": "./dist/theme-css.js"
187
- },
188
- "./tsx-tracer": {
189
- "types": "./dist/tsx-tracer.d.ts",
190
- "import": "./dist/tsx-tracer.js"
191
- },
192
- "./tsx-source-instrumentation": {
193
- "types": "./dist/tsx-source-instrumentation.d.ts",
194
- "import": "./dist/tsx-source-instrumentation.js"
195
- },
196
- "./variables": {
197
- "types": "./dist/variables.d.ts",
198
- "import": "./dist/variables.js"
199
- },
200
- "./generated/*": "./generated/*",
201
- "./input-schema": {
202
- "types": "./dist/input-schema.d.ts",
203
- "import": "./dist/input-schema.js"
204
- },
205
- "./template": {
206
- "types": "./dist/template.d.ts",
207
- "import": "./dist/template.js"
45
+ "./email": {
46
+ "types": "./dist/email.d.ts",
47
+ "import": "./dist/email.js"
208
48
  },
209
49
  "./email/jsx-runtime": {
210
50
  "types": "./dist/email/jsx-runtime.d.ts",
@@ -214,57 +54,48 @@
214
54
  "types": "./dist/email/jsx-dev-runtime.d.ts",
215
55
  "import": "./dist/email/jsx-dev-runtime.js"
216
56
  },
217
- "./email/render": {
218
- "types": "./dist/email/render.d.ts",
219
- "import": "./dist/email/render.js"
57
+ "./fmt": {
58
+ "types": "./dist/fmt.d.ts",
59
+ "import": "./dist/fmt.js"
220
60
  },
221
- "./email/elements": {
222
- "types": "./dist/email/elements.d.ts",
223
- "import": "./dist/email/elements.js"
61
+ "./sms": {
62
+ "types": "./dist/sms.d.ts",
63
+ "import": "./dist/sms.js"
224
64
  },
225
- "./email/components": {
226
- "types": "./dist/email/components.d.ts",
227
- "import": "./dist/email/components.js"
65
+ "./whatsapp": {
66
+ "types": "./dist/whatsapp.d.ts",
67
+ "import": "./dist/whatsapp.js"
228
68
  },
229
- "./email/diagnostics": {
230
- "types": "./dist/email/diagnostics.d.ts",
231
- "import": "./dist/email/diagnostics.js"
69
+ "./input-schema": {
70
+ "types": "./dist/input-schema.d.ts",
71
+ "import": "./dist/input-schema.js"
232
72
  },
233
- "./email/assets": {
234
- "types": "./dist/email/assets.d.ts",
235
- "import": "./dist/email/assets.js"
73
+ "./compiler": {
74
+ "types": "./dist/compiler.d.ts",
75
+ "import": "./dist/compiler.js"
236
76
  },
237
- "./email/source-edit": {
238
- "types": "./dist/email/source-edit.d.ts",
239
- "import": "./dist/email/source-edit.js"
77
+ "./diagnostics": {
78
+ "types": "./dist/diagnostics.d.ts",
79
+ "import": "./dist/diagnostics.js"
240
80
  },
241
- "./email/selection": {
242
- "types": "./dist/email/selection.d.ts",
243
- "import": "./dist/email/selection.js"
81
+ "./render": {
82
+ "types": "./dist/render.d.ts",
83
+ "import": "./dist/render.js"
244
84
  },
245
- "./email/html": {
246
- "types": "./dist/email/html.d.ts",
247
- "import": "./dist/email/html.js"
85
+ "./edit": {
86
+ "types": "./dist/edit.d.ts",
87
+ "import": "./dist/edit.js"
248
88
  },
249
- "./email/text": {
250
- "types": "./dist/email/text.d.ts",
251
- "import": "./dist/email/text.js"
89
+ "./brand": {
90
+ "types": "./dist/brand.d.ts",
91
+ "import": "./dist/brand.js"
252
92
  },
253
93
  "./samva-brand": {
254
94
  "types": "./samva-brand.d.ts"
255
95
  },
256
- "./email/brand-footer": {
257
- "types": "./dist/email/brand-footer.d.ts",
258
- "import": "./dist/email/brand-footer.js"
259
- },
260
- "./email/brand": {
261
- "types": "./dist/email/brand.d.ts",
262
- "import": "./dist/email/brand.js"
263
- },
264
- "./email/stylesheets": {
265
- "types": "./dist/email/stylesheets.d.ts",
266
- "import": "./dist/email/stylesheets.js"
267
- }
96
+ "./contract.json": "./generated/contract.json",
97
+ "./reference.md": "./generated/reference.md",
98
+ "./package.json": "./package.json"
268
99
  },
269
100
  "publishConfig": {
270
101
  "access": "public"
@@ -272,54 +103,30 @@
272
103
  "scripts": {
273
104
  "build": "tsdown",
274
105
  "prepack": "bun run build",
275
- "codegen:starters": "bun run ../vite/scripts/codegen-starters.ts && oxfmt starters/sources.gen.ts starters/library.gen.ts",
276
- "import:public-handoff": "bun run ../vite/scripts/import-public-template-handoff.ts",
277
106
  "corpus:render": "bun run scripts/render-compatibility-corpus.ts",
278
107
  "codegen:tailwind": "bun run scripts/codegen-tailwind.ts && oxfmt src/email/tailwind-stylesheets.gen.ts",
279
- "codegen:tokens": "bun run scripts/codegen-tokens.ts && oxfmt src/tokens.ts",
280
- "codegen:sml-reference": "bun run scripts/generate-sml-reference.ts",
108
+ "codegen:contract": "bun run scripts/generate-contract.ts",
281
109
  "codegen:docs": "bun run scripts/codegen-docs.ts",
282
- "refresh-caniemail": "bun run scripts/refresh-caniemail.ts",
283
- "test": "vitest run --root ../.. --project packages packages/markup/tests",
110
+ "test": "vitest run",
284
111
  "typecheck": "tsc --noEmit && tsc --noEmit -p tests/consumer/tsconfig.json"
285
112
  },
286
113
  "dependencies": {
114
+ "@babel/parser": "^8.0.4",
287
115
  "@cfworker/json-schema": "4.1.1",
288
116
  "@standard-schema/spec": "1.1.0",
289
- "better-result": "3.0.1"
117
+ "better-result": "3.0.1",
118
+ "caniemail": "2.0.2",
119
+ "css-tree": "3.2.1",
120
+ "tailwindcss": "^4.3.3"
290
121
  },
291
122
  "devDependencies": {
292
- "@babel/parser": "^8.0.4",
293
123
  "@css-inline/css-inline-wasm": "0.15.0",
294
124
  "@effect/vitest": "4.0.0-rc.117",
295
125
  "@types/css-tree": "3.2.0",
296
- "caniemail": "2.0.2",
297
- "css-tree": "3.2.1",
298
126
  "effect": "4.0.0-rc.117",
299
- "tailwindcss": "^4.3.3",
300
127
  "tsdown": "^0.22.13",
301
128
  "typescript": "^7.0.2",
302
129
  "vitest": "^4.1.11",
303
130
  "zod": "4.6.5"
304
- },
305
- "peerDependencies": {
306
- "@babel/parser": "^8.0.4",
307
- "caniemail": "2.0.2",
308
- "css-tree": "3.2.1",
309
- "tailwindcss": "^4.3.3"
310
- },
311
- "peerDependenciesMeta": {
312
- "@babel/parser": {
313
- "optional": true
314
- },
315
- "caniemail": {
316
- "optional": true
317
- },
318
- "css-tree": {
319
- "optional": true
320
- },
321
- "tailwindcss": {
322
- "optional": true
323
- }
324
131
  }
325
132
  }
package/samva-brand.d.ts CHANGED
@@ -4,11 +4,11 @@
4
4
  // `"types": ["@samva/markup/samva-brand"]` to the project's tsconfig.
5
5
 
6
6
  declare module "samva:brand" {
7
- export const BrandLogo: import("@samva/markup/email/brand").BrandComponents["BrandLogo"];
8
- export const BrandFooter: import("@samva/markup/email/brand").BrandComponents["BrandFooter"];
7
+ export const BrandLogo: import("@samva/markup/brand").BrandComponents["BrandLogo"];
8
+ export const BrandFooter: import("@samva/markup/brand").BrandComponents["BrandFooter"];
9
9
  }
10
10
 
11
11
  declare module "samva:brand/*" {
12
- export const BrandLogo: import("@samva/markup/email/brand").BrandComponents["BrandLogo"];
13
- export const BrandFooter: import("@samva/markup/email/brand").BrandComponents["BrandFooter"];
12
+ export const BrandLogo: import("@samva/markup/brand").BrandComponents["BrandLogo"];
13
+ export const BrandFooter: import("@samva/markup/brand").BrandComponents["BrandFooter"];
14
14
  }
@@ -0,0 +1,123 @@
1
+ ---
2
+ name: sml
3
+ description: Author, check, render and repair Samva email templates written as static-profile TSX (defineTemplate). Use when creating or editing a file under templates/ or emails/, fixing template diagnostics, or previewing a template.
4
+ ---
5
+
6
+ # Authoring Samva templates
7
+
8
+ A template is one `.tsx` file that default-exports `defineTemplate` from `@samva/markup`. It is
9
+ ordinary JSX, HTML and Tailwind written in a static profile: the compiler reads it without running
10
+ it and produces a JSON IR. Every preview and every send renders that IR against the input, so
11
+ nothing you write executes at send time.
12
+
13
+ ## The loop
14
+
15
+ Write, check, render, look, repair. Repeat until the check is clean.
16
+
17
+ ```bash
18
+ samva templates check # compile every template, print diagnostics with fixes
19
+ samva templates render --fixture no-tracking # subject, preheader, text and HTML for one fixture
20
+ samva templates snapshot # desktop and mobile PNGs, light and dark
21
+ samva templates dev # local editor with every fixture rendered
22
+ ```
23
+
24
+ Add `--json` for diagnostics as data: each has a `code`, a location, a severity and a `fix`. Apply
25
+ the fix the diagnostic names rather than rewriting around it. Without the CLI, call
26
+ `compileTemplate` from `@samva/markup/compiler` and `renderIr` from `@samva/markup/render`.
27
+
28
+ ## Upgrades
29
+
30
+ When a diagnostic has an `upgrade` field in `@samva/markup/contract.json`, follow that recipe
31
+ for every affected entry while preserving project edits and entry paths. The Upgrades section of
32
+ `generated/reference.md` renders the same recipes. Check every converted entry and render its
33
+ fixtures before saving the project.
34
+
35
+ ## Shape
36
+
37
+ ```tsx
38
+ import { defineTemplate } from "@samva/markup";
39
+ import { Email } from "@samva/markup/email";
40
+ import { fmt } from "@samva/markup/fmt";
41
+ import { jsonSchema } from "@samva/markup/input-schema";
42
+
43
+ export default defineTemplate({
44
+ id: "order-shipped",
45
+ schema: jsonSchema<{ name: string; total: number; currency: string; trackingUrl?: string }>({
46
+ type: "object",
47
+ properties: {
48
+ name: { type: "string" },
49
+ total: { type: "number" },
50
+ currency: { type: "string" },
51
+ trackingUrl: { type: "string" },
52
+ },
53
+ required: ["name", "total", "currency"],
54
+ additionalProperties: false,
55
+ }),
56
+ fixtures: {
57
+ default: { name: "Ada", total: 84, currency: "EUR", trackingUrl: "https://example.com/t/1" },
58
+ "no-tracking": { name: "Ada", total: 84, currency: "EUR" },
59
+ },
60
+ email: {
61
+ subject: (input) => `${input.name}, your order shipped`,
62
+ body: (input) => (
63
+ <Email>
64
+ <h1 className="text-2xl font-semibold">Hi {input.name}, it shipped.</h1>
65
+ <p>Total {fmt.money(input.total, input.currency)}</p>
66
+ {input.trackingUrl && <a href={input.trackingUrl}>Track package</a>}
67
+ </Email>
68
+ ),
69
+ },
70
+ });
71
+ ```
72
+
73
+ - `id` is lowercase kebab-case and is the template's public handle.
74
+ - Put templates in `templates/` (`emails/` also works). Import only `@samva/markup` and files in
75
+ the project; there are no dependencies to install.
76
+ - `subject` and `preheader` belong to the `email` channel, never to `<Email>`.
77
+ - Declare at least one fixture, and one per branch: default, missing optional fields, many items.
78
+
79
+ ## The static profile
80
+
81
+ Use these forms; they are what models already write for React.
82
+
83
+ | Form | Example |
84
+ | ------------------- | --------------------------------------------------------------------------- |
85
+ | Text and attributes | `{input.name}`, `href={input.trackingUrl}`, template strings |
86
+ | Condition | `{input.trackingUrl && <A />}`, `{input.vip ? <A /> : <B />}` |
87
+ | Comparison | `===`, `!==`, `<`, `>`, `!`, `&&`, `\|\|`, `.length` |
88
+ | Loop | `input.items.map((item) => <Row />)` |
89
+ | Filter and count | `input.items.filter((item) => item.done).length` |
90
+ | Grid | `<Columns each={input.deals} per={2}>{(deal) => <Column />}</Columns>` |
91
+ | Formatter | `fmt.money`, `fmt.number`, `fmt.date`, `fmt.time`, `fmt.plural`, `fmt.list` |
92
+ | Partial | any project component, inlined at compile time |
93
+ | Conditional class | `className={input.vip ? "bg-amber-100" : "bg-white"}` |
94
+
95
+ Anything else is a diagnostic: other calls (`reduce`, `Math.floor`, `Date.now`), statements in a
96
+ body (`const`, `if`, loops), imports outside the project, hooks, event handlers,
97
+ `dangerouslySetInnerHTML`, and class names built at run time. There is no escape hatch. When the
98
+ profile cannot express something, compute it where the message is sent and add a field to the
99
+ schema.
100
+
101
+ ## Data
102
+
103
+ - The schema is a literal `jsonSchema<Input>({ ... })` or any Standard JSON Schema converter. It
104
+ validates every send and drives the binding checker: `input.ordr` fails with a suggestion.
105
+ - Guard optional fields before binding them: `{input.trackingUrl && ...}` (`unguarded-optional`).
106
+ - Every fixture must validate against the schema (`fixture-invalid`). Nothing is coerced and no
107
+ defaults are inserted.
108
+ - Locale and time zone are send options; `fmt` reads them, and an explicit locale argument wins.
109
+
110
+ ## Styling and components
111
+
112
+ Write HTML for content and Tailwind classes for style. Components exist only where an email client
113
+ needs something HTML cannot say: `Email`, `Section`, `Columns`/`Column`, `Button`, `Image`,
114
+ `Spacer`, `Divider`, and `BrandLogo`/`BrandFooter` from `samva:brand`. `theme.css` layers
115
+ `starter.css`, then `@import "samva:brand";`, then the project's own `@theme`. Fonts are `.woff2`
116
+ files declared with `@font-face`, and a font stack ends in a generic family.
117
+
118
+ ## References
119
+
120
+ - `contract.json` (`@samva/markup/contract.json`): components with props, profile forms,
121
+ formatters, elements and every diagnostic code, generated from the compiler.
122
+ - `generated/reference.md`: the same contract as a readable reference.
123
+ - `AGENTS.md`: the package guide, including what goes wrong and why.
@@ -1,107 +0,0 @@
1
- import { a as Span } from "./diagnostics-OcQKQYSY.js";
2
- //#region src/ast.d.ts
3
- declare const BLOCK_TAGS: readonly ["Email", "Subject", "Preview", "Container", "Section", "Row", "Column", "Heading", "Text", "Button", "Image", "Divider", "Spacer", "List", "ListItem", "If", "Else"];
4
- declare const INLINE_TAGS: readonly ["strong", "em", "a"];
5
- /** Email-only helper tags scoped by their parent primitive. */
6
- declare const AUXILIARY_TAGS: readonly ["Source"];
7
- /** Structured-channel tags: the sms/whatsapp vocabulary beyond shared If/Else. */
8
- declare const CHANNEL_TAGS: readonly ["Sms", "WhatsApp", "Header", "Body", "Footer", "Buttons"];
9
- declare const SML_TAGS: readonly ["Email", "Subject", "Preview", "Container", "Section", "Row", "Column", "Heading", "Text", "Button", "Image", "Divider", "Spacer", "List", "ListItem", "If", "Else", "strong", "em", "a", "Source", "Sms", "WhatsApp", "Header", "Body", "Footer", "Buttons"];
10
- /**
11
- * JSX component name → the SML tag that component emits. TSX authors write
12
- * capitalized component names, and the inline tags are lowercase in SML, so
13
- * `<Strong>` emits `strong` and `<A>` emits `a`. The table is derived from
14
- * `SML_TAGS` rather than written out, so a new tag is mapped the moment it
15
- * joins the vocabulary. `components.ts` is held to it by the component test
16
- * suite, and `tsx-tracer.ts` resolves authored JSX names through it.
17
- */
18
- declare const SML_TAG_BY_COMPONENT_NAME: Readonly<Record<string, SmlTag>>;
19
- /** The SML tag a JSX component name emits, or `undefined` when it is not a Samva primitive. */
20
- declare const smlTagForComponentName: (name: string) => SmlTag | undefined;
21
- /** The JSX component name that emits an SML tag, for printing SML back into TSX. */
22
- declare const componentNameForSmlTag: (tag: SmlTag) => string;
23
- type BlockTag = (typeof BLOCK_TAGS)[number];
24
- type InlineTag = (typeof INLINE_TAGS)[number];
25
- type AuxiliaryTag = (typeof AUXILIARY_TAGS)[number];
26
- type ChannelTag = (typeof CHANNEL_TAGS)[number];
27
- type SmlTag = (typeof SML_TAGS)[number];
28
- /** Channels supported by the public SML document model. */
29
- type Channel = "email" | "sms" | "whatsapp";
30
- /** Resolved primary width for email documents that omit `<Email width={…}>`. */
31
- declare const DEFAULT_EMAIL_WIDTH = 600;
32
- /** Root tag → channel. The root tag IS the channel declaration. */
33
- declare const CHANNEL_BY_ROOT_TAG: {
34
- readonly Email: "email";
35
- readonly Sms: "sms";
36
- readonly WhatsApp: "whatsapp";
37
- };
38
- type RootTag = keyof typeof CHANNEL_BY_ROOT_TAG;
39
- declare const ROOT_TAGS: ReadonlyArray<RootTag>;
40
- declare const isRootTag: (tag: string) => tag is RootTag;
41
- /** The channel a parsed document targets, read off its root tag. */
42
- declare const documentChannel: (document: SmlDocument) => Channel;
43
- type AttributeValue = {
44
- readonly kind: "string";
45
- readonly value: string;
46
- } | {
47
- readonly kind: "number";
48
- readonly value: number;
49
- };
50
- interface Attribute {
51
- readonly name: string;
52
- readonly value: AttributeValue;
53
- /** Span of the whole `name="value"` pair. */
54
- readonly span: Span;
55
- /** Span of the value contents (inside quotes/braces) — class diagnostics point here. */
56
- readonly valueSpan: Span;
57
- }
58
- interface TextNode {
59
- readonly kind: "text";
60
- readonly id: string;
61
- readonly value: string;
62
- readonly span: Span;
63
- }
64
- interface InterpolationNode {
65
- readonly kind: "interpolation";
66
- readonly id: string;
67
- readonly name: string;
68
- /** {{name}} vs ${name} — both today's syntaxes, preserved through print. */
69
- readonly syntax: "curly" | "dollar";
70
- readonly span: Span;
71
- }
72
- interface ElementNode {
73
- readonly kind: "element";
74
- readonly id: string;
75
- readonly tag: SmlTag;
76
- readonly attributes: ReadonlyArray<Attribute>;
77
- readonly children: ReadonlyArray<SmlNode>;
78
- readonly span: Span;
79
- }
80
- type SmlNode = ElementNode | TextNode | InterpolationNode;
81
- interface SmlDocument {
82
- readonly kind: "document";
83
- /** Always a root element: `<Email>`, `<Sms>`, or `<WhatsApp>`. */
84
- readonly root: ElementNode;
85
- }
86
- declare const attributeValue: (node: ElementNode, name: string) => AttributeValue | undefined;
87
- declare const stringAttribute: (node: ElementNode, name: string) => string | undefined;
88
- declare const numberAttribute: (node: ElementNode, name: string) => number | undefined;
89
- /**
90
- * The editor-only display label (navigator rename) — a universal attribute the
91
- * compiler never reads, so it never reaches HTML. Absent when unset.
92
- */
93
- declare const nodeLabel: (node: ElementNode) => string | undefined;
94
- /**
95
- * The editor-only visibility flag. A `hidden="true"` node stays in the source
96
- * (and the navigator, dimmed) but is dropped from every compile — preview and
97
- * send alike. Any other value / absence means visible.
98
- */
99
- declare const isHiddenNode: (node: ElementNode) => boolean;
100
- /**
101
- * All variable references in the document: `{{name}}` / `${name}` in children
102
- * and attribute values, plus names referenced by `<If test="...">` predicates.
103
- */
104
- declare const collectVariableReferences: (document: SmlDocument) => ReadonlySet<string>;
105
- //#endregion
106
- export { nodeLabel as A, TextNode as C, documentChannel as D, componentNameForSmlTag as E, smlTagForComponentName as M, stringAttribute as N, isHiddenNode as O, SmlTag as S, collectVariableReferences as T, RootTag as _, BLOCK_TAGS as a, SmlDocument as b, CHANNEL_TAGS as c, DEFAULT_EMAIL_WIDTH as d, ElementNode as f, ROOT_TAGS as g, InterpolationNode as h, AuxiliaryTag as i, numberAttribute as j, isRootTag as k, Channel as l, InlineTag as m, Attribute as n, BlockTag as o, INLINE_TAGS as p, AttributeValue as r, CHANNEL_BY_ROOT_TAG as s, AUXILIARY_TAGS as t, ChannelTag as u, SML_TAGS as v, attributeValue as w, SmlNode as x, SML_TAG_BY_COMPONENT_NAME as y };
107
- //# sourceMappingURL=ast-BrDtApwS.d.ts.map
package/dist/ast.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import { A as nodeLabel, C as TextNode, D as documentChannel, E as componentNameForSmlTag, M as smlTagForComponentName, N as stringAttribute, O as isHiddenNode, S as SmlTag, T as collectVariableReferences, _ as RootTag, a as BLOCK_TAGS, b as SmlDocument, c as CHANNEL_TAGS, d as DEFAULT_EMAIL_WIDTH, f as ElementNode, g as ROOT_TAGS, h as InterpolationNode, i as AuxiliaryTag, j as numberAttribute, k as isRootTag, l as Channel, m as InlineTag, n as Attribute, o as BlockTag, p as INLINE_TAGS, r as AttributeValue, s as CHANNEL_BY_ROOT_TAG, t as AUXILIARY_TAGS, u as ChannelTag, v as SML_TAGS, w as attributeValue, x as SmlNode, y as SML_TAG_BY_COMPONENT_NAME } from "./ast-BrDtApwS.js";
2
- export { AUXILIARY_TAGS, Attribute, AttributeValue, AuxiliaryTag, BLOCK_TAGS, BlockTag, CHANNEL_BY_ROOT_TAG, CHANNEL_TAGS, Channel, ChannelTag, DEFAULT_EMAIL_WIDTH, ElementNode, INLINE_TAGS, InlineTag, InterpolationNode, ROOT_TAGS, RootTag, SML_TAGS, SML_TAG_BY_COMPONENT_NAME, SmlDocument, SmlNode, SmlTag, TextNode, attributeValue, collectVariableReferences, componentNameForSmlTag, documentChannel, isHiddenNode, isRootTag, nodeLabel, numberAttribute, smlTagForComponentName, stringAttribute };