@samva/markup 0.18.1 → 0.19.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 (54) hide show
  1. package/AGENTS.md +11 -4
  2. package/CHANGELOG.md +36 -0
  3. package/README.md +89 -5
  4. package/dist/assets-BSpgZOSR.js +61 -0
  5. package/dist/assets-k7_v3IOJ.d.ts +39 -0
  6. package/dist/{assets-CS5Xa_mr.d.ts → brand-Bxb6Sm7y.d.ts} +34 -41
  7. package/dist/brand.d.ts +2 -2
  8. package/dist/brand.js +3 -3
  9. package/dist/compatibility.d.ts +15 -5
  10. package/dist/compatibility.js +48 -5
  11. package/dist/compile-C1GWLQ5C.js +490 -0
  12. package/dist/compile-CIeuGmP-.d.ts +98 -0
  13. package/dist/{compiled-template-Bc4Dq9zy.d.ts → compiled-template-CPDHvFlt.d.ts} +157 -6
  14. package/dist/compiler.d.ts +4 -89
  15. package/dist/compiler.js +8 -486
  16. package/dist/components-DNBCz20_.js +3267 -0
  17. package/dist/{css-color-DLM12Osu.js → dark-scheme-BGDCCaUq.js} +12 -1
  18. package/dist/{diagnostic-codes-DZKb0Xcg.js → diagnostic-codes-BCwfUgnF.js} +33 -36
  19. package/dist/diagnostic-model-DJtqbETd.js +36 -0
  20. package/dist/{diagnostics-D4vSLQrO.d.ts → diagnostics-C3TSx6SU.d.ts} +22 -2
  21. package/dist/diagnostics.d.ts +33 -1
  22. package/dist/diagnostics.js +2 -1
  23. package/dist/edit.d.ts +15 -4
  24. package/dist/edit.js +67 -4
  25. package/dist/email/jsx-dev-runtime.d.ts +2 -2
  26. package/dist/email/jsx-runtime.d.ts +1 -1
  27. package/dist/email.d.ts +6 -2
  28. package/dist/email.js +6 -2
  29. package/dist/index.d.ts +1 -1
  30. package/dist/{jsx-runtime-DL8NVF1f.d.ts → jsx-runtime-HHfrVZEf.d.ts} +1 -2
  31. package/dist/markdown.d.ts +69 -0
  32. package/dist/markdown.js +95 -0
  33. package/dist/parse-Bex7QFqj.js +921 -0
  34. package/dist/{preview-rNoJBEIY.d.ts → preview-DRLWgmfg.d.ts} +3 -3
  35. package/dist/profile-DFk4gs7o.js +56 -0
  36. package/dist/{profile-JTvgCD6X.js → project-B6D64SZS.js} +497 -234
  37. package/dist/render.d.ts +8 -8
  38. package/dist/render.js +1 -2
  39. package/dist/{css-B_aVKrDo.js → selectors-CKGuc9MO.js} +158 -4
  40. package/dist/sms.d.ts +1 -1
  41. package/dist/{template-DmNcoH4Q.d.ts → template-4Dse7_OC.d.ts} +1 -1
  42. package/dist/{theme-css-P9F5S7Ic.js → theme-css-BujDuuEA.js} +1 -2
  43. package/dist/whatsapp.d.ts +1 -1
  44. package/generated/contract.json +41 -1
  45. package/generated/reference.md +97 -89
  46. package/package.json +15 -4
  47. package/dist/brand-CIiEqkU7.js +0 -193
  48. package/dist/brand-plugin-Dj9SMpfS.d.ts +0 -33
  49. package/dist/components-C5850-Qg.js +0 -409
  50. package/dist/dark-scheme-CbCwGDWH.js +0 -12
  51. package/dist/html-DJUK2YJF.js +0 -483
  52. package/dist/render-template-DwPDm3Hq.js +0 -1226
  53. package/dist/selectors-CYWCoxZr.js +0 -157
  54. package/dist/source-locations-C8wCsiAy.d.ts +0 -22
@@ -1,3 +1,127 @@
1
+ import { a as EmailBrand, m as BrandPlugin } from "./brand-Bxb6Sm7y.js";
2
+ //#region src/ir/degradations.d.ts
3
+ /** What a reader loses when a component is lowered from the shared document to email. */
4
+ interface EmailDegradation {
5
+ readonly kind: "same" | "static" | "omitted";
6
+ readonly note: string;
7
+ }
8
+ /** Content fidelity declarations; client-specific presentation is checked against the HTML. */
9
+ declare const COMPONENT_DEGRADATIONS: {
10
+ readonly Email: {
11
+ readonly kind: "same";
12
+ readonly note: "Recipients get the full message with the theme's colors and font.";
13
+ };
14
+ readonly Section: {
15
+ readonly kind: "same";
16
+ readonly note: "Recipients see the section and everything in it.";
17
+ };
18
+ readonly Columns: {
19
+ readonly kind: "same";
20
+ readonly note: "Recipients see every cell of every row.";
21
+ };
22
+ readonly Column: {
23
+ readonly kind: "same";
24
+ readonly note: "Recipients see the cell and everything in it.";
25
+ };
26
+ readonly Button: {
27
+ readonly kind: "same";
28
+ readonly note: "Recipients see the button's label and can follow its link.";
29
+ };
30
+ readonly Spacer: {
31
+ readonly kind: "same";
32
+ readonly note: "Recipients see the space between blocks.";
33
+ };
34
+ readonly Divider: {
35
+ readonly kind: "same";
36
+ readonly note: "Recipients see the horizontal rule.";
37
+ };
38
+ readonly Image: {
39
+ readonly kind: "same";
40
+ readonly note: "Recipients get the image and its alternative text.";
41
+ };
42
+ readonly Link: {
43
+ readonly kind: "same";
44
+ readonly note: "Recipients can follow the link.";
45
+ };
46
+ readonly BrandLogo: {
47
+ readonly kind: "same";
48
+ readonly note: "Recipients get the brand logo, with the dark version where their client supports it.";
49
+ };
50
+ readonly BrandFooter: {
51
+ readonly kind: "same";
52
+ readonly note: "Recipients see the brand's contact details and links, including the unsubscribe link when supplied.";
53
+ };
54
+ };
55
+ type SemanticComponentName = keyof typeof COMPONENT_DEGRADATIONS;
56
+ /** The content fidelity declaration for one supported component. */
57
+ declare const componentDegradation: (name: SemanticComponentName) => EmailDegradation;
58
+ //#endregion
59
+ //#region src/ir/nodes.d.ts
60
+ /** An authored component prop: values retain bindings, and object props retain their fields. */
61
+ type SemanticProp = CompiledValue | {
62
+ readonly object: Readonly<Record<string, SemanticProp>>;
63
+ };
64
+ /** A component's identity and authored content, before any target introduces layout markup. */
65
+ interface SemanticComponent {
66
+ readonly type: "component";
67
+ readonly name: SemanticComponentName;
68
+ readonly props?: Readonly<Record<string, SemanticProp>>;
69
+ readonly children?: readonly CompiledNode[];
70
+ /** Resolved brand data, without its stylesheet, for brand components only. */
71
+ readonly brand?: Omit<EmailBrand, "css">;
72
+ /** Resolved at the authoring call site: partials intentionally clear inherited cell layout. */
73
+ readonly emailColumn?: {
74
+ readonly width?: CompiledValue;
75
+ readonly stack: boolean;
76
+ };
77
+ readonly src?: CompiledSource;
78
+ }
79
+ interface SemanticIntrinsicBase {
80
+ readonly tag: string;
81
+ readonly attrs?: Readonly<Record<string, CompiledValue>>;
82
+ readonly style?: CompiledStyle;
83
+ readonly children?: readonly CompiledNode[];
84
+ readonly src?: CompiledSource;
85
+ }
86
+ interface SemanticBlock extends SemanticIntrinsicBase {
87
+ readonly type: "block";
88
+ }
89
+ interface SemanticInline extends SemanticIntrinsicBase {
90
+ readonly type: "inline";
91
+ }
92
+ /** The original tag retains the meaning of headings, lists, links, images and table cells. */
93
+ type SemanticIntrinsic = SemanticBlock | SemanticInline;
94
+ /** Only presentation that differs from the primitives' deterministic expansion is recorded. */
95
+ interface EmailPresentationOverride {
96
+ readonly attrs?: Readonly<Record<string, CompiledValue>>;
97
+ /** Empty means the cascade removed the primitive's authored declarations. */
98
+ readonly style?: CompiledStyle;
99
+ /** VML/conditional-comment markup after stylesheet token resolution. */
100
+ readonly raw?: readonly CompiledRawPart[];
101
+ }
102
+ interface EmailPresentation {
103
+ /** Preorder ordinals of email elements and raw compatibility nodes, before head additions. */
104
+ readonly nodes: Readonly<Record<string, EmailPresentationOverride>>;
105
+ readonly headCss: string;
106
+ readonly fontFaceCss: string;
107
+ readonly brandPlugin: BrandPlugin;
108
+ }
109
+ /** Parsed CSS structure: the renderer validates each context before writing shell-owned CSS. */
110
+ interface WebCssRule {
111
+ readonly selector?: string;
112
+ readonly at?: string;
113
+ readonly style?: readonly (readonly [property: string, value: CompiledValue])[];
114
+ readonly children?: readonly WebCssRule[];
115
+ }
116
+ interface WebPresentation {
117
+ readonly rules: readonly WebCssRule[];
118
+ readonly componentLayer?: number;
119
+ /** A generated class must outrank normal project selectors to retain authored style priority. */
120
+ readonly inlineSpecificity?: number;
121
+ /** Authored style elements in document traversal order, independent of project stylesheets. */
122
+ readonly stylesheets?: readonly (readonly WebCssRule[])[];
123
+ }
124
+ //#endregion
1
125
  //#region src/sms-segments.d.ts
2
126
  /** The encoding a message needs: GSM-7 when every character fits, UCS-2 otherwise. */
3
127
  type SmsEncoding = "gsm7" | "ucs2";
@@ -10,7 +134,7 @@ declare const smsSegmentInfo: (text: string) => SmsSegmentInfo;
10
134
  //#endregion
11
135
  //#region src/compiled-template.d.ts
12
136
  /** The version this package writes. A publication pins the version it was built with. */
13
- declare const COMPILED_TEMPLATE_VERSION = 1;
137
+ declare const COMPILED_TEMPLATE_VERSION = 2;
14
138
  /**
15
139
  * Where a node came from: `[line, column]` in the entry file, or `[line, column, file]` with an
16
140
  * index into `CompiledTemplate.sources` when the node came from an imported project file. Published
@@ -145,12 +269,16 @@ interface CompiledRaw {
145
269
  interface CompiledPreheader {
146
270
  readonly preheader: true;
147
271
  }
148
- /** A node in an email body. A bare value in child position is rendered as escaped text. */
149
- type CompiledNode = CompiledValue | CompiledElement | CompiledIf | CompiledEach | CompiledRaw | CompiledPreheader;
272
+ /** A semantic body node or an email primitive produced by target lowering. Bare values are escaped text. */
273
+ type CompiledNode = CompiledValue | CompiledElement | CompiledIf | CompiledEach | CompiledRaw | CompiledPreheader | SemanticComponent | SemanticIntrinsic;
150
274
  interface CompiledEmail {
151
275
  readonly subject: CompiledValue;
152
276
  readonly preheader?: CompiledValue;
153
277
  readonly body: CompiledNode;
278
+ /** Resolved email presentation, indexed by deterministic lowering order; contains no body. */
279
+ readonly presentation?: EmailPresentation;
280
+ /** Project CSS for the web target; email's resolved cascade is independent. */
281
+ readonly web?: WebPresentation;
154
282
  }
155
283
  /** A plain-text channel body: text pieces, conditionals and loops. */
156
284
  interface CompiledSms {
@@ -211,8 +339,30 @@ interface CompiledTemplate {
211
339
  /** The portable JSON Schema every send's input is validated against. */
212
340
  readonly schema: Readonly<Record<string, unknown>>;
213
341
  }
214
- /** The channels a template can declare and `render` can render. */
342
+ /** The channels a template can declare. */
215
343
  type Channel = "email" | "sms" | "whatsapp";
344
+ /** Email and web lower the same body; plain-message targets keep their authored channels. */
345
+ type Target = Channel | "web";
346
+ /** An element's offsets in rendered HTML and its authored source reference. */
347
+ interface RenderedPosition {
348
+ readonly start: number;
349
+ readonly end: number;
350
+ readonly tag: string;
351
+ readonly src?: CompiledSource;
352
+ }
353
+ /** Values for a host-owned page shell. Styles are CSS text, never HTML. */
354
+ interface PageHeadHints {
355
+ readonly title?: string;
356
+ readonly lang?: string;
357
+ readonly dir?: "ltr" | "rtl" | "auto";
358
+ readonly styles: string;
359
+ }
360
+ /** A semantic body fragment, with shell hints and offsets for source selection. */
361
+ interface RenderedPage {
362
+ readonly html: string;
363
+ readonly headHints: PageHeadHints;
364
+ readonly positions: readonly RenderedPosition[];
365
+ }
216
366
  interface RenderedEmail {
217
367
  readonly subject: string;
218
368
  readonly preheader: string | undefined;
@@ -258,11 +408,12 @@ interface RenderedWhatsApp {
258
408
  readonly footer?: string;
259
409
  readonly buttons: readonly RenderedWhatsAppButton[];
260
410
  }
261
- /** What `render` returns for each channel. */
411
+ /** What `render` returns for each target. */
262
412
  interface RenderedMessage {
263
413
  readonly email: RenderedEmail;
414
+ readonly web: RenderedPage;
264
415
  readonly sms: RenderedSms;
265
416
  readonly whatsapp: RenderedWhatsApp;
266
417
  }
267
418
  //#endregion
268
- export { smsSegmentInfo as A, RenderedEmail as C, RenderedWhatsAppButton as D, RenderedWhatsApp as E, SmsEncoding as O, CompiledWhatsAppButtonNode as S, RenderedSms as T, CompiledStyle as _, CompiledEach as a, CompiledWhatsApp as b, CompiledFormatter as c, CompiledPredicate as d, CompiledPreheader as f, CompiledSource as g, CompiledSms as h, CompiledComparison as i, SmsSegmentInfo as k, CompiledIf as l, CompiledRawPart as m, Channel as n, CompiledElement as o, CompiledRaw as p, CompiledArithmetic as r, CompiledEmail as s, COMPILED_TEMPLATE_VERSION as t, CompiledNode as u, CompiledTemplate as v, RenderedMessage as w, CompiledWhatsAppButton as x, CompiledValue as y };
419
+ export { RenderedWhatsAppButton as A, SemanticIntrinsic as B, PageHeadHints as C, RenderedPosition as D, RenderedPage as E, EmailPresentation as F, EmailDegradation as G, WebCssRule as H, EmailPresentationOverride as I, SemanticComponentName as K, SemanticBlock as L, SmsEncoding as M, SmsSegmentInfo as N, RenderedSms as O, smsSegmentInfo as P, SemanticComponent as R, CompiledWhatsAppButtonNode as S, RenderedMessage as T, WebPresentation as U, SemanticProp as V, COMPONENT_DEGRADATIONS as W, CompiledStyle as _, CompiledEach as a, CompiledWhatsApp as b, CompiledFormatter as c, CompiledPredicate as d, CompiledPreheader as f, CompiledSource as g, CompiledSms as h, CompiledComparison as i, Target as j, RenderedWhatsApp as k, CompiledIf as l, CompiledRawPart as m, Channel as n, CompiledElement as o, CompiledRaw as p, componentDegradation as q, CompiledArithmetic as r, CompiledEmail as s, COMPILED_TEMPLATE_VERSION as t, CompiledNode as u, CompiledTemplate as v, RenderedEmail as w, CompiledWhatsAppButton as x, CompiledValue as y, SemanticInline as z };
@@ -1,92 +1,7 @@
1
- import { n as parseBrandSpecifier, t as BrandPlugin } from "./brand-plugin-Dj9SMpfS.js";
2
- import { i as TemplateDiagnostic, n as EmailDiagnostic } from "./diagnostics-D4vSLQrO.js";
3
- import { n as AssetEntry, p as EmailBrand } from "./assets-CS5Xa_mr.js";
4
- import { v as CompiledTemplate } from "./compiled-template-Bc4Dq9zy.js";
5
- import { i as TEMPLATE_NAME_PATTERN } from "./template-DmNcoH4Q.js";
6
- import "css-tree";
7
- //#region src/email/tailwind.d.ts
8
- interface TailwindOptions {
9
- /**
10
- * Project CSS appended to the compiled entry: `@theme` overrides, `@utility`
11
- * definitions and ordinary rules. This is the project's pinned configuration.
12
- */
13
- readonly css?: string | undefined;
14
- /**
15
- * The project path `css` was read from (`theme.css` by default). Its
16
- * relative `@import`s resolve from this file's directory.
17
- */
18
- readonly cssPath?: string | undefined;
19
- /** Classes the compiler cannot discover, declared by the project on purpose. */
20
- readonly safelist?: readonly string[] | undefined;
21
- /** Tailwind's browser reset is off by default; email clients do not want it. */
22
- readonly preflight?: boolean | undefined;
23
- /**
24
- * Bounds on what the compiler may generate. Class discovery reads authored
25
- * source, so a project can hand it an unbounded candidate set and get an
26
- * unbounded stylesheet back — inside a build that has a wall clock and a
27
- * bundle a Worker then has to load. A host that publishes supplies these.
28
- */
29
- readonly limits?: TailwindLimits | undefined;
30
- }
31
- interface TailwindLimits {
32
- /** Distinct classes handed to the compiler. */
33
- readonly candidates: number;
34
- /** Bytes of generated CSS. */
35
- readonly cssBytes: number;
36
- }
37
- //#endregion
38
- //#region src/email/transform.d.ts
39
- /** Where this build serves assets from, and how Tailwind is configured. */
40
- interface TransformOptions {
41
- readonly assetBase: string;
42
- /** `false` compiles no Tailwind at all. */
43
- readonly tailwind?: TailwindOptions | false | undefined;
44
- /**
45
- * The brand the brand import resolves to, supplied by the host. A project
46
- * that imports a brand with no brand here fails to compile.
47
- */
48
- readonly brand?: EmailBrand | undefined;
49
- /** Names the brand import and marks the footer `BrandFooter` renders; `samvaBrandPlugin` when omitted. */
50
- readonly brandPlugin?: BrandPlugin | undefined;
51
- }
52
- /**
53
- * The brand specifier a project imports — from its theme's `@import`s or its
54
- * TSX — so a host can fetch that brand before it compiles. `undefined` when
55
- * the project imports no brand. A project that names two brands gets the
56
- * first here and a refusal from the compile.
57
- */
58
- declare const projectBrandSpecifier: (files: Readonly<Record<string, string | Uint8Array>>, options?: {
59
- readonly themePath?: string | undefined;
60
- readonly brandPlugin?: BrandPlugin | undefined;
61
- }) => string | undefined;
62
- //#endregion
63
- //#region src/sml/lower-project.d.ts
64
- interface CompileResult {
65
- /** The compiled template, or `undefined` when a finding blocks it. */
66
- readonly template: CompiledTemplate | undefined;
67
- /** The fixtures read from the entry, with imported assets resolved to their URLs. */
68
- readonly fixtures: Readonly<Record<string, unknown>>;
69
- readonly assets: readonly AssetEntry[];
70
- /** Errors block the template; warnings ride along. */
71
- readonly diagnostics: readonly TemplateDiagnostic[];
72
- }
73
- //#endregion
74
- //#region src/sml/compile.d.ts
75
- interface CompileTemplateOptions extends TransformOptions {
76
- /** The project's files by path. Binary files are addressed as assets. */
77
- readonly files: Readonly<Record<string, string | Uint8Array>>;
78
- /** The entry: a `.tsx` file that default-exports `defineTemplate({ ... })`. */
79
- readonly entry: string;
80
- /**
81
- * The portable JSON Schema, for an entry whose `schema` is not a literal `jsonSchema(...)`
82
- * (a Zod or Effect schema needs a library to become JSON Schema). A host that has evaluated the
83
- * schema passes its conversion here; a literal schema is read from source and this is ignored.
84
- */
85
- readonly schema?: Readonly<Record<string, unknown>> | undefined;
86
- }
87
- /** Compile a project's entry template without evaluating any of it. */
88
- declare const compileTemplate: (options: CompileTemplateOptions) => Promise<CompileResult>;
89
- //#endregion
1
+ import { a as EmailBrand, h as parseBrandSpecifier, m as BrandPlugin } from "./brand-Bxb6Sm7y.js";
2
+ import { i as TemplateDiagnostic, n as EmailDiagnostic } from "./diagnostics-C3TSx6SU.js";
3
+ import { a as TailwindOptions, i as projectBrandSpecifier, n as compileTemplate, r as CompileResult, t as CompileTemplateOptions } from "./compile-CIeuGmP-.js";
4
+ import { i as TEMPLATE_NAME_PATTERN } from "./template-4Dse7_OC.js";
90
5
  //#region src/sml/profile.d.ts
91
6
  /**
92
7
  * Check an entry against the static profile. Pass the entry's source alone, or the project's files