@motion-proto/live-tokens 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/live-tokens-add-component/SKILL.md +488 -0
- package/README.md +84 -29
- package/dist-plugin/index.cjs +177 -125
- package/dist-plugin/index.d.cts +3 -2
- package/dist-plugin/index.d.ts +3 -2
- package/dist-plugin/index.js +177 -125
- package/package.json +8 -2
- package/src/editor/component-editor/BadgeEditor.svelte +44 -42
- package/src/editor/component-editor/ButtonEditor.svelte +224 -0
- package/src/editor/component-editor/CollapsibleSectionEditor.svelte +1 -7
- package/src/editor/component-editor/CornerBadgeEditor.svelte +44 -34
- package/src/editor/component-editor/ImageLightboxEditor.svelte +58 -0
- package/src/editor/component-editor/InputEditor.svelte +272 -0
- package/src/editor/component-editor/NotificationEditor.svelte +44 -65
- package/src/editor/component-editor/ProgressBarEditor.svelte +71 -87
- package/src/editor/component-editor/SegmentedControlEditor.svelte +98 -37
- package/src/editor/component-editor/SideNavigationEditor.svelte +342 -0
- package/src/editor/component-editor/index.ts +16 -1
- package/src/editor/component-editor/registry.ts +138 -28
- package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +3 -2
- package/src/editor/component-editor/scaffolding/ComponentsTab.svelte +2 -2
- package/src/editor/component-editor/scaffolding/StateBlock.svelte +9 -10
- package/src/editor/component-editor/scaffolding/TokenLayout.svelte +60 -36
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +38 -1
- package/src/editor/component-editor/scaffolding/buildTypeGroupTokens.ts +1 -1
- package/src/editor/component-editor/scaffolding/componentSources.ts +3 -3
- package/src/editor/component-editor/scaffolding/defaultSections.ts +15 -10
- package/src/editor/component-editor/scaffolding/siblings.ts +2 -2
- package/src/editor/component-editor/scaffolding/types.ts +2 -1
- package/src/editor/core/components/componentConfigKeys.ts +14 -3
- package/src/editor/core/components/componentConfigService.ts +7 -6
- package/src/editor/core/manifests/manifestService.ts +5 -4
- package/src/editor/core/storage/apiBase.ts +15 -0
- package/src/editor/core/storage/files/versionedFileResourceClient.ts +1 -1
- package/src/editor/core/themes/migrations/2026-05-24-collapsiblesection-drop-active-state.ts +28 -0
- package/src/editor/core/themes/migrations/2026-05-24-progressbar-collapse-variants.ts +41 -0
- package/src/editor/core/themes/migrations/2026-05-24-promote-state-shared-tokens.ts +59 -0
- package/src/editor/core/themes/migrations/2026-05-24-segmentedcontrol-divider-inset.ts +29 -0
- package/src/editor/core/themes/migrations/2026-05-25-cornerbadge-flatten-variants.ts +46 -0
- package/src/editor/core/themes/migrations/index.ts +10 -0
- package/src/editor/core/themes/slices/components.ts +9 -0
- package/src/editor/core/themes/themeInit.ts +3 -2
- package/src/editor/core/themes/themeService.ts +3 -2
- package/src/editor/index.ts +10 -1
- package/src/editor/pages/ComponentEditorPage.svelte +53 -3
- package/src/editor/pages/EditorShell.svelte +53 -3
- package/src/editor/ui/UIEasingSelector.svelte +240 -0
- package/src/editor/ui/variantScales.ts +34 -0
- package/src/system/components/Button.svelte +34 -85
- package/src/system/components/CollapsibleSection.svelte +1 -48
- package/src/system/components/CornerBadge.svelte +72 -138
- package/src/system/components/Dialog.svelte +24 -4
- package/src/system/components/ImageLightbox.svelte +578 -0
- package/src/system/components/Input.svelte +387 -0
- package/src/system/components/ProgressBar.svelte +62 -258
- package/src/system/components/SectionDivider.svelte +117 -43
- package/src/system/components/SegmentedControl.svelte +81 -15
- package/src/system/components/SideNavigation.svelte +777 -0
- package/src/system/styles/tokens.css +43 -0
- package/src/system/styles/tokens.generated.css +4 -183
- package/src/editor/component-editor/StandardButtonsEditor.svelte +0 -190
package/dist-plugin/index.cjs
CHANGED
|
@@ -35,8 +35,8 @@ __export(index_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
|
|
37
37
|
// vite-plugin/themeFileApi.ts
|
|
38
|
-
var
|
|
39
|
-
var
|
|
38
|
+
var import_fs3 = __toESM(require("fs"), 1);
|
|
39
|
+
var import_path3 = __toESM(require("path"), 1);
|
|
40
40
|
|
|
41
41
|
// src/editor/core/themes/parsers/globalRootBlock.ts
|
|
42
42
|
function extractGlobalRootBody(source) {
|
|
@@ -556,19 +556,64 @@ function nextAvailableName(exists, baseName, maxAttempts = 1e3) {
|
|
|
556
556
|
throw new Error(`Could not allocate a non-colliding name for "${baseName}"`);
|
|
557
557
|
}
|
|
558
558
|
|
|
559
|
+
// vite-plugin/files/dataPaths.ts
|
|
560
|
+
var import_fs2 = __toESM(require("fs"), 1);
|
|
561
|
+
var import_path2 = __toESM(require("path"), 1);
|
|
562
|
+
var DEFAULT_DATA_DIR = "src/live-tokens/data";
|
|
563
|
+
var KNOWN_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
564
|
+
"dataDir",
|
|
565
|
+
"themesDir",
|
|
566
|
+
"componentConfigsDir",
|
|
567
|
+
"manifestsDir"
|
|
568
|
+
]);
|
|
569
|
+
var cached = null;
|
|
570
|
+
function readLiveTokensConfig() {
|
|
571
|
+
if (cached) return cached;
|
|
572
|
+
try {
|
|
573
|
+
const configPath = import_path2.default.resolve("live-tokens.config.json");
|
|
574
|
+
if (!import_fs2.default.existsSync(configPath)) return cached = {};
|
|
575
|
+
const parsed = JSON.parse(import_fs2.default.readFileSync(configPath, "utf-8"));
|
|
576
|
+
if (!parsed || typeof parsed !== "object") return cached = {};
|
|
577
|
+
const unknown = Object.keys(parsed).filter(
|
|
578
|
+
(k) => k !== "$schema" && !KNOWN_CONFIG_KEYS.has(k)
|
|
579
|
+
);
|
|
580
|
+
if (unknown.length > 0) {
|
|
581
|
+
console.warn(
|
|
582
|
+
`[live-tokens] Unknown key(s) in live-tokens.config.json: ${unknown.join(", ")}. Known keys: ${Array.from(KNOWN_CONFIG_KEYS).join(", ")}.`
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
cached = parsed;
|
|
586
|
+
return cached;
|
|
587
|
+
} catch {
|
|
588
|
+
return cached = {};
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
function resolveDataDirs(opts = {}) {
|
|
592
|
+
const fileConfig = readLiveTokensConfig();
|
|
593
|
+
const dataDirRaw = opts.dataDir ?? fileConfig.dataDir ?? DEFAULT_DATA_DIR;
|
|
594
|
+
const dataDir = import_path2.default.resolve(dataDirRaw);
|
|
595
|
+
const sub = (name) => import_path2.default.resolve(dataDir, name);
|
|
596
|
+
return {
|
|
597
|
+
dataDir,
|
|
598
|
+
themesDir: opts.themesDir ? import_path2.default.resolve(opts.themesDir) : fileConfig.themesDir ? import_path2.default.resolve(fileConfig.themesDir) : sub("themes"),
|
|
599
|
+
componentConfigsDir: opts.componentConfigsDir ? import_path2.default.resolve(opts.componentConfigsDir) : fileConfig.componentConfigsDir ? import_path2.default.resolve(fileConfig.componentConfigsDir) : sub("component-configs"),
|
|
600
|
+
manifestsDir: opts.manifestsDir ? import_path2.default.resolve(opts.manifestsDir) : fileConfig.manifestsDir ? import_path2.default.resolve(fileConfig.manifestsDir) : sub("manifests")
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
|
|
559
604
|
// vite-plugin/themeFileApi.ts
|
|
560
605
|
var import_node_url = require("url");
|
|
561
606
|
var import_meta = {};
|
|
562
607
|
var PKG_VERSION = (() => {
|
|
563
608
|
try {
|
|
564
|
-
let dir =
|
|
609
|
+
let dir = import_path3.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
565
610
|
for (let i = 0; i < 4; i++) {
|
|
566
|
-
const p =
|
|
567
|
-
if (
|
|
568
|
-
const json = JSON.parse(
|
|
611
|
+
const p = import_path3.default.join(dir, "package.json");
|
|
612
|
+
if (import_fs3.default.existsSync(p)) {
|
|
613
|
+
const json = JSON.parse(import_fs3.default.readFileSync(p, "utf-8"));
|
|
569
614
|
if (json?.name === "@motion-proto/live-tokens") return json.version ?? "";
|
|
570
615
|
}
|
|
571
|
-
const up =
|
|
616
|
+
const up = import_path3.default.dirname(dir);
|
|
572
617
|
if (up === dir) break;
|
|
573
618
|
dir = up;
|
|
574
619
|
}
|
|
@@ -577,15 +622,21 @@ var PKG_VERSION = (() => {
|
|
|
577
622
|
return "";
|
|
578
623
|
})();
|
|
579
624
|
function themeFileApi(opts) {
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
const
|
|
587
|
-
const
|
|
588
|
-
const
|
|
625
|
+
const dataDirs = resolveDataDirs({
|
|
626
|
+
dataDir: opts.dataDir,
|
|
627
|
+
themesDir: opts.themesDir,
|
|
628
|
+
componentConfigsDir: opts.componentConfigsDir,
|
|
629
|
+
manifestsDir: opts.manifestsDir
|
|
630
|
+
});
|
|
631
|
+
const THEMES_DIR = dataDirs.themesDir;
|
|
632
|
+
const COMPONENT_CONFIGS_DIR = dataDirs.componentConfigsDir;
|
|
633
|
+
const MANIFESTS_DIR = dataDirs.manifestsDir;
|
|
634
|
+
const CSS_PATH = import_path3.default.resolve(opts.tokensCssPath);
|
|
635
|
+
const GENERATED_CSS_PATH = opts.tokensGeneratedCssPath ? import_path3.default.resolve(opts.tokensGeneratedCssPath) : import_path3.default.join(import_path3.default.dirname(CSS_PATH), "tokens.generated.css");
|
|
636
|
+
const FONTS_CSS_PATH = opts.fontsCssPath ? import_path3.default.resolve(opts.fontsCssPath) : import_path3.default.join(import_path3.default.dirname(CSS_PATH), "fonts.css");
|
|
637
|
+
const API_BASE = opts.apiBase ?? "/api/live-tokens";
|
|
638
|
+
const COMPONENTS_SRC_DIR = opts.componentsSrcDir ? import_path3.default.resolve(opts.componentsSrcDir) : import_path3.default.resolve("src/system/components");
|
|
639
|
+
const LEGACY_PRESETS_DIR = import_path3.default.resolve("presets");
|
|
589
640
|
const themesResource = versionedFileResourceServer({
|
|
590
641
|
dir: THEMES_DIR
|
|
591
642
|
});
|
|
@@ -593,7 +644,7 @@ function themeFileApi(opts) {
|
|
|
593
644
|
function componentResource(comp) {
|
|
594
645
|
let r = componentResourceCache.get(comp);
|
|
595
646
|
if (!r) {
|
|
596
|
-
r = versionedFileResourceServer({ dir:
|
|
647
|
+
r = versionedFileResourceServer({ dir: import_path3.default.join(COMPONENT_CONFIGS_DIR, comp) });
|
|
597
648
|
componentResourceCache.set(comp, r);
|
|
598
649
|
}
|
|
599
650
|
return r;
|
|
@@ -601,7 +652,7 @@ function themeFileApi(opts) {
|
|
|
601
652
|
const manifestsResource = versionedFileResourceServer({ dir: MANIFESTS_DIR });
|
|
602
653
|
function ensureThemesDir() {
|
|
603
654
|
themesResource.ensureDir();
|
|
604
|
-
if (!
|
|
655
|
+
if (!import_fs3.default.existsSync(import_path3.default.join(THEMES_DIR, "default.json"))) {
|
|
605
656
|
const defaultTheme = {
|
|
606
657
|
name: "Default Theme",
|
|
607
658
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -609,7 +660,7 @@ function themeFileApi(opts) {
|
|
|
609
660
|
editorConfigs: {},
|
|
610
661
|
cssVariables: {}
|
|
611
662
|
};
|
|
612
|
-
|
|
663
|
+
import_fs3.default.writeFileSync(import_path3.default.join(THEMES_DIR, "default.json"), JSON.stringify(defaultTheme, null, 2));
|
|
613
664
|
}
|
|
614
665
|
themesResource.ensureMeta();
|
|
615
666
|
}
|
|
@@ -674,10 +725,10 @@ function themeFileApi(opts) {
|
|
|
674
725
|
lines.push("/* tokens.css holds developer-authored defaults; this file holds editor overrides. */");
|
|
675
726
|
lines.push("");
|
|
676
727
|
const productionThemeName = themesResource.getProductionName();
|
|
677
|
-
const themePath =
|
|
728
|
+
const themePath = import_path3.default.join(THEMES_DIR, `${productionThemeName}.json`);
|
|
678
729
|
let themeVarCount = 0;
|
|
679
|
-
if (
|
|
680
|
-
const themeData = JSON.parse(
|
|
730
|
+
if (import_fs3.default.existsSync(themePath)) {
|
|
731
|
+
const themeData = JSON.parse(import_fs3.default.readFileSync(themePath, "utf-8"));
|
|
681
732
|
const cssVars = { ...themeData.cssVariables || {} };
|
|
682
733
|
Object.assign(cssVars, palettesToVars(themeData.editorConfigs ?? {}));
|
|
683
734
|
const resolvedFontVars = resolveFontStacks(themeData);
|
|
@@ -696,7 +747,7 @@ function themeFileApi(opts) {
|
|
|
696
747
|
}
|
|
697
748
|
}
|
|
698
749
|
let componentOverrideCount = 0;
|
|
699
|
-
if (
|
|
750
|
+
if (import_fs3.default.existsSync(COMPONENT_CONFIGS_DIR)) {
|
|
700
751
|
const blocks = [];
|
|
701
752
|
for (const comp of listComponentNames()) {
|
|
702
753
|
const prod = componentResource(comp).getProductionName();
|
|
@@ -730,21 +781,21 @@ function themeFileApi(opts) {
|
|
|
730
781
|
lines.push("");
|
|
731
782
|
}
|
|
732
783
|
}
|
|
733
|
-
if (!
|
|
734
|
-
|
|
784
|
+
if (!import_fs3.default.existsSync(import_path3.default.dirname(GENERATED_CSS_PATH))) {
|
|
785
|
+
import_fs3.default.mkdirSync(import_path3.default.dirname(GENERATED_CSS_PATH), { recursive: true });
|
|
735
786
|
}
|
|
736
|
-
|
|
787
|
+
import_fs3.default.writeFileSync(GENERATED_CSS_PATH, lines.join("\n"));
|
|
737
788
|
console.log(
|
|
738
|
-
`[regenerateTokensCss] Wrote ${
|
|
789
|
+
`[regenerateTokensCss] Wrote ${import_path3.default.basename(GENERATED_CSS_PATH)} (${themeVarCount} theme vars, ${componentOverrideCount} component overrides)`
|
|
739
790
|
);
|
|
740
791
|
}
|
|
741
792
|
function syncTokensToCss(_fileName) {
|
|
742
793
|
regenerateTokensCss();
|
|
743
794
|
}
|
|
744
795
|
function syncFontsToCss(fileName) {
|
|
745
|
-
const themePath =
|
|
746
|
-
if (!
|
|
747
|
-
const themeData = JSON.parse(
|
|
796
|
+
const themePath = import_path3.default.join(THEMES_DIR, `${fileName}.json`);
|
|
797
|
+
if (!import_fs3.default.existsSync(themePath)) return;
|
|
798
|
+
const themeData = JSON.parse(import_fs3.default.readFileSync(themePath, "utf-8"));
|
|
748
799
|
const sources = themeData.fontSources;
|
|
749
800
|
if (!sources) return;
|
|
750
801
|
const lines = [];
|
|
@@ -768,11 +819,11 @@ function themeFileApi(opts) {
|
|
|
768
819
|
lines.push("");
|
|
769
820
|
}
|
|
770
821
|
const content = lines.join("\n");
|
|
771
|
-
if (!
|
|
772
|
-
|
|
822
|
+
if (!import_fs3.default.existsSync(import_path3.default.dirname(FONTS_CSS_PATH))) {
|
|
823
|
+
import_fs3.default.mkdirSync(import_path3.default.dirname(FONTS_CSS_PATH), { recursive: true });
|
|
773
824
|
}
|
|
774
|
-
|
|
775
|
-
console.log(`[syncFontsToCss] Wrote ${sources.length} source(s) into ${
|
|
825
|
+
import_fs3.default.writeFileSync(FONTS_CSS_PATH, content);
|
|
826
|
+
console.log(`[syncFontsToCss] Wrote ${sources.length} source(s) into ${import_path3.default.basename(FONTS_CSS_PATH)}`);
|
|
776
827
|
}
|
|
777
828
|
function extractAliasDeclarations(body) {
|
|
778
829
|
const aliases = {};
|
|
@@ -782,35 +833,35 @@ function themeFileApi(opts) {
|
|
|
782
833
|
return aliases;
|
|
783
834
|
}
|
|
784
835
|
function componentNameFromFile(filePath) {
|
|
785
|
-
return
|
|
836
|
+
return import_path3.default.basename(filePath, ".svelte").toLowerCase();
|
|
786
837
|
}
|
|
787
838
|
function listComponentSourcePaths() {
|
|
788
|
-
if (!
|
|
789
|
-
return
|
|
839
|
+
if (!import_fs3.default.existsSync(COMPONENTS_SRC_DIR)) return [];
|
|
840
|
+
return import_fs3.default.readdirSync(COMPONENTS_SRC_DIR).filter((f) => f.endsWith(".svelte")).map((f) => import_path3.default.join(COMPONENTS_SRC_DIR, f));
|
|
790
841
|
}
|
|
791
842
|
function listComponentNames() {
|
|
792
843
|
return listComponentSourcePaths().map(componentNameFromFile);
|
|
793
844
|
}
|
|
794
845
|
function generateDefaultConfig(comp, sourcePath) {
|
|
795
|
-
if (!
|
|
846
|
+
if (!import_fs3.default.existsSync(sourcePath)) return;
|
|
796
847
|
const r = componentResource(comp);
|
|
797
848
|
r.ensureDir();
|
|
798
849
|
const defaultPath = r.filePath("default");
|
|
799
|
-
const sourceStat =
|
|
800
|
-
if (
|
|
801
|
-
const defaultStat =
|
|
850
|
+
const sourceStat = import_fs3.default.statSync(sourcePath);
|
|
851
|
+
if (import_fs3.default.existsSync(defaultPath)) {
|
|
852
|
+
const defaultStat = import_fs3.default.statSync(defaultPath);
|
|
802
853
|
if (defaultStat.mtimeMs >= sourceStat.mtimeMs) return;
|
|
803
854
|
}
|
|
804
|
-
const source =
|
|
855
|
+
const source = import_fs3.default.readFileSync(sourcePath, "utf-8");
|
|
805
856
|
const body = extractGlobalRootBody(source);
|
|
806
857
|
const aliases = extractAliasDeclarations(body);
|
|
807
858
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
808
859
|
let createdAt = now;
|
|
809
860
|
let existingUpdatedAt;
|
|
810
861
|
let existingAliases;
|
|
811
|
-
if (
|
|
862
|
+
if (import_fs3.default.existsSync(defaultPath)) {
|
|
812
863
|
try {
|
|
813
|
-
const existing = JSON.parse(
|
|
864
|
+
const existing = JSON.parse(import_fs3.default.readFileSync(defaultPath, "utf-8"));
|
|
814
865
|
if (existing.createdAt) createdAt = existing.createdAt;
|
|
815
866
|
if (typeof existing.updatedAt === "string") existingUpdatedAt = existing.updatedAt;
|
|
816
867
|
if (existing.aliases && typeof existing.aliases === "object") {
|
|
@@ -829,14 +880,14 @@ function themeFileApi(opts) {
|
|
|
829
880
|
};
|
|
830
881
|
if (aliasesUnchanged && existingUpdatedAt) {
|
|
831
882
|
const t = /* @__PURE__ */ new Date();
|
|
832
|
-
|
|
883
|
+
import_fs3.default.utimesSync(defaultPath, t, t);
|
|
833
884
|
return;
|
|
834
885
|
}
|
|
835
|
-
|
|
886
|
+
import_fs3.default.writeFileSync(defaultPath, JSON.stringify(defaultConfig, null, 2));
|
|
836
887
|
}
|
|
837
888
|
function ensureComponentConfigsDir() {
|
|
838
|
-
if (!
|
|
839
|
-
|
|
889
|
+
if (!import_fs3.default.existsSync(COMPONENT_CONFIGS_DIR)) {
|
|
890
|
+
import_fs3.default.mkdirSync(COMPONENT_CONFIGS_DIR, { recursive: true });
|
|
840
891
|
}
|
|
841
892
|
for (const sourcePath of listComponentSourcePaths()) {
|
|
842
893
|
const comp = componentNameFromFile(sourcePath);
|
|
@@ -847,14 +898,14 @@ function themeFileApi(opts) {
|
|
|
847
898
|
}
|
|
848
899
|
}
|
|
849
900
|
function ensureManifestsDir() {
|
|
850
|
-
if (!
|
|
851
|
-
|
|
852
|
-
const legacyProd =
|
|
853
|
-
if (
|
|
901
|
+
if (!import_fs3.default.existsSync(MANIFESTS_DIR) && import_fs3.default.existsSync(LEGACY_PRESETS_DIR)) {
|
|
902
|
+
import_fs3.default.renameSync(LEGACY_PRESETS_DIR, MANIFESTS_DIR);
|
|
903
|
+
const legacyProd = import_path3.default.join(MANIFESTS_DIR, "_production.json");
|
|
904
|
+
if (import_fs3.default.existsSync(legacyProd)) import_fs3.default.unlinkSync(legacyProd);
|
|
854
905
|
}
|
|
855
906
|
manifestsResource.ensureDir();
|
|
856
|
-
const defaultPath =
|
|
857
|
-
if (!
|
|
907
|
+
const defaultPath = import_path3.default.join(MANIFESTS_DIR, "default.json");
|
|
908
|
+
if (!import_fs3.default.existsSync(defaultPath)) {
|
|
858
909
|
const componentConfigs = {};
|
|
859
910
|
for (const comp of listComponentNames()) {
|
|
860
911
|
componentConfigs[comp] = componentResource(comp).getActiveName();
|
|
@@ -867,30 +918,30 @@ function themeFileApi(opts) {
|
|
|
867
918
|
theme: themesResource.getActiveName(),
|
|
868
919
|
componentConfigs
|
|
869
920
|
};
|
|
870
|
-
|
|
921
|
+
import_fs3.default.writeFileSync(defaultPath, JSON.stringify(defaultManifest, null, 2));
|
|
871
922
|
}
|
|
872
|
-
if (!
|
|
873
|
-
|
|
923
|
+
if (!import_fs3.default.existsSync(manifestsResource.activePath)) {
|
|
924
|
+
import_fs3.default.writeFileSync(
|
|
874
925
|
manifestsResource.activePath,
|
|
875
926
|
JSON.stringify({ activeFile: "default" })
|
|
876
927
|
);
|
|
877
928
|
} else {
|
|
878
929
|
const activeName = manifestsResource.getActiveName();
|
|
879
|
-
if (!
|
|
930
|
+
if (!import_fs3.default.existsSync(manifestsResource.filePath(activeName))) {
|
|
880
931
|
manifestsResource.setActiveName("default");
|
|
881
932
|
}
|
|
882
933
|
}
|
|
883
|
-
const stragglerProd =
|
|
884
|
-
if (
|
|
934
|
+
const stragglerProd = import_path3.default.join(MANIFESTS_DIR, "_production.json");
|
|
935
|
+
if (import_fs3.default.existsSync(stragglerProd)) import_fs3.default.unlinkSync(stragglerProd);
|
|
885
936
|
}
|
|
886
937
|
function patchActiveManifest(field, comp, fileName) {
|
|
887
938
|
const activeFile = manifestsResource.getActiveName();
|
|
888
939
|
if (activeFile === "default") return false;
|
|
889
940
|
const manifestPath = manifestsResource.filePath(activeFile);
|
|
890
|
-
if (!
|
|
941
|
+
if (!import_fs3.default.existsSync(manifestPath)) return false;
|
|
891
942
|
let manifest;
|
|
892
943
|
try {
|
|
893
|
-
manifest = JSON.parse(
|
|
944
|
+
manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
|
|
894
945
|
} catch {
|
|
895
946
|
return false;
|
|
896
947
|
}
|
|
@@ -901,7 +952,7 @@ function themeFileApi(opts) {
|
|
|
901
952
|
manifest.componentConfigs[comp] = fileName;
|
|
902
953
|
}
|
|
903
954
|
manifest.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
904
|
-
|
|
955
|
+
import_fs3.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
905
956
|
return true;
|
|
906
957
|
}
|
|
907
958
|
function formatAliasGradient(v) {
|
|
@@ -933,9 +984,9 @@ function themeFileApi(opts) {
|
|
|
933
984
|
}
|
|
934
985
|
function readComponentConfig(comp, name) {
|
|
935
986
|
const filePath = componentResource(comp).filePath(name);
|
|
936
|
-
if (!
|
|
987
|
+
if (!import_fs3.default.existsSync(filePath)) return null;
|
|
937
988
|
try {
|
|
938
|
-
return JSON.parse(
|
|
989
|
+
return JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
|
|
939
990
|
} catch {
|
|
940
991
|
return null;
|
|
941
992
|
}
|
|
@@ -961,9 +1012,9 @@ function themeFileApi(opts) {
|
|
|
961
1012
|
const MANIFEST_BY_NAME_REGEX = new RegExp(`^${escapedBase}/manifests/([a-z0-9\\-_]+)$`);
|
|
962
1013
|
async function handleListThemes(_ctx) {
|
|
963
1014
|
const activeFile = themesResource.getActiveName();
|
|
964
|
-
const files =
|
|
965
|
-
const filePath =
|
|
966
|
-
const data = JSON.parse(
|
|
1015
|
+
const files = import_fs3.default.readdirSync(THEMES_DIR).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
|
|
1016
|
+
const filePath = import_path3.default.join(THEMES_DIR, f);
|
|
1017
|
+
const data = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
|
|
967
1018
|
const fileName = f.replace(".json", "");
|
|
968
1019
|
return {
|
|
969
1020
|
name: data.name || fileName,
|
|
@@ -977,18 +1028,18 @@ function themeFileApi(opts) {
|
|
|
977
1028
|
async function handleGetActiveTheme({ res }) {
|
|
978
1029
|
const activeFile = themesResource.getActiveName();
|
|
979
1030
|
const filePath = themesResource.filePath(activeFile);
|
|
980
|
-
if (!
|
|
1031
|
+
if (!import_fs3.default.existsSync(filePath)) {
|
|
981
1032
|
jsonResponse(res, 404, { error: "Active theme not found" });
|
|
982
1033
|
return;
|
|
983
1034
|
}
|
|
984
|
-
const data = normalizeTheme(JSON.parse(
|
|
1035
|
+
const data = normalizeTheme(JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8")));
|
|
985
1036
|
data._fileName = activeFile;
|
|
986
1037
|
jsonResponse(res, 200, data);
|
|
987
1038
|
}
|
|
988
1039
|
async function handleSetActiveTheme({ req, res }) {
|
|
989
1040
|
const body = JSON.parse(await readBody(req));
|
|
990
1041
|
const fileName = sanitizeFileName(body.name || "default");
|
|
991
|
-
if (!
|
|
1042
|
+
if (!import_fs3.default.existsSync(themesResource.filePath(fileName))) {
|
|
992
1043
|
jsonResponse(res, 404, { error: "Theme not found" });
|
|
993
1044
|
return;
|
|
994
1045
|
}
|
|
@@ -998,11 +1049,11 @@ function themeFileApi(opts) {
|
|
|
998
1049
|
async function handleGetProductionTheme({ res }) {
|
|
999
1050
|
const prodFile = themesResource.getProductionName();
|
|
1000
1051
|
const filePath = themesResource.filePath(prodFile);
|
|
1001
|
-
if (!
|
|
1052
|
+
if (!import_fs3.default.existsSync(filePath)) {
|
|
1002
1053
|
jsonResponse(res, 200, { fileName: prodFile, name: prodFile, cssVariables: {} });
|
|
1003
1054
|
return;
|
|
1004
1055
|
}
|
|
1005
|
-
const data = normalizeTheme(JSON.parse(
|
|
1056
|
+
const data = normalizeTheme(JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8")));
|
|
1006
1057
|
jsonResponse(res, 200, {
|
|
1007
1058
|
fileName: prodFile,
|
|
1008
1059
|
name: data.name || prodFile,
|
|
@@ -1013,7 +1064,7 @@ function themeFileApi(opts) {
|
|
|
1013
1064
|
async function handleSetProductionTheme({ req, res }) {
|
|
1014
1065
|
const body = JSON.parse(await readBody(req));
|
|
1015
1066
|
const fileName = sanitizeFileName(body.name || "default");
|
|
1016
|
-
if (!
|
|
1067
|
+
if (!import_fs3.default.existsSync(themesResource.filePath(fileName))) {
|
|
1017
1068
|
jsonResponse(res, 404, { error: "Theme not found" });
|
|
1018
1069
|
return;
|
|
1019
1070
|
}
|
|
@@ -1029,7 +1080,7 @@ function themeFileApi(opts) {
|
|
|
1029
1080
|
syncFontsToCss(fileName);
|
|
1030
1081
|
syncComponentsToCss();
|
|
1031
1082
|
patchActiveManifest("theme", null, fileName);
|
|
1032
|
-
const data = JSON.parse(
|
|
1083
|
+
const data = JSON.parse(import_fs3.default.readFileSync(themesResource.filePath(fileName), "utf-8"));
|
|
1033
1084
|
jsonResponse(res, 200, {
|
|
1034
1085
|
ok: true,
|
|
1035
1086
|
fileName,
|
|
@@ -1041,11 +1092,11 @@ function themeFileApi(opts) {
|
|
|
1041
1092
|
const [fileName] = params;
|
|
1042
1093
|
const filePath = themesResource.filePath(fileName);
|
|
1043
1094
|
if (req.method === "GET") {
|
|
1044
|
-
if (!
|
|
1095
|
+
if (!import_fs3.default.existsSync(filePath)) {
|
|
1045
1096
|
jsonResponse(res, 404, { error: "Not found" });
|
|
1046
1097
|
return;
|
|
1047
1098
|
}
|
|
1048
|
-
const data = normalizeTheme(JSON.parse(
|
|
1099
|
+
const data = normalizeTheme(JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8")));
|
|
1049
1100
|
data._fileName = fileName;
|
|
1050
1101
|
jsonResponse(res, 200, data);
|
|
1051
1102
|
return;
|
|
@@ -1053,15 +1104,15 @@ function themeFileApi(opts) {
|
|
|
1053
1104
|
if (req.method === "PUT") {
|
|
1054
1105
|
const body = JSON.parse(await readBody(req));
|
|
1055
1106
|
body.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1056
|
-
if (
|
|
1107
|
+
if (import_fs3.default.existsSync(filePath)) {
|
|
1057
1108
|
try {
|
|
1058
|
-
const existing = JSON.parse(
|
|
1109
|
+
const existing = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
|
|
1059
1110
|
if (existing.createdAt) body.createdAt = existing.createdAt;
|
|
1060
1111
|
} catch {
|
|
1061
1112
|
}
|
|
1062
1113
|
}
|
|
1063
1114
|
if (!body.createdAt) body.createdAt = body.updatedAt;
|
|
1064
|
-
|
|
1115
|
+
import_fs3.default.writeFileSync(filePath, JSON.stringify(body, null, 2));
|
|
1065
1116
|
if (fileName === themesResource.getProductionName()) {
|
|
1066
1117
|
syncTokensToCss(fileName);
|
|
1067
1118
|
syncFontsToCss(fileName);
|
|
@@ -1082,8 +1133,8 @@ function themeFileApi(opts) {
|
|
|
1082
1133
|
});
|
|
1083
1134
|
return;
|
|
1084
1135
|
}
|
|
1085
|
-
if (
|
|
1086
|
-
|
|
1136
|
+
if (import_fs3.default.existsSync(filePath)) {
|
|
1137
|
+
import_fs3.default.unlinkSync(filePath);
|
|
1087
1138
|
if (themesResource.getActiveName() === fileName) {
|
|
1088
1139
|
themesResource.setActiveName("default");
|
|
1089
1140
|
}
|
|
@@ -1120,7 +1171,7 @@ function themeFileApi(opts) {
|
|
|
1120
1171
|
const fileName = sanitizeFileName(body.name || "default");
|
|
1121
1172
|
const r = componentResource(comp);
|
|
1122
1173
|
const configPath = r.filePath(fileName);
|
|
1123
|
-
if (!
|
|
1174
|
+
if (!import_fs3.default.existsSync(configPath)) {
|
|
1124
1175
|
jsonResponse(res, 404, { error: "Config not found" });
|
|
1125
1176
|
return;
|
|
1126
1177
|
}
|
|
@@ -1145,7 +1196,7 @@ function themeFileApi(opts) {
|
|
|
1145
1196
|
const fileName = sanitizeFileName(body.name || "default");
|
|
1146
1197
|
const r = componentResource(comp);
|
|
1147
1198
|
const configPath = r.filePath(fileName);
|
|
1148
|
-
if (!
|
|
1199
|
+
if (!import_fs3.default.existsSync(configPath)) {
|
|
1149
1200
|
jsonResponse(res, 404, { error: "Config not found" });
|
|
1150
1201
|
return;
|
|
1151
1202
|
}
|
|
@@ -1173,11 +1224,11 @@ function themeFileApi(opts) {
|
|
|
1173
1224
|
const r = componentResource(comp);
|
|
1174
1225
|
const configPath = r.filePath(name);
|
|
1175
1226
|
if (req.method === "GET") {
|
|
1176
|
-
if (!
|
|
1227
|
+
if (!import_fs3.default.existsSync(configPath)) {
|
|
1177
1228
|
jsonResponse(res, 404, { error: "Not found" });
|
|
1178
1229
|
return;
|
|
1179
1230
|
}
|
|
1180
|
-
const data = JSON.parse(
|
|
1231
|
+
const data = JSON.parse(import_fs3.default.readFileSync(configPath, "utf-8"));
|
|
1181
1232
|
data._fileName = name;
|
|
1182
1233
|
jsonResponse(res, 200, data);
|
|
1183
1234
|
return;
|
|
@@ -1191,16 +1242,16 @@ function themeFileApi(opts) {
|
|
|
1191
1242
|
body.component = comp;
|
|
1192
1243
|
body.name = body.name || name;
|
|
1193
1244
|
body.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1194
|
-
if (
|
|
1245
|
+
if (import_fs3.default.existsSync(configPath)) {
|
|
1195
1246
|
try {
|
|
1196
|
-
const existing = JSON.parse(
|
|
1247
|
+
const existing = JSON.parse(import_fs3.default.readFileSync(configPath, "utf-8"));
|
|
1197
1248
|
if (existing.createdAt) body.createdAt = existing.createdAt;
|
|
1198
1249
|
} catch {
|
|
1199
1250
|
}
|
|
1200
1251
|
}
|
|
1201
1252
|
if (!body.createdAt) body.createdAt = body.updatedAt;
|
|
1202
1253
|
r.ensureDir();
|
|
1203
|
-
|
|
1254
|
+
import_fs3.default.writeFileSync(configPath, JSON.stringify(body, null, 2));
|
|
1204
1255
|
if (r.getProductionName() === name) {
|
|
1205
1256
|
syncComponentsToCss();
|
|
1206
1257
|
}
|
|
@@ -1212,8 +1263,8 @@ function themeFileApi(opts) {
|
|
|
1212
1263
|
jsonResponse(res, 403, { error: "Cannot delete default config" });
|
|
1213
1264
|
return;
|
|
1214
1265
|
}
|
|
1215
|
-
if (
|
|
1216
|
-
|
|
1266
|
+
if (import_fs3.default.existsSync(configPath)) {
|
|
1267
|
+
import_fs3.default.unlinkSync(configPath);
|
|
1217
1268
|
if (r.getActiveName() === name) {
|
|
1218
1269
|
r.setActiveName("default");
|
|
1219
1270
|
}
|
|
@@ -1229,15 +1280,15 @@ function themeFileApi(opts) {
|
|
|
1229
1280
|
async function handleListComponentConfigs({ params, res }) {
|
|
1230
1281
|
const [comp] = params;
|
|
1231
1282
|
const r = componentResource(comp);
|
|
1232
|
-
if (!
|
|
1283
|
+
if (!import_fs3.default.existsSync(r.dir)) {
|
|
1233
1284
|
jsonResponse(res, 404, { error: "Component not found" });
|
|
1234
1285
|
return;
|
|
1235
1286
|
}
|
|
1236
1287
|
const activeFile = r.getActiveName();
|
|
1237
1288
|
const productionFile = r.getProductionName();
|
|
1238
|
-
const files =
|
|
1239
|
-
const filePath =
|
|
1240
|
-
const data = JSON.parse(
|
|
1289
|
+
const files = import_fs3.default.readdirSync(r.dir).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
|
|
1290
|
+
const filePath = import_path3.default.join(r.dir, f);
|
|
1291
|
+
const data = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
|
|
1241
1292
|
const fileName = f.replace(".json", "");
|
|
1242
1293
|
return {
|
|
1243
1294
|
name: data.name || fileName,
|
|
@@ -1251,9 +1302,9 @@ function themeFileApi(opts) {
|
|
|
1251
1302
|
}
|
|
1252
1303
|
async function handleListManifests({ res }) {
|
|
1253
1304
|
const activeFile = manifestsResource.getActiveName();
|
|
1254
|
-
const files =
|
|
1255
|
-
const filePath =
|
|
1256
|
-
const data = JSON.parse(
|
|
1305
|
+
const files = import_fs3.default.readdirSync(MANIFESTS_DIR).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => {
|
|
1306
|
+
const filePath = import_path3.default.join(MANIFESTS_DIR, f);
|
|
1307
|
+
const data = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
|
|
1257
1308
|
const fileName = f.replace(".json", "");
|
|
1258
1309
|
return {
|
|
1259
1310
|
name: data.name || fileName,
|
|
@@ -1268,18 +1319,18 @@ function themeFileApi(opts) {
|
|
|
1268
1319
|
async function handleGetActiveManifest({ res }) {
|
|
1269
1320
|
const activeFile = manifestsResource.getActiveName();
|
|
1270
1321
|
const filePath = manifestsResource.filePath(activeFile);
|
|
1271
|
-
if (!
|
|
1322
|
+
if (!import_fs3.default.existsSync(filePath)) {
|
|
1272
1323
|
jsonResponse(res, 404, { error: "Active manifest not found" });
|
|
1273
1324
|
return;
|
|
1274
1325
|
}
|
|
1275
|
-
const data = JSON.parse(
|
|
1326
|
+
const data = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
|
|
1276
1327
|
data._fileName = activeFile;
|
|
1277
1328
|
jsonResponse(res, 200, data);
|
|
1278
1329
|
}
|
|
1279
1330
|
async function handleSetActiveManifest({ req, res }) {
|
|
1280
1331
|
const body = JSON.parse(await readBody(req));
|
|
1281
1332
|
const fileName = sanitizeFileName(body.name || "default");
|
|
1282
|
-
if (!
|
|
1333
|
+
if (!import_fs3.default.existsSync(manifestsResource.filePath(fileName))) {
|
|
1283
1334
|
jsonResponse(res, 404, { error: "Manifest not found" });
|
|
1284
1335
|
return;
|
|
1285
1336
|
}
|
|
@@ -1290,11 +1341,11 @@ function themeFileApi(opts) {
|
|
|
1290
1341
|
const [fileName] = params;
|
|
1291
1342
|
const filePath = manifestsResource.filePath(fileName);
|
|
1292
1343
|
if (req.method === "GET") {
|
|
1293
|
-
if (!
|
|
1344
|
+
if (!import_fs3.default.existsSync(filePath)) {
|
|
1294
1345
|
jsonResponse(res, 404, { error: "Not found" });
|
|
1295
1346
|
return;
|
|
1296
1347
|
}
|
|
1297
|
-
const data = JSON.parse(
|
|
1348
|
+
const data = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
|
|
1298
1349
|
data._fileName = fileName;
|
|
1299
1350
|
jsonResponse(res, 200, data);
|
|
1300
1351
|
return;
|
|
@@ -1306,15 +1357,15 @@ function themeFileApi(opts) {
|
|
|
1306
1357
|
}
|
|
1307
1358
|
const body = JSON.parse(await readBody(req));
|
|
1308
1359
|
body.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1309
|
-
if (
|
|
1360
|
+
if (import_fs3.default.existsSync(filePath)) {
|
|
1310
1361
|
try {
|
|
1311
|
-
const existing = JSON.parse(
|
|
1362
|
+
const existing = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
|
|
1312
1363
|
if (existing.createdAt) body.createdAt = existing.createdAt;
|
|
1313
1364
|
} catch {
|
|
1314
1365
|
}
|
|
1315
1366
|
}
|
|
1316
1367
|
if (!body.createdAt) body.createdAt = body.updatedAt;
|
|
1317
|
-
|
|
1368
|
+
import_fs3.default.writeFileSync(filePath, JSON.stringify(body, null, 2));
|
|
1318
1369
|
jsonResponse(res, 200, { ok: true, fileName });
|
|
1319
1370
|
return;
|
|
1320
1371
|
}
|
|
@@ -1323,8 +1374,8 @@ function themeFileApi(opts) {
|
|
|
1323
1374
|
jsonResponse(res, 403, { error: "Cannot delete the default manifest" });
|
|
1324
1375
|
return;
|
|
1325
1376
|
}
|
|
1326
|
-
if (
|
|
1327
|
-
|
|
1377
|
+
if (import_fs3.default.existsSync(filePath)) {
|
|
1378
|
+
import_fs3.default.unlinkSync(filePath);
|
|
1328
1379
|
if (manifestsResource.getActiveName() === fileName) {
|
|
1329
1380
|
manifestsResource.setActiveName("default");
|
|
1330
1381
|
}
|
|
@@ -1336,14 +1387,14 @@ function themeFileApi(opts) {
|
|
|
1336
1387
|
async function handleApplyManifest({ params, res }) {
|
|
1337
1388
|
const [fileName] = params;
|
|
1338
1389
|
const manifestPath = manifestsResource.filePath(fileName);
|
|
1339
|
-
if (!
|
|
1390
|
+
if (!import_fs3.default.existsSync(manifestPath)) {
|
|
1340
1391
|
jsonResponse(res, 404, { error: "Manifest not found" });
|
|
1341
1392
|
return;
|
|
1342
1393
|
}
|
|
1343
|
-
const manifest = JSON.parse(
|
|
1394
|
+
const manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
|
|
1344
1395
|
const themeName = sanitizeFileName(manifest.theme || "default");
|
|
1345
1396
|
const themePath = themesResource.filePath(themeName);
|
|
1346
|
-
if (!
|
|
1397
|
+
if (!import_fs3.default.existsSync(themePath)) {
|
|
1347
1398
|
jsonResponse(res, 422, { error: `Manifest references missing theme: ${themeName}` });
|
|
1348
1399
|
return;
|
|
1349
1400
|
}
|
|
@@ -1356,7 +1407,7 @@ function themeFileApi(opts) {
|
|
|
1356
1407
|
const sanitized = sanitizeFileName(String(configFile) || "default");
|
|
1357
1408
|
const r = componentResource(comp);
|
|
1358
1409
|
const cfgPath = r.filePath(sanitized);
|
|
1359
|
-
if (!
|
|
1410
|
+
if (!import_fs3.default.existsSync(cfgPath)) {
|
|
1360
1411
|
jsonResponse(res, 422, {
|
|
1361
1412
|
error: `Manifest references missing config: ${comp}/${sanitized}`
|
|
1362
1413
|
});
|
|
@@ -1368,7 +1419,7 @@ function themeFileApi(opts) {
|
|
|
1368
1419
|
themesResource.setProductionName(themeName);
|
|
1369
1420
|
syncTokensToCss(themeName);
|
|
1370
1421
|
syncFontsToCss(themeName);
|
|
1371
|
-
const themeData = normalizeTheme(JSON.parse(
|
|
1422
|
+
const themeData = normalizeTheme(JSON.parse(import_fs3.default.readFileSync(themePath, "utf-8")));
|
|
1372
1423
|
themeData._fileName = themeName;
|
|
1373
1424
|
for (const [comp, configFile] of apply) {
|
|
1374
1425
|
const r = componentResource(comp);
|
|
@@ -1395,18 +1446,18 @@ function themeFileApi(opts) {
|
|
|
1395
1446
|
async function handleExportManifest({ params, res }) {
|
|
1396
1447
|
const [fileName] = params;
|
|
1397
1448
|
const manifestPath = manifestsResource.filePath(fileName);
|
|
1398
|
-
if (!
|
|
1449
|
+
if (!import_fs3.default.existsSync(manifestPath)) {
|
|
1399
1450
|
jsonResponse(res, 404, { error: "Manifest not found" });
|
|
1400
1451
|
return;
|
|
1401
1452
|
}
|
|
1402
|
-
const manifest = JSON.parse(
|
|
1453
|
+
const manifest = JSON.parse(import_fs3.default.readFileSync(manifestPath, "utf-8"));
|
|
1403
1454
|
const themeName = sanitizeFileName(manifest.theme || "default");
|
|
1404
1455
|
const themePath = themesResource.filePath(themeName);
|
|
1405
|
-
if (!
|
|
1456
|
+
if (!import_fs3.default.existsSync(themePath)) {
|
|
1406
1457
|
jsonResponse(res, 422, { error: `Manifest references missing theme: ${themeName}` });
|
|
1407
1458
|
return;
|
|
1408
1459
|
}
|
|
1409
|
-
const theme = JSON.parse(
|
|
1460
|
+
const theme = JSON.parse(import_fs3.default.readFileSync(themePath, "utf-8"));
|
|
1410
1461
|
const knownComponents = new Set(listComponentNames());
|
|
1411
1462
|
const componentConfigs = {};
|
|
1412
1463
|
for (const [comp, configFile] of Object.entries(manifest.componentConfigs ?? {})) {
|
|
@@ -1414,13 +1465,13 @@ function themeFileApi(opts) {
|
|
|
1414
1465
|
const sanitized = sanitizeFileName(String(configFile) || "default");
|
|
1415
1466
|
if (sanitized === "default") continue;
|
|
1416
1467
|
const cfgPath = componentResource(comp).filePath(sanitized);
|
|
1417
|
-
if (!
|
|
1468
|
+
if (!import_fs3.default.existsSync(cfgPath)) {
|
|
1418
1469
|
jsonResponse(res, 422, {
|
|
1419
1470
|
error: `Manifest references missing config: ${comp}/${sanitized}`
|
|
1420
1471
|
});
|
|
1421
1472
|
return;
|
|
1422
1473
|
}
|
|
1423
|
-
const cfg = JSON.parse(
|
|
1474
|
+
const cfg = JSON.parse(import_fs3.default.readFileSync(cfgPath, "utf-8"));
|
|
1424
1475
|
componentConfigs[`${comp}/${sanitized}`] = cfg;
|
|
1425
1476
|
}
|
|
1426
1477
|
const bundle = {
|
|
@@ -1442,7 +1493,7 @@ function themeFileApi(opts) {
|
|
|
1442
1493
|
}
|
|
1443
1494
|
function nextAvailableName2(resourceFilePath, baseName) {
|
|
1444
1495
|
return nextAvailableName(
|
|
1445
|
-
(n) =>
|
|
1496
|
+
(n) => import_fs3.default.existsSync(resourceFilePath(n)),
|
|
1446
1497
|
sanitizeFileName(baseName)
|
|
1447
1498
|
);
|
|
1448
1499
|
}
|
|
@@ -1484,7 +1535,7 @@ function themeFileApi(opts) {
|
|
|
1484
1535
|
themeBody.updatedAt = now;
|
|
1485
1536
|
if (!themeBody.createdAt) themeBody.createdAt = now;
|
|
1486
1537
|
themesResource.ensureDir();
|
|
1487
|
-
|
|
1538
|
+
import_fs3.default.writeFileSync(themesResource.filePath(finalThemeName), JSON.stringify(themeBody, null, 2));
|
|
1488
1539
|
const knownComponents = new Set(listComponentNames());
|
|
1489
1540
|
const componentRenames = {};
|
|
1490
1541
|
for (const [key, cfgValue] of Object.entries(bundle.componentConfigs)) {
|
|
@@ -1506,7 +1557,7 @@ function themeFileApi(opts) {
|
|
|
1506
1557
|
cfgBody.updatedAt = now;
|
|
1507
1558
|
if (!cfgBody.createdAt) cfgBody.createdAt = now;
|
|
1508
1559
|
r.ensureDir();
|
|
1509
|
-
|
|
1560
|
+
import_fs3.default.writeFileSync(r.filePath(finalName), JSON.stringify(cfgBody, null, 2));
|
|
1510
1561
|
}
|
|
1511
1562
|
const rewrittenManifest = {
|
|
1512
1563
|
...bundle.manifest,
|
|
@@ -1533,7 +1584,7 @@ function themeFileApi(opts) {
|
|
|
1533
1584
|
renames[`manifest:${originalManifestName}`] = finalManifestName;
|
|
1534
1585
|
}
|
|
1535
1586
|
manifestsResource.ensureDir();
|
|
1536
|
-
|
|
1587
|
+
import_fs3.default.writeFileSync(
|
|
1537
1588
|
manifestsResource.filePath(finalManifestName),
|
|
1538
1589
|
JSON.stringify(rewrittenManifest, null, 2)
|
|
1539
1590
|
);
|
|
@@ -1606,7 +1657,8 @@ function themeFileApi(opts) {
|
|
|
1606
1657
|
return {
|
|
1607
1658
|
define: {
|
|
1608
1659
|
__PROJECT_ROOT__: JSON.stringify(process.cwd()),
|
|
1609
|
-
__APP_VERSION__: JSON.stringify(PKG_VERSION)
|
|
1660
|
+
__APP_VERSION__: JSON.stringify(PKG_VERSION),
|
|
1661
|
+
__LIVE_TOKENS_API_BASE__: JSON.stringify(API_BASE)
|
|
1610
1662
|
}
|
|
1611
1663
|
};
|
|
1612
1664
|
},
|
|
@@ -1621,7 +1673,7 @@ function themeFileApi(opts) {
|
|
|
1621
1673
|
});
|
|
1622
1674
|
},
|
|
1623
1675
|
handleHotUpdate(ctx) {
|
|
1624
|
-
const normalized =
|
|
1676
|
+
const normalized = import_path3.default.resolve(ctx.file);
|
|
1625
1677
|
if (!normalized.startsWith(COMPONENTS_SRC_DIR)) return;
|
|
1626
1678
|
if (!normalized.endsWith(".svelte")) return;
|
|
1627
1679
|
const comp = componentNameFromFile(normalized);
|