@samva/markup 0.7.0 → 0.9.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.
- package/AGENTS.md +104 -37
- package/README.md +188 -52
- package/dist/assets-C5duwTya.d.ts +40 -0
- package/dist/brand-B-0bN_Ir.d.ts +88 -0
- package/dist/{render-aaJBnsXK.js → cascade-t6kxlgEI.js} +130 -160
- package/dist/channel-edit.d.ts +121 -0
- package/dist/channel-edit.js +609 -0
- package/dist/channel-specs-B6M_HlaV.js +29 -0
- package/dist/channel-specs-C2feJwuP.d.ts +13 -0
- package/dist/compatibility-DbISoFIq.js +589 -0
- package/dist/compiler.d.ts +19 -249
- package/dist/compiler.js +10 -1408
- package/dist/{css-COcFOT1y.d.ts → css-BVQKICKC.d.ts} +30 -4
- package/dist/diagnostic-codes.d.ts +403 -0
- package/dist/diagnostic-codes.js +399 -0
- package/dist/{diagnostics-BMYtBCQk.d.ts → diagnostics-B-Gym34R.d.ts} +8 -4
- package/dist/diagnostics.d.ts +31 -2
- package/dist/diagnostics.js +1 -19
- package/dist/{elements-BzjjnoCS.d.ts → elements-cqldpaJt.d.ts} +3 -3
- package/dist/email/assets.d.ts +2 -0
- package/dist/email/assets.js +63 -0
- package/dist/email/brand-footer.d.ts +34 -0
- package/dist/email/brand-footer.js +63 -0
- package/dist/email/brand.d.ts +2 -0
- package/dist/email/brand.js +148 -0
- package/dist/email/components.d.ts +21 -10
- package/dist/email/components.js +46 -11
- package/dist/email/diagnostics.d.ts +2 -2
- package/dist/email/diagnostics.js +2 -1
- package/dist/email/elements.d.ts +1 -1
- package/dist/email/html.d.ts +2 -42
- package/dist/email/html.js +56 -2
- package/dist/email/jsx-dev-runtime.d.ts +2 -2
- package/dist/email/jsx-runtime.d.ts +1 -1
- package/dist/email/render.d.ts +10 -13
- package/dist/email/render.js +163 -6
- package/dist/email/text.d.ts +1 -1
- package/dist/fmt.d.ts +32 -0
- package/dist/fmt.js +174 -0
- package/dist/html-BJepOwZ4.d.ts +56 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/ir-aaqNE987.d.ts +252 -0
- package/dist/ir.d.ts +2 -0
- package/dist/ir.js +7 -0
- package/dist/preview-Ekdg1dXG.d.ts +100 -0
- package/dist/preview.d.ts +2 -0
- package/dist/preview.js +160 -0
- package/dist/profile-BH-OtdDA.js +3670 -0
- package/dist/render-ir.d.ts +19 -0
- package/dist/render-ir.js +826 -0
- package/dist/sms-segments.d.ts +13 -2
- package/dist/sms.d.ts +16 -0
- package/dist/sms.js +12 -0
- package/dist/{email/source-edit.d.ts → source-edit.d.ts} +55 -6
- package/dist/source-edit.js +343 -0
- package/dist/source-locations-C8wCsiAy.d.ts +23 -0
- package/dist/source-locations.d.ts +2 -2
- package/dist/source-locations.js +3 -89
- package/dist/static.d.ts +57 -0
- package/dist/static.js +69 -0
- package/dist/tailwind-CMYpZf1v.js +614 -0
- package/dist/template-_QE_rQND.d.ts +65 -0
- package/dist/template.d.ts +2 -2
- package/dist/template.js +15 -10
- package/dist/theme-css-hFqcPSar.js +587 -0
- package/dist/theme-css.d.ts +57 -16
- package/dist/theme-css.js +2 -509
- package/dist/theme-imports-lvBw3AD1.js +109 -0
- package/dist/transform-Ct2OMkFN.d.ts +153 -0
- package/dist/unsubscribe-link-CoesnQDU.js +26 -0
- package/dist/whatsapp.d.ts +57 -0
- package/dist/whatsapp.js +22 -0
- package/generated/contract.json +1782 -0
- package/generated/reference.md +353 -0
- package/package.json +56 -154
- package/samva-brand.d.ts +14 -0
- package/skills/sml/SKILL.md +123 -0
- package/dist/ast-BrDtApwS.d.ts +0 -107
- package/dist/ast.d.ts +0 -2
- package/dist/ast.js +0 -124
- package/dist/candidate.d.ts +0 -29
- package/dist/candidate.js +0 -88
- package/dist/catalog-60eaYC7b.d.ts +0 -356
- package/dist/checks-DBweSIPN.js +0 -58954
- package/dist/checks.d.ts +0 -33
- package/dist/checks.js +0 -2
- package/dist/classes.d.ts +0 -27
- package/dist/classes.js +0 -184
- package/dist/compile-sms.d.ts +0 -28
- package/dist/compile-sms.js +0 -44
- package/dist/compile-whatsapp.d.ts +0 -56
- package/dist/compile-whatsapp.js +0 -186
- package/dist/compile.d.ts +0 -18
- package/dist/compile.js +0 -29
- package/dist/components.d.ts +0 -289
- package/dist/components.js +0 -106
- package/dist/conditionals.d.ts +0 -10
- package/dist/conditionals.js +0 -74
- package/dist/corpus-BjYMqOoY.d.ts +0 -106
- package/dist/diagnostics-OcQKQYSY.d.ts +0 -49
- package/dist/email/selection.d.ts +0 -91
- package/dist/email/selection.js +0 -91
- package/dist/email/source-edit.js +0 -185
- package/dist/email/stylesheets.d.ts +0 -15
- package/dist/email/stylesheets.js +0 -45
- package/dist/emit.d.ts +0 -51
- package/dist/emit.js +0 -151
- package/dist/footer.d.ts +0 -66
- package/dist/footer.js +0 -93
- package/dist/interpolate.d.ts +0 -24
- package/dist/interpolate.js +0 -43
- package/dist/jsx-dev-runtime.d.ts +0 -11
- package/dist/jsx-dev-runtime.js +0 -15
- package/dist/jsx-runtime-I-1nCtl2.d.ts +0 -57
- package/dist/jsx-runtime.d.ts +0 -2
- package/dist/jsx-runtime.js +0 -121
- package/dist/lexer.d.ts +0 -60
- package/dist/lexer.js +0 -281
- package/dist/model.d.ts +0 -24
- package/dist/model.js +0 -77
- package/dist/ops-2aiiYO7m.js +0 -630
- package/dist/ops.d.ts +0 -114
- package/dist/ops.js +0 -2
- package/dist/parser-t29cHLVL.d.ts +0 -396
- package/dist/parser.d.ts +0 -2
- package/dist/parser.js +0 -859
- package/dist/predicate-BI6uRRM-.js +0 -549
- package/dist/predicate-M-05Nd7R.d.ts +0 -56
- package/dist/predicate.d.ts +0 -2
- package/dist/predicate.js +0 -2
- package/dist/presets/category-mapping.d.ts +0 -13
- package/dist/presets/category-mapping.js +0 -49
- package/dist/presets/corpus.d.ts +0 -2
- package/dist/presets/corpus.js +0 -194
- package/dist/presets/public-gallery.d.ts +0 -266
- package/dist/presets/public-gallery.js +0 -916
- package/dist/presets/public-handoff.d.ts +0 -164
- package/dist/presets/public-handoff.js +0 -361
- package/dist/presets/public-preview-artifacts.d.ts +0 -43
- package/dist/presets/public-preview-artifacts.js +0 -104
- package/dist/presets/public-preview.d.ts +0 -61
- package/dist/presets/public-preview.js +0 -83
- package/dist/presets/showcase.d.ts +0 -2
- package/dist/presets/showcase.js +0 -627
- package/dist/presets/sources.d.ts +0 -38
- package/dist/presets/sources.js +0 -6083
- package/dist/presets.d.ts +0 -2
- package/dist/presets.js +0 -881
- package/dist/printer.d.ts +0 -6
- package/dist/printer.js +0 -122
- package/dist/registry.d.ts +0 -42
- package/dist/registry.js +0 -646
- package/dist/render-template.d.ts +0 -45
- package/dist/render-template.js +0 -76
- package/dist/showcase-DGZAWn4Z.d.ts +0 -456
- package/dist/sms-segments-y4FpPilJ.d.ts +0 -13
- package/dist/source-locations-DrCM82Ym.d.ts +0 -67
- package/dist/template-DWftqh4x.d.ts +0 -60
- package/dist/theme-6ApjjiBo.d.ts +0 -116
- package/dist/theme.d.ts +0 -2
- package/dist/theme.js +0 -118
- package/dist/tokens.d.ts +0 -6
- package/dist/tokens.js +0 -417
- package/dist/tsx-source-instrumentation.d.ts +0 -30
- package/dist/tsx-source-instrumentation.js +0 -115
- package/dist/tsx-tracer.d.ts +0 -112
- package/dist/tsx-tracer.js +0 -985
- package/dist/variables-J_L3qxRa.d.ts +0 -77
- package/dist/variables.d.ts +0 -2
- package/dist/variables.js +0 -141
- package/dist/version-BITr58kk.js +0 -96
- package/generated/sml-agent-contract.json +0 -709
- package/generated/sml-email-agent-contract.json +0 -615
- package/generated/sml-email-language-reference.md +0 -94
- package/generated/sml-language-reference.md +0 -195
package/dist/footer.d.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { s as TokenTable } from "./theme-6ApjjiBo.js";
|
|
2
|
-
//#region src/footer.d.ts
|
|
3
|
-
/** The per-recipient unsubscribe URL is not known at accept time (the body is
|
|
4
|
-
* shared across a send's deliveries), so the footer is composed with this
|
|
5
|
-
* placeholder in the unsubscribe href and the plain-text tail. The email queue
|
|
6
|
-
* processor substitutes each delivery's minted token URL at dispatch. The link
|
|
7
|
-
* carries `ses:no-track` so click tracking never rewrites (and thereby breaks)
|
|
8
|
-
* the placeholder. */
|
|
9
|
-
declare const FOOTER_UNSUBSCRIBE_PLACEHOLDER = "%samva:unsubscribe-url%";
|
|
10
|
-
/** One labelled social link. Structurally mirrors `DesignSocialLink`. */
|
|
11
|
-
interface FooterSocialLink {
|
|
12
|
-
readonly label: string;
|
|
13
|
-
readonly url: string;
|
|
14
|
-
}
|
|
15
|
-
/** A structured postal address. Structurally mirrors `DesignAddress`. */
|
|
16
|
-
interface FooterAddress {
|
|
17
|
-
readonly street1: string;
|
|
18
|
-
readonly street2?: string | undefined;
|
|
19
|
-
readonly city: string;
|
|
20
|
-
readonly region: string;
|
|
21
|
-
readonly postalCode: string;
|
|
22
|
-
readonly country: string;
|
|
23
|
-
}
|
|
24
|
-
/** The effective footer content. Structurally mirrors `DesignFooter`. */
|
|
25
|
-
interface FooterContent {
|
|
26
|
-
readonly companyName?: string | undefined;
|
|
27
|
-
readonly address?: FooterAddress | undefined;
|
|
28
|
-
readonly socialLinks?: ReadonlyArray<FooterSocialLink> | undefined;
|
|
29
|
-
readonly customHtml?: string | undefined;
|
|
30
|
-
}
|
|
31
|
-
/** Which compliance-relevant footer fields the effective content is missing,
|
|
32
|
-
* surfaced on the design read path for the dashboard's footer nudge. */
|
|
33
|
-
interface FooterCompleteness {
|
|
34
|
-
/** No physical mailing address is set anywhere in the cascade (CAN-SPAM). */
|
|
35
|
-
readonly missingAddress: boolean;
|
|
36
|
-
}
|
|
37
|
-
interface RenderedFooter {
|
|
38
|
-
/** Table-based footer block, ready to inject before the body's `</body>`. */
|
|
39
|
-
readonly html: string;
|
|
40
|
-
/** Plain-text footer tail, appended to the text alternative. */
|
|
41
|
-
readonly text: string;
|
|
42
|
-
readonly completeness: FooterCompleteness;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Which compliance-relevant fields the footer content lacks — the signal the
|
|
46
|
-
* dashboard's footer nudge reads. Derivable from `design.footer` alone (no token table),
|
|
47
|
-
* so the design read path can report it without composing the block. A
|
|
48
|
-
* `customHtml` footer is treated as complete (the org owns its own content).
|
|
49
|
-
*/
|
|
50
|
-
declare const footerCompleteness: (footer: FooterContent | undefined) => FooterCompleteness;
|
|
51
|
-
/**
|
|
52
|
-
* Compose the injected footer for one send. `unsubscribeUrl` is the placeholder
|
|
53
|
-
* (`FOOTER_UNSUBSCRIBE_PLACEHOLDER`) when a group resolved and dispatch will
|
|
54
|
-
* mint the per-recipient link, or `null` to omit the unsubscribe row entirely
|
|
55
|
-
* (no group resolved). Never throws and never blocks: whatever content exists
|
|
56
|
-
* renders, and the missing pieces are reported via `completeness`.
|
|
57
|
-
*/
|
|
58
|
-
declare const renderFooterBlock: (input: {
|
|
59
|
-
readonly footer: FooterContent;
|
|
60
|
-
readonly tokens: TokenTable;
|
|
61
|
-
readonly unsubscribeUrl: string | null;
|
|
62
|
-
readonly unsubscribeLabel?: string | undefined;
|
|
63
|
-
}) => RenderedFooter;
|
|
64
|
-
//#endregion
|
|
65
|
-
export { FOOTER_UNSUBSCRIBE_PLACEHOLDER, FooterAddress, FooterCompleteness, FooterContent, FooterSocialLink, RenderedFooter, footerCompleteness, renderFooterBlock };
|
|
66
|
-
//# sourceMappingURL=footer.d.ts.map
|
package/dist/footer.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
//#region src/footer.ts
|
|
2
|
-
/** The per-recipient unsubscribe URL is not known at accept time (the body is
|
|
3
|
-
* shared across a send's deliveries), so the footer is composed with this
|
|
4
|
-
* placeholder in the unsubscribe href and the plain-text tail. The email queue
|
|
5
|
-
* processor substitutes each delivery's minted token URL at dispatch. The link
|
|
6
|
-
* carries `ses:no-track` so click tracking never rewrites (and thereby breaks)
|
|
7
|
-
* the placeholder. */
|
|
8
|
-
const FOOTER_UNSUBSCRIBE_PLACEHOLDER = "%samva:unsubscribe-url%";
|
|
9
|
-
const escapeText = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
10
|
-
const escapeAttribute = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
11
|
-
const isSafeUrl = (url) => /^(https?:|mailto:)/i.test(url.trim());
|
|
12
|
-
const addressLines = (address) => {
|
|
13
|
-
const region = [
|
|
14
|
-
address.city,
|
|
15
|
-
address.region,
|
|
16
|
-
address.postalCode
|
|
17
|
-
].filter(Boolean).join(", ");
|
|
18
|
-
return [
|
|
19
|
-
address.street1,
|
|
20
|
-
address.street2,
|
|
21
|
-
region,
|
|
22
|
-
address.country
|
|
23
|
-
].filter((line) => typeof line === "string" && line.trim().length > 0);
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Which compliance-relevant fields the footer content lacks — the signal the
|
|
27
|
-
* dashboard's footer nudge reads. Derivable from `design.footer` alone (no token table),
|
|
28
|
-
* so the design read path can report it without composing the block. A
|
|
29
|
-
* `customHtml` footer is treated as complete (the org owns its own content).
|
|
30
|
-
*/
|
|
31
|
-
const footerCompleteness = (footer) => ({ missingAddress: footer?.customHtml === void 0 && (footer?.address === void 0 || addressLines(footer.address).length === 0) });
|
|
32
|
-
/**
|
|
33
|
-
* Compose the injected footer for one send. `unsubscribeUrl` is the placeholder
|
|
34
|
-
* (`FOOTER_UNSUBSCRIBE_PLACEHOLDER`) when a group resolved and dispatch will
|
|
35
|
-
* mint the per-recipient link, or `null` to omit the unsubscribe row entirely
|
|
36
|
-
* (no group resolved). Never throws and never blocks: whatever content exists
|
|
37
|
-
* renders, and the missing pieces are reported via `completeness`.
|
|
38
|
-
*/
|
|
39
|
-
const renderFooterBlock = (input) => {
|
|
40
|
-
const { footer, tokens, unsubscribeUrl } = input;
|
|
41
|
-
const unsubscribeLabel = input.unsubscribeLabel ?? "Unsubscribe";
|
|
42
|
-
const fontFamily = tokens.fontFamilies["body"] ?? tokens.fontFamilies["sans"] ?? "sans-serif";
|
|
43
|
-
const mutedColor = tokens.colors["gray-500"] ?? tokens.colors["neutral-500"] ?? "#6a7282";
|
|
44
|
-
const linkColor = tokens.colors["brand"] ?? mutedColor;
|
|
45
|
-
const containerPx = tokens.containerPx["xl"] ?? 600;
|
|
46
|
-
const fontSizePx = tokens.text["xs"]?.sizePx ?? 12;
|
|
47
|
-
const lineHeightPx = tokens.text["xs"]?.lineHeightPx ?? 18;
|
|
48
|
-
const fontFamilyAttribute = escapeAttribute(fontFamily);
|
|
49
|
-
const mutedColorAttribute = escapeAttribute(mutedColor);
|
|
50
|
-
const linkColorAttribute = escapeAttribute(linkColor);
|
|
51
|
-
const rows = [];
|
|
52
|
-
const textLines = [];
|
|
53
|
-
if (typeof footer.customHtml === "string" && footer.customHtml.trim().length > 0) rows.push(`<tr><td style="padding:0 0 12px 0;">${footer.customHtml}</td></tr>`);
|
|
54
|
-
else {
|
|
55
|
-
if (typeof footer.companyName === "string" && footer.companyName.trim().length > 0) {
|
|
56
|
-
rows.push(`<tr><td style="padding:0 0 4px 0;font-weight:600;">${escapeText(footer.companyName)}</td></tr>`);
|
|
57
|
-
textLines.push(footer.companyName);
|
|
58
|
-
}
|
|
59
|
-
if (footer.address !== void 0) {
|
|
60
|
-
const lines = addressLines(footer.address);
|
|
61
|
-
if (lines.length > 0) {
|
|
62
|
-
rows.push(`<tr><td style="padding:0 0 8px 0;">${lines.map(escapeText).join("<br />")}</td></tr>`);
|
|
63
|
-
textLines.push(lines.join(", "));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (footer.socialLinks !== void 0 && footer.socialLinks.length > 0) {
|
|
67
|
-
const links = footer.socialLinks.map((link) => isSafeUrl(link.url) ? `<a href="${escapeAttribute(link.url.trim())}" style="color:${linkColorAttribute};text-decoration:underline;" ses:no-track>${escapeText(link.label)}</a>` : escapeText(link.label));
|
|
68
|
-
rows.push(`<tr><td style="padding:0 0 8px 0;">${links.join("<span style=\"padding:0 6px;\">·</span>")}</td></tr>`);
|
|
69
|
-
textLines.push(footer.socialLinks.map((link) => `${link.label}: ${link.url}`).join(" "));
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (unsubscribeUrl !== null) {
|
|
73
|
-
rows.push(`<tr><td style="padding:0;"><a href="${escapeAttribute(unsubscribeUrl)}" style="color:${mutedColorAttribute};text-decoration:underline;" ses:no-track>${escapeText(unsubscribeLabel)}</a></td></tr>`);
|
|
74
|
-
textLines.push(`${unsubscribeLabel}: ${unsubscribeUrl}`);
|
|
75
|
-
}
|
|
76
|
-
return {
|
|
77
|
-
html: rows.length === 0 ? "" : [
|
|
78
|
-
`<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="width:100%;border-collapse:collapse;">`,
|
|
79
|
-
`<tr><td align="center" style="padding:32px 16px;">`,
|
|
80
|
-
`<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="${containerPx}" style="width:100%;max-width:${containerPx}px;border-collapse:collapse;font-family:${fontFamilyAttribute};font-size:${fontSizePx}px;line-height:${lineHeightPx}px;color:${mutedColorAttribute};text-align:center;">`,
|
|
81
|
-
...rows,
|
|
82
|
-
`</table>`,
|
|
83
|
-
`</td></tr>`,
|
|
84
|
-
`</table>`
|
|
85
|
-
].join(""),
|
|
86
|
-
text: textLines.length === 0 ? "" : `\n\n---\n${textLines.join("\n")}`,
|
|
87
|
-
completeness: footerCompleteness(footer)
|
|
88
|
-
};
|
|
89
|
-
};
|
|
90
|
-
//#endregion
|
|
91
|
-
export { FOOTER_UNSUBSCRIBE_PLACEHOLDER, footerCompleteness, renderFooterBlock };
|
|
92
|
-
|
|
93
|
-
//# sourceMappingURL=footer.js.map
|
package/dist/interpolate.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
//#region src/interpolate.d.ts
|
|
2
|
-
type DocumentVariableType = "string" | "number" | "boolean" | "date" | "array" | "object";
|
|
3
|
-
/** One entry of a template's declared variable schema. */
|
|
4
|
-
interface DocumentVariable {
|
|
5
|
-
readonly name: string;
|
|
6
|
-
readonly type: DocumentVariableType;
|
|
7
|
-
readonly required: boolean;
|
|
8
|
-
readonly default?: unknown;
|
|
9
|
-
readonly description?: string | undefined;
|
|
10
|
-
}
|
|
11
|
-
declare const variableReferencePattern: RegExp;
|
|
12
|
-
declare const getVariableValue: (variables: Record<string, unknown>, variableSchema: ReadonlyArray<DocumentVariable>, name: string) => unknown;
|
|
13
|
-
declare const stringifyVariable: (value: unknown) => string;
|
|
14
|
-
interface InterpolationResult {
|
|
15
|
-
readonly rendered: string;
|
|
16
|
-
/** Required variables that resolved to nothing (no value, no default). */
|
|
17
|
-
readonly missing: ReadonlySet<string>;
|
|
18
|
-
}
|
|
19
|
-
declare const interpolate: (text: string, variables: Record<string, unknown>, variableSchema: ReadonlyArray<DocumentVariable>) => InterpolationResult;
|
|
20
|
-
declare const variableReferences: (text: string) => Set<string>;
|
|
21
|
-
declare const addVariableReferences: (target: Set<string>, text: string) => void;
|
|
22
|
-
//#endregion
|
|
23
|
-
export { DocumentVariable, DocumentVariableType, InterpolationResult, addVariableReferences, getVariableValue, interpolate, stringifyVariable, variableReferencePattern, variableReferences };
|
|
24
|
-
//# sourceMappingURL=interpolate.d.ts.map
|
package/dist/interpolate.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
//#region src/interpolate.ts
|
|
2
|
-
const variableReferencePattern = /\$\{\s*\/?([\w.]+)\s*\}|\{\{\s*([\w.]+)\s*\}\}/g;
|
|
3
|
-
const getVariableValue = (variables, variableSchema, name) => {
|
|
4
|
-
const schema = variableSchema.find((item) => item.name === name);
|
|
5
|
-
const value = variables[name];
|
|
6
|
-
if (value !== void 0 && value !== null) return value;
|
|
7
|
-
return schema?.default;
|
|
8
|
-
};
|
|
9
|
-
const stringifyVariable = (value) => {
|
|
10
|
-
if (value === void 0 || value === null) return "";
|
|
11
|
-
if (value instanceof Date) return value.toISOString();
|
|
12
|
-
if (Array.isArray(value)) return value.join(", ");
|
|
13
|
-
if (typeof value === "object") return JSON.stringify(value);
|
|
14
|
-
return String(value);
|
|
15
|
-
};
|
|
16
|
-
const interpolate = (text, variables, variableSchema) => {
|
|
17
|
-
const missing = /* @__PURE__ */ new Set();
|
|
18
|
-
const substitute = (name) => {
|
|
19
|
-
const value = getVariableValue(variables, variableSchema, name);
|
|
20
|
-
const schema = variableSchema.find((item) => item.name === name);
|
|
21
|
-
if ((value === void 0 || value === null) && schema?.required) missing.add(name);
|
|
22
|
-
return stringifyVariable(value);
|
|
23
|
-
};
|
|
24
|
-
return {
|
|
25
|
-
rendered: text.replace(variableReferencePattern, (_match, dollarName, braceName) => substitute(dollarName ?? braceName ?? "")),
|
|
26
|
-
missing
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
const variableReferences = (text) => {
|
|
30
|
-
const names = /* @__PURE__ */ new Set();
|
|
31
|
-
for (const match of text.matchAll(variableReferencePattern)) {
|
|
32
|
-
const name = match[1] ?? match[2];
|
|
33
|
-
if (name !== void 0 && name !== "") names.add(name);
|
|
34
|
-
}
|
|
35
|
-
return names;
|
|
36
|
-
};
|
|
37
|
-
const addVariableReferences = (target, text) => {
|
|
38
|
-
variableReferences(text).forEach((name) => target.add(name));
|
|
39
|
-
};
|
|
40
|
-
//#endregion
|
|
41
|
-
export { addVariableReferences, getVariableValue, interpolate, stringifyVariable, variableReferencePattern, variableReferences };
|
|
42
|
-
|
|
43
|
-
//# sourceMappingURL=interpolate.js.map
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { r as JsxSource } from "./source-locations-DrCM82Ym.js";
|
|
2
|
-
import { a as JsxResult, i as JSX, n as Fragment, t as Component } from "./jsx-runtime-I-1nCtl2.js";
|
|
3
|
-
//#region src/jsx-dev-runtime.d.ts
|
|
4
|
-
interface JsxDevProps {
|
|
5
|
-
readonly children?: unknown;
|
|
6
|
-
readonly [key: string]: unknown;
|
|
7
|
-
}
|
|
8
|
-
declare const jsxDEV: <P>(type: Component<P> | typeof Fragment, props: P, _key?: string | number | null, _isStaticChildren?: boolean, source?: JsxSource | null, _self?: unknown) => JsxResult;
|
|
9
|
-
//#endregion
|
|
10
|
-
export { Fragment, type JSX, JsxDevProps, jsxDEV };
|
|
11
|
-
//# sourceMappingURL=jsx-dev-runtime.d.ts.map
|
package/dist/jsx-dev-runtime.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { attachJsxSourceLocation, completeJsxSourceLocation } from "./source-locations.js";
|
|
2
|
-
import { Fragment, jsx } from "./jsx-runtime.js";
|
|
3
|
-
//#region src/jsx-dev-runtime.ts
|
|
4
|
-
const jsxDEV = (type, props, _key, _isStaticChildren, source, _self) => {
|
|
5
|
-
const result = jsx(type, props);
|
|
6
|
-
if (type !== Fragment && result.kind === "element") {
|
|
7
|
-
const location = completeJsxSourceLocation(source);
|
|
8
|
-
if (location !== void 0) attachJsxSourceLocation(result, location);
|
|
9
|
-
}
|
|
10
|
-
return result;
|
|
11
|
-
};
|
|
12
|
-
//#endregion
|
|
13
|
-
export { Fragment, jsxDEV };
|
|
14
|
-
|
|
15
|
-
//# sourceMappingURL=jsx-dev-runtime.js.map
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { f as ElementNode, n as Attribute, x as SmlNode } from "./ast-BrDtApwS.js";
|
|
2
|
-
import { s as VariableRef } from "./variables-J_L3qxRa.js";
|
|
3
|
-
//#region src/jsx-runtime.d.ts
|
|
4
|
-
/** A component is a plain function of its props that returns a draft node. */
|
|
5
|
-
type Component<P> = (props: P) => SmlNode;
|
|
6
|
-
/**
|
|
7
|
-
* What may appear in a component's `children`. Booleans/null/undefined are
|
|
8
|
-
* skipped (so `{cond && <X/>}` and `{cond ? <A/> : null}` are BUILD-TIME
|
|
9
|
-
* conditionals that evaluate away); strings/numbers become text; VariableRefs
|
|
10
|
-
* become `{{interpolation}}` nodes; arrays flatten; nested nodes nest. Anything
|
|
11
|
-
* else is a typed authoring error.
|
|
12
|
-
*/
|
|
13
|
-
type SmlChild = SmlNode | FragmentDraft | VariableRef<unknown> | string | number | boolean | null | undefined | ReadonlyArray<SmlChild>;
|
|
14
|
-
type SmlChildren = SmlChild | ReadonlyArray<SmlChild>;
|
|
15
|
-
/** Fragment children pass through un-wrapped — a Fragment is not an element. */
|
|
16
|
-
interface FragmentDraft {
|
|
17
|
-
readonly kind: "fragment";
|
|
18
|
-
readonly children: ReadonlyArray<SmlNode>;
|
|
19
|
-
}
|
|
20
|
-
type JsxResult = SmlNode | FragmentDraft;
|
|
21
|
-
/**
|
|
22
|
-
* Flattens and normalizes a component's raw `children` prop into AST child
|
|
23
|
-
* nodes. Fragments splice their children in; booleans/null/undefined drop out.
|
|
24
|
-
*/
|
|
25
|
-
declare const normalizeChildren: (children: unknown) => Array<SmlNode>;
|
|
26
|
-
/**
|
|
27
|
-
* Builds an element draft from a tag, attribute list (already in authored
|
|
28
|
-
* order), and normalized children. Kept here so the runtime owns the AST shape;
|
|
29
|
-
* ./components maps typed props onto attributes and calls this.
|
|
30
|
-
*/
|
|
31
|
-
declare const elementDraft: (tag: ElementNode["tag"], attributes: ReadonlyArray<Attribute>, children: ReadonlyArray<SmlNode>) => ElementNode;
|
|
32
|
-
interface JsxProps {
|
|
33
|
-
readonly children?: unknown;
|
|
34
|
-
readonly [key: string]: unknown;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* The automatic-runtime entry point. `type` is always one of our typed
|
|
38
|
-
* component functions (or `Fragment`); we invoke it with its props. The JSX
|
|
39
|
-
* transform routes single-child elements here and multi-child elements to
|
|
40
|
-
* `jsxs` — behaviour is identical for us (components normalize their own
|
|
41
|
-
* children), so `jsxs` re-exports this.
|
|
42
|
-
*/
|
|
43
|
-
declare const jsx: (type: Component<JsxProps> | typeof Fragment, props: JsxProps) => JsxResult;
|
|
44
|
-
declare const jsxs: typeof jsx;
|
|
45
|
-
/** Groups children without an element wrapper. Its children splice into the parent. */
|
|
46
|
-
declare const Fragment: unique symbol;
|
|
47
|
-
declare namespace JSX {
|
|
48
|
-
type Element = JsxResult;
|
|
49
|
-
type ElementType = Component<never> | typeof Fragment;
|
|
50
|
-
interface ElementChildrenAttribute {
|
|
51
|
-
readonly children: object;
|
|
52
|
-
}
|
|
53
|
-
type IntrinsicElements = Record<string, never>;
|
|
54
|
-
}
|
|
55
|
-
//#endregion
|
|
56
|
-
export { JsxResult as a, elementDraft as c, normalizeChildren as d, JSX as i, jsx as l, Fragment as n, SmlChild as o, FragmentDraft as r, SmlChildren as s, Component as t, jsxs as u };
|
|
57
|
-
//# sourceMappingURL=jsx-runtime-I-1nCtl2.d.ts.map
|
package/dist/jsx-runtime.d.ts
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import { a as JsxResult, c as elementDraft, d as normalizeChildren, i as JSX, l as jsx, n as Fragment, o as SmlChild, r as FragmentDraft, s as SmlChildren, t as Component, u as jsxs } from "./jsx-runtime-I-1nCtl2.js";
|
|
2
|
-
export { Component, Fragment, FragmentDraft, JSX, JsxResult, SmlChild, SmlChildren, elementDraft, jsx, jsxs, normalizeChildren };
|
package/dist/jsx-runtime.js
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import { t as hasProperty } from "./guards-eV1qLbf2.js";
|
|
2
|
-
import { JSX_SOURCE_LOCATION_PROP, attachJsxSourceLocation, completeJsxSourceLocation } from "./source-locations.js";
|
|
3
|
-
import { VARIABLE_REF, isVariableRef } from "./variables.js";
|
|
4
|
-
//#region src/jsx-runtime.ts
|
|
5
|
-
const PLACEHOLDER_SPAN = {
|
|
6
|
-
start: 0,
|
|
7
|
-
end: 0
|
|
8
|
-
};
|
|
9
|
-
const isFragmentDraft = (value) => hasProperty(value, "kind") && value.kind === "fragment";
|
|
10
|
-
const isSmlNode = (value) => {
|
|
11
|
-
if (!hasProperty(value, "kind")) return false;
|
|
12
|
-
const kind = value.kind;
|
|
13
|
-
return kind === "element" || kind === "text" || kind === "interpolation";
|
|
14
|
-
};
|
|
15
|
-
const textNode = (value) => ({
|
|
16
|
-
kind: "text",
|
|
17
|
-
id: "",
|
|
18
|
-
value,
|
|
19
|
-
span: PLACEHOLDER_SPAN
|
|
20
|
-
});
|
|
21
|
-
const interpolationNode = (ref) => ({
|
|
22
|
-
kind: "interpolation",
|
|
23
|
-
id: "",
|
|
24
|
-
name: ref[VARIABLE_REF].path,
|
|
25
|
-
syntax: "curly",
|
|
26
|
-
span: PLACEHOLDER_SPAN
|
|
27
|
-
});
|
|
28
|
-
/**
|
|
29
|
-
* Flattens and normalizes a component's raw `children` prop into AST child
|
|
30
|
-
* nodes. Fragments splice their children in; booleans/null/undefined drop out.
|
|
31
|
-
*/
|
|
32
|
-
const normalizeChildren = (children) => {
|
|
33
|
-
const out = [];
|
|
34
|
-
const push = (child) => {
|
|
35
|
-
if (child === null || child === void 0 || typeof child === "boolean") return;
|
|
36
|
-
if (typeof child === "string") {
|
|
37
|
-
out.push(textNode(child));
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
if (typeof child === "number") {
|
|
41
|
-
out.push(textNode(String(child)));
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
if (Array.isArray(child)) {
|
|
45
|
-
for (const item of child) push(item);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (isVariableRef(child)) {
|
|
49
|
-
out.push(interpolationNode(child));
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
if (isFragmentDraft(child)) {
|
|
53
|
-
for (const node of child.children) out.push(node);
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
if (isSmlNode(child)) {
|
|
57
|
-
out.push(child);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
throw new TypeError(`invalid SML child: ${describe(child)} — children may be text, numbers, variables, elements, arrays of these, or false/null/undefined (which are skipped)`);
|
|
61
|
-
};
|
|
62
|
-
push(children);
|
|
63
|
-
return out;
|
|
64
|
-
};
|
|
65
|
-
const describe = (value) => {
|
|
66
|
-
if (typeof value === "function") return "a function (did you pass a component instead of an element?)";
|
|
67
|
-
if (typeof value === "object") return `an object (${JSON.stringify(value)})`;
|
|
68
|
-
return `${typeof value} (${JSON.stringify(value)})`;
|
|
69
|
-
};
|
|
70
|
-
/**
|
|
71
|
-
* Builds an element draft from a tag, attribute list (already in authored
|
|
72
|
-
* order), and normalized children. Kept here so the runtime owns the AST shape;
|
|
73
|
-
* ./components maps typed props onto attributes and calls this.
|
|
74
|
-
*/
|
|
75
|
-
const elementDraft = (tag, attributes, children) => ({
|
|
76
|
-
kind: "element",
|
|
77
|
-
id: "",
|
|
78
|
-
tag,
|
|
79
|
-
attributes,
|
|
80
|
-
children,
|
|
81
|
-
span: PLACEHOLDER_SPAN
|
|
82
|
-
});
|
|
83
|
-
const stripSourceLocation = (props) => {
|
|
84
|
-
const source = props[JSX_SOURCE_LOCATION_PROP];
|
|
85
|
-
if (source === void 0) return {
|
|
86
|
-
props,
|
|
87
|
-
source: void 0
|
|
88
|
-
};
|
|
89
|
-
const { [JSX_SOURCE_LOCATION_PROP]: _source, ...rest } = props;
|
|
90
|
-
return {
|
|
91
|
-
props: rest,
|
|
92
|
-
source
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
/**
|
|
96
|
-
* The automatic-runtime entry point. `type` is always one of our typed
|
|
97
|
-
* component functions (or `Fragment`); we invoke it with its props. The JSX
|
|
98
|
-
* transform routes single-child elements here and multi-child elements to
|
|
99
|
-
* `jsxs` — behaviour is identical for us (components normalize their own
|
|
100
|
-
* children), so `jsxs` re-exports this.
|
|
101
|
-
*/
|
|
102
|
-
const jsx = (type, props) => {
|
|
103
|
-
if (type === Fragment) return {
|
|
104
|
-
kind: "fragment",
|
|
105
|
-
children: normalizeChildren(props.children)
|
|
106
|
-
};
|
|
107
|
-
const { props: cleanProps, source } = stripSourceLocation(props);
|
|
108
|
-
const result = type(cleanProps);
|
|
109
|
-
if (source !== void 0 && result.kind === "element") {
|
|
110
|
-
const location = completeJsxSourceLocation(source);
|
|
111
|
-
if (location !== void 0) attachJsxSourceLocation(result, location);
|
|
112
|
-
}
|
|
113
|
-
return result;
|
|
114
|
-
};
|
|
115
|
-
const jsxs = jsx;
|
|
116
|
-
/** Groups children without an element wrapper. Its children splice into the parent. */
|
|
117
|
-
const Fragment = Symbol.for("@samva/markup/Fragment");
|
|
118
|
-
//#endregion
|
|
119
|
-
export { Fragment, elementDraft, jsx, jsxs, normalizeChildren };
|
|
120
|
-
|
|
121
|
-
//# sourceMappingURL=jsx-runtime.js.map
|
package/dist/lexer.d.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
//#region src/lexer.d.ts
|
|
2
|
-
declare const TokenKind: {
|
|
3
|
-
readonly EndOfFile: 0;
|
|
4
|
-
/** `<` opening a start tag (text mode). */
|
|
5
|
-
readonly LessThan: 1;
|
|
6
|
-
/** `</` opening a close tag (text mode). */
|
|
7
|
-
readonly LessThanSlash: 2;
|
|
8
|
-
readonly GreaterThan: 3;
|
|
9
|
-
readonly SlashGreaterThan: 4;
|
|
10
|
-
readonly Identifier: 5;
|
|
11
|
-
readonly Equals: 6;
|
|
12
|
-
/** Quoted attribute value; getStringValue decodes entities. */
|
|
13
|
-
readonly String: 7;
|
|
14
|
-
readonly OpenBrace: 8;
|
|
15
|
-
readonly CloseBrace: 9;
|
|
16
|
-
/** Unsigned integer inside a brace attribute value. */
|
|
17
|
-
readonly Number: 10;
|
|
18
|
-
/** Raw text run; getTextValue decodes entities. */
|
|
19
|
-
readonly Text: 11;
|
|
20
|
-
/** `{{name}}` or `${name}`; name/syntax carried on the token. */
|
|
21
|
-
readonly Interpolation: 12;
|
|
22
|
-
/** Lexically invalid input; error carried on the token. */
|
|
23
|
-
readonly Unknown: 13;
|
|
24
|
-
};
|
|
25
|
-
type TokenKind = (typeof TokenKind)[keyof typeof TokenKind];
|
|
26
|
-
interface TokenError {
|
|
27
|
-
readonly code: string;
|
|
28
|
-
readonly message: string;
|
|
29
|
-
}
|
|
30
|
-
interface Token {
|
|
31
|
-
readonly kind: TokenKind;
|
|
32
|
-
readonly start: number;
|
|
33
|
-
readonly end: number;
|
|
34
|
-
/** Interpolation only. */
|
|
35
|
-
readonly name?: string | undefined;
|
|
36
|
-
/** Interpolation only. */
|
|
37
|
-
readonly syntax?: "curly" | "dollar" | undefined;
|
|
38
|
-
/** Unknown only. */
|
|
39
|
-
readonly error?: TokenError | undefined;
|
|
40
|
-
}
|
|
41
|
-
/** Decodes entities in text that already passed `scanEntity` validation. */
|
|
42
|
-
declare const decodeEntities: (raw: string) => string;
|
|
43
|
-
interface Lexer {
|
|
44
|
-
/** Current scan position (start of the next token). */
|
|
45
|
-
readonly position: () => number;
|
|
46
|
-
/** Scan one token in text mode (between tags). */
|
|
47
|
-
readonly scanTextToken: () => Token;
|
|
48
|
-
/** Scan one token in tag mode (inside `<...>`), skipping whitespace. */
|
|
49
|
-
readonly scanTagToken: () => Token;
|
|
50
|
-
/** Lazy raw source slice for a token. */
|
|
51
|
-
readonly getText: (token: Token) => string;
|
|
52
|
-
/** Entity-decoded value of a Text token. */
|
|
53
|
-
readonly getTextValue: (token: Token) => string;
|
|
54
|
-
/** Entity-decoded contents of a String token (without quotes). */
|
|
55
|
-
readonly getStringValue: (token: Token) => string;
|
|
56
|
-
}
|
|
57
|
-
declare const createLexer: (source: string) => Lexer;
|
|
58
|
-
//#endregion
|
|
59
|
-
export { Lexer, Token, TokenError, TokenKind, createLexer, decodeEntities };
|
|
60
|
-
//# sourceMappingURL=lexer.d.ts.map
|