@samva/markup 0.4.0 → 0.5.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 +17 -0
- package/dist/{ast-63I-VLQx.d.ts → ast-BLybiDxp.d.ts} +34 -60
- package/dist/ast.d.ts +2 -2
- package/dist/ast.js +4 -52
- package/dist/{catalog-Ck1tAGwO.d.ts → catalog-Db0UcCTg.d.ts} +2 -2
- package/dist/{checks-DXuERO4B.js → checks-CmmITP6j.js} +14 -14
- package/dist/checks.d.ts +1 -1
- package/dist/checks.js +1 -1
- package/dist/classes.d.ts +1 -1
- package/dist/compile-sms.d.ts +3 -3
- package/dist/compile-whatsapp.d.ts +5 -5
- package/dist/compile-whatsapp.js +3 -3
- package/dist/compile.d.ts +5 -5
- package/dist/compile.js +5 -5
- package/dist/compiler.d.ts +4 -4
- package/dist/compiler.js +6 -6
- package/dist/components.d.ts +4 -4
- package/dist/conditionals.js +3 -3
- package/dist/corpus-CM7rKX41.d.ts +106 -0
- package/dist/{css-ar2lU3NC.d.ts → css-DoNc7CiC.d.ts} +4 -5
- package/dist/diagnostics-CqepLcpI.d.ts +47 -0
- package/dist/diagnostics-eFM9A_TU.d.ts +46 -0
- package/dist/diagnostics.d.ts +2 -2
- package/dist/diagnostics.js +15 -29
- package/dist/{elements-DtwKlFVH.d.ts → elements-ChJULZlh.d.ts} +40 -161
- package/dist/email/components.d.ts +1 -1
- package/dist/email/diagnostics.d.ts +1 -1
- package/dist/email/diagnostics.js +8 -43
- package/dist/email/elements.d.ts +1 -1
- package/dist/email/html.d.ts +2 -2
- package/dist/email/html.js +9 -9
- package/dist/email/jsx-dev-runtime.d.ts +3 -21
- package/dist/email/jsx-runtime.d.ts +1 -1
- package/dist/email/jsx-runtime.js +29 -3
- package/dist/email/render.d.ts +4 -4
- package/dist/email/render.js +1 -1
- package/dist/email/selection.d.ts +20 -31
- package/dist/email/selection.js +1 -53
- package/dist/email/source-edit.d.ts +1 -1
- package/dist/email/source-edit.js +2 -2
- package/dist/email/stylesheets.d.ts +1 -1
- package/dist/email/text.d.ts +1 -1
- package/dist/email/text.js +3 -3
- package/dist/emit.d.ts +2 -2
- package/dist/emit.js +5 -5
- package/dist/guards-eV1qLbf2.js +9 -0
- package/dist/{input-schema-BIfzI63B.d.ts → input-schema-7dPFVvNE.d.ts} +2 -2
- package/dist/input-schema-zjkgrXn2.js +455 -0
- package/dist/input-schema.d.ts +1 -1
- package/dist/input-schema.js +1 -169
- package/dist/interpolate.d.ts +9 -12
- package/dist/interpolate.js +1 -19
- package/dist/jsx-dev-runtime.d.ts +2 -2
- package/dist/{jsx-runtime-C5k_Zq0A.d.ts → jsx-runtime-BI4gI19E.d.ts} +3 -3
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/jsx-runtime.js +3 -3
- package/dist/model.d.ts +18 -33
- package/dist/model.js +4 -17
- package/dist/ops.d.ts +78 -172
- package/dist/ops.js +51 -117
- package/dist/{parser-CGBS73Gz.d.ts → parser-b_Kp5MT6.d.ts} +5 -5
- package/dist/parser.d.ts +1 -1
- package/dist/parser.js +8 -8
- package/dist/{predicate-G2SeSvoN.d.ts → predicate-Bmvgw7Ao.d.ts} +4 -4
- package/dist/{predicate-CvkzT-a2.js → predicate-DwXzmqIY.js} +11 -11
- package/dist/predicate.d.ts +1 -1
- package/dist/predicate.js +1 -1
- package/dist/presets/category-mapping.d.ts +1 -1
- package/dist/presets/corpus.d.ts +1 -1
- package/dist/presets/corpus.js +74 -117
- package/dist/presets/public-gallery.d.ts +2 -2
- package/dist/presets/public-gallery.js +7 -7
- package/dist/presets/public-handoff.d.ts +4 -4
- package/dist/presets/public-handoff.js +10 -9
- package/dist/presets/public-preview-artifacts.d.ts +5 -5
- package/dist/presets/public-preview-artifacts.js +9 -9
- package/dist/presets/showcase.d.ts +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/printer.d.ts +1 -1
- package/dist/{render-ykQhtMs_.js → render-T6IFPnP4.js} +12 -12
- package/dist/render-template.d.ts +7 -7
- package/dist/render-template.js +6 -6
- package/dist/{showcase-C_xgl6hz.d.ts → showcase-dvJMn-Lo.d.ts} +2 -2
- package/dist/{source-locations-BCJQnIfU.d.ts → source-locations-D6Te6Gy1.d.ts} +4 -26
- package/dist/source-locations.d.ts +2 -2
- package/dist/source-locations.js +3 -26
- package/dist/{template-Dy5yOPyp.d.ts → template-G-QPcfmn.d.ts} +4 -4
- package/dist/template.d.ts +1 -1
- package/dist/template.js +3 -3
- package/dist/theme-css.d.ts +3 -3
- package/dist/theme-css.js +3 -3
- package/dist/tsx-source-instrumentation.d.ts +1 -3
- package/dist/tsx-source-instrumentation.js +6 -6
- package/dist/tsx-tracer.d.ts +7 -11
- package/dist/tsx-tracer.js +164 -164
- package/dist/{variables-if1VrV34.d.ts → variables-BnKs1iqb.d.ts} +2 -2
- package/dist/variables.d.ts +1 -1
- package/dist/variables.js +4 -4
- package/package.json +4 -3
- package/dist/corpus-U2EeALvS.d.ts +0 -234
- package/dist/diagnostics-Djd9ckLg.d.ts +0 -90
- package/dist/diagnostics-oveE-laV.d.ts +0 -79
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { n as OwnedShowcaseId, t as BrandRecreationShowcaseId } from "./showcase-dvJMn-Lo.js";
|
|
2
|
+
import { Result } from "better-result";
|
|
3
|
+
//#region presets/corpus.d.ts
|
|
4
|
+
type TemplateCorpusKind = "owned-editable-sml" | "brand-recreation-sml" | "inspiration-reference";
|
|
5
|
+
declare const templateFacetOptions: {
|
|
6
|
+
readonly jobType: readonly ["account-access", "commerce", "product-communication", "lifecycle", "publishing-campaigns"];
|
|
7
|
+
readonly lifecycle: readonly ["acquisition", "activation", "engagement", "transaction", "retention", "recovery"];
|
|
8
|
+
readonly industry: readonly ["saas", "ecommerce", "developer-tools", "newsletters-media"];
|
|
9
|
+
readonly season: readonly ["evergreen", "seasonal"];
|
|
10
|
+
readonly audience: readonly ["product-users", "customers", "members", "readers", "shoppers", "teams"];
|
|
11
|
+
readonly design: readonly ["minimal", "branded", "editorial", "data-heavy", "single-cta"];
|
|
12
|
+
readonly brandProvenance: readonly ["samva-original", "third-party-reference"];
|
|
13
|
+
};
|
|
14
|
+
/** Every facet dimension, with the closed value list each accepts. */
|
|
15
|
+
type TemplateFacetSet = { readonly [Dimension in keyof typeof templateFacetOptions]: ReadonlyArray<(typeof templateFacetOptions)[Dimension][number]>; };
|
|
16
|
+
interface CorpusReview {
|
|
17
|
+
readonly state: "draft" | "approved" | "rejected";
|
|
18
|
+
readonly reviewedBy: string;
|
|
19
|
+
readonly reviewedAt: string;
|
|
20
|
+
readonly notes: string;
|
|
21
|
+
}
|
|
22
|
+
interface CorpusDisplay {
|
|
23
|
+
readonly state: "hidden" | "public";
|
|
24
|
+
readonly attributionLabel: string;
|
|
25
|
+
}
|
|
26
|
+
interface CorpusRetention {
|
|
27
|
+
readonly policy: "retain-until-withdrawn" | "retain-while-linked";
|
|
28
|
+
readonly reviewedAt: string;
|
|
29
|
+
}
|
|
30
|
+
interface CorpusTakedown {
|
|
31
|
+
readonly state: "active" | "removed";
|
|
32
|
+
readonly contact: string;
|
|
33
|
+
readonly procedureUrl: string;
|
|
34
|
+
}
|
|
35
|
+
interface OwnedEditablePreset {
|
|
36
|
+
readonly type: "OwnedEditablePreset";
|
|
37
|
+
readonly corpusKind: "owned-editable-sml";
|
|
38
|
+
readonly provenance: {
|
|
39
|
+
readonly owner: "Samva";
|
|
40
|
+
readonly sourcePath: string;
|
|
41
|
+
readonly recordedAt: string;
|
|
42
|
+
};
|
|
43
|
+
readonly review: CorpusReview;
|
|
44
|
+
readonly display: CorpusDisplay;
|
|
45
|
+
readonly retention: CorpusRetention;
|
|
46
|
+
readonly takedown: CorpusTakedown;
|
|
47
|
+
}
|
|
48
|
+
interface BrandRecreationPreset {
|
|
49
|
+
readonly type: "BrandRecreationPreset";
|
|
50
|
+
readonly corpusKind: "brand-recreation-sml";
|
|
51
|
+
readonly provenance: {
|
|
52
|
+
readonly owner: "Samva";
|
|
53
|
+
readonly sourcePath: string;
|
|
54
|
+
readonly recordedAt: string;
|
|
55
|
+
/** The brand whose own email is recreated, named on every public surface. */
|
|
56
|
+
readonly brand: string;
|
|
57
|
+
/** What that brand's email does, in the customer's words. */
|
|
58
|
+
readonly subject: string;
|
|
59
|
+
readonly reviewedNote: string;
|
|
60
|
+
};
|
|
61
|
+
readonly review: CorpusReview;
|
|
62
|
+
readonly display: CorpusDisplay;
|
|
63
|
+
readonly retention: CorpusRetention;
|
|
64
|
+
readonly takedown: CorpusTakedown;
|
|
65
|
+
}
|
|
66
|
+
/** Clean-room recreations of a named brand's own email, authored as editable Samva projects. */
|
|
67
|
+
declare const brandRecreationProvenance: Record<BrandRecreationShowcaseId, BrandRecreationPreset["provenance"]>;
|
|
68
|
+
/**
|
|
69
|
+
* Owned presets authored as complete showcase projects with their own stylesheet and assets.
|
|
70
|
+
* Every other owned preset is the single module `packages/markup/presets/<id>.tsx`.
|
|
71
|
+
*/
|
|
72
|
+
declare const ownedShowcasePresetSources: Record<OwnedShowcaseId, string>;
|
|
73
|
+
declare const ownedPresetSourcePath: (id: string) => string;
|
|
74
|
+
interface InspirationReference {
|
|
75
|
+
readonly type: "InspirationReference";
|
|
76
|
+
readonly corpusKind: "inspiration-reference";
|
|
77
|
+
readonly provenance: {
|
|
78
|
+
readonly publisher: string;
|
|
79
|
+
readonly sourceUrl: string;
|
|
80
|
+
readonly capturedAt: string;
|
|
81
|
+
readonly rightsBasis: "display-link-and-commentary" | "permission";
|
|
82
|
+
};
|
|
83
|
+
readonly review: CorpusReview;
|
|
84
|
+
readonly display: CorpusDisplay;
|
|
85
|
+
readonly retention: CorpusRetention;
|
|
86
|
+
readonly takedown: CorpusTakedown;
|
|
87
|
+
}
|
|
88
|
+
type TemplateCorpusRecord = OwnedEditablePreset | BrandRecreationPreset | InspirationReference;
|
|
89
|
+
interface PublicCorpusRegistration {
|
|
90
|
+
readonly id: string;
|
|
91
|
+
readonly corpus: TemplateCorpusRecord;
|
|
92
|
+
readonly facets: TemplateFacetSet;
|
|
93
|
+
}
|
|
94
|
+
interface PublicCorpusRegistrationIssue {
|
|
95
|
+
readonly id: string;
|
|
96
|
+
readonly message: string;
|
|
97
|
+
}
|
|
98
|
+
/** Decode and gate a record before it can enter any public projection. */
|
|
99
|
+
declare const registerPublicCorpusEntry: (input: unknown) => Result<PublicCorpusRegistration, PublicCorpusRegistrationIssue>;
|
|
100
|
+
/** A facet selection: any dimension may be left unselected. */
|
|
101
|
+
type TemplateFacetQuery = Partial<TemplateFacetSet>;
|
|
102
|
+
/** Strict intersection: every selected value in every selected dimension must match. */
|
|
103
|
+
declare const matchesTemplateFacets: (facets: TemplateFacetSet, query: TemplateFacetQuery) => boolean;
|
|
104
|
+
//#endregion
|
|
105
|
+
export { PublicCorpusRegistrationIssue as a, TemplateFacetQuery as c, matchesTemplateFacets as d, ownedPresetSourcePath as f, templateFacetOptions as h, PublicCorpusRegistration as i, TemplateFacetSet as l, registerPublicCorpusEntry as m, InspirationReference as n, TemplateCorpusKind as o, ownedShowcasePresetSources as p, OwnedEditablePreset as r, TemplateCorpusRecord as s, BrandRecreationPreset as t, brandRecreationProvenance as u };
|
|
106
|
+
//# sourceMappingURL=corpus-CM7rKX41.d.ts.map
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import {
|
|
3
|
-
import { m as EmailNode } from "./elements-DtwKlFVH.js";
|
|
1
|
+
import { r as EmailDiagnostic } from "./diagnostics-eFM9A_TU.js";
|
|
2
|
+
import { m as EmailNode } from "./elements-ChJULZlh.js";
|
|
4
3
|
import "css-tree";
|
|
5
4
|
//#region src/email/selectors.d.ts
|
|
6
5
|
type EmailElementNode = Extract<EmailNode, {
|
|
7
|
-
|
|
6
|
+
type: "Element";
|
|
8
7
|
}>;
|
|
9
8
|
interface AttributeTest {
|
|
10
9
|
readonly name: string;
|
|
@@ -81,4 +80,4 @@ declare const parseStylesheet: (source: string, options?: {
|
|
|
81
80
|
}) => Stylesheet;
|
|
82
81
|
//#endregion
|
|
83
82
|
export { compileSelector as a, CompiledSelector as c, matchesSelector as d, Stylesheet as i, Compound as l, CssRule as n, parseStylesheet as o, Specificity as r, Ancestry as s, CssDeclaration as t, classListOf as u };
|
|
84
|
-
//# sourceMappingURL=css-
|
|
83
|
+
//# sourceMappingURL=css-DoNc7CiC.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
//#region src/diagnostics.d.ts
|
|
2
|
+
interface Span {
|
|
3
|
+
readonly start: number;
|
|
4
|
+
readonly end: number;
|
|
5
|
+
}
|
|
6
|
+
interface DiagnosticRepair {
|
|
7
|
+
readonly kind: "replace-class" | "remove-class" | "rewrite-node" | "use-primitive";
|
|
8
|
+
readonly raw?: string | undefined;
|
|
9
|
+
readonly suggestions: ReadonlyArray<string>;
|
|
10
|
+
readonly explanation: string;
|
|
11
|
+
}
|
|
12
|
+
interface Diagnostic {
|
|
13
|
+
readonly code: string;
|
|
14
|
+
readonly message: string;
|
|
15
|
+
readonly span: Span;
|
|
16
|
+
readonly repair?: DiagnosticRepair | undefined;
|
|
17
|
+
}
|
|
18
|
+
declare const SmlParseError_base: import("better-result").TaggedErrorClass<"SmlParseError">;
|
|
19
|
+
declare class SmlParseError extends SmlParseError_base<{
|
|
20
|
+
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
21
|
+
readonly message: string;
|
|
22
|
+
}> {
|
|
23
|
+
constructor(args: {
|
|
24
|
+
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
declare const SmlCompileError_base: import("better-result").TaggedErrorClass<"SmlCompileError">;
|
|
28
|
+
declare class SmlCompileError extends SmlCompileError_base<{
|
|
29
|
+
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
30
|
+
readonly message: string;
|
|
31
|
+
}> {
|
|
32
|
+
constructor(args: {
|
|
33
|
+
readonly diagnostics: ReadonlyArray<Diagnostic>;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/** Newline-offset line map. Build once per source, query with `lineColumn`. */
|
|
37
|
+
declare const buildLineMap: (source: string) => ReadonlyArray<number>;
|
|
38
|
+
/** 1-based line/column for an absolute offset, via binary search. */
|
|
39
|
+
declare const lineColumn: (lineMap: ReadonlyArray<number>, offset: number) => {
|
|
40
|
+
readonly line: number;
|
|
41
|
+
readonly column: number;
|
|
42
|
+
};
|
|
43
|
+
/** "line 12:8 unknown class ..." — the shape agents iterate on. */
|
|
44
|
+
declare const formatDiagnostic: (source: string, diagnostic: Diagnostic) => string;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { Span as a, lineColumn as c, SmlParseError as i, DiagnosticRepair as n, buildLineMap as o, SmlCompileError as r, formatDiagnostic as s, Diagnostic as t };
|
|
47
|
+
//# sourceMappingURL=diagnostics-CqepLcpI.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { i as JsxSourceLocation } from "./source-locations-D6Te6Gy1.js";
|
|
2
|
+
//#region src/email/diagnostics.d.ts
|
|
3
|
+
type EmailDiagnosticSeverity = "error" | "warning" | "info";
|
|
4
|
+
/** What the emitted document establishes beyond the client feature matrix. */
|
|
5
|
+
interface EmailCompatibilityAssessment {
|
|
6
|
+
readonly assessment: "risk" | "degradation" | "unverified" | "not-applicable";
|
|
7
|
+
/** A short description of the consequence or the remaining verification. */
|
|
8
|
+
readonly title: string;
|
|
9
|
+
}
|
|
10
|
+
interface EmailDiagnostic {
|
|
11
|
+
/** Stable identifier, e.g. `unsupported-element` or `caniemail/css-border-radius`. */
|
|
12
|
+
readonly code: string;
|
|
13
|
+
readonly severity: EmailDiagnosticSeverity;
|
|
14
|
+
/** States what is wrong and what to write instead. */
|
|
15
|
+
readonly message: string;
|
|
16
|
+
/** Innermost authoring element first, then each enclosing component call site. */
|
|
17
|
+
readonly origins: ReadonlyArray<JsxSourceLocation>;
|
|
18
|
+
/** Target clients a compatibility finding applies to. */
|
|
19
|
+
readonly clients?: ReadonlyArray<string> | undefined;
|
|
20
|
+
/** Partial-support notes and other caveats a client matrix carries. */
|
|
21
|
+
readonly notes?: string | undefined;
|
|
22
|
+
/** Which pinned rule data produced the finding. */
|
|
23
|
+
readonly provenance?: string | undefined;
|
|
24
|
+
/** Declared fixtures whose rendered output produced this finding. */
|
|
25
|
+
readonly fixtures?: ReadonlyArray<string> | undefined;
|
|
26
|
+
/** Source chains for every located emitted occurrence; origins identifies the first. */
|
|
27
|
+
readonly occurrences?: ReadonlyArray<ReadonlyArray<JsxSourceLocation>> | undefined;
|
|
28
|
+
/** Compatibility observations are not automatically defects or proof of client rendering. */
|
|
29
|
+
readonly compatibility?: EmailCompatibilityAssessment | undefined;
|
|
30
|
+
}
|
|
31
|
+
declare const EmailCompileError_base: import("better-result").TaggedErrorClass<"EmailCompileError">;
|
|
32
|
+
declare class EmailCompileError extends EmailCompileError_base<{
|
|
33
|
+
readonly diagnostics: ReadonlyArray<EmailDiagnostic>;
|
|
34
|
+
readonly message: string;
|
|
35
|
+
}> {
|
|
36
|
+
constructor(args: {
|
|
37
|
+
readonly diagnostics: ReadonlyArray<EmailDiagnostic>;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** `emails/welcome.tsx:12:3 unsupported-element: …` — the shape agents iterate on. */
|
|
41
|
+
declare const formatEmailDiagnostic: (diagnostic: EmailDiagnostic) => string;
|
|
42
|
+
/** True when a set of findings must stop the compile or refuse a publication. */
|
|
43
|
+
declare const hasBlockingDiagnostic: (diagnostics: readonly EmailDiagnostic[]) => boolean;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { formatEmailDiagnostic as a, EmailDiagnosticSeverity as i, EmailCompileError as n, hasBlockingDiagnostic as o, EmailDiagnostic as r, EmailCompatibilityAssessment as t };
|
|
46
|
+
//# sourceMappingURL=diagnostics-eFM9A_TU.d.ts.map
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { Diagnostic, DiagnosticRepair,
|
|
1
|
+
import { a as Span, c as lineColumn, i as SmlParseError, n as DiagnosticRepair, o as buildLineMap, r as SmlCompileError, s as formatDiagnostic, t as Diagnostic } from "./diagnostics-CqepLcpI.js";
|
|
2
|
+
export { Diagnostic, DiagnosticRepair, SmlCompileError, SmlParseError, Span, buildLineMap, formatDiagnostic, lineColumn };
|
package/dist/diagnostics.js
CHANGED
|
@@ -1,34 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TaggedError } from "better-result";
|
|
2
2
|
//#region src/diagnostics.ts
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"remove-class",
|
|
11
|
-
"rewrite-node",
|
|
12
|
-
"use-primitive"
|
|
13
|
-
]),
|
|
14
|
-
raw: Schema.optional(Schema.String),
|
|
15
|
-
suggestions: Schema.Array(Schema.String),
|
|
16
|
-
explanation: Schema.String
|
|
17
|
-
});
|
|
18
|
-
const DiagnosticSchema = Schema.Struct({
|
|
19
|
-
code: Schema.String,
|
|
20
|
-
message: Schema.String,
|
|
21
|
-
span: SpanSchema,
|
|
22
|
-
repair: Schema.optional(DiagnosticRepairSchema)
|
|
23
|
-
});
|
|
24
|
-
var SmlParseError = class extends Schema.TaggedError()("SmlParseError", { diagnostics: Schema.Array(DiagnosticSchema) }) {
|
|
25
|
-
get message() {
|
|
26
|
-
return this.diagnostics.map((diagnostic) => diagnostic.message).join("\n");
|
|
3
|
+
const diagnosticsMessage = (diagnostics) => diagnostics.map((diagnostic) => diagnostic.message).join("\n");
|
|
4
|
+
var SmlParseError = class extends TaggedError("SmlParseError") {
|
|
5
|
+
constructor(args) {
|
|
6
|
+
super({
|
|
7
|
+
diagnostics: args.diagnostics,
|
|
8
|
+
message: diagnosticsMessage(args.diagnostics)
|
|
9
|
+
});
|
|
27
10
|
}
|
|
28
11
|
};
|
|
29
|
-
var SmlCompileError = class extends
|
|
30
|
-
|
|
31
|
-
|
|
12
|
+
var SmlCompileError = class extends TaggedError("SmlCompileError") {
|
|
13
|
+
constructor(args) {
|
|
14
|
+
super({
|
|
15
|
+
diagnostics: args.diagnostics,
|
|
16
|
+
message: diagnosticsMessage(args.diagnostics)
|
|
17
|
+
});
|
|
32
18
|
}
|
|
33
19
|
};
|
|
34
20
|
/** Newline-offset line map. Build once per source, query with `lineColumn`. */
|
|
@@ -60,6 +46,6 @@ const formatDiagnostic = (source, diagnostic) => {
|
|
|
60
46
|
return `line ${line}:${column} ${diagnostic.message}`;
|
|
61
47
|
};
|
|
62
48
|
//#endregion
|
|
63
|
-
export {
|
|
49
|
+
export { SmlCompileError, SmlParseError, buildLineMap, formatDiagnostic, lineColumn };
|
|
64
50
|
|
|
65
51
|
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -1,169 +1,48 @@
|
|
|
1
|
-
import { i as JsxSourceLocation } from "./source-locations-
|
|
2
|
-
import { r as EmailDiagnostic } from "./diagnostics-
|
|
3
|
-
import { Data } from "effect";
|
|
1
|
+
import { i as JsxSourceLocation } from "./source-locations-D6Te6Gy1.js";
|
|
2
|
+
import { r as EmailDiagnostic } from "./diagnostics-eFM9A_TU.js";
|
|
4
3
|
//#region src/email/jsx-runtime.d.ts
|
|
5
4
|
/** Derived authoring tree; source stays canonical. Origins run from inner element to component call sites. */
|
|
6
|
-
type EmailNode =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* True when this element is written at `origins[0]`; false when a compiler
|
|
17
|
-
* primitive generated it and `origins[0]` is the call site that asked for
|
|
18
|
-
* it. Both point at the same authoring target, but only an authored element
|
|
19
|
-
* can have its own props edited there.
|
|
20
|
-
*/
|
|
21
|
-
readonly authored: boolean;
|
|
22
|
-
};
|
|
23
|
-
Fragment: {
|
|
24
|
-
readonly children: readonly EmailNode[];
|
|
25
|
-
};
|
|
5
|
+
type EmailNode = {
|
|
6
|
+
readonly type: "Text";
|
|
7
|
+
readonly value: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly type: "Element";
|
|
10
|
+
readonly tag: string;
|
|
11
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
12
|
+
readonly children: readonly EmailNode[];
|
|
13
|
+
readonly origins: readonly JsxSourceLocation[];
|
|
26
14
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
15
|
+
* True when this element is written at `origins[0]`; false when a compiler
|
|
16
|
+
* primitive generated it and `origins[0]` is the call site that asked for
|
|
17
|
+
* it. Both point at the same authoring target, but only an authored element
|
|
18
|
+
* can have its own props edited there.
|
|
30
19
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
20
|
+
readonly authored: boolean;
|
|
21
|
+
} | {
|
|
22
|
+
readonly type: "Fragment";
|
|
23
|
+
readonly children: readonly EmailNode[];
|
|
24
|
+
} |
|
|
25
|
+
/**
|
|
26
|
+
* Compatibility markup a compiler primitive emits verbatim — conditional
|
|
27
|
+
* comments and VML. Only the primitives in `./components` construct it;
|
|
28
|
+
* nothing an author passes as a string reaches this node.
|
|
29
|
+
*/
|
|
30
|
+
{
|
|
31
|
+
readonly type: "Raw";
|
|
32
|
+
readonly html: string;
|
|
33
|
+
readonly text: string;
|
|
34
|
+
readonly origins: readonly JsxSourceLocation[];
|
|
35
|
+
};
|
|
36
|
+
type EmailNodeOf<Type extends EmailNode["type"]> = Extract<EmailNode, {
|
|
37
|
+
readonly type: Type;
|
|
36
38
|
}>;
|
|
39
|
+
type EmailNodeFields<Type extends EmailNode["type"]> = Omit<EmailNodeOf<Type>, "type">;
|
|
40
|
+
/** Constructors for the authoring tree. The tree is data; nothing here validates it. */
|
|
37
41
|
declare const EmailNode: {
|
|
38
|
-
readonly
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
readonly children: readonly EmailNode[];
|
|
43
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
44
|
-
readonly authored: boolean;
|
|
45
|
-
}, {
|
|
46
|
-
readonly _tag: Tag;
|
|
47
|
-
}> | Extract<{
|
|
48
|
-
readonly _tag: "Fragment";
|
|
49
|
-
readonly children: readonly EmailNode[];
|
|
50
|
-
}, {
|
|
51
|
-
readonly _tag: Tag;
|
|
52
|
-
}> | Extract<{
|
|
53
|
-
readonly _tag: "Raw";
|
|
54
|
-
readonly html: string;
|
|
55
|
-
readonly text: string;
|
|
56
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
57
|
-
}, {
|
|
58
|
-
readonly _tag: Tag;
|
|
59
|
-
}> | Extract<{
|
|
60
|
-
readonly _tag: "Text";
|
|
61
|
-
readonly value: string;
|
|
62
|
-
}, {
|
|
63
|
-
readonly _tag: Tag;
|
|
64
|
-
}>;
|
|
65
|
-
readonly $match: {
|
|
66
|
-
<Cases extends { readonly [Tag in "Element" | "Fragment" | "Raw" | "Text"]: (args: Extract<{
|
|
67
|
-
readonly _tag: "Element";
|
|
68
|
-
readonly tag: string;
|
|
69
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
70
|
-
readonly children: readonly EmailNode[];
|
|
71
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
72
|
-
readonly authored: boolean;
|
|
73
|
-
} | {
|
|
74
|
-
readonly _tag: "Fragment";
|
|
75
|
-
readonly children: readonly EmailNode[];
|
|
76
|
-
} | {
|
|
77
|
-
readonly _tag: "Raw";
|
|
78
|
-
readonly html: string;
|
|
79
|
-
readonly text: string;
|
|
80
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
81
|
-
} | {
|
|
82
|
-
readonly _tag: "Text";
|
|
83
|
-
readonly value: string;
|
|
84
|
-
}, {
|
|
85
|
-
readonly _tag: Tag;
|
|
86
|
-
}>) => any; }>(cases: Cases): (value: {
|
|
87
|
-
readonly _tag: "Element";
|
|
88
|
-
readonly tag: string;
|
|
89
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
90
|
-
readonly children: readonly EmailNode[];
|
|
91
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
92
|
-
readonly authored: boolean;
|
|
93
|
-
} | {
|
|
94
|
-
readonly _tag: "Fragment";
|
|
95
|
-
readonly children: readonly EmailNode[];
|
|
96
|
-
} | {
|
|
97
|
-
readonly _tag: "Raw";
|
|
98
|
-
readonly html: string;
|
|
99
|
-
readonly text: string;
|
|
100
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
101
|
-
} | {
|
|
102
|
-
readonly _tag: "Text";
|
|
103
|
-
readonly value: string;
|
|
104
|
-
}) => import("effect/Unify").Unify<ReturnType<Cases["Element" | "Fragment" | "Raw" | "Text"]>>;
|
|
105
|
-
<Cases extends { readonly [Tag in "Element" | "Fragment" | "Raw" | "Text"]: (args: Extract<{
|
|
106
|
-
readonly _tag: "Element";
|
|
107
|
-
readonly tag: string;
|
|
108
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
109
|
-
readonly children: readonly EmailNode[];
|
|
110
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
111
|
-
readonly authored: boolean;
|
|
112
|
-
} | {
|
|
113
|
-
readonly _tag: "Fragment";
|
|
114
|
-
readonly children: readonly EmailNode[];
|
|
115
|
-
} | {
|
|
116
|
-
readonly _tag: "Raw";
|
|
117
|
-
readonly html: string;
|
|
118
|
-
readonly text: string;
|
|
119
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
120
|
-
} | {
|
|
121
|
-
readonly _tag: "Text";
|
|
122
|
-
readonly value: string;
|
|
123
|
-
}, {
|
|
124
|
-
readonly _tag: Tag;
|
|
125
|
-
}>) => any; }>(value: {
|
|
126
|
-
readonly _tag: "Element";
|
|
127
|
-
readonly tag: string;
|
|
128
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
129
|
-
readonly children: readonly EmailNode[];
|
|
130
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
131
|
-
readonly authored: boolean;
|
|
132
|
-
} | {
|
|
133
|
-
readonly _tag: "Fragment";
|
|
134
|
-
readonly children: readonly EmailNode[];
|
|
135
|
-
} | {
|
|
136
|
-
readonly _tag: "Raw";
|
|
137
|
-
readonly html: string;
|
|
138
|
-
readonly text: string;
|
|
139
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
140
|
-
} | {
|
|
141
|
-
readonly _tag: "Text";
|
|
142
|
-
readonly value: string;
|
|
143
|
-
}, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["Element" | "Fragment" | "Raw" | "Text"]>>;
|
|
144
|
-
};
|
|
145
|
-
readonly Element: Data.TaggedEnum.ConstructorFrom<{
|
|
146
|
-
readonly _tag: "Element";
|
|
147
|
-
readonly tag: string;
|
|
148
|
-
readonly props: Readonly<Record<string, unknown>>;
|
|
149
|
-
readonly children: readonly EmailNode[];
|
|
150
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
151
|
-
readonly authored: boolean;
|
|
152
|
-
}, "_tag">;
|
|
153
|
-
readonly Fragment: Data.TaggedEnum.ConstructorFrom<{
|
|
154
|
-
readonly _tag: "Fragment";
|
|
155
|
-
readonly children: readonly EmailNode[];
|
|
156
|
-
}, "_tag">;
|
|
157
|
-
readonly Raw: Data.TaggedEnum.ConstructorFrom<{
|
|
158
|
-
readonly _tag: "Raw";
|
|
159
|
-
readonly html: string;
|
|
160
|
-
readonly text: string;
|
|
161
|
-
readonly origins: readonly JsxSourceLocation[];
|
|
162
|
-
}, "_tag">;
|
|
163
|
-
readonly Text: Data.TaggedEnum.ConstructorFrom<{
|
|
164
|
-
readonly _tag: "Text";
|
|
165
|
-
readonly value: string;
|
|
166
|
-
}, "_tag">;
|
|
42
|
+
readonly Text: (fields: EmailNodeFields<"Text">) => EmailNodeOf<"Text">;
|
|
43
|
+
readonly Element: (fields: EmailNodeFields<"Element">) => EmailNodeOf<"Element">;
|
|
44
|
+
readonly Fragment: (fields: EmailNodeFields<"Fragment">) => EmailNodeOf<"Fragment">;
|
|
45
|
+
readonly Raw: (fields: EmailNodeFields<"Raw">) => EmailNodeOf<"Raw">;
|
|
167
46
|
};
|
|
168
47
|
type EmailChild = EmailNode | string | number | boolean | null | undefined | readonly EmailChild[];
|
|
169
48
|
type EmailComponent<P = never> = (props: P) => EmailChild;
|
|
@@ -817,4 +696,4 @@ type ChildrenProp<Content extends EmailElementSpec["content"]> = Content extends
|
|
|
817
696
|
type EmailIntrinsicElements = { readonly [Tag in EmailTag]: EmailGlobalProps & AttributeProps<typeof EMAIL_GLOBAL_ATTRIBUTES> & AttributeProps<(typeof EMAIL_ELEMENTS)[Tag]["attributes"]> & ChildrenProp<(typeof EMAIL_ELEMENTS)[Tag]["content"]>; };
|
|
818
697
|
//#endregion
|
|
819
698
|
export { reportEmailDiagnostic as C, rawMarkup as S, currentEmailOrigins as _, EmailGlobalProps as a, jsxs as b, EmailStyle as c, isUrlAttribute as d, EmailChild as f, JSX as g, Fragment as h, EmailElementSpec as i, EmailTag as l, EmailNode as m, EMAIL_GLOBAL_ATTRIBUTES as n, EmailIntrinsicElements as o, EmailComponent as p, EmailAttributeSpec as r, EmailLayout as s, EMAIL_ELEMENTS as t, emailElement as u, drainEmailDiagnostics as v, normalizeChildren as x, jsx as y };
|
|
820
|
-
//# sourceMappingURL=elements-
|
|
699
|
+
//# sourceMappingURL=elements-ChJULZlh.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as EmailStyle, f as EmailChild, m as EmailNode } from "../elements-
|
|
1
|
+
import { c as EmailStyle, f as EmailChild, m as EmailNode } from "../elements-ChJULZlh.js";
|
|
2
2
|
//#region src/email/components.d.ts
|
|
3
3
|
/** Marks the hidden preview block so the renderer can read it back and the text lane can keep it. */
|
|
4
4
|
declare const PREHEADER_ATTRIBUTE = "data-samva-preheader";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as formatEmailDiagnostic, i as EmailDiagnosticSeverity, n as EmailCompileError, o as hasBlockingDiagnostic, r as EmailDiagnostic, t as EmailCompatibilityAssessment } from "../diagnostics-
|
|
1
|
+
import { a as formatEmailDiagnostic, i as EmailDiagnosticSeverity, n as EmailCompileError, o as hasBlockingDiagnostic, r as EmailDiagnostic, t as EmailCompatibilityAssessment } from "../diagnostics-eFM9A_TU.js";
|
|
2
2
|
export { EmailCompatibilityAssessment, EmailCompileError, EmailDiagnostic, EmailDiagnosticSeverity, formatEmailDiagnostic, hasBlockingDiagnostic };
|
|
@@ -1,46 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Schema } from "effect";
|
|
1
|
+
import { TaggedError } from "better-result";
|
|
3
2
|
//#region src/email/diagnostics.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const EmailCompatibilityAssessment = Schema.Struct({
|
|
11
|
-
assessment: Schema.Literals([
|
|
12
|
-
"risk",
|
|
13
|
-
"degradation",
|
|
14
|
-
"unverified",
|
|
15
|
-
"not-applicable"
|
|
16
|
-
]),
|
|
17
|
-
/** A short description of the consequence or the remaining verification. */
|
|
18
|
-
title: Schema.String
|
|
19
|
-
});
|
|
20
|
-
const EmailDiagnostic = Schema.Struct({
|
|
21
|
-
/** Stable identifier, e.g. `unsupported-element` or `caniemail/css-border-radius`. */
|
|
22
|
-
code: Schema.String,
|
|
23
|
-
severity: EmailDiagnosticSeverity,
|
|
24
|
-
/** States what is wrong and what to write instead. */
|
|
25
|
-
message: Schema.String,
|
|
26
|
-
/** Innermost authoring element first, then each enclosing component call site. */
|
|
27
|
-
origins: Schema.Array(JsxSourceLocation),
|
|
28
|
-
/** Target clients a compatibility finding applies to. */
|
|
29
|
-
clients: Schema.optional(Schema.Array(Schema.String)),
|
|
30
|
-
/** Partial-support notes and other caveats a client matrix carries. */
|
|
31
|
-
notes: Schema.optional(Schema.String),
|
|
32
|
-
/** Which pinned rule data produced the finding. */
|
|
33
|
-
provenance: Schema.optional(Schema.String),
|
|
34
|
-
/** Declared fixtures whose rendered output produced this finding. */
|
|
35
|
-
fixtures: Schema.optional(Schema.Array(Schema.String)),
|
|
36
|
-
/** Source chains for every located emitted occurrence; origins identifies the first. */
|
|
37
|
-
occurrences: Schema.optional(Schema.Array(Schema.Array(JsxSourceLocation))),
|
|
38
|
-
/** Compatibility observations are not automatically defects or proof of client rendering. */
|
|
39
|
-
compatibility: Schema.optional(EmailCompatibilityAssessment)
|
|
40
|
-
});
|
|
41
|
-
var EmailCompileError = class extends Schema.TaggedError()("EmailCompileError", { diagnostics: Schema.Array(EmailDiagnostic) }) {
|
|
42
|
-
get message() {
|
|
43
|
-
return this.diagnostics.map(formatEmailDiagnostic).join("\n");
|
|
3
|
+
var EmailCompileError = class extends TaggedError("EmailCompileError") {
|
|
4
|
+
constructor(args) {
|
|
5
|
+
super({
|
|
6
|
+
diagnostics: args.diagnostics,
|
|
7
|
+
message: args.diagnostics.map(formatEmailDiagnostic).join("\n")
|
|
8
|
+
});
|
|
44
9
|
}
|
|
45
10
|
};
|
|
46
11
|
/** `emails/welcome.tsx:12:3 unsupported-element: …` — the shape agents iterate on. */
|
|
@@ -51,6 +16,6 @@ const formatEmailDiagnostic = (diagnostic) => {
|
|
|
51
16
|
/** True when a set of findings must stop the compile or refuse a publication. */
|
|
52
17
|
const hasBlockingDiagnostic = (diagnostics) => diagnostics.some((diagnostic) => diagnostic.severity === "error");
|
|
53
18
|
//#endregion
|
|
54
|
-
export {
|
|
19
|
+
export { EmailCompileError, formatEmailDiagnostic, hasBlockingDiagnostic };
|
|
55
20
|
|
|
56
21
|
//# sourceMappingURL=diagnostics.js.map
|
package/dist/email/elements.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as EmailGlobalProps, c as EmailStyle, d as isUrlAttribute, i as EmailElementSpec, l as EmailTag, n as EMAIL_GLOBAL_ATTRIBUTES, o as EmailIntrinsicElements, r as EmailAttributeSpec, s as EmailLayout, t as EMAIL_ELEMENTS, u as emailElement } from "../elements-
|
|
1
|
+
import { a as EmailGlobalProps, c as EmailStyle, d as isUrlAttribute, i as EmailElementSpec, l as EmailTag, n as EMAIL_GLOBAL_ATTRIBUTES, o as EmailIntrinsicElements, r as EmailAttributeSpec, s as EmailLayout, t as EMAIL_ELEMENTS, u as emailElement } from "../elements-ChJULZlh.js";
|
|
2
2
|
export { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, EmailAttributeSpec, EmailElementSpec, EmailGlobalProps, EmailIntrinsicElements, EmailLayout, EmailStyle, EmailTag, emailElement, isUrlAttribute };
|
package/dist/email/html.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as EmailDiagnostic } from "../diagnostics-
|
|
2
|
-
import { m as EmailNode } from "../elements-
|
|
1
|
+
import { r as EmailDiagnostic } from "../diagnostics-eFM9A_TU.js";
|
|
2
|
+
import { m as EmailNode } from "../elements-ChJULZlh.js";
|
|
3
3
|
import { EmittedPosition } from "./selection.js";
|
|
4
4
|
//#region src/email/html.d.ts
|
|
5
5
|
/** Escape a value for element content. */
|
package/dist/email/html.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { n as isObject } from "../guards-eV1qLbf2.js";
|
|
1
2
|
import { EMAIL_ELEMENTS, EMAIL_GLOBAL_ATTRIBUTES, emailElement } from "./elements.js";
|
|
2
3
|
import { INSTANCE_PATH_ATTRIBUTE } from "./selection.js";
|
|
3
|
-
import { Predicate } from "effect";
|
|
4
4
|
//#region src/email/html.ts
|
|
5
5
|
/** Escape a value for element content. */
|
|
6
6
|
const escapeText = (value) => value.replace(/[&<>]/g, (character) => ({
|
|
@@ -136,7 +136,7 @@ const attributes = (sink, tag, spec, props, origins) => {
|
|
|
136
136
|
}
|
|
137
137
|
if (name === "style") {
|
|
138
138
|
if (value === void 0 || value === null) continue;
|
|
139
|
-
if (!
|
|
139
|
+
if (!isObject(value) || Array.isArray(value)) {
|
|
140
140
|
report(sink, "invalid-style", `<${tag} style> must be a property object, for example style={{ backgroundColor: "#fff" }}.`, origins);
|
|
141
141
|
continue;
|
|
142
142
|
}
|
|
@@ -172,24 +172,24 @@ const attributes = (sink, tag, spec, props, origins) => {
|
|
|
172
172
|
return emitted.join("");
|
|
173
173
|
};
|
|
174
174
|
/** Fragments are transparent to a content model; raw compatibility markup is not content. */
|
|
175
|
-
const contentChildren = (children) => children.flatMap((child) => child.
|
|
175
|
+
const contentChildren = (children) => children.flatMap((child) => child.type === "Fragment" ? contentChildren(child.children) : [child]);
|
|
176
176
|
const checkContentModel = (sink, tag, spec, children, origins) => {
|
|
177
177
|
if (spec.content === "void") {
|
|
178
178
|
if (contentChildren(children).length > 0) report(sink, "void-element-children", `<${tag}> cannot have children.`, origins);
|
|
179
179
|
return;
|
|
180
180
|
}
|
|
181
181
|
if (spec.content === "text" || spec.content === "raw") {
|
|
182
|
-
for (const child of contentChildren(children)) if (child.
|
|
182
|
+
for (const child of contentChildren(children)) if (child.type !== "Text") report(sink, "invalid-content", `<${tag}> accepts text only.`, child.type === "Element" ? child.origins : origins);
|
|
183
183
|
return;
|
|
184
184
|
}
|
|
185
185
|
if (spec.childElements === void 0) return;
|
|
186
186
|
for (const child of contentChildren(children)) {
|
|
187
|
-
if (child.
|
|
188
|
-
if (child.
|
|
187
|
+
if (child.type === "Raw") continue;
|
|
188
|
+
if (child.type === "Text") {
|
|
189
189
|
if (child.value.trim() !== "") report(sink, "invalid-content", `<${tag}> cannot contain text directly; put it inside <${spec.childElements[0]}>.`, origins);
|
|
190
190
|
continue;
|
|
191
191
|
}
|
|
192
|
-
if (child.
|
|
192
|
+
if (child.type === "Element" && !spec.childElements.includes(child.tag)) report(sink, "invalid-content", `<${tag}> accepts only ${spec.childElements.map((name) => `<${name}>`).join(", ")}; found <${child.tag}>.`, child.origins);
|
|
193
193
|
}
|
|
194
194
|
};
|
|
195
195
|
/** Every write goes through here so `sink.written` stays the emitted offset. */
|
|
@@ -198,7 +198,7 @@ const emit = (sink, text) => {
|
|
|
198
198
|
return text;
|
|
199
199
|
};
|
|
200
200
|
const serialize = (sink, node, parentPath, counter) => {
|
|
201
|
-
switch (node.
|
|
201
|
+
switch (node.type) {
|
|
202
202
|
case "Text": return emit(sink, escapeText(node.value));
|
|
203
203
|
case "Raw": return emit(sink, node.html);
|
|
204
204
|
case "Fragment": return node.children.map((child) => serialize(sink, child, parentPath, counter)).join("");
|
|
@@ -215,7 +215,7 @@ const serialize = (sink, node, parentPath, counter) => {
|
|
|
215
215
|
}
|
|
216
216
|
checkContentModel(sink, node.tag, spec, node.children, node.origins);
|
|
217
217
|
if (spec.content === "raw") {
|
|
218
|
-
const css = node.children.map((child) => child.
|
|
218
|
+
const css = node.children.map((child) => child.type === "Text" ? child.value : "").join("");
|
|
219
219
|
if (/<\/|<!--/i.test(css)) {
|
|
220
220
|
report(sink, "unsafe-raw-text", `<${node.tag}> content cannot contain markup.`, node.origins);
|
|
221
221
|
return "";
|