@samva/vite 0.10.0 → 0.11.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/dist/project.d.ts CHANGED
@@ -1,2 +1,192 @@
1
- import { A as loadBrandEnv, C as renderChannelFixture, D as BrandSnapshot, E as BrandResolution, F as discoverEntries, I as readProjectFiles, L as templateDirectories, M as DEFAULT_TEMPLATE_DIRS, N as ProjectFiles, O as BrandWarning, P as SAMVA_DIR, S as hasErrors, T as BRAND_SNAPSHOT_DIR, _ as TemplateChannel, a as ProjectOptions, b as emailCompatibility, c as exportProject, d as CompileProjectInput, f as CompiledEntry, g as RenderedFixture, h as RenderedChannel, i as ProjectExportReceipt, j as resolveProjectBrand, k as ResolvedBrand, l as loadProject, m as FailedEntry, n as ExportedFixture, o as ProjectSession, p as CompiledProject, r as LoadedProject, s as createProjectSession, t as DEFAULT_EXPORT_ASSET_BASE, u as projectRoot, v as channelsOf, w as renderEmailFixtures, x as finding, y as compileProject } from "./project-CRqjs-wV.js";
2
- export { BRAND_SNAPSHOT_DIR, type BrandResolution, type BrandSnapshot, type BrandWarning, CompileProjectInput, CompiledEntry, CompiledProject, DEFAULT_EXPORT_ASSET_BASE, DEFAULT_TEMPLATE_DIRS, ExportedFixture, FailedEntry, LoadedProject, ProjectExportReceipt, type ProjectFiles, ProjectOptions, ProjectSession, RenderedChannel, RenderedFixture, type ResolvedBrand, SAMVA_DIR, TemplateChannel, channelsOf, compileProject, createProjectSession, discoverEntries, emailCompatibility, exportProject, finding, hasErrors, loadBrandEnv, loadProject, projectRoot, readProjectFiles, renderChannelFixture, renderEmailFixtures, resolveProjectBrand, templateDirectories };
1
+ import { a as DEFAULT_TEMPLATE_DIRS, c as discoverEntries, i as ResolvedBrand, l as readProjectFiles, n as BrandResolver, o as ProjectFiles, r as BrandWarning, s as SAMVA_DIR, t as BrandResolution, u as templateDirectories } from "./brand-BkXQMGgY.js";
2
+ import { RenderOptions, RenderedIrEmail, RenderedIrWhatsApp, TemplateIr } from "@samva/markup/render";
3
+ import { AssetEntry, BrandPlugin } from "@samva/markup/brand";
4
+ import { EmailDiagnostic } from "@samva/markup/diagnostics";
5
+ //#region src/compile.d.ts
6
+ type TemplateChannel = "email" | "sms" | "whatsapp";
7
+ /** The channels a compiled template declares, in a fixed order. */
8
+ declare const channelsOf: (ir: TemplateIr) => readonly TemplateChannel[];
9
+ declare const finding: (code: string, severity: EmailDiagnostic["severity"], message: string, extra?: Partial<EmailDiagnostic>) => EmailDiagnostic;
10
+ /** One entry that declares a template and compiled. */
11
+ interface CompiledEntry {
12
+ /** The identity the definition declares for itself (`ir.template`). */
13
+ readonly id: string;
14
+ /** Project-relative path of the authored entry. */
15
+ readonly entryPath: string;
16
+ readonly ir: TemplateIr;
17
+ readonly fixtures: Readonly<Record<string, unknown>>;
18
+ readonly assets: readonly AssetEntry[];
19
+ /** Compile warnings. Errors leave no IR, so they are on a `FailedEntry` instead. */
20
+ readonly diagnostics: readonly EmailDiagnostic[];
21
+ readonly channels: readonly TemplateChannel[];
22
+ readonly brandPlugin?: BrandPlugin | undefined;
23
+ }
24
+ /** An entry that is a template but did not compile. */
25
+ interface FailedEntry {
26
+ readonly entryPath: string;
27
+ readonly diagnostics: readonly EmailDiagnostic[];
28
+ }
29
+ interface CompiledProject {
30
+ /** Sorted by id. */
31
+ readonly templates: readonly CompiledEntry[];
32
+ /** Entries that declare a template and did not compile, sorted by path. */
33
+ readonly failures: readonly FailedEntry[];
34
+ /** Candidate entries that declare no template: ordinary modules, partials and components. */
35
+ readonly helpers: readonly string[];
36
+ /** Project-level findings: a duplicate id. */
37
+ readonly diagnostics: readonly EmailDiagnostic[];
38
+ /** Every asset the templates import, deduplicated by content. */
39
+ readonly assets: readonly AssetEntry[];
40
+ }
41
+ interface CompileProjectInput {
42
+ readonly files: ProjectFiles;
43
+ /** Candidate entries, project-relative. */
44
+ readonly entries: readonly string[];
45
+ /**
46
+ * Where imported assets are served from. Empty is deliberately invalid for
47
+ * assets: no invented serving origin. A project that imports none needs none.
48
+ */
49
+ readonly assetBase: string;
50
+ readonly theme?: {
51
+ readonly css: string;
52
+ readonly path: string;
53
+ } | undefined;
54
+ readonly brand?: ResolvedBrand | undefined;
55
+ readonly brandPlugin?: BrandPlugin | undefined;
56
+ }
57
+ /**
58
+ * Compile every candidate entry. An entry the compiler reports `no-template`
59
+ * for is a helper module, not a template; that is how a partial is told apart
60
+ * from a template without evaluating either. One failure stays with its entry.
61
+ */
62
+ declare const compileProject: (input: CompileProjectInput) => Promise<CompiledProject>;
63
+ /** One fixture rendered through the email channel of the template it belongs to. */
64
+ interface RenderedFixture {
65
+ readonly templateId: string;
66
+ readonly fixture: string;
67
+ readonly rendered: RenderedIrEmail | undefined;
68
+ readonly diagnostics: readonly EmailDiagnostic[];
69
+ }
70
+ /**
71
+ * Render every fixture a template declares through its email channel. A fixture
72
+ * the renderer refuses is a finding on that fixture, never a thrown error, so
73
+ * one bad input does not take the rest of the catalog with it.
74
+ */
75
+ declare const renderEmailFixtures: (entry: Pick<CompiledEntry, "id" | "ir" | "fixtures" | "brandPlugin">, options?: RenderOptions) => readonly RenderedFixture[];
76
+ /** Client-matrix findings across the fixtures that rendered. */
77
+ declare const emailCompatibility: (entry: Pick<CompiledEntry, "ir" | "fixtures">, rendered: readonly RenderedFixture[]) => readonly EmailDiagnostic[];
78
+ /** A channel's rendered output for one fixture, or the findings that stopped it. */
79
+ type RenderedChannel = {
80
+ readonly ok: true;
81
+ readonly channel: "sms";
82
+ readonly text: string;
83
+ } | {
84
+ readonly ok: true;
85
+ readonly channel: "whatsapp";
86
+ readonly message: RenderedIrWhatsApp;
87
+ } | {
88
+ readonly ok: false;
89
+ readonly diagnostics: readonly EmailDiagnostic[];
90
+ };
91
+ /** Render the SMS or WhatsApp channel of one fixture. */
92
+ declare const renderChannelFixture: (entry: Pick<CompiledEntry, "id" | "ir" | "fixtures" | "brandPlugin">, channel: "sms" | "whatsapp", fixture: string, options?: RenderOptions) => RenderedChannel;
93
+ declare const hasErrors: (diagnostics: readonly EmailDiagnostic[]) => boolean;
94
+ //#endregion
95
+ //#region src/project.d.ts
96
+ interface ProjectOptions {
97
+ /** The project root: `theme.css`, shared imports and `.samva/` live here. Default: the working directory. */
98
+ readonly root?: string | undefined;
99
+ /**
100
+ * The templates directory, relative to `root` (or absolute, inside it). When set, only it is
101
+ * scanned; otherwise `templates/` and `emails/` are, whichever exist.
102
+ */
103
+ readonly dir?: string | undefined;
104
+ /** Host-owned brand resolution. Brand imports fail when no resolver is supplied. */
105
+ readonly brandResolver?: BrandResolver | undefined;
106
+ /** Brand import specifier and footer markers passed to the compiler. */
107
+ readonly brandPlugin?: BrandPlugin | undefined;
108
+ /** Theme stylesheet relative to `root`; `false` compiles with no project theme. Default `theme.css`. */
109
+ readonly theme?: string | false | undefined;
110
+ /**
111
+ * Where imported assets are served from. A template that imports none needs none; an import
112
+ * with no base is a finding.
113
+ */
114
+ readonly assetBase?: string | undefined;
115
+ }
116
+ /** A project compiled: its catalog, and the findings about the project as a whole. */
117
+ interface LoadedProject {
118
+ readonly root: string;
119
+ readonly files: ProjectFiles;
120
+ readonly catalog: CompiledProject;
121
+ /** The theme path, project-relative; `undefined` when theming is off or the file is absent. */
122
+ readonly themePath: string | undefined;
123
+ readonly brand: BrandResolution;
124
+ /** Brand findings and project-level findings (a duplicate id). */
125
+ readonly diagnostics: readonly EmailDiagnostic[];
126
+ }
127
+ /** Resolve the root a set of options names. */
128
+ declare const projectRoot: (options: Pick<ProjectOptions, "root">) => string;
129
+ /**
130
+ * Read, resolve the brand of, and compile every template in a project. `only`
131
+ * limits compilation to the named project-relative entries.
132
+ */
133
+ declare const loadProject: (options?: ProjectOptions, only?: readonly string[] | undefined) => Promise<LoadedProject>;
134
+ /** A live project over a directory, reloaded when its source changes. */
135
+ interface ProjectSession {
136
+ readonly load: () => Promise<LoadedProject>;
137
+ readonly current: () => LoadedProject | undefined;
138
+ /** Called with the project-relative path of each changed file; `.samva/` and `node_modules` are ignored. */
139
+ readonly subscribe: (listener: (path: string) => void) => () => void;
140
+ readonly close: () => Promise<void>;
141
+ }
142
+ /**
143
+ * The authoring loop: one watcher, one brand resolver, a catalog reloaded on
144
+ * demand. Each `load` re-reads the project and recompiles every template, so a
145
+ * partial that changed reaches every template that imports it.
146
+ */
147
+ declare const createProjectSession: (options?: ProjectOptions) => ProjectSession;
148
+ interface ExportedFixture {
149
+ readonly fixture: string;
150
+ readonly html?: string | undefined;
151
+ readonly text?: string | undefined;
152
+ readonly sms?: string | undefined;
153
+ readonly whatsapp?: string | undefined;
154
+ }
155
+ interface ProjectExportReceipt {
156
+ readonly templates: readonly {
157
+ readonly id: string;
158
+ readonly entryPath: string;
159
+ readonly fixtures: readonly ExportedFixture[];
160
+ }[];
161
+ readonly assets: {
162
+ readonly base: string;
163
+ readonly assets: readonly AssetEntry[];
164
+ };
165
+ readonly diagnostics: readonly EmailDiagnostic[];
166
+ }
167
+ /**
168
+ * Where an export serves its assets from when the caller names no origin.
169
+ *
170
+ * An export writes one page at `templates/<id>/<fixture>.html` and every asset
171
+ * once at `assets/<content address>`, so the base a page resolves against is
172
+ * the path from its own directory back to that one. A template id is one path
173
+ * segment, so every page sits at the same depth and one base serves them all.
174
+ */
175
+ declare const DEFAULT_EXPORT_ASSET_BASE = "../../assets";
176
+ /**
177
+ * Render every template's fixtures to files beside the bytes of every asset they
178
+ * reference, with the manifest that maps each address to its file. Email
179
+ * fixtures write `<fixture>.html` and `<fixture>.txt`; a template's SMS and
180
+ * WhatsApp channels write `<fixture>.sms.txt` and `<fixture>.whatsapp.json`.
181
+ *
182
+ * A relative `assetBase` is accepted, and the written page resolves its images
183
+ * from the directory it sits in. Delivery keeps refusing relative references,
184
+ * because an inbox has no directory to resolve one against, so an export
185
+ * destined for sending names the https origin it will be served from instead.
186
+ */
187
+ declare const exportProject: (input: ProjectOptions & {
188
+ readonly out: string;
189
+ }) => Promise<ProjectExportReceipt>;
190
+ //#endregion
191
+ export { type BrandResolution, type BrandResolver, type BrandWarning, CompileProjectInput, CompiledEntry, CompiledProject, DEFAULT_EXPORT_ASSET_BASE, DEFAULT_TEMPLATE_DIRS, ExportedFixture, FailedEntry, LoadedProject, ProjectExportReceipt, type ProjectFiles, ProjectOptions, ProjectSession, RenderedChannel, RenderedFixture, type ResolvedBrand, SAMVA_DIR, TemplateChannel, channelsOf, compileProject, createProjectSession, discoverEntries, emailCompatibility, exportProject, finding, hasErrors, loadProject, projectRoot, readProjectFiles, renderChannelFixture, renderEmailFixtures, templateDirectories };
192
+ //# sourceMappingURL=project.d.ts.map
package/dist/project.js CHANGED
@@ -1,2 +1,2 @@
1
- import { C as discoverEntries, D as readProjectFiles, O as templateDirectories, S as SAMVA_DIR, a as projectRoot, b as resolveProjectBrand, d as emailCompatibility, f as finding, g as BRAND_SNAPSHOT_DIR, h as renderEmailFixtures, i as loadProject, l as channelsOf, m as renderChannelFixture, n as createProjectSession, p as hasErrors, r as exportProject, t as DEFAULT_EXPORT_ASSET_BASE, u as compileProject, x as DEFAULT_TEMPLATE_DIRS, y as loadBrandEnv } from "./project-Ut6wra0r.js";
2
- export { BRAND_SNAPSHOT_DIR, DEFAULT_EXPORT_ASSET_BASE, DEFAULT_TEMPLATE_DIRS, SAMVA_DIR, channelsOf, compileProject, createProjectSession, discoverEntries, emailCompatibility, exportProject, finding, hasErrors, loadBrandEnv, loadProject, projectRoot, readProjectFiles, renderChannelFixture, renderEmailFixtures, resolveProjectBrand, templateDirectories };
1
+ import { C as renderEmailFixtures, S as renderChannelFixture, _ as channelsOf, a as projectRoot, b as finding, d as discoverEntries, g as templateDirectories, h as readProjectFiles, i as loadProject, l as DEFAULT_TEMPLATE_DIRS, n as createProjectSession, r as exportProject, t as DEFAULT_EXPORT_ASSET_BASE, u as SAMVA_DIR, v as compileProject, x as hasErrors, y as emailCompatibility } from "./project-DwbOoPDk.js";
2
+ export { DEFAULT_EXPORT_ASSET_BASE, DEFAULT_TEMPLATE_DIRS, SAMVA_DIR, channelsOf, compileProject, createProjectSession, discoverEntries, emailCompatibility, exportProject, finding, hasErrors, loadProject, projectRoot, readProjectFiles, renderChannelFixture, renderEmailFixtures, templateDirectories };
package/dist/render.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as ProjectOptions } from "./project-CRqjs-wV.js";
1
+ import { ProjectOptions } from "./project.js";
2
2
  import { RenderedIrWhatsApp } from "@samva/markup/render";
3
3
  import { EmailDiagnostic } from "@samva/markup/diagnostics";
4
4
  //#region src/render.d.ts
package/dist/render.js CHANGED
@@ -1,9 +1,9 @@
1
- import { _ as brandDiagnostics, f as finding, h as renderEmailFixtures, i as loadProject, m as renderChannelFixture, p as hasErrors } from "./project-Ut6wra0r.js";
1
+ import { C as renderEmailFixtures, S as renderChannelFixture, b as finding, i as loadProject, w as brandDiagnostics, x as hasErrors } from "./project-DwbOoPDk.js";
2
2
  //#region src/render.ts
3
3
  /** Compile just enough of the project to find and build the named template. */
4
4
  const locate = async (input) => {
5
5
  const byPath = input.template.endsWith(".tsx");
6
- const project = await loadProject(input, void 0, byPath ? [input.template.replace(/^\.\//, "")] : void 0);
6
+ const project = await loadProject(input, byPath ? [input.template.replace(/^\.\//, "")] : void 0);
7
7
  const { catalog } = project;
8
8
  const entry = catalog.templates.find((candidate) => byPath ? candidate.entryPath === input.template.replace(/^\.\//, "") : candidate.id === input.template);
9
9
  const brand = brandDiagnostics(project.brand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samva/vite",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Local editor, dev server and build for Samva email, SMS and WhatsApp templates",
5
5
  "keywords": [
6
6
  "email",
@@ -70,15 +70,15 @@
70
70
  "test:browser:cross": "turbo run build --filter=@samva/vite && playwright test --config playwright.config.ts"
71
71
  },
72
72
  "dependencies": {
73
- "@samva/markup": "^0.10.0"
73
+ "@samva/markup": "^0.11.0"
74
74
  },
75
75
  "devDependencies": {
76
- "@effect/vitest": "4.0.0-rc.117",
76
+ "@effect/vitest": "4.0.0",
77
77
  "@playwright/test": "^1.63.0",
78
78
  "tsdown": "^0.22.13",
79
79
  "typescript": "^7.0.2",
80
80
  "vite": "~8.3.0",
81
- "vitest": "^4.1.11"
81
+ "vitest": "^5.0.3"
82
82
  },
83
83
  "peerDependencies": {
84
84
  "vite": "^8.2.2"