@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
@@ -1,76 +0,0 @@
1
- import { mapJsxSourceLocations } from "./source-locations.js";
2
- import { i as parsePredicate, n as collectPredicateVariables } from "./predicate-BI6uRRM-.js";
3
- import { isRootTag } from "./ast.js";
4
- import { createVariablesProxy } from "./variables.js";
5
- import { parseSml } from "./parser.js";
6
- import { printSml } from "./printer.js";
7
- import { Result } from "better-result";
8
- //#region src/render-template.ts
9
- /**
10
- * Runs a template function and returns its canonical document, source, and
11
- * inferred variable schema. Grammar violations in the constructed tree surface
12
- * as a parse `SmlParseError` (Result failure) with spans into the printed
13
- * source. The template function itself may throw (e.g. the coercion guard) —
14
- * that is a programmer error in the user's build, so it propagates rather than
15
- * becoming a diagnostic.
16
- */
17
- const renderTemplate = (template) => {
18
- const { proxy, recorder } = createVariablesProxy();
19
- const root = template(proxy);
20
- if (root.kind !== "element" || !isRootTag(root.tag)) throw new TypeError("a template must return a single channel root element (<Email>, <Sms>, or <WhatsApp>), not a Fragment or other node");
21
- const source = printSml({
22
- kind: "document",
23
- root
24
- });
25
- const parsed = parseSml(source);
26
- if (Result.isError(parsed)) return Result.err(parsed.error);
27
- const document = parsed.value;
28
- return Result.ok({
29
- document,
30
- source,
31
- variables: collectVariableSchema(document, recorder),
32
- sourceLocations: mapJsxSourceLocations(root, document.root)
33
- });
34
- };
35
- /**
36
- * Merges the recorder's kind evidence with structural required-ness read off the
37
- * parsed document. A name referenced anywhere outside an `<If>` subtree is
38
- * required; names seen only inside conditional branches are optional.
39
- */
40
- const collectVariableSchema = (document, recorder) => {
41
- const unconditional = /* @__PURE__ */ new Set();
42
- const conditional = /* @__PURE__ */ new Set();
43
- const kindOf = new Map(recorder.collected().map((variable) => [variable.name, variable.kind]));
44
- const visit = (node, insideIf) => {
45
- if (node.kind === "interpolation") {
46
- (insideIf ? conditional : unconditional).add(node.name);
47
- return;
48
- }
49
- if (node.kind === "text") return;
50
- const nowInsideIf = insideIf || node.tag === "If";
51
- for (const attribute of node.attributes) {
52
- if (attribute.value.kind !== "string") continue;
53
- if (node.tag === "If" && attribute.name === "test") {
54
- const parsed = parsePredicate(attribute.value.value, 0);
55
- if (Result.isOk(parsed)) for (const name of collectPredicateVariables(parsed.value)) (insideIf ? conditional : unconditional).add(name);
56
- continue;
57
- }
58
- for (const match of attribute.value.value.matchAll(INTERPOLATION_PATTERN)) {
59
- const name = match[1] ?? match[2];
60
- if (name !== void 0) (nowInsideIf ? conditional : unconditional).add(name);
61
- }
62
- }
63
- for (const child of node.children) visit(child, nowInsideIf);
64
- };
65
- visit(document.root, false);
66
- return [.../* @__PURE__ */ new Set([...unconditional, ...conditional])].map((name) => ({
67
- name,
68
- kind: kindOf.get(name) ?? "unknown",
69
- required: unconditional.has(name)
70
- }));
71
- };
72
- const INTERPOLATION_PATTERN = /\$\{\s*\/?([\w.]+)\s*\}|\{\{\s*([\w.]+)\s*\}\}/g;
73
- //#endregion
74
- export { renderTemplate };
75
-
76
- //# sourceMappingURL=render-template.js.map
@@ -1,91 +0,0 @@
1
- import { i as JsxSourceLocation } from "./source-locations-DrCM82Ym.js";
2
- //#region src/email/selection.d.ts
3
- /**
4
- * The attribute a preview stamps so a click in a rendered document resolves to
5
- * exactly one rendered element. A delivered message never carries it.
6
- */
7
- declare const INSTANCE_PATH_ATTRIBUTE = "data-samva-instance";
8
- /** Where one element sits in the emitted document, with the authoring that produced it. */
9
- interface EmittedPosition {
10
- readonly start: number;
11
- readonly end: number;
12
- readonly origins: ReadonlyArray<JsxSourceLocation>;
13
- /**
14
- * Dot-separated element indices from the document root, assigned as the
15
- * document is written. It is the identity of one rendered instance.
16
- */
17
- readonly instancePath: string;
18
- readonly tag: string;
19
- /** False when a compiler primitive generated this element. */
20
- readonly authored: boolean;
21
- }
22
- /** One rendered element, and the authoring it came from. */
23
- interface EmailElementSelection {
24
- /**
25
- * Dot-separated element indices from the document root. It is the identity
26
- * of one rendered instance, which is what tells two iterations of the same
27
- * authored element apart: their origins are identical.
28
- */
29
- readonly instancePath: string;
30
- readonly tag: string;
31
- /**
32
- * The authored JSX element first, then each enclosing component call site,
33
- * innermost first. Empty when the compiler generated this element with no
34
- * authoring on the stack — the hidden preheader block, for instance.
35
- */
36
- readonly origins: ReadonlyArray<JsxSourceLocation>;
37
- /**
38
- * False when a compiler primitive generated this element. `origins[0]` is
39
- * then the authoring element that asked for it rather than this element
40
- * itself, so the wrapper selects the primitive the author wrote.
41
- */
42
- readonly authored: boolean;
43
- /** 1-based position among the rendered elements sharing this origin chain and tag. */
44
- readonly occurrence: number;
45
- /**
46
- * How many rendered elements share that chain and tag. Above one, one piece
47
- * of authoring produced several rendered elements — a loop over a component,
48
- * or a primitive that generates a repeated cell — so an edit there changes
49
- * all of them.
50
- */
51
- readonly occurrences: number;
52
- /** Absent for the document root. */
53
- readonly parentPath?: string;
54
- /** Offset range in the rendered HTML this selection was taken from. */
55
- readonly start: number;
56
- readonly end: number;
57
- }
58
- /**
59
- * Turn one render's emitted positions into selections, in document order.
60
- *
61
- * The serializer records an element once its content is written, so positions
62
- * arrive innermost-first; document order is what an outline and an ancestry
63
- * walk both need.
64
- */
65
- declare const emailSelections: (positions: readonly EmittedPosition[]) => readonly EmailElementSelection[];
66
- /** Look selections up by the instance path a rendered document carries. */
67
- declare const emailSelectionIndex: (selections: readonly EmailElementSelection[]) => ReadonlyMap<string, EmailElementSelection>;
68
- /**
69
- * The authoring element a selection edits. For an authored element that is the
70
- * element itself; for a generated wrapper it is the primitive that asked for
71
- * it. Undefined only where the compiler generated markup with no authoring on
72
- * the stack, which nothing can edit in place.
73
- */
74
- declare const emailAuthoringTarget: (selection: EmailElementSelection) => JsxSourceLocation | undefined;
75
- /** Root-first ancestry of a selection, itself last. */
76
- declare const emailSelectionAncestry: (index: ReadonlyMap<string, EmailElementSelection>, instancePath: string) => readonly EmailElementSelection[];
77
- /**
78
- * Every rendered instance produced through the same call site, in document
79
- * order. One entry means the call ran once; several mean it repeated.
80
- */
81
- declare const emailSelectionSiblings: (selections: readonly EmailElementSelection[], selection: EmailElementSelection) => readonly EmailElementSelection[];
82
- /**
83
- * Every rendered instance of the same authored element, across every call site
84
- * that reaches it. A shared component edited at its definition changes all of
85
- * these; edited at one call site it changes only `emailSelectionSiblings`. A
86
- * control has to say which of the two it is doing before it applies.
87
- */
88
- declare const emailDefinitionInstances: (selections: readonly EmailElementSelection[], selection: EmailElementSelection) => readonly EmailElementSelection[];
89
- //#endregion
90
- export { emailDefinitionInstances as a, emailSelectionSiblings as c, emailAuthoringTarget as i, emailSelections as l, EmittedPosition as n, emailSelectionAncestry as o, INSTANCE_PATH_ATTRIBUTE as r, emailSelectionIndex as s, EmailElementSelection as t };
91
- //# sourceMappingURL=selection-CCArx9lU.d.ts.map
@@ -1,415 +0,0 @@
1
- import { r as StarterCategory } from "./catalog-CKuOooB8.js";
2
- //#region starters/showcase.d.ts
3
- /**
4
- * The showcase projects: starters authored as complete editable projects under
5
- * `examples/email-showcase/starters` rather than as the single module
6
- * `packages/markup/starters/<id>.tsx`.
7
- *
8
- * This registry is the one place a showcase project is declared. Each project is the directory
9
- * `examples/email-showcase/starters/<id>`, whose files `starter-manifest.json` lists. Codegen reads
10
- * both to bundle the project, the corpus reads the registry for provenance and canonical source paths, and
11
- * `showcase.test.ts` fails when an entry here is missing from the catalog, the public gallery or
12
- * the previews — so a project cannot be half-registered.
13
- */
14
- /** How a showcase project's design came about, and what a public surface must say about it. */
15
- type ShowcaseProvenance = {
16
- readonly kind: "owned";
17
- } | {
18
- readonly kind: "brand-recreation";
19
- /** The brand whose own email is recreated, named on every public surface. */
20
- readonly brand: string;
21
- /** What that brand's email does, in the customer's words. */
22
- readonly subject: string;
23
- readonly reviewedNote: string;
24
- };
25
- interface ShowcaseProject {
26
- /** The starter id, matching its catalog row and its entry file's stem. */
27
- readonly id: string;
28
- /** The project's TSX entry, relative to the starter's own directory. */
29
- readonly entryPath: `emails/${string}.tsx`;
30
- readonly provenance: ShowcaseProvenance;
31
- /** Must equal the catalog row's category. */
32
- readonly category: StarterCategory;
33
- /** Must equal the public gallery entry's slug. */
34
- readonly gallerySlug: string;
35
- /** Stable ISO-8601 timestamp recorded on the corpus entry. */
36
- readonly recordedAt: string;
37
- }
38
- /** Repository-relative directory holding one directory per showcase project. */
39
- declare const SHOWCASE_ROOT = "examples/email-showcase/starters";
40
- declare const showcaseProjects: readonly [{
41
- readonly id: "data-sharing-review";
42
- readonly entryPath: "emails/data-sharing-review.tsx";
43
- readonly provenance: {
44
- readonly kind: "owned";
45
- };
46
- readonly category: "transactional";
47
- readonly gallerySlug: "data-sharing-review";
48
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
49
- }, {
50
- readonly id: "editorial-newsletter";
51
- readonly entryPath: "emails/editorial-newsletter.tsx";
52
- readonly provenance: {
53
- readonly kind: "owned";
54
- };
55
- readonly category: "digest";
56
- readonly gallerySlug: "editorial-newsletter";
57
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
58
- }, {
59
- readonly id: "email-verification";
60
- readonly entryPath: "emails/email-verification.tsx";
61
- readonly provenance: {
62
- readonly kind: "owned";
63
- };
64
- readonly category: "transactional";
65
- readonly gallerySlug: "email-verification";
66
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
67
- }, {
68
- readonly id: "events-roundup";
69
- readonly entryPath: "emails/events-roundup.tsx";
70
- readonly provenance: {
71
- readonly kind: "owned";
72
- };
73
- readonly category: "digest";
74
- readonly gallerySlug: "events-roundup";
75
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
76
- }, {
77
- readonly id: "feature-release-roundup";
78
- readonly entryPath: "emails/feature-release-roundup.tsx";
79
- readonly provenance: {
80
- readonly kind: "owned";
81
- };
82
- readonly category: "marketing";
83
- readonly gallerySlug: "feature-release-roundup";
84
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
85
- }, {
86
- readonly id: "feedback-request";
87
- readonly entryPath: "emails/feedback-request.tsx";
88
- readonly provenance: {
89
- readonly kind: "owned";
90
- };
91
- readonly category: "lifecycle";
92
- readonly gallerySlug: "feedback-request";
93
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
94
- }, {
95
- readonly id: "flash-getaway-offer";
96
- readonly entryPath: "emails/flash-getaway-offer.tsx";
97
- readonly provenance: {
98
- readonly kind: "owned";
99
- };
100
- readonly category: "marketing";
101
- readonly gallerySlug: "flash-getaway-offer";
102
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
103
- }, {
104
- readonly id: "industry-news-digest";
105
- readonly entryPath: "emails/industry-news-digest.tsx";
106
- readonly provenance: {
107
- readonly kind: "owned";
108
- };
109
- readonly category: "digest";
110
- readonly gallerySlug: "industry-news-digest";
111
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
112
- }, {
113
- readonly id: "rewards-milestone";
114
- readonly entryPath: "emails/rewards-milestone.tsx";
115
- readonly provenance: {
116
- readonly kind: "owned";
117
- };
118
- readonly category: "marketing";
119
- readonly gallerySlug: "rewards-milestone";
120
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
121
- }, {
122
- readonly id: "member-referral-offer";
123
- readonly entryPath: "emails/member-referral-offer.tsx";
124
- readonly provenance: {
125
- readonly kind: "owned";
126
- };
127
- readonly category: "marketing";
128
- readonly gallerySlug: "member-referral-offer";
129
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
130
- }, {
131
- readonly id: "catalog-sale-newsletter";
132
- readonly entryPath: "emails/catalog-sale-newsletter.tsx";
133
- readonly provenance: {
134
- readonly kind: "owned";
135
- };
136
- readonly category: "marketing";
137
- readonly gallerySlug: "catalog-sale-newsletter";
138
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
139
- }, {
140
- readonly id: "event-invite";
141
- readonly entryPath: "emails/event-invite.tsx";
142
- readonly provenance: {
143
- readonly kind: "owned";
144
- };
145
- readonly category: "marketing";
146
- readonly gallerySlug: "event-invite";
147
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
148
- }, {
149
- readonly id: "limited-time-savings";
150
- readonly entryPath: "emails/limited-time-savings.tsx";
151
- readonly provenance: {
152
- readonly kind: "owned";
153
- };
154
- readonly category: "marketing";
155
- readonly gallerySlug: "limited-time-savings";
156
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
157
- }, {
158
- readonly id: "membership-promo";
159
- readonly entryPath: "emails/membership-promo.tsx";
160
- readonly provenance: {
161
- readonly kind: "owned";
162
- };
163
- readonly category: "marketing";
164
- readonly gallerySlug: "membership-promotion";
165
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
166
- }, {
167
- readonly id: "announcement";
168
- readonly entryPath: "emails/announcement.tsx";
169
- readonly provenance: {
170
- readonly kind: "owned";
171
- };
172
- readonly category: "marketing";
173
- readonly gallerySlug: "feature-announcement";
174
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
175
- }, {
176
- readonly id: "linear-login-code";
177
- readonly entryPath: "emails/linear-login-code.tsx";
178
- readonly provenance: {
179
- readonly kind: "brand-recreation";
180
- readonly brand: "Linear";
181
- readonly subject: "login code";
182
- readonly reviewedNote: "Reviewed recreation of Linear's login code email, its canonical project assets, and its brand attribution.";
183
- };
184
- readonly category: "transactional";
185
- readonly gallerySlug: "linear-login-code";
186
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
187
- }, {
188
- readonly id: "membership-benefits-promo";
189
- readonly entryPath: "emails/membership-benefits-promo.tsx";
190
- readonly provenance: {
191
- readonly kind: "owned";
192
- };
193
- readonly category: "marketing";
194
- readonly gallerySlug: "membership-benefits-promo";
195
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
196
- }, {
197
- readonly id: "notification";
198
- readonly entryPath: "emails/notification.tsx";
199
- readonly provenance: {
200
- readonly kind: "owned";
201
- };
202
- readonly category: "transactional";
203
- readonly gallerySlug: "activity-notification";
204
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
205
- }, {
206
- readonly id: "onboarding-step";
207
- readonly entryPath: "emails/onboarding-step.tsx";
208
- readonly provenance: {
209
- readonly kind: "owned";
210
- };
211
- readonly category: "lifecycle";
212
- readonly gallerySlug: "onboarding-step";
213
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
214
- }, {
215
- readonly id: "order-receipt";
216
- readonly entryPath: "emails/order-receipt.tsx";
217
- readonly provenance: {
218
- readonly kind: "owned";
219
- };
220
- readonly category: "transactional";
221
- readonly gallerySlug: "order-receipt";
222
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
223
- }, {
224
- readonly id: "otp";
225
- readonly entryPath: "emails/otp.tsx";
226
- readonly provenance: {
227
- readonly kind: "owned";
228
- };
229
- readonly category: "transactional";
230
- readonly gallerySlug: "one-time-passcode";
231
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
232
- }, {
233
- readonly id: "password-reset";
234
- readonly entryPath: "emails/password-reset.tsx";
235
- readonly provenance: {
236
- readonly kind: "owned";
237
- };
238
- readonly category: "transactional";
239
- readonly gallerySlug: "password-reset";
240
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
241
- }, {
242
- readonly id: "payment-failed";
243
- readonly entryPath: "emails/payment-failed.tsx";
244
- readonly provenance: {
245
- readonly kind: "owned";
246
- };
247
- readonly category: "transactional";
248
- readonly gallerySlug: "payment-failed";
249
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
250
- }, {
251
- readonly id: "product-digest";
252
- readonly entryPath: "emails/product-digest.tsx";
253
- readonly provenance: {
254
- readonly kind: "owned";
255
- };
256
- readonly category: "digest";
257
- readonly gallerySlug: "product-digest";
258
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
259
- }, {
260
- readonly id: "product-launch-promo";
261
- readonly entryPath: "emails/product-launch-promo.tsx";
262
- readonly provenance: {
263
- readonly kind: "owned";
264
- };
265
- readonly category: "marketing";
266
- readonly gallerySlug: "product-launch-promotion";
267
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
268
- }, {
269
- readonly id: "product-newsletter";
270
- readonly entryPath: "emails/product-newsletter.tsx";
271
- readonly provenance: {
272
- readonly kind: "owned";
273
- };
274
- readonly category: "digest";
275
- readonly gallerySlug: "product-newsletter";
276
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
277
- }, {
278
- readonly id: "product-onboarding-tour";
279
- readonly entryPath: "emails/product-onboarding-tour.tsx";
280
- readonly provenance: {
281
- readonly kind: "owned";
282
- };
283
- readonly category: "lifecycle";
284
- readonly gallerySlug: "product-onboarding-tour";
285
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
286
- }, {
287
- readonly id: "product-updates-roundup";
288
- readonly entryPath: "emails/product-updates-roundup.tsx";
289
- readonly provenance: {
290
- readonly kind: "owned";
291
- };
292
- readonly category: "marketing";
293
- readonly gallerySlug: "product-updates-roundup";
294
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
295
- }, {
296
- readonly id: "season-clearance-promo";
297
- readonly entryPath: "emails/season-clearance-promo.tsx";
298
- readonly provenance: {
299
- readonly kind: "owned";
300
- };
301
- readonly category: "marketing";
302
- readonly gallerySlug: "season-clearance-promo";
303
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
304
- }, {
305
- readonly id: "seasonal-sale-flyer";
306
- readonly entryPath: "emails/seasonal-sale-flyer.tsx";
307
- readonly provenance: {
308
- readonly kind: "owned";
309
- };
310
- readonly category: "marketing";
311
- readonly gallerySlug: "seasonal-sale-flyer";
312
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
313
- }, {
314
- readonly id: "setup-checklist";
315
- readonly entryPath: "emails/setup-checklist.tsx";
316
- readonly provenance: {
317
- readonly kind: "owned";
318
- };
319
- readonly category: "lifecycle";
320
- readonly gallerySlug: "setup-checklist";
321
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
322
- }, {
323
- readonly id: "shipping-update";
324
- readonly entryPath: "emails/shipping-update.tsx";
325
- readonly provenance: {
326
- readonly kind: "owned";
327
- };
328
- readonly category: "transactional";
329
- readonly gallerySlug: "shipping-update";
330
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
331
- }, {
332
- readonly id: "team-invite";
333
- readonly entryPath: "emails/team-invite.tsx";
334
- readonly provenance: {
335
- readonly kind: "owned";
336
- };
337
- readonly category: "transactional";
338
- readonly gallerySlug: "team-invite";
339
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
340
- }, {
341
- readonly id: "travel-rewards-promo";
342
- readonly entryPath: "emails/travel-rewards-promo.tsx";
343
- readonly provenance: {
344
- readonly kind: "owned";
345
- };
346
- readonly category: "marketing";
347
- readonly gallerySlug: "travel-rewards-promo";
348
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
349
- }, {
350
- readonly id: "trial-ending";
351
- readonly entryPath: "emails/trial-ending.tsx";
352
- readonly provenance: {
353
- readonly kind: "owned";
354
- };
355
- readonly category: "lifecycle";
356
- readonly gallerySlug: "trial-ending";
357
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
358
- }, {
359
- readonly id: "vercel-invitation";
360
- readonly entryPath: "emails/vercel-invitation.tsx";
361
- readonly provenance: {
362
- readonly kind: "brand-recreation";
363
- readonly brand: "Vercel";
364
- readonly subject: "team invitation";
365
- readonly reviewedNote: "Reviewed recreation of Vercel's team invitation email, its canonical project assets, and its brand attribution.";
366
- };
367
- readonly category: "transactional";
368
- readonly gallerySlug: "vercel-team-invitation";
369
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
370
- }, {
371
- readonly id: "weekly-deals-circular";
372
- readonly entryPath: "emails/weekly-deals-circular.tsx";
373
- readonly provenance: {
374
- readonly kind: "owned";
375
- };
376
- readonly category: "marketing";
377
- readonly gallerySlug: "weekly-deals-circular";
378
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
379
- }, {
380
- readonly id: "welcome";
381
- readonly entryPath: "emails/welcome.tsx";
382
- readonly provenance: {
383
- readonly kind: "owned";
384
- };
385
- readonly category: "transactional";
386
- readonly gallerySlug: "welcome-email";
387
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
388
- }, {
389
- readonly id: "win-back";
390
- readonly entryPath: "emails/win-back.tsx";
391
- readonly provenance: {
392
- readonly kind: "owned";
393
- };
394
- readonly category: "lifecycle";
395
- readonly gallerySlug: "win-back";
396
- readonly recordedAt: "2026-09-08T00:00:00.000Z";
397
- }];
398
- type ShowcaseProjectId = (typeof showcaseProjects)[number]["id"];
399
- type BrandRecreationShowcaseId = Extract<(typeof showcaseProjects)[number], {
400
- readonly provenance: {
401
- readonly kind: "brand-recreation";
402
- };
403
- }>["id"];
404
- type OwnedShowcaseId = Extract<(typeof showcaseProjects)[number], {
405
- readonly provenance: {
406
- readonly kind: "owned";
407
- };
408
- }>["id"];
409
- declare const isShowcaseProjectId: (id: string) => id is ShowcaseProjectId;
410
- declare const showcaseProject: (id: string) => ShowcaseProject | undefined;
411
- /** Repository-relative path of a showcase project's TSX entry. */
412
- declare const showcaseSourcePath: (project: ShowcaseProject) => string;
413
- //#endregion
414
- export { ShowcaseProjectId as a, showcaseProject as c, ShowcaseProject as i, showcaseProjects as l, OwnedShowcaseId as n, ShowcaseProvenance as o, SHOWCASE_ROOT as r, isShowcaseProjectId as s, BrandRecreationShowcaseId as t, showcaseSourcePath as u };
415
- //# sourceMappingURL=showcase-egkusQBf.d.ts.map
@@ -1,13 +0,0 @@
1
- //#region src/sms-segments.d.ts
2
- /** Lowercase per the CompiledSms union (document's "GSM-7"/"UCS-2" renamed). */
3
- type SmsEncoding = "gsm7" | "ucs2";
4
- interface SmsSegmentInfo {
5
- readonly encoding: SmsEncoding;
6
- readonly characterCount: number;
7
- readonly segmentCount: number;
8
- }
9
- declare const smsSegmentInfo: (text: string) => SmsSegmentInfo;
10
- declare const hasSmsOptOut: (text: string) => boolean;
11
- //#endregion
12
- export { smsSegmentInfo as i, SmsSegmentInfo as n, hasSmsOptOut as r, SmsEncoding as t };
13
- //# sourceMappingURL=sms-segments-y4FpPilJ.d.ts.map
@@ -1,2 +0,0 @@
1
- import { i as smsSegmentInfo, n as SmsSegmentInfo, r as hasSmsOptOut, t as SmsEncoding } from "./sms-segments-y4FpPilJ.js";
2
- export { SmsEncoding, SmsSegmentInfo, hasSmsOptOut, smsSegmentInfo };
@@ -1,46 +0,0 @@
1
- //#region src/sms-segments.ts
2
- const GSM7_EXTENDED = /* @__PURE__ */ new Set([
3
- "[",
4
- "]",
5
- "{",
6
- "}",
7
- "\\",
8
- "~",
9
- "|",
10
- "€",
11
- "^",
12
- "\f"
13
- ]);
14
- const GSM7_BASIC_PATTERN = /^[@£$¥èéùìòÇ\nØø\rÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ !"#¤%&'()*+,\-./:;<=>?¡0-9ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà]*$/;
15
- const containsNonGsmCharacters = (text) => {
16
- for (const char of text) {
17
- if (GSM7_EXTENDED.has(char)) continue;
18
- if (!GSM7_BASIC_PATTERN.test(char)) return true;
19
- }
20
- return false;
21
- };
22
- const smsSegmentInfo = (text) => {
23
- if (containsNonGsmCharacters(text)) {
24
- const codePoints = [...text].length;
25
- const segmentCount = codePoints <= 70 ? 1 : Math.ceil(codePoints / 67);
26
- return {
27
- encoding: "ucs2",
28
- characterCount: text.length,
29
- segmentCount
30
- };
31
- }
32
- let encodedLength = 0;
33
- for (const char of text) encodedLength += GSM7_EXTENDED.has(char) ? 2 : 1;
34
- const segmentCount = encodedLength <= 160 ? 1 : Math.ceil(encodedLength / 153);
35
- return {
36
- encoding: "gsm7",
37
- characterCount: text.length,
38
- segmentCount
39
- };
40
- };
41
- const SMS_OPT_OUT_PATTERN = /\b(stop|unsubscribe|opt[\s-]?out|cancel|quit)\b/i;
42
- const hasSmsOptOut = (text) => SMS_OPT_OUT_PATTERN.test(text);
43
- //#endregion
44
- export { hasSmsOptOut, smsSegmentInfo };
45
-
46
- //# sourceMappingURL=sms-segments.js.map