@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/AGENTS.md +8 -8
- package/CHANGELOG.md +41 -0
- package/README.md +43 -29
- package/dist/brand-BkXQMGgY.d.ts +52 -0
- package/dist/build.d.ts +1 -1
- package/dist/build.js +1 -1
- package/dist/dev.d.ts +8 -0
- package/dist/dev.js +8 -2
- package/dist/editor/assets/index-BBtWrzoS.css +2 -0
- package/dist/editor/assets/index-gqTrwEST.js +34 -0
- package/dist/editor/index.html +2 -2
- package/dist/editor/licenses/hugeicons-core-free-icons.md +21 -0
- package/dist/editor/licenses/hugeicons-react.md +21 -0
- package/dist/editor-DfdlKEeu.d.ts +48 -0
- package/dist/{editor-B_2rlC_U.js → editor-DnFOzVJA.js} +14 -15
- package/dist/index.d.ts +3 -27
- package/dist/index.js +1 -1
- package/dist/{project-Ut6wra0r.js → project-DwbOoPDk.js} +117 -374
- package/dist/project.d.ts +192 -2
- package/dist/project.js +2 -2
- package/dist/render.d.ts +1 -1
- package/dist/render.js +2 -2
- package/package.json +4 -4
- package/dist/editor/assets/index-BRnxqVXL.js +0 -34
- package/dist/editor/assets/index-Bv6OXYH5.css +0 -2
- package/dist/project-CRqjs-wV.d.ts +0 -270
package/dist/editor/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>Samva editor</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-gqTrwEST.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-BBtWrzoS.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Hugeicons
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Hugeicons
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { n as BrandResolver } from "./brand-BkXQMGgY.js";
|
|
2
|
+
import { BrandPlugin } from "@samva/markup/brand";
|
|
3
|
+
import { Plugin } from "vite";
|
|
4
|
+
//#region src/editor.d.ts
|
|
5
|
+
/** Host-owned text for authenticated and publishing capabilities. */
|
|
6
|
+
interface EditorAffordances {
|
|
7
|
+
readonly publishingInstructions?: {
|
|
8
|
+
readonly reason: string;
|
|
9
|
+
readonly cta: {
|
|
10
|
+
readonly label: string;
|
|
11
|
+
readonly href: string;
|
|
12
|
+
};
|
|
13
|
+
} | undefined;
|
|
14
|
+
readonly authenticatedLabel: string;
|
|
15
|
+
readonly authenticatedTitle: string;
|
|
16
|
+
}
|
|
17
|
+
interface SamvaEditorPluginOptions {
|
|
18
|
+
/** Host-owned brand resolution. Brand imports fail without it. */
|
|
19
|
+
readonly brandResolver?: BrandResolver | undefined;
|
|
20
|
+
/** Brand import specifier and footer markers passed to the compiler. */
|
|
21
|
+
readonly brandPlugin?: BrandPlugin | undefined;
|
|
22
|
+
/** Whether the host provides authenticated editor capabilities. */
|
|
23
|
+
readonly authenticated?: boolean | undefined;
|
|
24
|
+
readonly editorAffordances?: EditorAffordances | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* The directory containing `.tsx` templates: an absolute path, or a path relative to the
|
|
27
|
+
* project root. When set, only it is scanned. Otherwise `templates/` and `emails/` are, whichever
|
|
28
|
+
* exist.
|
|
29
|
+
*/
|
|
30
|
+
readonly templatesDir?: string | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* The project root: the folder holding `theme.css`, shared imports and the generated `.samva/`
|
|
33
|
+
* folder. A path relative to the Vite root; default the Vite root. Set it for templates that
|
|
34
|
+
* live in another folder of a monorepo; the templates directory must be inside it.
|
|
35
|
+
*/
|
|
36
|
+
readonly projectRoot?: string | undefined;
|
|
37
|
+
/** Editor UI route. Default `/`; its API and assets are mounted as siblings below it. */
|
|
38
|
+
readonly route?: string | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Project theme file: a path relative to the project root. Default `theme.css`; false compiles
|
|
41
|
+
* without a project theme.
|
|
42
|
+
*/
|
|
43
|
+
readonly theme?: string | false | undefined;
|
|
44
|
+
}
|
|
45
|
+
declare const samvaEditor: (options?: SamvaEditorPluginOptions) => Plugin;
|
|
46
|
+
//#endregion
|
|
47
|
+
export { SamvaEditorPluginOptions as n, samvaEditor as r, EditorAffordances as t };
|
|
48
|
+
//# sourceMappingURL=editor-DfdlKEeu.d.ts.map
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as renderEmailFixtures, S as renderChannelFixture, c as restoreBase, f as isProjectFile, g as templateDirectories, i as loadProject, m as projectPath, o as compileBase, p as isWithin, y as emailCompatibility } from "./project-DwbOoPDk.js";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { open, readFile, realpath, rename, rm, stat } from "node:fs/promises";
|
|
4
4
|
import { isIP } from "node:net";
|
|
5
5
|
import { extname, isAbsolute, join, resolve } from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
import { loadEnv } from "vite";
|
|
8
7
|
import { createHash, randomUUID } from "node:crypto";
|
|
9
8
|
import { renderIrPreview } from "@samva/markup/render";
|
|
9
|
+
//#region src/internal/guards.ts
|
|
10
|
+
/** A non-null, non-array object, narrowed for property access. */
|
|
11
|
+
const isObject = (input) => typeof input === "object" && input !== null && !Array.isArray(input);
|
|
10
12
|
/** The refusal both the store and the dev-server route return for an oversized entry. */
|
|
11
13
|
const EDITOR_SOURCE_TOO_LARGE_MESSAGE = `Authored source exceeds the 1 MiB limit.`;
|
|
12
14
|
const hashSource = (source) => createHash("sha256").update(source, "utf8").digest("hex").slice(0, 16);
|
|
@@ -39,7 +41,7 @@ const chooseFixture = (fixtures, wanted) => wanted !== void 0 && fixtures.includ
|
|
|
39
41
|
/** One preview render of the viewed fixture, or null when the renderer refuses it. */
|
|
40
42
|
const previewRender = (entry, fixture, revision, assetBase) => {
|
|
41
43
|
try {
|
|
42
|
-
const preview = renderIrPreview(entry.ir, entry.fixtures[fixture]);
|
|
44
|
+
const preview = renderIrPreview(entry.ir, entry.fixtures[fixture], entry.brandPlugin === void 0 ? {} : { brandPlugin: entry.brandPlugin });
|
|
43
45
|
return {
|
|
44
46
|
revision,
|
|
45
47
|
subject: preview.subject,
|
|
@@ -216,7 +218,7 @@ var EditorFileStore = class {
|
|
|
216
218
|
}
|
|
217
219
|
async rebuild(emitDocuments) {
|
|
218
220
|
const previous = new Map(this.entries);
|
|
219
|
-
const project = await loadProject(this.projectOptions
|
|
221
|
+
const project = await loadProject(this.projectOptions);
|
|
220
222
|
this.project = project;
|
|
221
223
|
this.options.onProject?.(project);
|
|
222
224
|
this.entries.clear();
|
|
@@ -551,8 +553,7 @@ const samvaEditor = (options = {}) => {
|
|
|
551
553
|
const apiPrefix = childRoute(route, "api");
|
|
552
554
|
let root = process.cwd();
|
|
553
555
|
let store = new EditorFileStore({ root });
|
|
554
|
-
|
|
555
|
-
let env = {};
|
|
556
|
+
const authenticated = options.authenticated === true;
|
|
556
557
|
const clients = /* @__PURE__ */ new Set();
|
|
557
558
|
const catalogClients = /* @__PURE__ */ new Set();
|
|
558
559
|
let refreshTail = Promise.resolve();
|
|
@@ -572,14 +573,8 @@ const samvaEditor = (options = {}) => {
|
|
|
572
573
|
},
|
|
573
574
|
configResolved(resolved) {
|
|
574
575
|
root = resolve(resolved.root, options.projectRoot ?? ".");
|
|
575
|
-
env = loadEnv(resolved.mode, root, "");
|
|
576
|
-
authenticated = Boolean(env.SAMVA_API_KEY);
|
|
577
576
|
},
|
|
578
577
|
async configureServer(server) {
|
|
579
|
-
const brands = createBrandResolver({
|
|
580
|
-
root,
|
|
581
|
-
env
|
|
582
|
-
});
|
|
583
578
|
let brandReport = "";
|
|
584
579
|
const reportBrand = (resolution) => {
|
|
585
580
|
const text = resolution.ok ? resolution.warnings.map((warning) => warning.message).join("\n") : resolution.message;
|
|
@@ -594,7 +589,8 @@ const samvaEditor = (options = {}) => {
|
|
|
594
589
|
dir: options.templatesDir,
|
|
595
590
|
theme: options.theme,
|
|
596
591
|
assetBase: childRoute(apiPrefix, "assets"),
|
|
597
|
-
|
|
592
|
+
brandResolver: options.brandResolver,
|
|
593
|
+
brandPlugin: options.brandPlugin,
|
|
598
594
|
onProject: (project) => reportBrand(project.brand)
|
|
599
595
|
});
|
|
600
596
|
server.watcher.add(root);
|
|
@@ -675,7 +671,10 @@ const samvaEditor = (options = {}) => {
|
|
|
675
671
|
if (!apiRequest && !underRoute(route, pathname)) return next();
|
|
676
672
|
if (!apiRequest && route === "/" && isViteInternalPath(pathname)) return next();
|
|
677
673
|
(async () => {
|
|
678
|
-
if (pathname === `${apiPrefix}/capabilities`) return sendJson(res, 200, {
|
|
674
|
+
if (pathname === `${apiPrefix}/capabilities`) return sendJson(res, 200, {
|
|
675
|
+
authenticated,
|
|
676
|
+
...options.editorAffordances === void 0 ? {} : { editorAffordances: options.editorAffordances }
|
|
677
|
+
});
|
|
679
678
|
if (pathname === `${apiPrefix}/templates`) {
|
|
680
679
|
const catalog = await store.catalog();
|
|
681
680
|
return sendJson(res, 200, {
|
|
@@ -777,4 +776,4 @@ const samvaEditor = (options = {}) => {
|
|
|
777
776
|
//#endregion
|
|
778
777
|
export { samvaEditor as t };
|
|
779
778
|
|
|
780
|
-
//# sourceMappingURL=editor-
|
|
779
|
+
//# sourceMappingURL=editor-DnFOzVJA.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The directory containing `.tsx` templates: an absolute path, or a path relative to the
|
|
6
|
-
* project root. When set, only it is scanned. Otherwise `templates/` and `emails/` are, whichever
|
|
7
|
-
* exist.
|
|
8
|
-
*/
|
|
9
|
-
readonly templatesDir?: string | undefined;
|
|
10
|
-
/**
|
|
11
|
-
* The project root: the folder holding `theme.css`, shared imports and the generated `.samva/`
|
|
12
|
-
* folder. A path relative to the Vite root; default the Vite root. Set it for templates that
|
|
13
|
-
* live in another folder of a monorepo; the templates directory must be inside it.
|
|
14
|
-
*/
|
|
15
|
-
readonly projectRoot?: string | undefined;
|
|
16
|
-
/** Editor UI route. Default `/`; its API and assets are mounted as siblings below it. */
|
|
17
|
-
readonly route?: string | undefined;
|
|
18
|
-
/**
|
|
19
|
-
* Project theme file: a path relative to the project root. Default `theme.css`; false compiles
|
|
20
|
-
* without a project theme.
|
|
21
|
-
*/
|
|
22
|
-
readonly theme?: string | false | undefined;
|
|
23
|
-
}
|
|
24
|
-
declare const samvaEditor: (options?: SamvaEditorPluginOptions) => Plugin;
|
|
25
|
-
//#endregion
|
|
26
|
-
export { type SamvaEditorPluginOptions, samvaEditor };
|
|
27
|
-
//# sourceMappingURL=index.d.ts.map
|
|
1
|
+
import { i as ResolvedBrand, n as BrandResolver, r as BrandWarning, t as BrandResolution } from "./brand-BkXQMGgY.js";
|
|
2
|
+
import { n as SamvaEditorPluginOptions, r as samvaEditor, t as EditorAffordances } from "./editor-DfdlKEeu.js";
|
|
3
|
+
export { type BrandResolution, type BrandResolver, type BrandWarning, type EditorAffordances, type ResolvedBrand, type SamvaEditorPluginOptions, samvaEditor };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as samvaEditor } from "./editor-
|
|
1
|
+
import { t as samvaEditor } from "./editor-DnFOzVJA.js";
|
|
2
2
|
export { samvaEditor };
|