@motion-proto/live-tokens 0.74.0 → 0.76.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-check-compliance/SKILL.md +33 -38
- package/.claude/skills/live-tokens-create-component/SKILL copy.md +196 -0
- package/.claude/skills/live-tokens-create-component/SKILL.md +198 -146
- package/.claude/skills/live-tokens-create-component/references/contract-tests.md +95 -52
- package/.claude/skills/live-tokens-create-component/references/intrinsics.md +2 -2
- package/.claude/skills/live-tokens-create-component/references/linked-siblings.md +2 -2
- package/.claude/skills/live-tokens-create-component/references/sketch-mode.md +12 -12
- package/.claude/skills/live-tokens-create-component/references/token-naming.md +2 -1
- package/.claude/skills/live-tokens-create-page/SKILL.md +187 -0
- package/.claude/skills/live-tokens-create-page/references/interaction-sources.md +66 -0
- package/.claude/skills/live-tokens-create-page/references/layout-sources.md +87 -0
- package/.claude/skills/live-tokens-create-theme/SKILL.md +52 -48
- package/.claude/skills/live-tokens-create-theme/references/design-directions.md +1 -1
- package/.claude/skills/live-tokens-fix-findings/SKILL.md +69 -60
- package/.claude/skills/live-tokens-pick-component/SKILL.md +64 -79
- package/.claude/skills/live-tokens-set-colors/SKILL.md +47 -38
- package/.claude/skills/live-tokens-set-geometry/SKILL.md +58 -35
- package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +5 -3
- package/.claude/skills/live-tokens-set-type/SKILL.md +30 -30
- package/CHANGELOG.md +138 -0
- package/README.md +17 -7
- package/bin/check-component.mjs +91 -19
- package/bin/check-page.mjs +102 -21
- package/bin/cli.mjs +87 -113
- package/bin/contractRunner.mjs +945 -0
- package/bin/create.mjs +1 -1
- package/bin/lib/catalogue.mjs +37 -30
- package/bin/lib/findings.mjs +46 -15
- package/bin/lib/report.mjs +3 -3
- package/bin/lib/tokenVocabulary.mjs +4 -4
- package/bin/migrate-routes.mjs +5 -5
- package/bin/migrate.mjs +4 -4
- package/bin/save-theme.mjs +8 -9
- package/bin/set-colors.mjs +9 -11
- package/bin/set-geometry.mjs +7 -7
- package/bin/set-type.mjs +5 -7
- package/bin/setup-claude.mjs +110 -0
- package/dist-plugin/{chunk-W6Y4BWFB.js → chunk-6WGFOJXO.js} +22 -0
- package/dist-plugin/{chunk-7VRTBGJT.js → chunk-PDNL4NC5.js} +9 -2
- package/dist-plugin/{chunk-V3YF6CGT.js → chunk-SWXRVZKT.js} +43 -1
- package/dist-plugin/{dataPaths-BhWzd5cL.d.cts → dataPaths-BpIK_Obx.d.cts} +1 -0
- package/dist-plugin/{dataPaths-BhWzd5cL.d.ts → dataPaths-BpIK_Obx.d.ts} +1 -0
- package/dist-plugin/index.cjs +310 -147
- package/dist-plugin/index.d.cts +1 -1
- package/dist-plugin/index.d.ts +1 -1
- package/dist-plugin/index.js +218 -122
- package/dist-plugin/migrateData/index.cjs +66 -2
- package/dist-plugin/migrateData/index.d.cts +1 -1
- package/dist-plugin/migrateData/index.d.ts +1 -1
- package/dist-plugin/migrateData/index.js +3 -3
- package/dist-plugin/setColors/index.cjs +61 -4
- package/dist-plugin/setColors/index.d.cts +1 -1
- package/dist-plugin/setColors/index.d.ts +1 -1
- package/dist-plugin/setColors/index.js +5 -5
- package/dist-plugin/setGeometry/index.cjs +107 -44
- package/dist-plugin/setGeometry/index.d.cts +5 -5
- package/dist-plugin/setGeometry/index.d.ts +5 -5
- package/dist-plugin/setGeometry/index.js +51 -45
- package/dist-plugin/setType/index.cjs +15 -0
- package/dist-plugin/setType/index.d.cts +1 -1
- package/dist-plugin/setType/index.d.ts +1 -1
- package/dist-plugin/setType/index.js +1 -1
- package/dist-plugin/tokensCssMigrations/index.d.cts +1 -1
- package/dist-plugin/tokensCssMigrations/index.d.ts +1 -1
- package/dist-plugin/tokensCssMigrations/index.js +1 -1
- package/package.json +35 -8
- package/src/app/site.css +19 -9
- package/src/editor/bootstrap.ts +2 -0
- package/src/editor/component-editor/CollapsibleSectionEditor.svelte +4 -4
- package/src/editor/component-editor/DialogEditor.svelte +4 -4
- package/src/editor/component-editor/MenuSelectEditor.svelte +4 -1
- package/src/editor/component-editor/SegmentedControlEditor.svelte +6 -1
- package/src/editor/component-editor/TabBarEditor.svelte +1 -1
- package/src/editor/component-editor/TableEditor.svelte +2 -2
- package/src/editor/component-editor/scaffolding/TokenLayout.svelte +6 -3
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +41 -20
- package/src/editor/core/components/adjustAliases.ts +59 -45
- package/src/editor/core/components/aliasKinds.ts +9 -5
- package/src/editor/core/preview/themePreview.ts +9 -2
- package/src/editor/core/sketch/sketchLayer.ts +22 -0
- package/src/editor/core/store/editorStore.ts +10 -1
- package/src/editor/core/themes/buildColors.ts +3 -3
- package/src/editor/core/themes/liveStateStream.ts +26 -0
- package/src/editor/core/themes/migrations/2026-09-07-stroke-role-renames.ts +52 -0
- package/src/editor/core/themes/migrations/index.ts +2 -0
- package/src/editor/core/themes/themeDocumentSync.ts +22 -11
- package/src/editor/core/themes/themeService.ts +9 -2
- package/src/editor/pages/ComponentEditorPage.svelte +17 -1
- package/src/editor/pages/liveTokensEditorHandle.ts +23 -0
- package/src/editor/skill-atlas/SkillAtlas.svelte +75 -573
- package/src/editor/skill-atlas/TreeCanvas.svelte +263 -0
- package/src/editor/skill-atlas/TreeNodeCard.svelte +136 -53
- package/src/editor/skill-atlas/edges.ts +31 -0
- package/src/editor/skill-atlas/skillSources.generated.ts +20 -19
- package/src/editor/skill-atlas/skillTrees.ts +19 -3840
- package/src/editor/skill-atlas/trees/check-compliance.ts +183 -0
- package/src/editor/skill-atlas/trees/create-component.ts +275 -0
- package/src/editor/skill-atlas/trees/create-page.ts +320 -0
- package/src/editor/skill-atlas/trees/create-theme.ts +255 -0
- package/src/editor/skill-atlas/trees/fix-findings.ts +469 -0
- package/src/editor/skill-atlas/trees/pick-component.ts +300 -0
- package/src/editor/skill-atlas/trees/set-colors.ts +148 -0
- package/src/editor/skill-atlas/trees/set-geometry.ts +136 -0
- package/src/editor/skill-atlas/trees/set-type.ts +142 -0
- package/src/editor/skill-atlas/types.ts +3 -4
- package/src/editor/skill-atlas/wireLayout.ts +287 -0
- package/src/live-tokens/data/themes/autumn.json +15 -15
- package/src/live-tokens/data/themes/halloween.json +15 -15
- package/src/live-tokens/data/themes/midnight-study.json +15 -15
- package/src/live-tokens/data/themes/ocean.json +15 -15
- package/src/live-tokens/data/themes/royal-velvet.json +15 -15
- package/src/live-tokens/data/themes/sketchy.json +15 -15
- package/src/live-tokens/data/themes/spring-meadow.json +15 -15
- package/src/live-tokens/data/themes/sunset.json +15 -15
- package/src/system/components/Badge.svelte +7 -0
- package/src/system/components/Button.svelte +7 -0
- package/src/system/components/Callout.svelte +10 -6
- package/src/system/components/Card.svelte +23 -4
- package/src/system/components/CodeSnippet.svelte +4 -3
- package/src/system/components/CollapsibleSection.svelte +23 -8
- package/src/system/components/CornerBadge.svelte +6 -0
- package/src/system/components/Dialog.svelte +13 -6
- package/src/system/components/IconButton.svelte +9 -0
- package/src/system/components/Image.svelte +8 -0
- package/src/system/components/ImageLightbox.svelte +6 -0
- package/src/system/components/InlineEditActions.svelte +7 -0
- package/src/system/components/Input.svelte +7 -0
- package/src/system/components/MenuSelect.svelte +7 -0
- package/src/system/components/Notification.svelte +7 -0
- package/src/system/components/Panel.svelte +6 -0
- package/src/system/components/ProgressBar.svelte +5 -0
- package/src/system/components/RadioButton.svelte +11 -5
- package/src/system/components/SectionDivider.svelte +8 -0
- package/src/system/components/SegmentedControl.svelte +6 -0
- package/src/system/components/SideNavigation.svelte +6 -0
- package/src/system/components/Slider.svelte +7 -4
- package/src/system/components/TabBar.svelte +15 -9
- package/src/system/components/Table.svelte +8 -3
- package/src/system/components/Toggle.svelte +4 -4
- package/src/system/components/Tooltip.svelte +6 -0
- package/src/testing-js/chunk-AO7EZHYV.js +776 -0
- package/src/testing-js/chunk-AO7EZHYV.js.map +1 -0
- package/src/testing-js/chunk-FAFOAWYL.js +39 -0
- package/src/testing-js/chunk-FAFOAWYL.js.map +1 -0
- package/src/testing-js/chunk-L73N4NSO.js +23 -0
- package/src/testing-js/chunk-L73N4NSO.js.map +1 -0
- package/src/testing-js/chunk-LXR3MN6N.js +3063 -0
- package/src/testing-js/chunk-LXR3MN6N.js.map +1 -0
- package/src/testing-js/chunk-ZMSX6CXR.js +53 -0
- package/src/testing-js/chunk-ZMSX6CXR.js.map +1 -0
- package/src/testing-js/component-alias.contract.js +81 -0
- package/src/testing-js/component-alias.contract.js.map +1 -0
- package/src/testing-js/component-editor.contract.js +62 -0
- package/src/testing-js/component-editor.contract.js.map +1 -0
- package/src/testing-js/component-render.contract.js +568 -0
- package/src/testing-js/component-render.contract.js.map +1 -0
- package/src/testing-js/index.d.ts +293 -0
- package/src/testing-js/index.js +222 -0
- package/src/testing-js/index.js.map +1 -0
- package/src/testing-js/registry.contract.js +39 -0
- package/src/testing-js/registry.contract.js.map +1 -0
- package/src/testing-js/vitest-BE6uGF31.d.ts +73 -0
- package/src/testing-js/vitest.d.ts +3 -0
- package/src/testing-js/vitest.js +13 -0
- package/src/testing-js/vitest.js.map +1 -0
- package/template/README.md +13 -0
- package/template/_gitignore +6 -0
- package/template/package.json +3 -1
- package/template/src/pages/Home.svelte +4 -18
- package/.claude/skills/live-tokens-build-page/SKILL.md +0 -103
- package/.claude/skills/live-tokens-build-page/references/layout-sources.md +0 -48
package/dist-plugin/index.cjs
CHANGED
|
@@ -38,8 +38,8 @@ __export(index_exports, {
|
|
|
38
38
|
module.exports = __toCommonJS(index_exports);
|
|
39
39
|
|
|
40
40
|
// vite-plugin/themeFileApi.ts
|
|
41
|
-
var
|
|
42
|
-
var
|
|
41
|
+
var import_fs5 = __toESM(require("fs"), 1);
|
|
42
|
+
var import_path5 = __toESM(require("path"), 1);
|
|
43
43
|
|
|
44
44
|
// src/editor/core/themes/parsers/globalRootBlock.ts
|
|
45
45
|
function extractGlobalRootBody(source) {
|
|
@@ -1664,6 +1664,47 @@ var colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys = {
|
|
|
1664
1664
|
}
|
|
1665
1665
|
};
|
|
1666
1666
|
|
|
1667
|
+
// src/editor/core/themes/migrations/2026-09-07-stroke-role-renames.ts
|
|
1668
|
+
var RENAMES2 = {
|
|
1669
|
+
tabbar: Object.fromEntries(
|
|
1670
|
+
["default", "hover", "active", "disabled"].map((s) => [
|
|
1671
|
+
`--tabbar-${s}-indicator-border-width`,
|
|
1672
|
+
`--tabbar-${s}-indicator-width`
|
|
1673
|
+
])
|
|
1674
|
+
),
|
|
1675
|
+
collapsiblesection: Object.fromEntries(
|
|
1676
|
+
["default", "hover"].flatMap((s) => [
|
|
1677
|
+
[`--collapsiblesection-divider-${s}-border`, `--collapsiblesection-divider-${s}-hairline-color`],
|
|
1678
|
+
[`--collapsiblesection-divider-${s}-border-width`, `--collapsiblesection-divider-${s}-hairline-thickness`]
|
|
1679
|
+
])
|
|
1680
|
+
),
|
|
1681
|
+
dialog: Object.fromEntries(
|
|
1682
|
+
["header", "footer"].flatMap((part) => [
|
|
1683
|
+
[`--dialog-${part}-border`, `--dialog-${part}-divider`],
|
|
1684
|
+
[`--dialog-${part}-border-width`, `--dialog-${part}-divider-width`]
|
|
1685
|
+
])
|
|
1686
|
+
),
|
|
1687
|
+
table: {
|
|
1688
|
+
"--table-default-header-border": "--table-default-header-divider",
|
|
1689
|
+
"--table-default-header-border-width": "--table-default-header-divider-width"
|
|
1690
|
+
}
|
|
1691
|
+
};
|
|
1692
|
+
var componentMigration_2026_09_07_strokeRoleRenames = {
|
|
1693
|
+
id: "2026-09-07-stroke-role-renames",
|
|
1694
|
+
fromVersion: 26,
|
|
1695
|
+
toVersion: 27,
|
|
1696
|
+
appliesTo: "component-config",
|
|
1697
|
+
apply(rawVars, meta) {
|
|
1698
|
+
const renames = meta.component ? RENAMES2[meta.component] : void 0;
|
|
1699
|
+
if (!renames) return { ...rawVars };
|
|
1700
|
+
const out = {};
|
|
1701
|
+
for (const [key, value] of Object.entries(rawVars)) {
|
|
1702
|
+
out[renames[key] ?? key] = value;
|
|
1703
|
+
}
|
|
1704
|
+
return out;
|
|
1705
|
+
}
|
|
1706
|
+
};
|
|
1707
|
+
|
|
1667
1708
|
// src/editor/core/themes/migrations/index.ts
|
|
1668
1709
|
var MIGRATIONS = [
|
|
1669
1710
|
colorsAndTypeMigration_2026_04_24_legacyKeysAndBgToCanvas,
|
|
@@ -1699,7 +1740,8 @@ var MIGRATIONS = [
|
|
|
1699
1740
|
componentMigration_2026_09_01_tabbarActiveTint,
|
|
1700
1741
|
componentMigration_2026_09_01_gateSuffixEnabled,
|
|
1701
1742
|
componentMigration_2026_09_02_sectiondividerDropTitleOutline,
|
|
1702
|
-
colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys
|
|
1743
|
+
colorsAndTypeMigration_2026_09_03_dropLegacyComponentKeys,
|
|
1744
|
+
componentMigration_2026_09_07_strokeRoleRenames
|
|
1703
1745
|
];
|
|
1704
1746
|
function countFor(kind) {
|
|
1705
1747
|
return MIGRATIONS.filter((m) => m.appliesTo === kind).length;
|
|
@@ -1815,9 +1857,11 @@ function versionedFileResourceServer(opts) {
|
|
|
1815
1857
|
function ensureMeta() {
|
|
1816
1858
|
if (!import_fs.default.existsSync(activePath)) {
|
|
1817
1859
|
import_fs.default.writeFileSync(activePath, JSON.stringify({ activeFile: defaultName }));
|
|
1860
|
+
opts.onWrite?.(activePath);
|
|
1818
1861
|
}
|
|
1819
1862
|
if (!import_fs.default.existsSync(productionPath)) {
|
|
1820
1863
|
import_fs.default.writeFileSync(productionPath, JSON.stringify({ productionFile: defaultName }));
|
|
1864
|
+
opts.onWrite?.(productionPath);
|
|
1821
1865
|
}
|
|
1822
1866
|
}
|
|
1823
1867
|
function filePath(name) {
|
|
@@ -1882,9 +1926,11 @@ function versionedFileResourceServer(opts) {
|
|
|
1882
1926
|
}
|
|
1883
1927
|
function setActiveName(name) {
|
|
1884
1928
|
import_fs.default.writeFileSync(activePath, JSON.stringify({ activeFile: name }));
|
|
1929
|
+
opts.onWrite?.(activePath);
|
|
1885
1930
|
}
|
|
1886
1931
|
function setProductionName(name) {
|
|
1887
1932
|
import_fs.default.writeFileSync(productionPath, JSON.stringify({ productionFile: name }));
|
|
1933
|
+
opts.onWrite?.(productionPath);
|
|
1888
1934
|
}
|
|
1889
1935
|
function hasWorking() {
|
|
1890
1936
|
return import_fs.default.existsSync(workingPath);
|
|
@@ -1900,9 +1946,12 @@ function versionedFileResourceServer(opts) {
|
|
|
1900
1946
|
function writeWorking(data) {
|
|
1901
1947
|
ensureDir();
|
|
1902
1948
|
import_fs.default.writeFileSync(workingPath, JSON.stringify(data, null, 2));
|
|
1949
|
+
opts.onWrite?.(workingPath);
|
|
1903
1950
|
}
|
|
1904
1951
|
function clearWorking() {
|
|
1905
|
-
if (import_fs.default.existsSync(workingPath))
|
|
1952
|
+
if (!import_fs.default.existsSync(workingPath)) return;
|
|
1953
|
+
import_fs.default.unlinkSync(workingPath);
|
|
1954
|
+
opts.onWrite?.(workingPath);
|
|
1906
1955
|
}
|
|
1907
1956
|
return {
|
|
1908
1957
|
dir,
|
|
@@ -1955,6 +2004,67 @@ async function dispatch(req, res, routes) {
|
|
|
1955
2004
|
return false;
|
|
1956
2005
|
}
|
|
1957
2006
|
|
|
2007
|
+
// vite-plugin/files/dataTreeWatch.ts
|
|
2008
|
+
var import_fs2 = __toESM(require("fs"), 1);
|
|
2009
|
+
var import_path2 = __toESM(require("path"), 1);
|
|
2010
|
+
function fingerprint(file) {
|
|
2011
|
+
try {
|
|
2012
|
+
return import_fs2.default.readFileSync(file, "utf-8");
|
|
2013
|
+
} catch {
|
|
2014
|
+
return null;
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
function dataTreeWatch(opts) {
|
|
2018
|
+
const debounceMs = opts.debounceMs ?? 100;
|
|
2019
|
+
const ownWrites = /* @__PURE__ */ new Map();
|
|
2020
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
2021
|
+
let watchers = [];
|
|
2022
|
+
let timer = null;
|
|
2023
|
+
function noteOwnWrite(file) {
|
|
2024
|
+
const resolved = import_path2.default.resolve(file);
|
|
2025
|
+
ownWrites.set(resolved, fingerprint(resolved));
|
|
2026
|
+
}
|
|
2027
|
+
function onEvent(dir, filename) {
|
|
2028
|
+
if (!filename) return;
|
|
2029
|
+
const file = import_path2.default.resolve(dir, filename.toString());
|
|
2030
|
+
if (!opts.isLive(file)) return;
|
|
2031
|
+
if (ownWrites.has(file) && ownWrites.get(file) === fingerprint(file)) return;
|
|
2032
|
+
ownWrites.delete(file);
|
|
2033
|
+
if (timer) clearTimeout(timer);
|
|
2034
|
+
timer = setTimeout(() => {
|
|
2035
|
+
timer = null;
|
|
2036
|
+
for (const listener of listeners) listener();
|
|
2037
|
+
}, debounceMs);
|
|
2038
|
+
}
|
|
2039
|
+
function start() {
|
|
2040
|
+
for (const dir of opts.dirs) {
|
|
2041
|
+
if (!import_fs2.default.existsSync(dir)) continue;
|
|
2042
|
+
const watcher = import_fs2.default.watch(
|
|
2043
|
+
dir,
|
|
2044
|
+
{ recursive: true, persistent: false },
|
|
2045
|
+
(_event, filename) => onEvent(dir, filename)
|
|
2046
|
+
);
|
|
2047
|
+
watcher.on("error", () => watcher.close());
|
|
2048
|
+
watchers.push(watcher);
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
function stop() {
|
|
2052
|
+
for (const watcher of watchers) watcher.close();
|
|
2053
|
+
watchers = [];
|
|
2054
|
+
if (timer) clearTimeout(timer);
|
|
2055
|
+
timer = null;
|
|
2056
|
+
}
|
|
2057
|
+
function subscribe(listener) {
|
|
2058
|
+
if (listeners.size === 0) start();
|
|
2059
|
+
listeners.add(listener);
|
|
2060
|
+
return () => {
|
|
2061
|
+
listeners.delete(listener);
|
|
2062
|
+
if (listeners.size === 0) stop();
|
|
2063
|
+
};
|
|
2064
|
+
}
|
|
2065
|
+
return { noteOwnWrite, subscribe };
|
|
2066
|
+
}
|
|
2067
|
+
|
|
1958
2068
|
// src/editor/core/themes/migrateComponentConfig.ts
|
|
1959
2069
|
function migrateComponentConfig(component, aliasesIn, rawConfig, fileVersion) {
|
|
1960
2070
|
const stringPart = {};
|
|
@@ -2671,9 +2781,19 @@ function nextAvailableName(exists, baseName, maxAttempts = 1e3) {
|
|
|
2671
2781
|
}
|
|
2672
2782
|
|
|
2673
2783
|
// vite-plugin/files/dataPaths.ts
|
|
2674
|
-
var
|
|
2675
|
-
var
|
|
2784
|
+
var import_fs3 = __toESM(require("fs"), 1);
|
|
2785
|
+
var import_path3 = __toESM(require("path"), 1);
|
|
2676
2786
|
var DEFAULT_DATA_DIR = "src/live-tokens/data";
|
|
2787
|
+
var TEST_DATA_DIR_ENV = "LIVE_TOKENS_TEST_DATA_DIR";
|
|
2788
|
+
function testDataDir() {
|
|
2789
|
+
const raw = process.env[TEST_DATA_DIR_ENV];
|
|
2790
|
+
return raw && raw.trim() !== "" ? import_path3.default.resolve(raw.trim()) : void 0;
|
|
2791
|
+
}
|
|
2792
|
+
var TEST_PACKAGE_DATA_DIR_ENV = "LIVE_TOKENS_TEST_PACKAGE_DATA_DIR";
|
|
2793
|
+
function testPackageDataDir() {
|
|
2794
|
+
const raw = process.env[TEST_PACKAGE_DATA_DIR_ENV];
|
|
2795
|
+
return raw && raw.trim() !== "" ? import_path3.default.resolve(raw.trim()) : void 0;
|
|
2796
|
+
}
|
|
2677
2797
|
var KNOWN_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
2678
2798
|
"dataDir",
|
|
2679
2799
|
"colorsAndTypeDir",
|
|
@@ -2688,9 +2808,9 @@ var cached = null;
|
|
|
2688
2808
|
function readLiveTokensConfig() {
|
|
2689
2809
|
if (cached) return cached;
|
|
2690
2810
|
try {
|
|
2691
|
-
const configPath =
|
|
2692
|
-
if (!
|
|
2693
|
-
const parsed = JSON.parse(
|
|
2811
|
+
const configPath = import_path3.default.resolve("live-tokens.config.json");
|
|
2812
|
+
if (!import_fs3.default.existsSync(configPath)) return cached = {};
|
|
2813
|
+
const parsed = JSON.parse(import_fs3.default.readFileSync(configPath, "utf-8"));
|
|
2694
2814
|
if (!parsed || typeof parsed !== "object") return cached = {};
|
|
2695
2815
|
const unknown = Object.keys(parsed).filter(
|
|
2696
2816
|
(k) => k !== "$schema" && !KNOWN_CONFIG_KEYS.has(k)
|
|
@@ -2707,71 +2827,81 @@ function readLiveTokensConfig() {
|
|
|
2707
2827
|
}
|
|
2708
2828
|
}
|
|
2709
2829
|
function resolveDataDirs(opts = {}) {
|
|
2830
|
+
const isolated = testDataDir();
|
|
2831
|
+
if (isolated) {
|
|
2832
|
+
return {
|
|
2833
|
+
dataDir: isolated,
|
|
2834
|
+
colorsAndTypeDir: import_path3.default.join(isolated, "colors-and-type"),
|
|
2835
|
+
componentConfigsDir: import_path3.default.join(isolated, "component-configs"),
|
|
2836
|
+
themesDir: import_path3.default.join(isolated, "themes"),
|
|
2837
|
+
sketchStylesDir: import_path3.default.join(isolated, "sketch-styles")
|
|
2838
|
+
};
|
|
2839
|
+
}
|
|
2710
2840
|
const fileConfig = readLiveTokensConfig();
|
|
2711
2841
|
const dataDirRaw = opts.dataDir ?? fileConfig.dataDir ?? DEFAULT_DATA_DIR;
|
|
2712
|
-
const dataDir =
|
|
2713
|
-
const sub = (name) =>
|
|
2842
|
+
const dataDir = import_path3.default.resolve(dataDirRaw);
|
|
2843
|
+
const sub = (name) => import_path3.default.resolve(dataDir, name);
|
|
2714
2844
|
return {
|
|
2715
2845
|
dataDir,
|
|
2716
|
-
colorsAndTypeDir: opts.colorsAndTypeDir ?
|
|
2717
|
-
componentConfigsDir: opts.componentConfigsDir ?
|
|
2718
|
-
themesDir: opts.themesDir ?
|
|
2846
|
+
colorsAndTypeDir: opts.colorsAndTypeDir ? import_path3.default.resolve(opts.colorsAndTypeDir) : fileConfig.colorsAndTypeDir ? import_path3.default.resolve(fileConfig.colorsAndTypeDir) : sub("colors-and-type"),
|
|
2847
|
+
componentConfigsDir: opts.componentConfigsDir ? import_path3.default.resolve(opts.componentConfigsDir) : fileConfig.componentConfigsDir ? import_path3.default.resolve(fileConfig.componentConfigsDir) : sub("component-configs"),
|
|
2848
|
+
themesDir: opts.themesDir ? import_path3.default.resolve(opts.themesDir) : fileConfig.themesDir ? import_path3.default.resolve(fileConfig.themesDir) : sub("themes"),
|
|
2719
2849
|
sketchStylesDir: sub("sketch-styles"),
|
|
2720
|
-
legacyManifestsDir: fileConfig.manifestsDir ?
|
|
2850
|
+
legacyManifestsDir: fileConfig.manifestsDir ? import_path3.default.resolve(fileConfig.manifestsDir) : void 0
|
|
2721
2851
|
};
|
|
2722
2852
|
}
|
|
2723
2853
|
|
|
2724
2854
|
// vite-plugin/files/legacyLayout.ts
|
|
2725
|
-
var
|
|
2726
|
-
var
|
|
2855
|
+
var import_fs4 = __toESM(require("fs"), 1);
|
|
2856
|
+
var import_path4 = __toESM(require("path"), 1);
|
|
2727
2857
|
function jsonFiles(dir) {
|
|
2728
|
-
if (!
|
|
2858
|
+
if (!import_fs4.default.existsSync(dir)) return [];
|
|
2729
2859
|
try {
|
|
2730
|
-
return
|
|
2860
|
+
return import_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => import_path4.default.join(dir, f));
|
|
2731
2861
|
} catch {
|
|
2732
2862
|
return [];
|
|
2733
2863
|
}
|
|
2734
2864
|
}
|
|
2735
2865
|
function isDirectory(dir) {
|
|
2736
2866
|
try {
|
|
2737
|
-
return
|
|
2867
|
+
return import_fs4.default.statSync(dir).isDirectory();
|
|
2738
2868
|
} catch {
|
|
2739
2869
|
return false;
|
|
2740
2870
|
}
|
|
2741
2871
|
}
|
|
2742
2872
|
function parseJsonFile(file) {
|
|
2743
2873
|
try {
|
|
2744
|
-
return JSON.parse(
|
|
2874
|
+
return JSON.parse(import_fs4.default.readFileSync(file, "utf-8"));
|
|
2745
2875
|
} catch {
|
|
2746
2876
|
return null;
|
|
2747
2877
|
}
|
|
2748
2878
|
}
|
|
2749
2879
|
function holdsATheme(themesDir) {
|
|
2750
2880
|
return jsonFiles(themesDir).some((file) => {
|
|
2751
|
-
if (
|
|
2881
|
+
if (import_path4.default.basename(file).startsWith("_")) return false;
|
|
2752
2882
|
const raw = parseJsonFile(file);
|
|
2753
2883
|
if (!raw || typeof raw !== "object") return false;
|
|
2754
2884
|
return "colorsAndType" in raw || "theme" in raw;
|
|
2755
2885
|
});
|
|
2756
2886
|
}
|
|
2757
2887
|
function detectLegacyLayout(input) {
|
|
2758
|
-
const manifestsDir = input.configuredManifestsDir ??
|
|
2888
|
+
const manifestsDir = input.configuredManifestsDir ?? import_path4.default.join(input.dataDir, "manifests");
|
|
2759
2889
|
const themesHoldAThemeFile = holdsATheme(input.themesDir);
|
|
2760
2890
|
if (isDirectory(manifestsDir) && !themesHoldAThemeFile) {
|
|
2761
2891
|
return { manifestsDir, evidence: `${manifestsDir} is the pre-0.48 whole-theme directory` };
|
|
2762
2892
|
}
|
|
2763
2893
|
if (jsonFiles(input.colorsAndTypeDir).length > 0) return null;
|
|
2764
2894
|
for (const file of jsonFiles(input.themesDir)) {
|
|
2765
|
-
if (
|
|
2895
|
+
if (import_path4.default.basename(file).startsWith("_")) continue;
|
|
2766
2896
|
if (isColorsAndTypeShaped(parseJsonFile(file))) {
|
|
2767
2897
|
return { manifestsDir, evidence: `${file} is a colors-and-type file, not a theme` };
|
|
2768
2898
|
}
|
|
2769
2899
|
}
|
|
2770
|
-
const pointer = ["_active.json", "_production.json"].map((name) =>
|
|
2771
|
-
if (pointer && !themesHoldAThemeFile && !
|
|
2900
|
+
const pointer = ["_active.json", "_production.json"].map((name) => import_path4.default.join(input.themesDir, name)).find((p) => import_fs4.default.existsSync(p));
|
|
2901
|
+
if (pointer && !themesHoldAThemeFile && !import_fs4.default.existsSync(input.colorsAndTypeDir)) {
|
|
2772
2902
|
return {
|
|
2773
2903
|
manifestsDir,
|
|
2774
|
-
evidence: `${pointer} points at colors and type, and there is no ${
|
|
2904
|
+
evidence: `${pointer} points at colors and type, and there is no ${import_path4.default.basename(input.colorsAndTypeDir)} directory`
|
|
2775
2905
|
};
|
|
2776
2906
|
}
|
|
2777
2907
|
return null;
|
|
@@ -3027,7 +3157,7 @@ var tokensCssMigration_2026_06_04_easingColorAndTypescaleAdditions = {
|
|
|
3027
3157
|
};
|
|
3028
3158
|
|
|
3029
3159
|
// vite-plugin/tokensCssMigrations/migrations/2026-07-20-line-height-rename.ts
|
|
3030
|
-
var
|
|
3160
|
+
var RENAMES3 = [
|
|
3031
3161
|
["--line-height-xs", "--line-height-none"],
|
|
3032
3162
|
["--line-height-sm", "--line-height-tighter"],
|
|
3033
3163
|
["--line-height-md", "--line-height-normal"],
|
|
@@ -3047,7 +3177,7 @@ var tokensCssMigration_2026_07_20_lineHeightRename = {
|
|
|
3047
3177
|
description: "Reshape --line-height-{xs..xl} to leading vocabulary (none/tightest/tighter/tight/normal/relaxed); retire the 2.0 slot",
|
|
3048
3178
|
apply(css) {
|
|
3049
3179
|
let out = css;
|
|
3050
|
-
for (const [oldName, newName] of
|
|
3180
|
+
for (const [oldName, newName] of RENAMES3) out = renameToken2(out, oldName, newName);
|
|
3051
3181
|
out = removeToken(out, "--line-height-xl");
|
|
3052
3182
|
out = ensureScale(out, {
|
|
3053
3183
|
anchorPrefixes: ["--line-height-", "--font-size-", "--font-weight-", "--font-"],
|
|
@@ -3280,7 +3410,7 @@ var tokensCssMigration_2026_08_27_editorialLargeSteps = {
|
|
|
3280
3410
|
};
|
|
3281
3411
|
|
|
3282
3412
|
// vite-plugin/tokensCssMigrations/migrations/2026-09-01-scrim-rename.ts
|
|
3283
|
-
var
|
|
3413
|
+
var RENAMES4 = [
|
|
3284
3414
|
["--overlay-low", "--scrim-low"],
|
|
3285
3415
|
["--overlay-high", "--scrim-high"],
|
|
3286
3416
|
["--overlay", "--scrim"]
|
|
@@ -3291,7 +3421,7 @@ var tokensCssMigration_2026_09_01_scrimRename = {
|
|
|
3291
3421
|
description: "Rename --overlay-{low,base,high} to --scrim-*; a scrim dims what is behind it",
|
|
3292
3422
|
apply(css) {
|
|
3293
3423
|
let out = css;
|
|
3294
|
-
for (const [oldName, newName] of
|
|
3424
|
+
for (const [oldName, newName] of RENAMES4) out = renameToken2(out, oldName, newName);
|
|
3295
3425
|
return out;
|
|
3296
3426
|
}
|
|
3297
3427
|
};
|
|
@@ -3382,14 +3512,14 @@ var import_node_url = require("url");
|
|
|
3382
3512
|
var import_meta = {};
|
|
3383
3513
|
var PKG_VERSION = (() => {
|
|
3384
3514
|
try {
|
|
3385
|
-
let dir =
|
|
3515
|
+
let dir = import_path5.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
3386
3516
|
for (let i = 0; i < 4; i++) {
|
|
3387
|
-
const p =
|
|
3388
|
-
if (
|
|
3389
|
-
const json = JSON.parse(
|
|
3517
|
+
const p = import_path5.default.join(dir, "package.json");
|
|
3518
|
+
if (import_fs5.default.existsSync(p)) {
|
|
3519
|
+
const json = JSON.parse(import_fs5.default.readFileSync(p, "utf-8"));
|
|
3390
3520
|
if (json?.name === "@motion-proto/live-tokens") return json.version ?? "";
|
|
3391
3521
|
}
|
|
3392
|
-
const up =
|
|
3522
|
+
const up = import_path5.default.dirname(dir);
|
|
3393
3523
|
if (up === dir) break;
|
|
3394
3524
|
dir = up;
|
|
3395
3525
|
}
|
|
@@ -3433,56 +3563,64 @@ function themeFileApi(opts) {
|
|
|
3433
3563
|
const COMPONENT_CONFIGS_DIR = dataDirs.componentConfigsDir;
|
|
3434
3564
|
const THEMES_DIR = dataDirs.themesDir;
|
|
3435
3565
|
const SKETCH_STYLES_DIR = dataDirs.sketchStylesDir;
|
|
3436
|
-
const CSS_PATH =
|
|
3437
|
-
const
|
|
3438
|
-
const
|
|
3566
|
+
const CSS_PATH = import_path5.default.resolve(opts.tokensCssPath);
|
|
3567
|
+
const ISOLATED_DATA_DIR = testDataDir();
|
|
3568
|
+
const GENERATED_CSS_PATH = ISOLATED_DATA_DIR ? import_path5.default.join(ISOLATED_DATA_DIR, "tokens.generated.css") : opts.tokensGeneratedCssPath ? import_path5.default.resolve(opts.tokensGeneratedCssPath) : import_path5.default.join(dataDirs.dataDir, "tokens.generated.css");
|
|
3569
|
+
const FONTS_CSS_PATH = ISOLATED_DATA_DIR ? import_path5.default.join(ISOLATED_DATA_DIR, "fonts.css") : opts.fontsCssPath ? import_path5.default.resolve(opts.fontsCssPath) : import_path5.default.join(import_path5.default.dirname(CSS_PATH), "fonts.css");
|
|
3439
3570
|
const API_BASE = opts.apiBase ?? "/api/live-tokens";
|
|
3440
|
-
const consumerComponentDirs = opts.componentsSrcDir ? [
|
|
3441
|
-
const packageComponentsDir =
|
|
3442
|
-
|
|
3571
|
+
const consumerComponentDirs = opts.componentsSrcDir ? [import_path5.default.resolve(opts.componentsSrcDir)] : [import_path5.default.resolve("src/components"), import_path5.default.resolve("src/system/components")];
|
|
3572
|
+
const packageComponentsDir = import_path5.default.resolve(
|
|
3573
|
+
import_path5.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url)),
|
|
3443
3574
|
"..",
|
|
3444
3575
|
"src",
|
|
3445
3576
|
"system",
|
|
3446
3577
|
"components"
|
|
3447
3578
|
);
|
|
3448
|
-
const packageDataDir =
|
|
3449
|
-
|
|
3579
|
+
const packageDataDir = testPackageDataDir() ?? import_path5.default.resolve(
|
|
3580
|
+
import_path5.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url)),
|
|
3450
3581
|
"..",
|
|
3451
3582
|
"src",
|
|
3452
3583
|
"live-tokens",
|
|
3453
3584
|
"data"
|
|
3454
3585
|
);
|
|
3455
|
-
const packageColorsAndTypeDir =
|
|
3456
|
-
const packageThemesDir =
|
|
3457
|
-
const packageComponentConfigsDir =
|
|
3458
|
-
const packageSketchStylesDir =
|
|
3586
|
+
const packageColorsAndTypeDir = import_path5.default.join(packageDataDir, "colors-and-type");
|
|
3587
|
+
const packageThemesDir = import_path5.default.join(packageDataDir, "themes");
|
|
3588
|
+
const packageComponentConfigsDir = import_path5.default.join(packageDataDir, "component-configs");
|
|
3589
|
+
const packageSketchStylesDir = import_path5.default.join(packageDataDir, "sketch-styles");
|
|
3459
3590
|
function shippedNames(dataDir, subdir) {
|
|
3460
3591
|
try {
|
|
3461
|
-
const pkgRoot =
|
|
3462
|
-
const pkg = JSON.parse(
|
|
3592
|
+
const pkgRoot = import_path5.default.resolve(dataDir, "..", "..", "..");
|
|
3593
|
+
const pkg = JSON.parse(import_fs5.default.readFileSync(import_path5.default.join(pkgRoot, "package.json"), "utf-8"));
|
|
3463
3594
|
const files = Array.isArray(pkg.files) ? pkg.files : [];
|
|
3464
3595
|
const owned = new RegExp(`^src/live-tokens/data/${subdir}/[^/]+\\.json$`);
|
|
3465
|
-
return files.filter((f) => owned.test(f)).map((f) =>
|
|
3596
|
+
return files.filter((f) => owned.test(f)).map((f) => import_path5.default.basename(f, ".json"));
|
|
3466
3597
|
} catch {
|
|
3467
3598
|
return [];
|
|
3468
3599
|
}
|
|
3469
3600
|
}
|
|
3470
3601
|
const COMPONENTS_SCAN_DIRS = [...consumerComponentDirs];
|
|
3471
|
-
if (!COMPONENTS_SCAN_DIRS.includes(packageComponentsDir) &&
|
|
3602
|
+
if (!COMPONENTS_SCAN_DIRS.includes(packageComponentsDir) && import_fs5.default.existsSync(packageComponentsDir)) {
|
|
3472
3603
|
COMPONENTS_SCAN_DIRS.push(packageComponentsDir);
|
|
3473
3604
|
}
|
|
3605
|
+
const isLiveStateFile = (file) => file === import_path5.default.join(THEMES_DIR, "_active.json") || import_path5.default.basename(file) === "_working.json" && (file.startsWith(COLORS_AND_TYPE_DIR + import_path5.default.sep) || file.startsWith(COMPONENT_CONFIGS_DIR + import_path5.default.sep));
|
|
3606
|
+
const liveWatch = dataTreeWatch({
|
|
3607
|
+
dirs: [COLORS_AND_TYPE_DIR, COMPONENT_CONFIGS_DIR, THEMES_DIR],
|
|
3608
|
+
isLive: isLiveStateFile
|
|
3609
|
+
});
|
|
3474
3610
|
const colorsAndTypeResource = versionedFileResourceServer({
|
|
3475
3611
|
dir: COLORS_AND_TYPE_DIR,
|
|
3476
3612
|
packageDir: packageColorsAndTypeDir,
|
|
3477
|
-
packageOwnedNames: shippedNames(packageDataDir, "colors-and-type")
|
|
3613
|
+
packageOwnedNames: shippedNames(packageDataDir, "colors-and-type"),
|
|
3614
|
+
onWrite: liveWatch.noteOwnWrite
|
|
3478
3615
|
});
|
|
3479
3616
|
const componentResourceCache = /* @__PURE__ */ new Map();
|
|
3480
3617
|
function componentResource(comp) {
|
|
3481
3618
|
let r = componentResourceCache.get(comp);
|
|
3482
3619
|
if (!r) {
|
|
3483
3620
|
r = versionedFileResourceServer({
|
|
3484
|
-
dir:
|
|
3485
|
-
packageDir:
|
|
3621
|
+
dir: import_path5.default.join(COMPONENT_CONFIGS_DIR, comp),
|
|
3622
|
+
packageDir: import_path5.default.join(packageComponentConfigsDir, comp),
|
|
3623
|
+
onWrite: liveWatch.noteOwnWrite
|
|
3486
3624
|
});
|
|
3487
3625
|
componentResourceCache.set(comp, r);
|
|
3488
3626
|
}
|
|
@@ -3490,7 +3628,8 @@ function themeFileApi(opts) {
|
|
|
3490
3628
|
}
|
|
3491
3629
|
const themesResource = versionedFileResourceServer({
|
|
3492
3630
|
dir: THEMES_DIR,
|
|
3493
|
-
packageDir: packageThemesDir
|
|
3631
|
+
packageDir: packageThemesDir,
|
|
3632
|
+
onWrite: liveWatch.noteOwnWrite
|
|
3494
3633
|
});
|
|
3495
3634
|
const sketchStylesResource = versionedFileResourceServer({
|
|
3496
3635
|
dir: SKETCH_STYLES_DIR,
|
|
@@ -3571,7 +3710,7 @@ function themeFileApi(opts) {
|
|
|
3571
3710
|
const productionThemeName = themesResource.getProductionName();
|
|
3572
3711
|
const productionTheme = readTheme(productionThemeName)?.theme ?? null;
|
|
3573
3712
|
if (themesResource.existingPath(productionThemeName) !== null && !productionTheme?.colorsAndType) {
|
|
3574
|
-
const tail = `${
|
|
3713
|
+
const tail = `${import_path5.default.basename(GENERATED_CSS_PATH)} was left as it was.`;
|
|
3575
3714
|
throw new Error(
|
|
3576
3715
|
unreadableThemeReason(productionThemeName) === "colors-and-type" ? `[live-tokens] ${notAThemeError(productionThemeName)} ${tail}` : `[live-tokens] Production theme "${productionThemeName}" is unreadable, so ${tail} Repair the theme file or adopt another theme.`
|
|
3577
3716
|
);
|
|
@@ -3609,7 +3748,7 @@ function themeFileApi(opts) {
|
|
|
3609
3748
|
}
|
|
3610
3749
|
}
|
|
3611
3750
|
let componentOverrideCount = 0;
|
|
3612
|
-
if (
|
|
3751
|
+
if (import_fs5.default.existsSync(COMPONENT_CONFIGS_DIR)) {
|
|
3613
3752
|
const blocks = [];
|
|
3614
3753
|
for (const comp of listComponentNames()) {
|
|
3615
3754
|
const prodCfg = productionTheme?.componentConfigs[comp];
|
|
@@ -3642,12 +3781,12 @@ function themeFileApi(opts) {
|
|
|
3642
3781
|
lines.push("");
|
|
3643
3782
|
}
|
|
3644
3783
|
}
|
|
3645
|
-
if (!
|
|
3646
|
-
|
|
3784
|
+
if (!import_fs5.default.existsSync(import_path5.default.dirname(GENERATED_CSS_PATH))) {
|
|
3785
|
+
import_fs5.default.mkdirSync(import_path5.default.dirname(GENERATED_CSS_PATH), { recursive: true });
|
|
3647
3786
|
}
|
|
3648
|
-
|
|
3787
|
+
import_fs5.default.writeFileSync(GENERATED_CSS_PATH, lines.join("\n"));
|
|
3649
3788
|
console.log(
|
|
3650
|
-
`[regenerateTokensCss] Wrote ${
|
|
3789
|
+
`[regenerateTokensCss] Wrote ${import_path5.default.basename(GENERATED_CSS_PATH)} (${colorsAndTypeVarCount} theme vars, ${componentOverrideCount} component overrides)`
|
|
3651
3790
|
);
|
|
3652
3791
|
}
|
|
3653
3792
|
function syncFontsToCss(colorsAndTypeData) {
|
|
@@ -3675,18 +3814,18 @@ function themeFileApi(opts) {
|
|
|
3675
3814
|
lines.push("");
|
|
3676
3815
|
}
|
|
3677
3816
|
const content = lines.join("\n");
|
|
3678
|
-
if (!
|
|
3679
|
-
|
|
3817
|
+
if (!import_fs5.default.existsSync(import_path5.default.dirname(FONTS_CSS_PATH))) {
|
|
3818
|
+
import_fs5.default.mkdirSync(import_path5.default.dirname(FONTS_CSS_PATH), { recursive: true });
|
|
3680
3819
|
}
|
|
3681
|
-
|
|
3682
|
-
console.log(`[syncFontsToCss] Wrote ${sources.length} source(s) into ${
|
|
3820
|
+
import_fs5.default.writeFileSync(FONTS_CSS_PATH, content);
|
|
3821
|
+
console.log(`[syncFontsToCss] Wrote ${sources.length} source(s) into ${import_path5.default.basename(FONTS_CSS_PATH)}`);
|
|
3683
3822
|
}
|
|
3684
3823
|
function componentNameFromFile(filePath) {
|
|
3685
|
-
return
|
|
3824
|
+
return import_path5.default.basename(filePath, ".svelte").toLowerCase();
|
|
3686
3825
|
}
|
|
3687
3826
|
function isThemeAwareComponent(filePath) {
|
|
3688
3827
|
try {
|
|
3689
|
-
const source =
|
|
3828
|
+
const source = import_fs5.default.readFileSync(filePath, "utf-8");
|
|
3690
3829
|
return /:global\(:root\)\s*\{/.test(source);
|
|
3691
3830
|
} catch {
|
|
3692
3831
|
return false;
|
|
@@ -3695,10 +3834,10 @@ function themeFileApi(opts) {
|
|
|
3695
3834
|
function listComponentSourcePaths() {
|
|
3696
3835
|
const byName = /* @__PURE__ */ new Map();
|
|
3697
3836
|
for (const dir of COMPONENTS_SCAN_DIRS) {
|
|
3698
|
-
if (!
|
|
3699
|
-
for (const f of
|
|
3837
|
+
if (!import_fs5.default.existsSync(dir)) continue;
|
|
3838
|
+
for (const f of import_fs5.default.readdirSync(dir)) {
|
|
3700
3839
|
if (!f.endsWith(".svelte")) continue;
|
|
3701
|
-
const full =
|
|
3840
|
+
const full = import_path5.default.join(dir, f);
|
|
3702
3841
|
if (!isThemeAwareComponent(full)) continue;
|
|
3703
3842
|
const name = componentNameFromFile(f);
|
|
3704
3843
|
if (!byName.has(name)) byName.set(name, full);
|
|
@@ -3712,18 +3851,18 @@ function themeFileApi(opts) {
|
|
|
3712
3851
|
function warnOnTokenDrift(log) {
|
|
3713
3852
|
let tokensCss = "";
|
|
3714
3853
|
try {
|
|
3715
|
-
tokensCss =
|
|
3854
|
+
tokensCss = import_fs5.default.readFileSync(CSS_PATH, "utf-8");
|
|
3716
3855
|
} catch {
|
|
3717
3856
|
return;
|
|
3718
3857
|
}
|
|
3719
3858
|
let generatedCss = "";
|
|
3720
3859
|
try {
|
|
3721
|
-
generatedCss =
|
|
3860
|
+
generatedCss = import_fs5.default.readFileSync(GENERATED_CSS_PATH, "utf-8");
|
|
3722
3861
|
} catch {
|
|
3723
3862
|
}
|
|
3724
3863
|
const componentSources = listComponentSourcePaths().map((p) => ({
|
|
3725
3864
|
name: componentNameFromFile(p),
|
|
3726
|
-
source:
|
|
3865
|
+
source: import_fs5.default.readFileSync(p, "utf-8")
|
|
3727
3866
|
}));
|
|
3728
3867
|
const missing = validateTokensCss({ tokensCss, generatedCss, componentSources });
|
|
3729
3868
|
if (missing.length === 0) return;
|
|
@@ -3731,7 +3870,7 @@ function themeFileApi(opts) {
|
|
|
3731
3870
|
(m) => ` ${m.token} (referenced by ${m.referencedBy.join(", ")})`
|
|
3732
3871
|
);
|
|
3733
3872
|
log(
|
|
3734
|
-
`[live-tokens] ${missing.length} token(s) referenced by components are not defined in ${
|
|
3873
|
+
`[live-tokens] ${missing.length} token(s) referenced by components are not defined in ${import_path5.default.relative(process.cwd(), CSS_PATH)}:
|
|
3735
3874
|
${lines.join("\n")}
|
|
3736
3875
|
These render as blank/empty editor slots. Run \`npx live-tokens migrate\` to reconcile.`
|
|
3737
3876
|
);
|
|
@@ -3739,30 +3878,30 @@ ${lines.join("\n")}
|
|
|
3739
3878
|
function autoMigrateAdditive(log) {
|
|
3740
3879
|
let before = "";
|
|
3741
3880
|
try {
|
|
3742
|
-
before =
|
|
3881
|
+
before = import_fs5.default.readFileSync(CSS_PATH, "utf-8");
|
|
3743
3882
|
} catch {
|
|
3744
3883
|
return;
|
|
3745
3884
|
}
|
|
3746
3885
|
const { css, applied, changed } = runAdditiveTokensCssMigrations(before);
|
|
3747
3886
|
if (!changed) return;
|
|
3748
|
-
|
|
3887
|
+
import_fs5.default.writeFileSync(CSS_PATH, css);
|
|
3749
3888
|
log(
|
|
3750
|
-
`[live-tokens] autoMigrate applied ${applied.length} additive migration(s) to ${
|
|
3889
|
+
`[live-tokens] autoMigrate applied ${applied.length} additive migration(s) to ${import_path5.default.relative(process.cwd(), CSS_PATH)}: ${applied.join(", ")}. Review the diff in git.`
|
|
3751
3890
|
);
|
|
3752
3891
|
}
|
|
3753
3892
|
function generateDefaultConfig(comp, sourcePath) {
|
|
3754
|
-
if (!
|
|
3893
|
+
if (!import_fs5.default.existsSync(sourcePath)) return;
|
|
3755
3894
|
const r = componentResource(comp);
|
|
3756
3895
|
r.ensureDir();
|
|
3757
3896
|
const defaultPath = r.filePath("default");
|
|
3758
|
-
const sourceStat =
|
|
3897
|
+
const sourceStat = import_fs5.default.statSync(sourcePath);
|
|
3759
3898
|
let createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3760
3899
|
let existingUpdatedAt;
|
|
3761
3900
|
let existingAliases;
|
|
3762
3901
|
let existingSchemaVersion;
|
|
3763
|
-
if (
|
|
3902
|
+
if (import_fs5.default.existsSync(defaultPath)) {
|
|
3764
3903
|
try {
|
|
3765
|
-
const existing = JSON.parse(
|
|
3904
|
+
const existing = JSON.parse(import_fs5.default.readFileSync(defaultPath, "utf-8"));
|
|
3766
3905
|
if (existing.createdAt) createdAt = existing.createdAt;
|
|
3767
3906
|
if (typeof existing.updatedAt === "string") existingUpdatedAt = existing.updatedAt;
|
|
3768
3907
|
if (existing.aliases && typeof existing.aliases === "object") {
|
|
@@ -3771,13 +3910,13 @@ ${lines.join("\n")}
|
|
|
3771
3910
|
if (typeof existing.schemaVersion === "number") existingSchemaVersion = existing.schemaVersion;
|
|
3772
3911
|
} catch {
|
|
3773
3912
|
}
|
|
3774
|
-
const defaultStat =
|
|
3913
|
+
const defaultStat = import_fs5.default.statSync(defaultPath);
|
|
3775
3914
|
if (defaultStat.mtimeMs >= sourceStat.mtimeMs && existingSchemaVersion === CURRENT_COMPONENT_SCHEMA_VERSION) {
|
|
3776
3915
|
return;
|
|
3777
3916
|
}
|
|
3778
3917
|
}
|
|
3779
3918
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3780
|
-
const source =
|
|
3919
|
+
const source = import_fs5.default.readFileSync(sourcePath, "utf-8");
|
|
3781
3920
|
const body = extractGlobalRootBody(source);
|
|
3782
3921
|
const aliases = extractAliasDeclarations(body);
|
|
3783
3922
|
const aliasesUnchanged = existingAliases !== void 0 && JSON.stringify(existingAliases) === JSON.stringify(aliases);
|
|
@@ -3792,14 +3931,14 @@ ${lines.join("\n")}
|
|
|
3792
3931
|
};
|
|
3793
3932
|
if (aliasesUnchanged && schemaStampCurrent && existingUpdatedAt) {
|
|
3794
3933
|
const t = /* @__PURE__ */ new Date();
|
|
3795
|
-
|
|
3934
|
+
import_fs5.default.utimesSync(defaultPath, t, t);
|
|
3796
3935
|
return;
|
|
3797
3936
|
}
|
|
3798
|
-
|
|
3937
|
+
import_fs5.default.writeFileSync(defaultPath, JSON.stringify(defaultConfig, null, 2));
|
|
3799
3938
|
}
|
|
3800
3939
|
function ensureComponentConfigsDir() {
|
|
3801
|
-
if (!
|
|
3802
|
-
|
|
3940
|
+
if (!import_fs5.default.existsSync(COMPONENT_CONFIGS_DIR)) {
|
|
3941
|
+
import_fs5.default.mkdirSync(COMPONENT_CONFIGS_DIR, { recursive: true });
|
|
3803
3942
|
}
|
|
3804
3943
|
for (const sourcePath of listComponentSourcePaths()) {
|
|
3805
3944
|
const comp = componentNameFromFile(sourcePath);
|
|
@@ -3812,14 +3951,14 @@ ${lines.join("\n")}
|
|
|
3812
3951
|
const legacy = [];
|
|
3813
3952
|
const check = (dir) => {
|
|
3814
3953
|
for (const name of ["_active.json", "_production.json"]) {
|
|
3815
|
-
const p =
|
|
3816
|
-
if (
|
|
3954
|
+
const p = import_path5.default.join(dir, name);
|
|
3955
|
+
if (import_fs5.default.existsSync(p)) legacy.push(import_path5.default.relative(process.cwd(), p));
|
|
3817
3956
|
}
|
|
3818
3957
|
};
|
|
3819
3958
|
check(COLORS_AND_TYPE_DIR);
|
|
3820
|
-
if (
|
|
3821
|
-
for (const entry of
|
|
3822
|
-
if (entry.isDirectory()) check(
|
|
3959
|
+
if (import_fs5.default.existsSync(COMPONENT_CONFIGS_DIR)) {
|
|
3960
|
+
for (const entry of import_fs5.default.readdirSync(COMPONENT_CONFIGS_DIR, { withFileTypes: true })) {
|
|
3961
|
+
if (entry.isDirectory()) check(import_path5.default.join(COMPONENT_CONFIGS_DIR, entry.name));
|
|
3823
3962
|
}
|
|
3824
3963
|
}
|
|
3825
3964
|
return legacy;
|
|
@@ -3827,19 +3966,19 @@ ${lines.join("\n")}
|
|
|
3827
3966
|
function warnOnLegacyPointers(legacy, bakeHeld, warn) {
|
|
3828
3967
|
if (legacy.length === 0) return;
|
|
3829
3968
|
warn(
|
|
3830
|
-
`[live-tokens] ${legacy.length} legacy pointer file(s) left from the pre-working-set data model, starting with ${legacy[0]}. They are no longer read. Run \`npx live-tokens migrate\` to heal the tree.` + (bakeHeld ? ` Until then this tree has named no production theme, so ${
|
|
3969
|
+
`[live-tokens] ${legacy.length} legacy pointer file(s) left from the pre-working-set data model, starting with ${legacy[0]}. They are no longer read. Run \`npx live-tokens migrate\` to heal the tree.` + (bakeHeld ? ` Until then this tree has named no production theme, so ${import_path5.default.basename(GENERATED_CSS_PATH)} is left exactly as it is rather than rebuilt from the default.` : "")
|
|
3831
3970
|
);
|
|
3832
3971
|
}
|
|
3833
3972
|
function warnOnLegacyLayout(evidence, warn) {
|
|
3834
3973
|
warn(
|
|
3835
|
-
`[live-tokens] This project still uses the data layout from 0.47 and earlier: ${evidence}. Since 0.48 the whole-theme theme files live in \`themes/\` and the colors and type live in \`colors-and-type/\`. Nothing in the data directory was written, the editor cannot save, and ${
|
|
3974
|
+
`[live-tokens] This project still uses the data layout from 0.47 and earlier: ${evidence}. Since 0.48 the whole-theme theme files live in \`themes/\` and the colors and type live in \`colors-and-type/\`. Nothing in the data directory was written, the editor cannot save, and ${import_path5.default.basename(GENERATED_CSS_PATH)} is left exactly as it is. Run \`npx live-tokens migrate\` to move the directories and heal the tree, then restart the dev server.`
|
|
3836
3975
|
);
|
|
3837
3976
|
}
|
|
3838
3977
|
function warnOnUnmigratedSketchStyles(warn) {
|
|
3839
|
-
const legacyDir =
|
|
3840
|
-
if (!
|
|
3978
|
+
const legacyDir = import_path5.default.join(dataDirs.dataDir, "sketch-presets");
|
|
3979
|
+
if (!import_fs5.default.existsSync(legacyDir)) return;
|
|
3841
3980
|
warn(
|
|
3842
|
-
`[live-tokens] Saved sketchstyles still live under the retired ${
|
|
3981
|
+
`[live-tokens] Saved sketchstyles still live under the retired ${import_path5.default.basename(legacyDir)}/ directory name. Run \`npx live-tokens migrate\` to rename it to ${import_path5.default.basename(SKETCH_STYLES_DIR)}/; until then they will not show up in the Sketchstyle view.`
|
|
3843
3982
|
);
|
|
3844
3983
|
}
|
|
3845
3984
|
const diskThemeResolvers = {
|
|
@@ -3863,7 +4002,7 @@ ${lines.join("\n")}
|
|
|
3863
4002
|
const resolved = themesResource.existingPath(fileName);
|
|
3864
4003
|
if (resolved === null) return "missing";
|
|
3865
4004
|
try {
|
|
3866
|
-
if (isColorsAndTypeShaped(JSON.parse(
|
|
4005
|
+
if (isColorsAndTypeShaped(JSON.parse(import_fs5.default.readFileSync(resolved, "utf-8")))) {
|
|
3867
4006
|
return "colors-and-type";
|
|
3868
4007
|
}
|
|
3869
4008
|
} catch {
|
|
@@ -3871,7 +4010,7 @@ ${lines.join("\n")}
|
|
|
3871
4010
|
return "corrupt";
|
|
3872
4011
|
}
|
|
3873
4012
|
function notAThemeError(fileName) {
|
|
3874
|
-
return `"${fileName}" is a colors-and-type file, not a theme. Before 0.48 those lived in themes/; move it to ${
|
|
4013
|
+
return `"${fileName}" is a colors-and-type file, not a theme. Before 0.48 those lived in themes/; move it to ${import_path5.default.basename(COLORS_AND_TYPE_DIR)}/ or delete it. To build a theme, use the theme skill "create-theme".`;
|
|
3875
4014
|
}
|
|
3876
4015
|
function respondUnreadableTheme(res, fileName, missingError) {
|
|
3877
4016
|
switch (unreadableThemeReason(fileName)) {
|
|
@@ -3890,18 +4029,18 @@ ${lines.join("\n")}
|
|
|
3890
4029
|
}
|
|
3891
4030
|
function writeTheme(fileName, theme) {
|
|
3892
4031
|
themesResource.ensureDir();
|
|
3893
|
-
|
|
4032
|
+
import_fs5.default.writeFileSync(themesResource.filePath(fileName), JSON.stringify(theme, null, 2));
|
|
3894
4033
|
}
|
|
3895
4034
|
function migrateLocalThemes(warn) {
|
|
3896
|
-
if (
|
|
3897
|
-
if (!
|
|
3898
|
-
for (const file of
|
|
4035
|
+
if (import_path5.default.resolve(THEMES_DIR) === import_path5.default.resolve(packageThemesDir)) return;
|
|
4036
|
+
if (!import_fs5.default.existsSync(THEMES_DIR)) return;
|
|
4037
|
+
for (const file of import_fs5.default.readdirSync(THEMES_DIR)) {
|
|
3899
4038
|
if (!file.endsWith(".json") || file.startsWith("_")) continue;
|
|
3900
4039
|
const fileName = file.slice(0, -".json".length);
|
|
3901
4040
|
if (fileName === "default") continue;
|
|
3902
4041
|
let raw;
|
|
3903
4042
|
try {
|
|
3904
|
-
raw = JSON.parse(
|
|
4043
|
+
raw = JSON.parse(import_fs5.default.readFileSync(import_path5.default.join(THEMES_DIR, file), "utf-8"));
|
|
3905
4044
|
} catch {
|
|
3906
4045
|
continue;
|
|
3907
4046
|
}
|
|
@@ -3922,7 +4061,7 @@ ${lines.join("\n")}
|
|
|
3922
4061
|
function ensureDefaultTheme(warn) {
|
|
3923
4062
|
let existing = null;
|
|
3924
4063
|
try {
|
|
3925
|
-
existing = JSON.parse(
|
|
4064
|
+
existing = JSON.parse(import_fs5.default.readFileSync(themesResource.filePath("default"), "utf-8"));
|
|
3926
4065
|
} catch {
|
|
3927
4066
|
}
|
|
3928
4067
|
if (isColorsAndTypeShaped(existing)) {
|
|
@@ -3959,9 +4098,9 @@ ${lines.join("\n")}
|
|
|
3959
4098
|
themesResource.ensureDir();
|
|
3960
4099
|
ensureDefaultTheme(warn);
|
|
3961
4100
|
migrateLocalThemes(warn);
|
|
3962
|
-
const productionPointerHeld = !
|
|
4101
|
+
const productionPointerHeld = !import_fs5.default.existsSync(themesResource.productionPath) && listLegacyPointers().length > 0;
|
|
3963
4102
|
if (productionPointerHeld) {
|
|
3964
|
-
if (!
|
|
4103
|
+
if (!import_fs5.default.existsSync(themesResource.activePath)) themesResource.setActiveName("default");
|
|
3965
4104
|
} else {
|
|
3966
4105
|
themesResource.ensureMeta();
|
|
3967
4106
|
}
|
|
@@ -4040,8 +4179,8 @@ ${lines.join("\n")}
|
|
|
4040
4179
|
}
|
|
4041
4180
|
function clearAllWorking() {
|
|
4042
4181
|
colorsAndTypeResource.clearWorking();
|
|
4043
|
-
if (!
|
|
4044
|
-
for (const entry of
|
|
4182
|
+
if (!import_fs5.default.existsSync(COMPONENT_CONFIGS_DIR)) return;
|
|
4183
|
+
for (const entry of import_fs5.default.readdirSync(COMPONENT_CONFIGS_DIR, { withFileTypes: true })) {
|
|
4045
4184
|
if (entry.isDirectory()) componentResource(entry.name).clearWorking();
|
|
4046
4185
|
}
|
|
4047
4186
|
}
|
|
@@ -4084,6 +4223,7 @@ ${lines.join("\n")}
|
|
|
4084
4223
|
const SKETCH_STYLES_ROUTE = `${API_BASE}/sketch-styles`;
|
|
4085
4224
|
const SKETCH_STYLE_BY_NAME_REGEX = new RegExp(`^${escapedBase}/sketch-styles/([a-z0-9\\-_]+)$`);
|
|
4086
4225
|
const PRODUCTION_ROUTE = `${API_BASE}/production`;
|
|
4226
|
+
const EVENTS_ROUTE = `${API_BASE}/events`;
|
|
4087
4227
|
async function handleListColorsAndType(_ctx) {
|
|
4088
4228
|
const files = colorsAndTypeResource.listNames().map((fileName) => {
|
|
4089
4229
|
const data = colorsAndTypeResource.readJson(fileName);
|
|
@@ -4168,15 +4308,15 @@ ${lines.join("\n")}
|
|
|
4168
4308
|
}
|
|
4169
4309
|
const body = JSON.parse(await readBody(req));
|
|
4170
4310
|
body.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4171
|
-
if (
|
|
4311
|
+
if (import_fs5.default.existsSync(filePath)) {
|
|
4172
4312
|
try {
|
|
4173
|
-
const existing = JSON.parse(
|
|
4313
|
+
const existing = JSON.parse(import_fs5.default.readFileSync(filePath, "utf-8"));
|
|
4174
4314
|
if (existing.createdAt) body.createdAt = existing.createdAt;
|
|
4175
4315
|
} catch {
|
|
4176
4316
|
}
|
|
4177
4317
|
}
|
|
4178
4318
|
if (!body.createdAt) body.createdAt = body.updatedAt;
|
|
4179
|
-
|
|
4319
|
+
import_fs5.default.writeFileSync(filePath, JSON.stringify(body, null, 2));
|
|
4180
4320
|
jsonResponse(res, 200, { ok: true, fileName });
|
|
4181
4321
|
return;
|
|
4182
4322
|
}
|
|
@@ -4185,8 +4325,8 @@ ${lines.join("\n")}
|
|
|
4185
4325
|
jsonResponse(res, 403, { error: "Cannot delete the default colors and type" });
|
|
4186
4326
|
return;
|
|
4187
4327
|
}
|
|
4188
|
-
if (
|
|
4189
|
-
|
|
4328
|
+
if (import_fs5.default.existsSync(filePath)) {
|
|
4329
|
+
import_fs5.default.unlinkSync(filePath);
|
|
4190
4330
|
} else if (colorsAndTypeResource.existingPath(fileName)) {
|
|
4191
4331
|
jsonResponse(res, 403, {
|
|
4192
4332
|
error: "Cannot delete colors and type shipped with the package. Saving it creates a local copy; deleting that copy restores the shipped version.",
|
|
@@ -4273,16 +4413,16 @@ ${lines.join("\n")}
|
|
|
4273
4413
|
body.component = comp;
|
|
4274
4414
|
body.name = body.name || name;
|
|
4275
4415
|
body.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4276
|
-
if (
|
|
4416
|
+
if (import_fs5.default.existsSync(configPath)) {
|
|
4277
4417
|
try {
|
|
4278
|
-
const existing = JSON.parse(
|
|
4418
|
+
const existing = JSON.parse(import_fs5.default.readFileSync(configPath, "utf-8"));
|
|
4279
4419
|
if (existing.createdAt) body.createdAt = existing.createdAt;
|
|
4280
4420
|
} catch {
|
|
4281
4421
|
}
|
|
4282
4422
|
}
|
|
4283
4423
|
if (!body.createdAt) body.createdAt = body.updatedAt;
|
|
4284
4424
|
r.ensureDir();
|
|
4285
|
-
|
|
4425
|
+
import_fs5.default.writeFileSync(configPath, JSON.stringify(body, null, 2));
|
|
4286
4426
|
jsonResponse(res, 200, { ok: true, fileName: name });
|
|
4287
4427
|
return;
|
|
4288
4428
|
}
|
|
@@ -4291,7 +4431,7 @@ ${lines.join("\n")}
|
|
|
4291
4431
|
jsonResponse(res, 403, { error: "Cannot delete default config" });
|
|
4292
4432
|
return;
|
|
4293
4433
|
}
|
|
4294
|
-
if (
|
|
4434
|
+
if (import_fs5.default.existsSync(configPath)) import_fs5.default.unlinkSync(configPath);
|
|
4295
4435
|
jsonResponse(res, 200, { ok: true });
|
|
4296
4436
|
return;
|
|
4297
4437
|
}
|
|
@@ -4299,7 +4439,7 @@ ${lines.join("\n")}
|
|
|
4299
4439
|
async function handleListComponentConfigs({ params, res }) {
|
|
4300
4440
|
const [comp] = params;
|
|
4301
4441
|
const r = componentResource(comp);
|
|
4302
|
-
if (!
|
|
4442
|
+
if (!import_fs5.default.existsSync(r.dir)) {
|
|
4303
4443
|
jsonResponse(res, 404, { error: "Component not found" });
|
|
4304
4444
|
return;
|
|
4305
4445
|
}
|
|
@@ -4387,9 +4527,9 @@ ${lines.join("\n")}
|
|
|
4387
4527
|
const body = JSON.parse(await readBody(req));
|
|
4388
4528
|
const { theme } = normalizeTheme(body, diskThemeResolvers);
|
|
4389
4529
|
theme.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4390
|
-
if (
|
|
4530
|
+
if (import_fs5.default.existsSync(filePath)) {
|
|
4391
4531
|
try {
|
|
4392
|
-
const existing = JSON.parse(
|
|
4532
|
+
const existing = JSON.parse(import_fs5.default.readFileSync(filePath, "utf-8"));
|
|
4393
4533
|
if (existing.createdAt) theme.createdAt = existing.createdAt;
|
|
4394
4534
|
} catch {
|
|
4395
4535
|
}
|
|
@@ -4411,7 +4551,7 @@ ${lines.join("\n")}
|
|
|
4411
4551
|
});
|
|
4412
4552
|
return;
|
|
4413
4553
|
}
|
|
4414
|
-
if (
|
|
4554
|
+
if (import_fs5.default.existsSync(filePath)) {
|
|
4415
4555
|
const deletingActive = themesResource.getActiveName() === fileName;
|
|
4416
4556
|
const liveColors = deletingActive ? resolveLiveColorsAndType(activeTheme()) : null;
|
|
4417
4557
|
const liveComponents = {};
|
|
@@ -4421,7 +4561,7 @@ ${lines.join("\n")}
|
|
|
4421
4561
|
if (resolved) liveComponents[comp] = resolved.data;
|
|
4422
4562
|
}
|
|
4423
4563
|
}
|
|
4424
|
-
|
|
4564
|
+
import_fs5.default.unlinkSync(filePath);
|
|
4425
4565
|
if (themesResource.existingPath(fileName) === null && deletingActive) {
|
|
4426
4566
|
themesResource.setActiveName("default");
|
|
4427
4567
|
}
|
|
@@ -4468,30 +4608,50 @@ ${lines.join("\n")}
|
|
|
4468
4608
|
return;
|
|
4469
4609
|
}
|
|
4470
4610
|
clearAllWorking();
|
|
4471
|
-
const knownComponents = listComponentNames();
|
|
4472
4611
|
themesResource.setActiveName(fileName);
|
|
4473
|
-
const
|
|
4474
|
-
for (const comp of knownComponents) {
|
|
4475
|
-
const resolved = resolveLiveComponentConfig(comp, theme);
|
|
4476
|
-
if (resolved) resolvedConfigs[comp] = { ...resolved.data, _fileName: fileName, _source: resolved.source };
|
|
4477
|
-
}
|
|
4478
|
-
const resolvedColorsAndType = resolveLiveColorsAndType(theme);
|
|
4612
|
+
const knownComponents = listComponentNames();
|
|
4479
4613
|
const skippedComponents = Object.keys(theme.componentConfigs).filter(
|
|
4480
4614
|
(comp) => !knownComponents.includes(comp)
|
|
4481
4615
|
);
|
|
4482
4616
|
jsonResponse(res, 200, {
|
|
4483
4617
|
ok: true,
|
|
4484
|
-
|
|
4485
|
-
colorsAndType: resolvedColorsAndType && {
|
|
4486
|
-
...resolvedColorsAndType.data,
|
|
4487
|
-
_fileName: fileName,
|
|
4488
|
-
_source: resolvedColorsAndType.source
|
|
4489
|
-
},
|
|
4490
|
-
componentConfigs: resolvedConfigs,
|
|
4618
|
+
...resolveLiveState(theme, fileName),
|
|
4491
4619
|
skippedComponents,
|
|
4492
4620
|
filled
|
|
4493
4621
|
});
|
|
4494
4622
|
}
|
|
4623
|
+
function resolveLiveState(theme, fileName) {
|
|
4624
|
+
const componentConfigs = {};
|
|
4625
|
+
for (const comp of listComponentNames()) {
|
|
4626
|
+
const resolved = resolveLiveComponentConfig(comp, theme);
|
|
4627
|
+
if (resolved) componentConfigs[comp] = { ...resolved.data, _fileName: fileName, _source: resolved.source };
|
|
4628
|
+
}
|
|
4629
|
+
const colorsAndType = resolveLiveColorsAndType(theme);
|
|
4630
|
+
return {
|
|
4631
|
+
fileName,
|
|
4632
|
+
theme: { ...theme, _fileName: fileName },
|
|
4633
|
+
colorsAndType: colorsAndType && { ...colorsAndType.data, _fileName: fileName, _source: colorsAndType.source },
|
|
4634
|
+
componentConfigs
|
|
4635
|
+
};
|
|
4636
|
+
}
|
|
4637
|
+
async function handleEvents({ req, res }) {
|
|
4638
|
+
res.statusCode = 200;
|
|
4639
|
+
res.setHeader("Content-Type", "text/event-stream");
|
|
4640
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
4641
|
+
res.setHeader("Connection", "keep-alive");
|
|
4642
|
+
res.write(": connected\n\n");
|
|
4643
|
+
const unsubscribe = liveWatch.subscribe(() => {
|
|
4644
|
+
const activeFile = themesResource.getActiveName();
|
|
4645
|
+
const read = readTheme(activeFile);
|
|
4646
|
+
if (!read) return;
|
|
4647
|
+
const state = resolveLiveState(read.theme, activeFile);
|
|
4648
|
+
res.write(`event: live-state
|
|
4649
|
+
data: ${JSON.stringify(state)}
|
|
4650
|
+
|
|
4651
|
+
`);
|
|
4652
|
+
});
|
|
4653
|
+
req.on("close", unsubscribe);
|
|
4654
|
+
}
|
|
4495
4655
|
async function handleExportTheme({ params, res }) {
|
|
4496
4656
|
const [fileName] = params;
|
|
4497
4657
|
if (rejectReservedName(res, fileName)) return;
|
|
@@ -4652,22 +4812,22 @@ ${lines.join("\n")}
|
|
|
4652
4812
|
}
|
|
4653
4813
|
body.name = String(body.name || fileName);
|
|
4654
4814
|
body.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4655
|
-
if (
|
|
4815
|
+
if (import_fs5.default.existsSync(filePath)) {
|
|
4656
4816
|
try {
|
|
4657
|
-
const existing = JSON.parse(
|
|
4817
|
+
const existing = JSON.parse(import_fs5.default.readFileSync(filePath, "utf-8"));
|
|
4658
4818
|
if (existing.createdAt) body.createdAt = existing.createdAt;
|
|
4659
4819
|
} catch {
|
|
4660
4820
|
}
|
|
4661
4821
|
}
|
|
4662
4822
|
if (!body.createdAt) body.createdAt = body.updatedAt;
|
|
4663
4823
|
sketchStylesResource.ensureDir();
|
|
4664
|
-
|
|
4824
|
+
import_fs5.default.writeFileSync(filePath, JSON.stringify(body, null, 2));
|
|
4665
4825
|
jsonResponse(res, 200, { ok: true, fileName });
|
|
4666
4826
|
return;
|
|
4667
4827
|
}
|
|
4668
4828
|
if (req.method === "DELETE") {
|
|
4669
|
-
if (
|
|
4670
|
-
|
|
4829
|
+
if (import_fs5.default.existsSync(filePath)) {
|
|
4830
|
+
import_fs5.default.unlinkSync(filePath);
|
|
4671
4831
|
} else if (sketchStylesResource.existingPath(fileName)) {
|
|
4672
4832
|
jsonResponse(res, 403, {
|
|
4673
4833
|
error: "Cannot delete a sketchstyle shipped with the package. Saving it creates a local copy; deleting that copy restores the shipped version.",
|
|
@@ -4763,12 +4923,13 @@ ${lines.join("\n")}
|
|
|
4763
4923
|
{ method: "PUT", pattern: SKETCH_STYLE_BY_NAME_REGEX, handler: handleSketchStyleByName },
|
|
4764
4924
|
{ method: "DELETE", pattern: SKETCH_STYLE_BY_NAME_REGEX, handler: handleSketchStyleByName },
|
|
4765
4925
|
{ method: "POST", pattern: SKETCH_STYLE_BY_NAME_REGEX, handler: methodNotAllowed },
|
|
4926
|
+
{ method: "GET", pattern: EVENTS_ROUTE, handler: handleEvents },
|
|
4766
4927
|
{ method: "PUT", pattern: PRODUCTION_ROUTE, handler: handleAdoptTheme },
|
|
4767
4928
|
{ method: "GET", pattern: PRODUCTION_ROUTE, handler: methodNotAllowed },
|
|
4768
4929
|
{ method: "POST", pattern: PRODUCTION_ROUTE, handler: methodNotAllowed },
|
|
4769
4930
|
{ method: "DELETE", pattern: PRODUCTION_ROUTE, handler: methodNotAllowed }
|
|
4770
4931
|
];
|
|
4771
|
-
const isEditorOwnedJson = (file) => file.endsWith(".json") &&
|
|
4932
|
+
const isEditorOwnedJson = (file) => file.endsWith(".json") && import_path5.default.resolve(file).startsWith(dataDirs.dataDir + import_path5.default.sep);
|
|
4772
4933
|
return {
|
|
4773
4934
|
name: "theme-file-api",
|
|
4774
4935
|
config() {
|
|
@@ -4796,8 +4957,10 @@ ${lines.join("\n")}
|
|
|
4796
4957
|
const { productionPointerHeld } = ensureThemesDir((msg) => server.config.logger.warn(msg));
|
|
4797
4958
|
const openTheme = activeTheme();
|
|
4798
4959
|
if (openTheme) pruneMatchingWorking(openTheme);
|
|
4799
|
-
if (!productionPointerHeld || !
|
|
4800
|
-
if (opts.autoMigrate
|
|
4960
|
+
if (!productionPointerHeld || !import_fs5.default.existsSync(GENERATED_CSS_PATH)) regenerateTokensCss();
|
|
4961
|
+
if (opts.autoMigrate && !ISOLATED_DATA_DIR) {
|
|
4962
|
+
autoMigrateAdditive((msg) => server.config.logger.info(msg));
|
|
4963
|
+
}
|
|
4801
4964
|
warnOnTokenDrift((msg) => server.config.logger.warn(msg));
|
|
4802
4965
|
warnOnLegacyPointers(
|
|
4803
4966
|
listLegacyPointers(),
|
|
@@ -4820,7 +4983,7 @@ ${lines.join("\n")}
|
|
|
4820
4983
|
},
|
|
4821
4984
|
handleHotUpdate(ctx) {
|
|
4822
4985
|
if (legacyLayout) return;
|
|
4823
|
-
const normalized =
|
|
4986
|
+
const normalized = import_path5.default.resolve(ctx.file);
|
|
4824
4987
|
if (!COMPONENTS_SCAN_DIRS.some((d) => normalized.startsWith(d))) return;
|
|
4825
4988
|
if (!normalized.endsWith(".svelte")) return;
|
|
4826
4989
|
if (!isThemeAwareComponent(normalized)) return;
|