@samva/markup 0.9.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 (88) hide show
  1. package/AGENTS.md +48 -40
  2. package/CHANGELOG.md +345 -0
  3. package/README.md +6 -6
  4. package/dist/{brand-B-0bN_Ir.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/compiler.d.ts +231 -11
  9. package/dist/compiler.js +1312 -13
  10. package/dist/components-BZCqegS8.js +1864 -0
  11. package/dist/diagnostic-model-DJtqbETd.js +38 -0
  12. package/dist/diagnostic-model-DxthUZBT.d.ts +31 -0
  13. package/dist/{email/diagnostics.js → diagnostics-CnKFefKz.js} +2 -2
  14. package/dist/diagnostics.d.ts +406 -27
  15. package/dist/diagnostics.js +402 -34
  16. package/dist/edit.d.ts +234 -0
  17. package/dist/{channel-edit.js → edit.js} +341 -3
  18. package/dist/email/jsx-dev-runtime.d.ts +1 -1
  19. package/dist/email/jsx-dev-runtime.js +1 -2
  20. package/dist/email/jsx-runtime.d.ts +1 -1
  21. package/dist/email/jsx-runtime.js +1 -85
  22. package/dist/{email/components.d.ts → email.d.ts} +2 -2
  23. package/dist/email.js +2 -0
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/{cascade-t6kxlgEI.js → ir-CLhlklKV.js} +8 -4
  27. package/dist/jsx-runtime-CBlexoeR.js +98 -0
  28. package/dist/{elements-cqldpaJt.d.ts → jsx-runtime-ylIOnaSf.d.ts} +74 -74
  29. package/dist/{profile-BH-OtdDA.js → profile-pWGtWZXF.js} +153 -20
  30. package/dist/render-BPonDpCl.d.ts +539 -0
  31. package/dist/{email/render.js → render-BQmfh94k.js} +102 -8
  32. package/dist/render.d.ts +35 -0
  33. package/dist/render.js +49 -0
  34. package/dist/sms.d.ts +1 -1
  35. package/dist/sms.js +1 -1
  36. package/dist/{template-_QE_rQND.d.ts → template-DMPwxMSq.d.ts} +2 -2
  37. package/dist/{template.js → template-zLUjcwfF.js} +2 -2
  38. package/dist/{theme-css-hFqcPSar.js → theme-css-JtRCm1fb.js} +2 -2
  39. package/dist/whatsapp.d.ts +1 -1
  40. package/dist/whatsapp.js +1 -1
  41. package/generated/contract.json +16 -10
  42. package/generated/reference.md +17 -10
  43. package/package.json +36 -119
  44. package/samva-brand.d.ts +4 -4
  45. package/skills/sml/SKILL.md +2 -2
  46. package/dist/assets-C5duwTya.d.ts +0 -40
  47. package/dist/channel-edit.d.ts +0 -121
  48. package/dist/channel-specs-B6M_HlaV.js +0 -29
  49. package/dist/compatibility-DbISoFIq.js +0 -589
  50. package/dist/css-BVQKICKC.d.ts +0 -109
  51. package/dist/diagnostic-codes.d.ts +0 -403
  52. package/dist/diagnostic-codes.js +0 -399
  53. package/dist/email/assets.d.ts +0 -2
  54. package/dist/email/assets.js +0 -63
  55. package/dist/email/brand-footer.d.ts +0 -34
  56. package/dist/email/brand-footer.js +0 -63
  57. package/dist/email/brand.d.ts +0 -2
  58. package/dist/email/components.js +0 -275
  59. package/dist/email/diagnostics.d.ts +0 -2
  60. package/dist/email/elements.d.ts +0 -2
  61. package/dist/email/elements.js +0 -299
  62. package/dist/email/html.d.ts +0 -2
  63. package/dist/email/html.js +0 -321
  64. package/dist/email/render.d.ts +0 -40
  65. package/dist/email/text.d.ts +0 -7
  66. package/dist/email/text.js +0 -100
  67. package/dist/html-BJepOwZ4.d.ts +0 -56
  68. package/dist/ir-aaqNE987.d.ts +0 -252
  69. package/dist/ir.d.ts +0 -2
  70. package/dist/ir.js +0 -7
  71. package/dist/preview-Ekdg1dXG.d.ts +0 -100
  72. package/dist/preview.d.ts +0 -2
  73. package/dist/preview.js +0 -160
  74. package/dist/render-ir.d.ts +0 -19
  75. package/dist/render-ir.js +0 -826
  76. package/dist/sms-segments.d.ts +0 -13
  77. package/dist/sms-segments.js +0 -46
  78. package/dist/source-edit.d.ts +0 -116
  79. package/dist/source-edit.js +0 -343
  80. package/dist/source-locations.d.ts +0 -2
  81. package/dist/source-locations.js +0 -16
  82. package/dist/static.d.ts +0 -57
  83. package/dist/static.js +0 -69
  84. package/dist/tailwind-CMYpZf1v.js +0 -614
  85. package/dist/template.d.ts +0 -2
  86. package/dist/theme-css.js +0 -2
  87. package/dist/theme-imports-lvBw3AD1.js +0 -109
  88. package/dist/transform-Ct2OMkFN.d.ts +0 -153
@@ -0,0 +1,35 @@
1
+ import { C as isUrlAttribute, S as emailElement, _ as EmailGlobalProps, b as EmailStyle, g as EmailElementSpec, h as EmailAttributeSpec, m as EMAIL_GLOBAL_ATTRIBUTES, p as EMAIL_ELEMENTS, r as EmailNode, v as EmailIntrinsicElements, x as EmailTag, y as EmailLayout } from "./jsx-runtime-ylIOnaSf.js";
2
+ import { $ as IrWhatsApp, A as emailAuthoringTarget, B as IrElement, D as EmittedPosition, E as EmailElementSelection, F as emailSelections, G as IrPredicate, H as IrFormatter, I as renderIrPreview, J as IrRawPart, K as IrPreheader, L as IrArithmetic, M as emailSelectionAncestry, N as emailSelectionIndex, O as INSTANCE_PATH_ATTRIBUTE, P as emailSelectionSiblings, Q as IrValue, R as IrComparison, U as IrIf, V as IrEmail, W as IrNode, X as IrSource, Y as IrSms, Z as IrStyle, a as renderEmailContent, at as RenderedPosition, c as checkAttribute, ct as TemplateIr, d as escapeText, et as IrWhatsAppButton, f as kebab, i as compileEmail, it as RenderedIrWhatsApp, j as emailDefinitionInstances, k as IrPreview, l as declarationValue, m as serializeStyle, n as EmailCompileOutput, nt as RenderOptions, o as EmailHtmlOutput, ot as RenderedWhatsAppButton, p as serializeEmailHtml, q as IrRaw, r as RenderedEmail, rt as RenderedIrEmail, s as SerializeEmailOptions, st as SML_IR_VERSION, t as EMAIL_DOCTYPE, tt as IrWhatsAppButtonNode, u as escapeAttribute, z as IrEach } from "./render-BPonDpCl.js";
3
+ //#region src/render-ir.d.ts
4
+ interface IrRenderDiagnostic {
5
+ readonly code: string;
6
+ readonly message: string;
7
+ }
8
+ declare class IrRenderError extends Error {
9
+ readonly diagnostics: readonly IrRenderDiagnostic[];
10
+ constructor(diagnostics: readonly IrRenderDiagnostic[]);
11
+ }
12
+ /** Render the email channel of a compiled template against one validated input. */
13
+ declare const renderIr: (ir: TemplateIr, input: unknown, options?: RenderOptions) => RenderedIrEmail;
14
+ /** Render the SMS channel of a compiled template to plain text. */
15
+ declare const renderIrSms: (ir: TemplateIr, input: unknown, options?: RenderOptions) => string;
16
+ /** Render the WhatsApp channel of a compiled template: every text rendered, conditional buttons resolved. */
17
+ declare const renderIrWhatsApp: (ir: TemplateIr, input: unknown, options?: RenderOptions) => RenderedIrWhatsApp;
18
+ //#endregion
19
+ //#region src/email/text.d.ts
20
+ /** Derive the plain-text alternative from the semantic tree in reading order. */
21
+ declare const deriveEmailText: (node: EmailNode) => string;
22
+ //#endregion
23
+ //#region src/sms-segments.d.ts
24
+ /** The encoding a message needs: GSM-7 when every character fits, UCS-2 otherwise. */
25
+ type SmsEncoding = "gsm7" | "ucs2";
26
+ interface SmsSegmentInfo {
27
+ readonly encoding: SmsEncoding;
28
+ readonly characterCount: number;
29
+ readonly segmentCount: number;
30
+ }
31
+ declare const smsSegmentInfo: (text: string) => SmsSegmentInfo;
32
+ declare const hasSmsOptOut: (text: string) => boolean;
33
+ //#endregion
34
+ export { EMAIL_DOCTYPE, EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, EmailAttributeSpec, EmailCompileOutput, EmailElementSelection, EmailElementSpec, EmailGlobalProps, EmailHtmlOutput, EmailIntrinsicElements, EmailLayout, EmailStyle, EmailTag, EmittedPosition, INSTANCE_PATH_ATTRIBUTE, IrArithmetic, IrComparison, IrEach, IrElement, IrEmail, IrFormatter, IrIf, IrNode, IrPredicate, IrPreheader, IrPreview, IrRaw, IrRawPart, IrRenderDiagnostic, IrRenderError, IrSms, IrSource, IrStyle, IrValue, IrWhatsApp, IrWhatsAppButton, IrWhatsAppButtonNode, RenderOptions, RenderedEmail, RenderedIrEmail, RenderedIrWhatsApp, RenderedPosition, RenderedWhatsAppButton, SML_IR_VERSION, SerializeEmailOptions, SmsEncoding, SmsSegmentInfo, TemplateIr, checkAttribute, compileEmail, declarationValue, deriveEmailText, emailAuthoringTarget, emailDefinitionInstances, emailElement, emailSelectionAncestry, emailSelectionIndex, emailSelectionSiblings, emailSelections, escapeAttribute, escapeText, hasSmsOptOut, isUrlAttribute, kebab, renderEmailContent, renderIr, renderIrPreview, renderIrSms, renderIrWhatsApp, serializeEmailHtml, serializeStyle, smsSegmentInfo };
35
+ //# sourceMappingURL=render.d.ts.map
package/dist/render.js ADDED
@@ -0,0 +1,49 @@
1
+ import { A as renderIrSms, C as emailSelectionAncestry, D as renderIrPreview, E as emailSelections, F as isUrlAttribute, M as EMAIL_ELEMENTS, N as EMAIL_GLOBAL_ATTRIBUTES, O as IrRenderError, P as emailElement, S as emailDefinitionInstances, T as emailSelectionSiblings, _ as kebab, b as INSTANCE_PATH_ATTRIBUTE, g as escapeText, h as escapeAttribute, j as renderIrWhatsApp, k as renderIr, m as declarationValue, p as checkAttribute, v as serializeEmailHtml, w as emailSelectionIndex, x as emailAuthoringTarget, y as serializeStyle } from "./components-BZCqegS8.js";
2
+ import { t as SML_IR_VERSION } from "./ir-CLhlklKV.js";
3
+ import { i as deriveEmailText, n as compileEmail, r as renderEmailContent, t as EMAIL_DOCTYPE } from "./render-BQmfh94k.js";
4
+ //#region src/sms-segments.ts
5
+ const GSM7_EXTENDED = /* @__PURE__ */ new Set([
6
+ "[",
7
+ "]",
8
+ "{",
9
+ "}",
10
+ "\\",
11
+ "~",
12
+ "|",
13
+ "€",
14
+ "^",
15
+ "\f"
16
+ ]);
17
+ const GSM7_BASIC_PATTERN = /^[@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !"#¤%&'()*+,\-./:;<=>?¡0-9ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà]*$/;
18
+ const containsNonGsmCharacters = (text) => {
19
+ for (const char of text) {
20
+ if (GSM7_EXTENDED.has(char)) continue;
21
+ if (!GSM7_BASIC_PATTERN.test(char)) return true;
22
+ }
23
+ return false;
24
+ };
25
+ const smsSegmentInfo = (text) => {
26
+ if (containsNonGsmCharacters(text)) {
27
+ const codePoints = [...text].length;
28
+ const segmentCount = codePoints <= 70 ? 1 : Math.ceil(codePoints / 67);
29
+ return {
30
+ encoding: "ucs2",
31
+ characterCount: text.length,
32
+ segmentCount
33
+ };
34
+ }
35
+ let encodedLength = 0;
36
+ for (const char of text) encodedLength += GSM7_EXTENDED.has(char) ? 2 : 1;
37
+ const segmentCount = encodedLength <= 160 ? 1 : Math.ceil(encodedLength / 153);
38
+ return {
39
+ encoding: "gsm7",
40
+ characterCount: text.length,
41
+ segmentCount
42
+ };
43
+ };
44
+ const SMS_OPT_OUT_PATTERN = /\b(stop|unsubscribe|opt[\s-]?out|cancel|quit)\b/i;
45
+ const hasSmsOptOut = (text) => SMS_OPT_OUT_PATTERN.test(text);
46
+ //#endregion
47
+ export { EMAIL_DOCTYPE, EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, INSTANCE_PATH_ATTRIBUTE, IrRenderError, SML_IR_VERSION, checkAttribute, compileEmail, declarationValue, deriveEmailText, emailAuthoringTarget, emailDefinitionInstances, emailElement, emailSelectionAncestry, emailSelectionIndex, emailSelectionSiblings, emailSelections, escapeAttribute, escapeText, hasSmsOptOut, isUrlAttribute, kebab, renderEmailContent, renderIr, renderIrPreview, renderIrSms, renderIrWhatsApp, serializeEmailHtml, serializeStyle, smsSegmentInfo };
48
+
49
+ //# sourceMappingURL=render.js.map
package/dist/sms.d.ts CHANGED
@@ -1,5 +1,5 @@
1
+ import { r as EmailNode, t as EmailChild } from "./jsx-runtime-ylIOnaSf.js";
1
2
  import { t as SmsCategory } from "./channel-specs-C2feJwuP.js";
2
- import { f as EmailChild, m as EmailNode } from "./elements-cqldpaJt.js";
3
3
  //#region src/sms.d.ts
4
4
  interface SmsProps {
5
5
  readonly category?: SmsCategory | undefined;
package/dist/sms.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Fragment, jsx } from "./email/jsx-runtime.js";
1
+ import { a as jsx, n as Fragment } from "./jsx-runtime-CBlexoeR.js";
2
2
  //#region src/sms.ts
3
3
  /**
4
4
  * The root of an SMS body: plain text with bindings, conditionals and formatters. The compiler
@@ -1,4 +1,4 @@
1
- import { m as EmailNode } from "./elements-cqldpaJt.js";
1
+ import { r as EmailNode } from "./jsx-runtime-ylIOnaSf.js";
2
2
  import { r as InputSchema } from "./input-schema-7dPFVvNE.js";
3
3
  import { StandardJSONSchemaV1 } from "@standard-schema/spec";
4
4
  //#region src/template.d.ts
@@ -62,4 +62,4 @@ declare const defineTemplate: <S extends StandardJSONSchemaV1>(definition: {
62
62
  }) => SmlTemplate<StandardJSONSchemaV1.InferInput<S>>;
63
63
  //#endregion
64
64
  export { TEMPLATE_NAME_PATTERN as a, TEMPLATE_ID_PATTERN as i, EmailContent as n, TemplateInput as o, SmlTemplate as r, defineTemplate as s, EmailChannel as t };
65
- //# sourceMappingURL=template-_QE_rQND.d.ts.map
65
+ //# sourceMappingURL=template-DMPwxMSq.d.ts.map
@@ -37,6 +37,6 @@ const defineTemplate = (definition) => {
37
37
  };
38
38
  };
39
39
  //#endregion
40
- export { TEMPLATE_ID_PATTERN, TEMPLATE_NAME_PATTERN, defineTemplate };
40
+ export { TEMPLATE_NAME_PATTERN as n, defineTemplate as r, TEMPLATE_ID_PATTERN as t };
41
41
 
42
- //# sourceMappingURL=template.js.map
42
+ //# sourceMappingURL=template-zLUjcwfF.js.map
@@ -1,5 +1,5 @@
1
- import { Result } from "better-result";
2
1
  import { generate, parse, walk } from "css-tree";
2
+ import { Result } from "better-result";
3
3
  //#region src/email/css-color.ts
4
4
  const clamp = (value, low = 0, high = 1) => value < low ? low : value > high ? high : value;
5
5
  const toGamma = (channel) => channel <= .0031308 ? 12.92 * channel : 1.055 * channel ** (1 / 2.4) - .055;
@@ -584,4 +584,4 @@ const brandTailwindCss = (brand) => printBrandCss({
584
584
  //#endregion
585
585
  export { brandThemeVariables as a, parseBrandCss as c, formatColor as d, parseColor as f, brandTailwindCss as i, printBrandCss as l, BRAND_FOREGROUND_VARIABLE as n, contrastForeground as o, brandForegroundDefaults as r, darkVariableName as s, BRAND_COLOR_VARIABLE as t, downlevelColors as u };
586
586
 
587
- //# sourceMappingURL=theme-css-hFqcPSar.js.map
587
+ //# sourceMappingURL=theme-css-JtRCm1fb.js.map
@@ -1,5 +1,5 @@
1
+ import { r as EmailNode, t as EmailChild } from "./jsx-runtime-ylIOnaSf.js";
1
2
  import { n as WhatsAppCategory, r as WhatsAppHeaderType } from "./channel-specs-C2feJwuP.js";
2
- import { f as EmailChild, m as EmailNode } from "./elements-cqldpaJt.js";
3
3
  //#region src/whatsapp.d.ts
4
4
  interface WhatsAppProps {
5
5
  readonly name?: string | undefined;
package/dist/whatsapp.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Fragment, jsx } from "./email/jsx-runtime.js";
1
+ import { a as jsx, n as Fragment } from "./jsx-runtime-CBlexoeR.js";
2
2
  //#region src/whatsapp.ts
3
3
  const fragment = (children) => jsx(Fragment, { children });
4
4
  /**
@@ -137,7 +137,7 @@
137
137
  "components": [
138
138
  {
139
139
  "name": "Email",
140
- "import": "@samva/markup/email/components",
140
+ "import": "@samva/markup/email",
141
141
  "props": [
142
142
  {
143
143
  "name": "className",
@@ -181,7 +181,7 @@
181
181
  },
182
182
  {
183
183
  "name": "Section",
184
- "import": "@samva/markup/email/components",
184
+ "import": "@samva/markup/email",
185
185
  "props": [
186
186
  {
187
187
  "name": "className",
@@ -224,7 +224,7 @@
224
224
  },
225
225
  {
226
226
  "name": "Columns",
227
- "import": "@samva/markup/email/components",
227
+ "import": "@samva/markup/email",
228
228
  "props": [
229
229
  {
230
230
  "name": "className",
@@ -269,7 +269,7 @@
269
269
  },
270
270
  {
271
271
  "name": "Column",
272
- "import": "@samva/markup/email/components",
272
+ "import": "@samva/markup/email",
273
273
  "props": [
274
274
  {
275
275
  "name": "className",
@@ -306,7 +306,7 @@
306
306
  },
307
307
  {
308
308
  "name": "Button",
309
- "import": "@samva/markup/email/components",
309
+ "import": "@samva/markup/email",
310
310
  "props": [
311
311
  {
312
312
  "name": "className",
@@ -392,7 +392,7 @@
392
392
  },
393
393
  {
394
394
  "name": "Spacer",
395
- "import": "@samva/markup/email/components",
395
+ "import": "@samva/markup/email",
396
396
  "props": [
397
397
  {
398
398
  "name": "height",
@@ -403,7 +403,7 @@
403
403
  },
404
404
  {
405
405
  "name": "Divider",
406
- "import": "@samva/markup/email/components",
406
+ "import": "@samva/markup/email",
407
407
  "props": [
408
408
  {
409
409
  "name": "className",
@@ -430,7 +430,7 @@
430
430
  },
431
431
  {
432
432
  "name": "Image",
433
- "import": "@samva/markup/email/components",
433
+ "import": "@samva/markup/email",
434
434
  "props": [
435
435
  {
436
436
  "name": "className",
@@ -473,7 +473,7 @@
473
473
  },
474
474
  {
475
475
  "name": "Link",
476
- "import": "@samva/markup/email/components",
476
+ "import": "@samva/markup/email",
477
477
  "props": [
478
478
  {
479
479
  "name": "className",
@@ -1549,6 +1549,12 @@
1549
1549
  "summary": "The email channel has no subject.",
1550
1550
  "fix": "Add subject: (input) => ...."
1551
1551
  },
1552
+ {
1553
+ "code": "moved-import",
1554
+ "summary": "The file imports an @samva/markup entry that moved.",
1555
+ "fix": "Import email components from \"@samva/markup/email\".",
1556
+ "upgrade": "Replace every import from \"@samva/markup/email/components\" with \"@samva/markup/email\" in every project file, templates and partials alike. The imported names are unchanged; change only the specifier.\n\nCompile each entry and render every declared fixture to confirm the output is unchanged. Resolve errors before requesting one saved version for the whole project, approved by the user; do not publish."
1557
+ },
1552
1558
  {
1553
1559
  "code": "multiple-roots",
1554
1560
  "summary": "The body renders nothing or more than one root.",
@@ -1649,7 +1655,7 @@
1649
1655
  {
1650
1656
  "code": "unknown-component",
1651
1657
  "summary": "A component the profile cannot read.",
1652
- "fix": "Import components from @samva/markup/email/components, samva:brand, or the project."
1658
+ "fix": "Import components from @samva/markup/email, samva:brand, or the project."
1653
1659
  },
1654
1660
  {
1655
1661
  "code": "unknown-field",
@@ -50,7 +50,7 @@ There is no escape hatch: compute the value where the message is sent and add it
50
50
 
51
51
  ### Email
52
52
 
53
- Import from `@samva/markup/email/components`.
53
+ Import from `@samva/markup/email`.
54
54
 
55
55
  | Prop | Type | Notes |
56
56
  | ------------------ | ---------------- | -------------------------------------------------------------------- |
@@ -64,7 +64,7 @@ Import from `@samva/markup/email/components`.
64
64
 
65
65
  ### Section
66
66
 
67
- Import from `@samva/markup/email/components`.
67
+ Import from `@samva/markup/email`.
68
68
 
69
69
  | Prop | Type | Notes |
70
70
  | ------------- | ------------------------------- | -------------------------------------------------------------------- |
@@ -78,7 +78,7 @@ Import from `@samva/markup/email/components`.
78
78
 
79
79
  ### Columns
80
80
 
81
- Import from `@samva/markup/email/components`.
81
+ Import from `@samva/markup/email`.
82
82
 
83
83
  | Prop | Type | Notes |
84
84
  | ------------ | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -92,7 +92,7 @@ Import from `@samva/markup/email/components`.
92
92
 
93
93
  ### Column
94
94
 
95
- Import from `@samva/markup/email/components`.
95
+ Import from `@samva/markup/email`.
96
96
 
97
97
  | Prop | Type | Notes |
98
98
  | ------------ | ------------------------------- | ------------------------------------------------------- |
@@ -105,7 +105,7 @@ Import from `@samva/markup/email/components`.
105
105
 
106
106
  ### Button
107
107
 
108
- Import from `@samva/markup/email/components`.
108
+ Import from `@samva/markup/email`.
109
109
 
110
110
  | Prop | Type | Notes |
111
111
  | ------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -127,7 +127,7 @@ Import from `@samva/markup/email/components`.
127
127
 
128
128
  ### Spacer
129
129
 
130
- Import from `@samva/markup/email/components`.
130
+ Import from `@samva/markup/email`.
131
131
 
132
132
  | Prop | Type | Notes |
133
133
  | -------- | -------- | ----- |
@@ -135,7 +135,7 @@ Import from `@samva/markup/email/components`.
135
135
 
136
136
  ### Divider
137
137
 
138
- Import from `@samva/markup/email/components`.
138
+ Import from `@samva/markup/email`.
139
139
 
140
140
  | Prop | Type | Notes |
141
141
  | ------------ | ------------ | ------------------------------------------------------- |
@@ -146,7 +146,7 @@ Import from `@samva/markup/email/components`.
146
146
 
147
147
  ### Image
148
148
 
149
- Import from `@samva/markup/email/components`.
149
+ Import from `@samva/markup/email`.
150
150
 
151
151
  | Prop | Type | Notes |
152
152
  | ------------ | ------------------------------- | -------------------------------------------------------------------- |
@@ -160,7 +160,7 @@ Import from `@samva/markup/email/components`.
160
160
 
161
161
  ### Link
162
162
 
163
- Import from `@samva/markup/email/components`.
163
+ Import from `@samva/markup/email`.
164
164
 
165
165
  | Prop | Type | Notes |
166
166
  | ------------ | ------------ | ------------------------------------------------------- |
@@ -297,6 +297,7 @@ Global attributes: `id`, `title`, `lang`, `dir`, `role`.
297
297
  | `missing-head` | Styles that cannot be inlined need a <head> to live in. | Wrap the message in <Email>, or write those declarations inline. |
298
298
  | `missing-schema` | The template declares no input schema. | Add schema: jsonSchema<Input>({ ... }). |
299
299
  | `missing-subject` | The email channel has no subject. | Add subject: (input) => .... |
300
+ | `moved-import` | The file imports an @samva/markup entry that moved. | Import email components from "@samva/markup/email". |
300
301
  | `multiple-roots` | The body renders nothing or more than one root. | Wrap the body in a single element such as <Email>. |
301
302
  | `nesting-limit` | The template nests deeper than the compiler reads. | Flatten the structure. |
302
303
  | `no-channel` | The template declares no channel body. | Add an email body. |
@@ -314,7 +315,7 @@ Global attributes: `id`, `title`, `lang`, `dir`, `role`.
314
315
  | `tailwind-dynamic-class` | A class list is assembled at run time. | Write the classes literally. |
315
316
  | `too-many-class-variants` | A class list chooses between more literal lists than the compiler resolves. | Split the choice into fewer conditions, or move part of it to a partial. |
316
317
  | `unguarded-optional` | An optional field is read outside a guard, so a send without it would render a blank. | Guard it with {input.field && ...}, or make the field required. |
317
- | `unknown-component` | A component the profile cannot read. | Import components from @samva/markup/email/components, samva:brand, or the project. |
318
+ | `unknown-component` | A component the profile cannot read. | Import components from @samva/markup/email, samva:brand, or the project. |
318
319
  | `unknown-field` | A binding names a field the schema does not declare. | Add the field to the schema, or bind a field it declares (the message suggests the nearest). |
319
320
  | `unknown-formatter` | fmt.<name> is not a formatter. | Use fmt.money, number, date, time, plural or list. |
320
321
  | `unmatched-class` | A class produced no styles. | Use a class the theme or Tailwind defines, or write the style inline. |
@@ -345,6 +346,12 @@ Explicit text has no email-channel field: plain text is derived from the body. I
345
346
 
346
347
  Convert every affected entry in the project at its existing path, including emails/ entries. Compile each entry, render every declared fixture and inspect the affected output. Resolve errors before requesting one saved version for the whole project, approved by the user; do not publish.
347
348
 
349
+ ### `moved-import`
350
+
351
+ Replace every import from "@samva/markup/email/components" with "@samva/markup/email" in every project file, templates and partials alike. The imported names are unchanged; change only the specifier.
352
+
353
+ Compile each entry and render every declared fixture to confirm the output is unchanged. Resolve errors before requesting one saved version for the whole project, approved by the user; do not publish.
354
+
348
355
  ## Quality bar
349
356
 
350
357
  - Run the check until it reports no errors, then render every fixture.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samva/markup",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Type-safe authoring and compilation primitives for Samva templates",
5
5
  "keywords": [
6
6
  "email",
@@ -31,6 +31,7 @@
31
31
  "skills",
32
32
  "package.json",
33
33
  "README.md",
34
+ "CHANGELOG.md",
34
35
  "AGENTS.md",
35
36
  "LICENSE"
36
37
  ],
@@ -41,18 +42,21 @@
41
42
  "types": "./dist/index.d.ts",
42
43
  "import": "./dist/index.js"
43
44
  },
44
- "./package.json": "./package.json",
45
- "./static": {
46
- "types": "./dist/static.d.ts",
47
- "import": "./dist/static.js"
45
+ "./email": {
46
+ "types": "./dist/email.d.ts",
47
+ "import": "./dist/email.js"
48
48
  },
49
- "./ir": {
50
- "types": "./dist/ir.d.ts",
51
- "import": "./dist/ir.js"
49
+ "./email/jsx-runtime": {
50
+ "types": "./dist/email/jsx-runtime.d.ts",
51
+ "import": "./dist/email/jsx-runtime.js"
52
52
  },
53
- "./render-ir": {
54
- "types": "./dist/render-ir.d.ts",
55
- "import": "./dist/render-ir.js"
53
+ "./email/jsx-dev-runtime": {
54
+ "types": "./dist/email/jsx-dev-runtime.d.ts",
55
+ "import": "./dist/email/jsx-dev-runtime.js"
56
+ },
57
+ "./fmt": {
58
+ "types": "./dist/fmt.d.ts",
59
+ "import": "./dist/fmt.js"
56
60
  },
57
61
  "./sms": {
58
62
  "types": "./dist/sms.d.ts",
@@ -62,103 +66,36 @@
62
66
  "types": "./dist/whatsapp.d.ts",
63
67
  "import": "./dist/whatsapp.js"
64
68
  },
65
- "./fmt": {
66
- "types": "./dist/fmt.d.ts",
67
- "import": "./dist/fmt.js"
69
+ "./input-schema": {
70
+ "types": "./dist/input-schema.d.ts",
71
+ "import": "./dist/input-schema.js"
68
72
  },
69
73
  "./compiler": {
70
74
  "types": "./dist/compiler.d.ts",
71
75
  "import": "./dist/compiler.js"
72
76
  },
73
- "./sms-segments": {
74
- "types": "./dist/sms-segments.d.ts",
75
- "import": "./dist/sms-segments.js"
76
- },
77
- "./diagnostic-codes": {
78
- "types": "./dist/diagnostic-codes.d.ts",
79
- "import": "./dist/diagnostic-codes.js"
80
- },
81
77
  "./diagnostics": {
82
78
  "types": "./dist/diagnostics.d.ts",
83
79
  "import": "./dist/diagnostics.js"
84
80
  },
85
- "./source-locations": {
86
- "types": "./dist/source-locations.d.ts",
87
- "import": "./dist/source-locations.js"
88
- },
89
- "./theme-css": {
90
- "types": "./dist/theme-css.d.ts",
91
- "import": "./dist/theme-css.js"
81
+ "./render": {
82
+ "types": "./dist/render.d.ts",
83
+ "import": "./dist/render.js"
92
84
  },
93
- "./contract.json": "./generated/contract.json",
94
- "./generated/*": "./generated/*",
95
- "./input-schema": {
96
- "types": "./dist/input-schema.d.ts",
97
- "import": "./dist/input-schema.js"
85
+ "./edit": {
86
+ "types": "./dist/edit.d.ts",
87
+ "import": "./dist/edit.js"
98
88
  },
99
- "./template": {
100
- "types": "./dist/template.d.ts",
101
- "import": "./dist/template.js"
102
- },
103
- "./email/jsx-runtime": {
104
- "types": "./dist/email/jsx-runtime.d.ts",
105
- "import": "./dist/email/jsx-runtime.js"
106
- },
107
- "./email/jsx-dev-runtime": {
108
- "types": "./dist/email/jsx-dev-runtime.d.ts",
109
- "import": "./dist/email/jsx-dev-runtime.js"
110
- },
111
- "./email/render": {
112
- "types": "./dist/email/render.d.ts",
113
- "import": "./dist/email/render.js"
114
- },
115
- "./email/elements": {
116
- "types": "./dist/email/elements.d.ts",
117
- "import": "./dist/email/elements.js"
118
- },
119
- "./email/components": {
120
- "types": "./dist/email/components.d.ts",
121
- "import": "./dist/email/components.js"
122
- },
123
- "./email/diagnostics": {
124
- "types": "./dist/email/diagnostics.d.ts",
125
- "import": "./dist/email/diagnostics.js"
126
- },
127
- "./email/assets": {
128
- "types": "./dist/email/assets.d.ts",
129
- "import": "./dist/email/assets.js"
130
- },
131
- "./channel-edit": {
132
- "types": "./dist/channel-edit.d.ts",
133
- "import": "./dist/channel-edit.js"
134
- },
135
- "./source-edit": {
136
- "types": "./dist/source-edit.d.ts",
137
- "import": "./dist/source-edit.js"
138
- },
139
- "./preview": {
140
- "types": "./dist/preview.d.ts",
141
- "import": "./dist/preview.js"
142
- },
143
- "./email/html": {
144
- "types": "./dist/email/html.d.ts",
145
- "import": "./dist/email/html.js"
146
- },
147
- "./email/text": {
148
- "types": "./dist/email/text.d.ts",
149
- "import": "./dist/email/text.js"
89
+ "./brand": {
90
+ "types": "./dist/brand.d.ts",
91
+ "import": "./dist/brand.js"
150
92
  },
151
93
  "./samva-brand": {
152
94
  "types": "./samva-brand.d.ts"
153
95
  },
154
- "./email/brand-footer": {
155
- "types": "./dist/email/brand-footer.d.ts",
156
- "import": "./dist/email/brand-footer.js"
157
- },
158
- "./email/brand": {
159
- "types": "./dist/email/brand.d.ts",
160
- "import": "./dist/email/brand.js"
161
- }
96
+ "./contract.json": "./generated/contract.json",
97
+ "./reference.md": "./generated/reference.md",
98
+ "./package.json": "./package.json"
162
99
  },
163
100
  "publishConfig": {
164
101
  "access": "public"
@@ -170,46 +107,26 @@
170
107
  "codegen:tailwind": "bun run scripts/codegen-tailwind.ts && oxfmt src/email/tailwind-stylesheets.gen.ts",
171
108
  "codegen:contract": "bun run scripts/generate-contract.ts",
172
109
  "codegen:docs": "bun run scripts/codegen-docs.ts",
173
- "test": "vitest run --root ../.. --project packages packages/markup/tests",
110
+ "test": "vitest run",
174
111
  "typecheck": "tsc --noEmit && tsc --noEmit -p tests/consumer/tsconfig.json"
175
112
  },
176
113
  "dependencies": {
114
+ "@babel/parser": "^8.0.4",
177
115
  "@cfworker/json-schema": "4.1.1",
178
116
  "@standard-schema/spec": "1.1.0",
179
- "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"
180
121
  },
181
122
  "devDependencies": {
182
- "@babel/parser": "^8.0.4",
183
123
  "@css-inline/css-inline-wasm": "0.15.0",
184
124
  "@effect/vitest": "4.0.0-rc.117",
185
125
  "@types/css-tree": "3.2.0",
186
- "caniemail": "2.0.2",
187
- "css-tree": "3.2.1",
188
126
  "effect": "4.0.0-rc.117",
189
- "tailwindcss": "^4.3.3",
190
127
  "tsdown": "^0.22.13",
191
128
  "typescript": "^7.0.2",
192
129
  "vitest": "^4.1.11",
193
130
  "zod": "4.6.5"
194
- },
195
- "peerDependencies": {
196
- "@babel/parser": "^8.0.4",
197
- "caniemail": "2.0.2",
198
- "css-tree": "3.2.1",
199
- "tailwindcss": "^4.3.3"
200
- },
201
- "peerDependenciesMeta": {
202
- "@babel/parser": {
203
- "optional": true
204
- },
205
- "caniemail": {
206
- "optional": true
207
- },
208
- "css-tree": {
209
- "optional": true
210
- },
211
- "tailwindcss": {
212
- "optional": true
213
- }
214
131
  }
215
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
  }
@@ -23,7 +23,7 @@ samva templates dev # local editor with every fixture re
23
23
 
24
24
  Add `--json` for diagnostics as data: each has a `code`, a location, a severity and a `fix`. Apply
25
25
  the fix the diagnostic names rather than rewriting around it. Without the CLI, call
26
- `compileTemplate` from `@samva/markup/static` and `renderIr` from `@samva/markup/render-ir`.
26
+ `compileTemplate` from `@samva/markup/compiler` and `renderIr` from `@samva/markup/render`.
27
27
 
28
28
  ## Upgrades
29
29
 
@@ -36,7 +36,7 @@ fixtures before saving the project.
36
36
 
37
37
  ```tsx
38
38
  import { defineTemplate } from "@samva/markup";
39
- import { Email } from "@samva/markup/email/components";
39
+ import { Email } from "@samva/markup/email";
40
40
  import { fmt } from "@samva/markup/fmt";
41
41
  import { jsonSchema } from "@samva/markup/input-schema";
42
42