@motion-proto/live-tokens 0.47.0 → 0.48.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-adjust-shape-space/SKILL.md +68 -0
- package/.claude/skills/live-tokens-create-component/SKILL.md +2 -2
- package/.claude/skills/live-tokens-generate-theme/SKILL.md +152 -0
- package/CHANGELOG.md +292 -0
- package/README.md +37 -26
- package/bin/adjust.mjs +254 -0
- package/bin/cli.mjs +94 -7
- package/bin/generate-theme.mjs +251 -0
- package/bin/migrate.mjs +95 -6
- package/dist-plugin/adjust/index.cjs +259 -0
- package/dist-plugin/adjust/index.d.cts +45 -0
- package/dist-plugin/adjust/index.d.ts +45 -0
- package/dist-plugin/adjust/index.js +176 -0
- package/dist-plugin/{chunk-H4TRUINI.js → chunk-44RSTAII.js} +0 -48
- package/dist-plugin/chunk-6OZFXIQI.js +316 -0
- package/dist-plugin/chunk-76TFDTJO.js +556 -0
- package/dist-plugin/chunk-D3ZVKOR4.js +52 -0
- package/dist-plugin/dataPaths-DBN0RPuT.d.cts +54 -0
- package/dist-plugin/dataPaths-DBN0RPuT.d.ts +54 -0
- package/dist-plugin/generateColorsAndType/index.cjs +1781 -0
- package/dist-plugin/generateColorsAndType/index.d.cts +81 -0
- package/dist-plugin/generateColorsAndType/index.d.ts +81 -0
- package/dist-plugin/generateColorsAndType/index.js +1210 -0
- package/dist-plugin/index.cjs +901 -533
- package/dist-plugin/index.d.cts +3 -2
- package/dist-plugin/index.d.ts +3 -2
- package/dist-plugin/index.js +658 -1082
- package/dist-plugin/migrateData/index.cjs +728 -0
- package/dist-plugin/migrateData/index.d.cts +60 -0
- package/dist-plugin/migrateData/index.d.ts +60 -0
- package/dist-plugin/migrateData/index.js +348 -0
- package/dist-plugin/themeTypes-DMHZOnUn.d.cts +211 -0
- package/dist-plugin/themeTypes-DMHZOnUn.d.ts +211 -0
- package/dist-plugin/tokensCssMigrations/index.cjs +2 -1
- package/dist-plugin/tokensCssMigrations/index.d.cts +3 -15
- package/dist-plugin/tokensCssMigrations/index.d.ts +3 -15
- package/dist-plugin/tokensCssMigrations/index.js +4 -2
- package/package.json +18 -4
- package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +183 -158
- package/src/editor/component-editor/scaffolding/ComponentFileMenu.svelte +0 -4
- package/src/editor/component-editor/scaffolding/SaveAsDialog.svelte +4 -4
- package/src/editor/component-editor/scaffolding/TokenLayout.svelte +2 -59
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +1 -1
- package/src/editor/core/components/adjustAliases.ts +180 -0
- package/src/editor/core/components/aliasKinds.ts +73 -0
- package/src/editor/core/components/componentConfigService.ts +26 -38
- package/src/editor/core/flashStatus.ts +1 -1
- package/src/editor/core/fonts/fontMigration.ts +13 -13
- package/src/editor/core/fonts/fontPairing.ts +35 -0
- package/src/editor/core/palettes/paletteDerivation.ts +128 -16
- package/src/editor/core/preview/lookPreview.ts +141 -0
- package/src/editor/core/productionPulse.ts +34 -21
- package/src/editor/core/storage/files/versionedFileResourceClient.ts +18 -45
- package/src/editor/core/store/editorConfigStore.ts +2 -2
- package/src/editor/core/store/editorPersistence.ts +0 -1
- package/src/editor/core/store/editorStore.ts +114 -51
- package/src/editor/core/store/editorTypes.ts +0 -1
- package/src/editor/core/store/gradientSource.ts +2 -2
- package/src/editor/core/themes/colorsAndTypeService.ts +95 -0
- package/src/editor/core/themes/generateColorsAndType.ts +433 -0
- package/src/editor/core/themes/loadRows.ts +64 -0
- package/src/editor/core/themes/lookSummary.ts +75 -0
- package/src/editor/core/themes/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +3 -3
- package/src/editor/core/themes/migrations/2026-05-13-primary-to-brand.ts +2 -2
- package/src/editor/core/themes/migrations/2026-05-26-drop-overlay-extra-stops.ts +3 -3
- package/src/editor/core/themes/migrations/2026-08-13-drop-legacy-shape-space-keys.ts +38 -0
- package/src/editor/core/themes/migrations/2026-08-15-line-height-scale-rename.ts +57 -0
- package/src/editor/core/themes/migrations/index.ts +19 -11
- package/src/editor/core/themes/slices/components.ts +4 -4
- package/src/editor/core/themes/slices/fonts.ts +1 -1
- package/src/editor/core/themes/slices/gradients.ts +22 -0
- package/src/editor/core/themes/slices/palettes.ts +2 -2
- package/src/editor/core/themes/themeInit.ts +21 -29
- package/src/editor/core/themes/themeService.ts +218 -78
- package/src/editor/core/themes/themeTypes.ts +94 -51
- package/src/editor/docs/Docs.svelte +1 -0
- package/src/editor/docs/chapters.ts +1 -0
- package/src/editor/docs/content/01-overview.md +1 -1
- package/src/editor/docs/content/editing-tokens.md +6 -6
- package/src/editor/docs/content/getting-started.md +9 -7
- package/src/editor/docs/content/themes-workflow.md +74 -34
- package/src/editor/docs/content/where-themes-live.md +61 -0
- package/src/editor/docs/content.generated.ts +5 -4
- package/src/editor/index.ts +27 -27
- package/src/editor/pages/ComponentEditorPage.svelte +2 -2
- package/src/editor/pages/EditorShell.svelte +4 -30
- package/src/editor/ui/BezierCurveEditor.svelte +2 -2
- package/src/editor/ui/ColorEditPanel.svelte +1 -1
- package/src/editor/ui/FileLoadList.svelte +67 -7
- package/src/editor/ui/GradientEditor.svelte +3 -3
- package/src/editor/ui/PaletteEditor.svelte +26 -12
- package/src/editor/ui/ThemePanel.svelte +1067 -0
- package/src/editor/ui/UIDialog.svelte +11 -9
- package/src/editor/ui/UIPillButton.svelte +7 -2
- package/src/editor/ui/colors/ColorWheel.svelte +34 -1
- package/src/editor/ui/curveEngine.ts +48 -0
- package/src/editor/ui/index.ts +4 -2
- package/src/editor/ui/palette/PaletteBase.svelte +75 -51
- package/src/editor/ui/palette/PaletteJumpButton.svelte +3 -8
- package/src/live-tokens/data/colors-and-type/autumn.json +2490 -0
- package/src/live-tokens/data/{themes → colors-and-type}/default.json +816 -293
- package/src/live-tokens/data/colors-and-type/halloween.json +2529 -0
- package/src/live-tokens/data/colors-and-type/midnight-study.json +2536 -0
- package/src/live-tokens/data/colors-and-type/ocean.json +2489 -0
- package/src/live-tokens/data/colors-and-type/royal-velvet.json +2520 -0
- package/src/live-tokens/data/colors-and-type/spring-meadow.json +2476 -0
- package/src/live-tokens/data/colors-and-type/sunset.json +2528 -0
- package/src/live-tokens/data/themes/autumn.json +3918 -0
- package/src/live-tokens/data/themes/halloween.json +3992 -0
- package/src/live-tokens/data/themes/midnight-study.json +3932 -0
- package/src/live-tokens/data/themes/ocean.json +3917 -0
- package/src/live-tokens/data/themes/royal-velvet.json +3983 -0
- package/src/live-tokens/data/themes/spring-meadow.json +3904 -0
- package/src/live-tokens/data/themes/sunset.json +3931 -0
- package/src/live-tokens/data/tokens.generated.css +106 -117
- package/src/system/styles/CONVENTIONS.md +1 -1
- package/src/system/styles/fonts.css +1 -1
- package/template/README.md +7 -5
- package/template/_gitignore +0 -6
- package/src/editor/core/components/componentPersist.ts +0 -62
- package/src/editor/core/manifests/manifestService.ts +0 -172
- package/src/editor/ui/ManifestFileManager.svelte +0 -446
- package/src/editor/ui/ThemeFileManager.svelte +0 -785
- package/src/live-tokens/data/manifests/default.json +0 -35
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// vite-plugin/migrateData/index.ts
|
|
31
|
+
var migrateData_exports = {};
|
|
32
|
+
__export(migrateData_exports, {
|
|
33
|
+
migrateData: () => migrateData,
|
|
34
|
+
readLiveTokensConfig: () => readLiveTokensConfig,
|
|
35
|
+
resolveDataDirs: () => resolveDataDirs
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(migrateData_exports);
|
|
38
|
+
|
|
39
|
+
// vite-plugin/migrateData/migrateData.ts
|
|
40
|
+
var import_fs3 = __toESM(require("fs"), 1);
|
|
41
|
+
var import_path3 = __toESM(require("path"), 1);
|
|
42
|
+
|
|
43
|
+
// vite-plugin/files/versionedFileResourceServer.ts
|
|
44
|
+
var import_fs = __toESM(require("fs"), 1);
|
|
45
|
+
var import_path = __toESM(require("path"), 1);
|
|
46
|
+
function versionedFileResourceServer(opts) {
|
|
47
|
+
const dir = opts.dir;
|
|
48
|
+
const activePath = import_path.default.join(dir, "_active.json");
|
|
49
|
+
const productionPath = import_path.default.join(dir, "_production.json");
|
|
50
|
+
const workingPath = import_path.default.join(dir, "_working.json");
|
|
51
|
+
const defaultName = opts.defaultName ?? "default";
|
|
52
|
+
const resolvedDir = import_path.default.resolve(dir);
|
|
53
|
+
const resolvedPackageDir = opts.packageDir ? import_path.default.resolve(opts.packageDir) : null;
|
|
54
|
+
function ensureDir() {
|
|
55
|
+
if (!import_fs.default.existsSync(dir)) {
|
|
56
|
+
import_fs.default.mkdirSync(dir, { recursive: true });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function ensureMeta() {
|
|
60
|
+
if (!import_fs.default.existsSync(activePath)) {
|
|
61
|
+
import_fs.default.writeFileSync(activePath, JSON.stringify({ activeFile: defaultName }));
|
|
62
|
+
}
|
|
63
|
+
if (!import_fs.default.existsSync(productionPath)) {
|
|
64
|
+
import_fs.default.writeFileSync(productionPath, JSON.stringify({ productionFile: defaultName }));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function filePath(name) {
|
|
68
|
+
return import_path.default.join(dir, `${name}.json`);
|
|
69
|
+
}
|
|
70
|
+
function existingPath(name) {
|
|
71
|
+
const local = filePath(name);
|
|
72
|
+
if (import_fs.default.existsSync(local)) return local;
|
|
73
|
+
if (resolvedPackageDir) {
|
|
74
|
+
const pkg = import_path.default.join(resolvedPackageDir, `${name}.json`);
|
|
75
|
+
if (import_fs.default.existsSync(pkg)) return pkg;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
function isPackageFile(name) {
|
|
80
|
+
if (!resolvedPackageDir) return false;
|
|
81
|
+
const pkg = import_path.default.join(resolvedPackageDir, `${name}.json`);
|
|
82
|
+
if (!import_fs.default.existsSync(pkg)) return false;
|
|
83
|
+
const local = import_path.default.resolve(filePath(name));
|
|
84
|
+
if (local === pkg) {
|
|
85
|
+
return opts.packageOwnedNames ? opts.packageOwnedNames.includes(name) : true;
|
|
86
|
+
}
|
|
87
|
+
return !import_fs.default.existsSync(local);
|
|
88
|
+
}
|
|
89
|
+
function readJson(name) {
|
|
90
|
+
const resolved = existingPath(name);
|
|
91
|
+
if (!resolved) return null;
|
|
92
|
+
return JSON.parse(import_fs.default.readFileSync(resolved, "utf-8"));
|
|
93
|
+
}
|
|
94
|
+
function listNames() {
|
|
95
|
+
const names = [];
|
|
96
|
+
const seen = /* @__PURE__ */ new Set();
|
|
97
|
+
const collect = (d) => {
|
|
98
|
+
if (!d || !import_fs.default.existsSync(d)) return;
|
|
99
|
+
for (const f of import_fs.default.readdirSync(d)) {
|
|
100
|
+
if (!f.endsWith(".json") || f.startsWith("_")) continue;
|
|
101
|
+
const name = f.slice(0, -".json".length);
|
|
102
|
+
if (seen.has(name)) continue;
|
|
103
|
+
seen.add(name);
|
|
104
|
+
names.push(name);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
collect(resolvedDir);
|
|
108
|
+
if (resolvedPackageDir && resolvedPackageDir !== resolvedDir) collect(resolvedPackageDir);
|
|
109
|
+
return names;
|
|
110
|
+
}
|
|
111
|
+
function getActiveName() {
|
|
112
|
+
try {
|
|
113
|
+
const data = JSON.parse(import_fs.default.readFileSync(activePath, "utf-8"));
|
|
114
|
+
return data.activeFile || defaultName;
|
|
115
|
+
} catch {
|
|
116
|
+
return defaultName;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function getProductionName() {
|
|
120
|
+
try {
|
|
121
|
+
const data = JSON.parse(import_fs.default.readFileSync(productionPath, "utf-8"));
|
|
122
|
+
return data.productionFile || defaultName;
|
|
123
|
+
} catch {
|
|
124
|
+
return defaultName;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function setActiveName(name) {
|
|
128
|
+
import_fs.default.writeFileSync(activePath, JSON.stringify({ activeFile: name }));
|
|
129
|
+
}
|
|
130
|
+
function setProductionName(name) {
|
|
131
|
+
import_fs.default.writeFileSync(productionPath, JSON.stringify({ productionFile: name }));
|
|
132
|
+
}
|
|
133
|
+
function hasWorking() {
|
|
134
|
+
return import_fs.default.existsSync(workingPath);
|
|
135
|
+
}
|
|
136
|
+
function readWorking() {
|
|
137
|
+
if (!import_fs.default.existsSync(workingPath)) return null;
|
|
138
|
+
const parsed = JSON.parse(import_fs.default.readFileSync(workingPath, "utf-8"));
|
|
139
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
140
|
+
throw new Error(`${workingPath} does not hold a JSON object`);
|
|
141
|
+
}
|
|
142
|
+
return parsed;
|
|
143
|
+
}
|
|
144
|
+
function writeWorking(data) {
|
|
145
|
+
ensureDir();
|
|
146
|
+
import_fs.default.writeFileSync(workingPath, JSON.stringify(data, null, 2));
|
|
147
|
+
}
|
|
148
|
+
function clearWorking() {
|
|
149
|
+
if (import_fs.default.existsSync(workingPath)) import_fs.default.unlinkSync(workingPath);
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
dir,
|
|
153
|
+
activePath,
|
|
154
|
+
productionPath,
|
|
155
|
+
workingPath,
|
|
156
|
+
ensureDir,
|
|
157
|
+
ensureMeta,
|
|
158
|
+
filePath,
|
|
159
|
+
existingPath,
|
|
160
|
+
isPackageFile,
|
|
161
|
+
readJson,
|
|
162
|
+
listNames,
|
|
163
|
+
getActiveName,
|
|
164
|
+
getProductionName,
|
|
165
|
+
setActiveName,
|
|
166
|
+
setProductionName,
|
|
167
|
+
hasWorking,
|
|
168
|
+
readWorking,
|
|
169
|
+
writeWorking,
|
|
170
|
+
clearWorking
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// vite-plugin/themes/normalizeTheme.ts
|
|
175
|
+
var THEME_SCHEMA_VERSION = 3;
|
|
176
|
+
function asObject(value) {
|
|
177
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
178
|
+
}
|
|
179
|
+
function isColorsAndTypeShaped(raw) {
|
|
180
|
+
const obj = asObject(raw);
|
|
181
|
+
if (!obj) return false;
|
|
182
|
+
if ("theme" in obj || "colorsAndType" in obj) return false;
|
|
183
|
+
return "cssVariables" in obj || "editorConfigs" in obj;
|
|
184
|
+
}
|
|
185
|
+
function stripFileMarker(value) {
|
|
186
|
+
if (!("_fileName" in value)) return value;
|
|
187
|
+
const { _fileName, ...rest } = value;
|
|
188
|
+
return rest;
|
|
189
|
+
}
|
|
190
|
+
function asString(value, fallback) {
|
|
191
|
+
return typeof value === "string" && value ? value : fallback;
|
|
192
|
+
}
|
|
193
|
+
function migrateEmbeddedKey(src) {
|
|
194
|
+
const { theme, ...rest } = src;
|
|
195
|
+
return { ...rest, colorsAndType: theme };
|
|
196
|
+
}
|
|
197
|
+
function normalizeTheme(raw, resolvers) {
|
|
198
|
+
const input = asObject(raw) ?? {};
|
|
199
|
+
const migrated = input.schemaVersion !== THEME_SCHEMA_VERSION;
|
|
200
|
+
const src = migrated ? migrateEmbeddedKey(input) : input;
|
|
201
|
+
const dropped = [];
|
|
202
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
203
|
+
const embeddedColorsAndType = asObject(src.colorsAndType);
|
|
204
|
+
let colorsAndType = null;
|
|
205
|
+
if (embeddedColorsAndType) {
|
|
206
|
+
colorsAndType = stripFileMarker(embeddedColorsAndType);
|
|
207
|
+
} else {
|
|
208
|
+
const colorsAndTypeName = asString(src.colorsAndType, "default");
|
|
209
|
+
colorsAndType = asObject(resolvers.readColorsAndType(colorsAndTypeName));
|
|
210
|
+
if (!colorsAndType) {
|
|
211
|
+
dropped.push(`colors-and-type:${colorsAndTypeName}`);
|
|
212
|
+
if (colorsAndTypeName !== "default") colorsAndType = asObject(resolvers.readColorsAndType("default"));
|
|
213
|
+
}
|
|
214
|
+
if (colorsAndType) colorsAndType = resolvers.normalizeColorsAndType(stripFileMarker(colorsAndType));
|
|
215
|
+
}
|
|
216
|
+
const componentConfigs = {};
|
|
217
|
+
for (const [comp, value] of Object.entries(asObject(src.componentConfigs) ?? {})) {
|
|
218
|
+
const embedded = asObject(value);
|
|
219
|
+
if (embedded) {
|
|
220
|
+
componentConfigs[comp] = stripFileMarker(embedded);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const configName = asString(value, "default");
|
|
224
|
+
if (configName === "default") continue;
|
|
225
|
+
const resolved = asObject(resolvers.readComponentConfig(comp, configName));
|
|
226
|
+
if (!resolved) {
|
|
227
|
+
dropped.push(`${comp}/${configName}`);
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
componentConfigs[comp] = stripFileMarker(resolved);
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
theme: {
|
|
234
|
+
name: asString(src.name, "Untitled"),
|
|
235
|
+
createdAt: asString(src.createdAt, now),
|
|
236
|
+
updatedAt: asString(src.updatedAt, now),
|
|
237
|
+
schemaVersion: THEME_SCHEMA_VERSION,
|
|
238
|
+
colorsAndType,
|
|
239
|
+
componentConfigs
|
|
240
|
+
},
|
|
241
|
+
dropped,
|
|
242
|
+
migrated
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// vite-plugin/files/nameAllocator.ts
|
|
247
|
+
function nextAvailableName(exists, baseName, maxAttempts = 1e3) {
|
|
248
|
+
if (!exists(baseName)) return baseName;
|
|
249
|
+
for (let i = 2; i < maxAttempts; i++) {
|
|
250
|
+
const candidate = `${baseName}-${i}`;
|
|
251
|
+
if (!exists(candidate)) return candidate;
|
|
252
|
+
}
|
|
253
|
+
throw new Error(`Could not allocate a non-colliding name for "${baseName}"`);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// vite-plugin/files/legacyLayout.ts
|
|
257
|
+
var import_fs2 = __toESM(require("fs"), 1);
|
|
258
|
+
var import_path2 = __toESM(require("path"), 1);
|
|
259
|
+
function jsonFiles(dir) {
|
|
260
|
+
if (!import_fs2.default.existsSync(dir)) return [];
|
|
261
|
+
try {
|
|
262
|
+
return import_fs2.default.readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => import_path2.default.join(dir, f));
|
|
263
|
+
} catch {
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function isDirectory(dir) {
|
|
268
|
+
try {
|
|
269
|
+
return import_fs2.default.statSync(dir).isDirectory();
|
|
270
|
+
} catch {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function parseJsonFile(file) {
|
|
275
|
+
try {
|
|
276
|
+
return JSON.parse(import_fs2.default.readFileSync(file, "utf-8"));
|
|
277
|
+
} catch {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function holdsATheme(themesDir) {
|
|
282
|
+
return jsonFiles(themesDir).some((file) => {
|
|
283
|
+
if (import_path2.default.basename(file).startsWith("_")) return false;
|
|
284
|
+
const raw = parseJsonFile(file);
|
|
285
|
+
if (!raw || typeof raw !== "object") return false;
|
|
286
|
+
return "colorsAndType" in raw || "theme" in raw;
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
function detectLegacyLayout(input) {
|
|
290
|
+
const manifestsDir = input.configuredManifestsDir ?? import_path2.default.join(input.dataDir, "manifests");
|
|
291
|
+
const themesHoldAThemeFile = holdsATheme(input.themesDir);
|
|
292
|
+
if (isDirectory(manifestsDir) && !themesHoldAThemeFile) {
|
|
293
|
+
return { manifestsDir, evidence: `${manifestsDir} is the pre-0.48 whole-look directory` };
|
|
294
|
+
}
|
|
295
|
+
if (jsonFiles(input.colorsAndTypeDir).length > 0) return null;
|
|
296
|
+
for (const file of jsonFiles(input.themesDir)) {
|
|
297
|
+
if (import_path2.default.basename(file).startsWith("_")) continue;
|
|
298
|
+
if (isColorsAndTypeShaped(parseJsonFile(file))) {
|
|
299
|
+
return { manifestsDir, evidence: `${file} is a colors-and-type file, not a theme` };
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const pointer = ["_active.json", "_production.json"].map((name) => import_path2.default.join(input.themesDir, name)).find((p) => import_fs2.default.existsSync(p));
|
|
303
|
+
if (pointer && !themesHoldAThemeFile && !import_fs2.default.existsSync(input.colorsAndTypeDir)) {
|
|
304
|
+
return {
|
|
305
|
+
manifestsDir,
|
|
306
|
+
evidence: `${pointer} points at colors and type, and there is no ${import_path2.default.basename(input.colorsAndTypeDir)} directory`
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
function planLegacyRenames(layout, input) {
|
|
312
|
+
const defaultColorsAndType = import_path2.default.join(input.dataDir, "colors-and-type");
|
|
313
|
+
const defaultThemes = import_path2.default.join(input.dataDir, "themes");
|
|
314
|
+
if (input.configuredManifestsDir && import_path2.default.resolve(input.configuredManifestsDir) !== import_path2.default.join(input.dataDir, "manifests")) {
|
|
315
|
+
throw new Error(
|
|
316
|
+
`This project uses the pre-0.48 data layout (${layout.evidence}), and live-tokens.config.json sets the retired "manifestsDir" key to ${input.configuredManifestsDir}. That directory holds the whole looks, which now belong in ${input.themesDir}. Move it there by hand, drop the "manifestsDir" key, then run the migration again.`
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
if (import_path2.default.resolve(input.colorsAndTypeDir) !== import_path2.default.resolve(defaultColorsAndType) || import_path2.default.resolve(input.themesDir) !== import_path2.default.resolve(defaultThemes)) {
|
|
320
|
+
throw new Error(
|
|
321
|
+
`This project uses the pre-0.48 data layout (${layout.evidence}), and its data directories are configured to custom paths (colorsAndTypeDir=${input.colorsAndTypeDir}, themesDir=${input.themesDir}). The migration cannot tell which directory holds what. Move the old colors-and-type directory to ${input.colorsAndTypeDir} and the old whole-look directory to ${input.themesDir} by hand, then run the migration again.`
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
const renames = [];
|
|
325
|
+
if (import_fs2.default.existsSync(input.themesDir)) {
|
|
326
|
+
renames.push({ from: input.themesDir, to: input.colorsAndTypeDir });
|
|
327
|
+
}
|
|
328
|
+
if (import_fs2.default.existsSync(layout.manifestsDir)) {
|
|
329
|
+
renames.push({ from: layout.manifestsDir, to: input.themesDir });
|
|
330
|
+
}
|
|
331
|
+
return renames;
|
|
332
|
+
}
|
|
333
|
+
function applyLegacyRenames(renames) {
|
|
334
|
+
for (const { from, to } of renames) {
|
|
335
|
+
if (import_fs2.default.existsSync(to)) {
|
|
336
|
+
const contents = import_fs2.default.readdirSync(to);
|
|
337
|
+
if (contents.length > 0) {
|
|
338
|
+
throw new Error(
|
|
339
|
+
`Cannot move ${from} to ${to}: ${to} already exists and holds ${contents.length} file(s). Move or delete it, then run the migration again.`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
import_fs2.default.rmdirSync(to);
|
|
343
|
+
}
|
|
344
|
+
import_fs2.default.mkdirSync(import_path2.default.dirname(to), { recursive: true });
|
|
345
|
+
import_fs2.default.renameSync(from, to);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// vite-plugin/migrateData/migrateData.ts
|
|
350
|
+
var RECOVERED_SLUG = "recovered-production";
|
|
351
|
+
var RECOVERED_NAME = "Recovered production";
|
|
352
|
+
var MARKER_KEYS = ["_fileName", "_source"];
|
|
353
|
+
var VOLATILE_KEYS = [...MARKER_KEYS, "updatedAt"];
|
|
354
|
+
function isObject(value) {
|
|
355
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
356
|
+
}
|
|
357
|
+
function sortDeep(value) {
|
|
358
|
+
if (Array.isArray(value)) return value.map(sortDeep);
|
|
359
|
+
if (!isObject(value)) return value;
|
|
360
|
+
const out = {};
|
|
361
|
+
for (const key of Object.keys(value).sort()) out[key] = sortDeep(value[key]);
|
|
362
|
+
return out;
|
|
363
|
+
}
|
|
364
|
+
function comparable(value) {
|
|
365
|
+
if (!isObject(value)) return JSON.stringify(sortDeep(value));
|
|
366
|
+
const stable = {};
|
|
367
|
+
for (const key of Object.keys(value).sort()) {
|
|
368
|
+
if (VOLATILE_KEYS.includes(key)) continue;
|
|
369
|
+
stable[key] = sortDeep(value[key]);
|
|
370
|
+
}
|
|
371
|
+
return JSON.stringify(stable);
|
|
372
|
+
}
|
|
373
|
+
function sameContent(a, b) {
|
|
374
|
+
return comparable(a) === comparable(b);
|
|
375
|
+
}
|
|
376
|
+
function stripMarkers(value) {
|
|
377
|
+
const out = {};
|
|
378
|
+
for (const [key, v] of Object.entries(value)) {
|
|
379
|
+
if (!MARKER_KEYS.includes(key)) out[key] = v;
|
|
380
|
+
}
|
|
381
|
+
return out;
|
|
382
|
+
}
|
|
383
|
+
function readPointerName(file, key) {
|
|
384
|
+
if (!import_fs3.default.existsSync(file)) return null;
|
|
385
|
+
try {
|
|
386
|
+
const name = JSON.parse(import_fs3.default.readFileSync(file, "utf-8"))[key];
|
|
387
|
+
return typeof name === "string" && name ? name : null;
|
|
388
|
+
} catch {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
function localNamedFiles(dir) {
|
|
393
|
+
if (!import_fs3.default.existsSync(dir)) return [];
|
|
394
|
+
return import_fs3.default.readdirSync(dir).filter((f) => f.endsWith(".json") && !f.startsWith("_")).map((f) => f.slice(0, -".json".length)).filter((name) => name !== "default");
|
|
395
|
+
}
|
|
396
|
+
function componentNames(componentConfigsDir) {
|
|
397
|
+
if (!import_fs3.default.existsSync(componentConfigsDir)) return [];
|
|
398
|
+
return import_fs3.default.readdirSync(componentConfigsDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
399
|
+
}
|
|
400
|
+
function shippedNames(packageDataDir, subdir) {
|
|
401
|
+
try {
|
|
402
|
+
const pkgRoot = import_path3.default.resolve(packageDataDir, "..", "..", "..");
|
|
403
|
+
const pkg = JSON.parse(import_fs3.default.readFileSync(import_path3.default.join(pkgRoot, "package.json"), "utf-8"));
|
|
404
|
+
const files = Array.isArray(pkg.files) ? pkg.files : [];
|
|
405
|
+
const prefix = `src/live-tokens/data/${subdir}/`;
|
|
406
|
+
return files.filter((f) => f.startsWith(prefix) && /^[^/]+\.json$/.test(f.slice(prefix.length))).map((f) => import_path3.default.basename(f, ".json"));
|
|
407
|
+
} catch {
|
|
408
|
+
return [];
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
function migrateData(opts) {
|
|
412
|
+
const { componentConfigsDir, check = false } = opts;
|
|
413
|
+
const packageDataDir = opts.packageDataDir;
|
|
414
|
+
const layoutInput = {
|
|
415
|
+
dataDir: opts.dataDir,
|
|
416
|
+
colorsAndTypeDir: opts.colorsAndTypeDir,
|
|
417
|
+
themesDir: opts.themesDir,
|
|
418
|
+
configuredManifestsDir: opts.legacyManifestsDir
|
|
419
|
+
};
|
|
420
|
+
const legacyLayout = detectLegacyLayout(layoutInput);
|
|
421
|
+
const renames = legacyLayout ? planLegacyRenames(legacyLayout, layoutInput) : [];
|
|
422
|
+
if (legacyLayout && !check) applyLegacyRenames(renames);
|
|
423
|
+
const planningLegacy = legacyLayout !== null && check;
|
|
424
|
+
const colorsAndTypeDir = planningLegacy ? opts.themesDir : opts.colorsAndTypeDir;
|
|
425
|
+
const themesDir = planningLegacy ? legacyLayout.manifestsDir : opts.themesDir;
|
|
426
|
+
const reported = (p) => {
|
|
427
|
+
if (!planningLegacy) return p;
|
|
428
|
+
for (const { from, to } of renames) {
|
|
429
|
+
if (p.startsWith(from + import_path3.default.sep)) return import_path3.default.join(to, p.slice(from.length + 1));
|
|
430
|
+
}
|
|
431
|
+
return p;
|
|
432
|
+
};
|
|
433
|
+
const colorsRes = versionedFileResourceServer({
|
|
434
|
+
dir: colorsAndTypeDir,
|
|
435
|
+
packageDir: packageDataDir ? import_path3.default.join(packageDataDir, "colors-and-type") : void 0,
|
|
436
|
+
packageOwnedNames: packageDataDir ? shippedNames(packageDataDir, "colors-and-type") : void 0
|
|
437
|
+
});
|
|
438
|
+
const themesRes = versionedFileResourceServer({
|
|
439
|
+
dir: themesDir,
|
|
440
|
+
packageDir: packageDataDir ? import_path3.default.join(packageDataDir, "themes") : void 0
|
|
441
|
+
});
|
|
442
|
+
const componentResources = /* @__PURE__ */ new Map();
|
|
443
|
+
const compRes = (comp) => {
|
|
444
|
+
let r = componentResources.get(comp);
|
|
445
|
+
if (!r) {
|
|
446
|
+
r = versionedFileResourceServer({
|
|
447
|
+
dir: import_path3.default.join(componentConfigsDir, comp),
|
|
448
|
+
packageDir: packageDataDir ? import_path3.default.join(packageDataDir, "component-configs", comp) : void 0,
|
|
449
|
+
packageOwnedNames: packageDataDir ? shippedNames(packageDataDir, `component-configs/${comp}`) : void 0
|
|
450
|
+
});
|
|
451
|
+
componentResources.set(comp, r);
|
|
452
|
+
}
|
|
453
|
+
return r;
|
|
454
|
+
};
|
|
455
|
+
const comps = componentNames(componentConfigsDir);
|
|
456
|
+
const legacyPointers = [];
|
|
457
|
+
for (const dir of [colorsAndTypeDir, ...comps.map((c) => import_path3.default.join(componentConfigsDir, c))]) {
|
|
458
|
+
for (const name of ["_active.json", "_production.json"]) {
|
|
459
|
+
const p = import_path3.default.join(dir, name);
|
|
460
|
+
if (import_fs3.default.existsSync(p)) legacyPointers.push(p);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
const empty = {
|
|
464
|
+
status: "clean",
|
|
465
|
+
renames,
|
|
466
|
+
production: null,
|
|
467
|
+
recoveredThemePath: null,
|
|
468
|
+
workingWritten: [],
|
|
469
|
+
workingKept: [],
|
|
470
|
+
deletedFiles: [],
|
|
471
|
+
deletedPointers: [],
|
|
472
|
+
keptUserFiles: [],
|
|
473
|
+
notThemes: [],
|
|
474
|
+
droppedRefs: [],
|
|
475
|
+
shadowedDefaults: [],
|
|
476
|
+
upgradedThemes: []
|
|
477
|
+
};
|
|
478
|
+
if (legacyPointers.length === 0) {
|
|
479
|
+
if (!legacyLayout) return empty;
|
|
480
|
+
return { ...empty, status: check ? "planned" : "healed" };
|
|
481
|
+
}
|
|
482
|
+
const resolvers = {
|
|
483
|
+
readColorsAndType: (name) => colorsRes.readJson(name),
|
|
484
|
+
readComponentConfig: (comp, name) => compRes(comp).readJson(name),
|
|
485
|
+
normalizeColorsAndType: (colorsAndType) => colorsAndType
|
|
486
|
+
};
|
|
487
|
+
const upgradedThemes = [];
|
|
488
|
+
const notThemes = [];
|
|
489
|
+
const droppedRefs = [];
|
|
490
|
+
const themes = [];
|
|
491
|
+
for (const slug of themesRes.listNames()) {
|
|
492
|
+
let raw;
|
|
493
|
+
try {
|
|
494
|
+
raw = themesRes.readJson(slug);
|
|
495
|
+
} catch {
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
if (!raw) continue;
|
|
499
|
+
if (isColorsAndTypeShaped(raw)) {
|
|
500
|
+
notThemes.push(themesRes.filePath(slug));
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
const { theme, migrated, dropped } = normalizeTheme(raw, resolvers);
|
|
504
|
+
themes.push({ slug, theme });
|
|
505
|
+
for (const ref of dropped) {
|
|
506
|
+
droppedRefs.push(
|
|
507
|
+
`theme "${slug}": the reference ${ref} resolved to nothing, so it carries the shipped default instead`
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
if (migrated && import_fs3.default.existsSync(themesRes.filePath(slug))) {
|
|
511
|
+
upgradedThemes.push(themesRes.filePath(slug));
|
|
512
|
+
if (!check) import_fs3.default.writeFileSync(themesRes.filePath(slug), JSON.stringify(theme, null, 2));
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
const themeBySlug = new Map(themes.map((t) => [t.slug, t.theme]));
|
|
516
|
+
const resolveName = (res, dir, file, key) => {
|
|
517
|
+
const name = readPointerName(import_path3.default.join(dir, file), key);
|
|
518
|
+
if (!name || res.existingPath(name) === null) return "default";
|
|
519
|
+
return name;
|
|
520
|
+
};
|
|
521
|
+
const readPointed = (res, name) => {
|
|
522
|
+
try {
|
|
523
|
+
return res.readJson(name);
|
|
524
|
+
} catch (err) {
|
|
525
|
+
const file = res.existingPath(name) ?? res.filePath(name);
|
|
526
|
+
throw new Error(
|
|
527
|
+
`${file} will not parse (${err instanceof Error ? err.message : String(err)}), and a retired pointer names it. Fix or delete the file, then run the migration again.`
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
const defaultConfig = (comp) => compRes(comp).readJson("default");
|
|
532
|
+
const themeConfigFor = (theme, comp) => {
|
|
533
|
+
const embedded = theme.componentConfigs[comp];
|
|
534
|
+
return embedded ? { ...embedded, component: comp } : defaultConfig(comp);
|
|
535
|
+
};
|
|
536
|
+
const prodColorsName = resolveName(colorsRes, colorsAndTypeDir, "_production.json", "productionFile");
|
|
537
|
+
const prodConfigNames = new Map(
|
|
538
|
+
comps.map((comp) => [
|
|
539
|
+
comp,
|
|
540
|
+
resolveName(compRes(comp), import_path3.default.join(componentConfigsDir, comp), "_production.json", "productionFile")
|
|
541
|
+
])
|
|
542
|
+
);
|
|
543
|
+
const prodColors = readPointed(colorsRes, prodColorsName);
|
|
544
|
+
const prodConfigs = new Map(
|
|
545
|
+
comps.map((comp) => [comp, readPointed(compRes(comp), prodConfigNames.get(comp))])
|
|
546
|
+
);
|
|
547
|
+
const allDefault = prodColorsName === "default" && [...prodConfigNames.values()].every((n) => n === "default");
|
|
548
|
+
const matchesPointedProduction = (theme) => sameContent(theme.colorsAndType, prodColors) && comps.every((comp) => sameContent(themeConfigFor(theme, comp), prodConfigs.get(comp)));
|
|
549
|
+
let production;
|
|
550
|
+
let recoveredTheme = null;
|
|
551
|
+
let recoveredThemePath = null;
|
|
552
|
+
if (allDefault) {
|
|
553
|
+
production = { slug: "default", how: "all-default" };
|
|
554
|
+
} else {
|
|
555
|
+
const match = themes.find((t) => matchesPointedProduction(t.theme));
|
|
556
|
+
if (match) {
|
|
557
|
+
production = { slug: match.slug, how: "matched" };
|
|
558
|
+
} else {
|
|
559
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
560
|
+
const componentConfigs = {};
|
|
561
|
+
for (const comp of comps) {
|
|
562
|
+
const pointed = prodConfigs.get(comp);
|
|
563
|
+
if (!isObject(pointed)) continue;
|
|
564
|
+
if (sameContent(pointed, defaultConfig(comp))) continue;
|
|
565
|
+
componentConfigs[comp] = stripMarkers(pointed);
|
|
566
|
+
}
|
|
567
|
+
recoveredTheme = {
|
|
568
|
+
name: RECOVERED_NAME,
|
|
569
|
+
createdAt: now,
|
|
570
|
+
updatedAt: now,
|
|
571
|
+
schemaVersion: THEME_SCHEMA_VERSION,
|
|
572
|
+
colorsAndType: isObject(prodColors) ? stripMarkers(prodColors) : null,
|
|
573
|
+
componentConfigs
|
|
574
|
+
};
|
|
575
|
+
const slug = nextAvailableName((n) => themesRes.existingPath(n) !== null, RECOVERED_SLUG);
|
|
576
|
+
recoveredThemePath = themesRes.filePath(slug);
|
|
577
|
+
production = { slug, how: "recovered" };
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
const activeThemeSlug = themesRes.getActiveName();
|
|
581
|
+
const activeTheme = themeBySlug.get(activeThemeSlug) ?? null;
|
|
582
|
+
const workingWritten = [];
|
|
583
|
+
const workingKept = [];
|
|
584
|
+
const planWorking = (res, live, saved) => {
|
|
585
|
+
if (!isObject(live) || sameContent(live, saved)) return;
|
|
586
|
+
if (res.hasWorking()) {
|
|
587
|
+
workingKept.push(res.workingPath);
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
workingWritten.push(res.workingPath);
|
|
591
|
+
if (!check) res.writeWorking(stripMarkers(live));
|
|
592
|
+
};
|
|
593
|
+
const activeColorsName = resolveName(colorsRes, colorsAndTypeDir, "_active.json", "activeFile");
|
|
594
|
+
planWorking(
|
|
595
|
+
colorsRes,
|
|
596
|
+
readPointed(colorsRes, activeColorsName),
|
|
597
|
+
activeTheme?.colorsAndType ?? colorsRes.readJson("default")
|
|
598
|
+
);
|
|
599
|
+
for (const comp of comps) {
|
|
600
|
+
const activeName = resolveName(
|
|
601
|
+
compRes(comp),
|
|
602
|
+
import_path3.default.join(componentConfigsDir, comp),
|
|
603
|
+
"_active.json",
|
|
604
|
+
"activeFile"
|
|
605
|
+
);
|
|
606
|
+
planWorking(
|
|
607
|
+
compRes(comp),
|
|
608
|
+
readPointed(compRes(comp), activeName),
|
|
609
|
+
activeTheme ? themeConfigFor(activeTheme, comp) : defaultConfig(comp)
|
|
610
|
+
);
|
|
611
|
+
}
|
|
612
|
+
const deletedFiles = [];
|
|
613
|
+
const keptUserFiles = [];
|
|
614
|
+
const sweep = (res, dir, savedCopies) => {
|
|
615
|
+
for (const name of localNamedFiles(dir)) {
|
|
616
|
+
if (res.isPackageFile(name)) continue;
|
|
617
|
+
let content;
|
|
618
|
+
try {
|
|
619
|
+
content = res.readJson(name);
|
|
620
|
+
} catch {
|
|
621
|
+
keptUserFiles.push(res.filePath(name));
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
const matched = themes.some((t) => sameContent(savedCopies(t.theme), content));
|
|
625
|
+
if (!matched) {
|
|
626
|
+
keptUserFiles.push(res.filePath(name));
|
|
627
|
+
continue;
|
|
628
|
+
}
|
|
629
|
+
deletedFiles.push(res.filePath(name));
|
|
630
|
+
if (!check) import_fs3.default.unlinkSync(res.filePath(name));
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
sweep(colorsRes, colorsAndTypeDir, (theme) => theme.colorsAndType);
|
|
634
|
+
for (const comp of comps) {
|
|
635
|
+
sweep(compRes(comp), import_path3.default.join(componentConfigsDir, comp), (theme) => themeConfigFor(theme, comp));
|
|
636
|
+
}
|
|
637
|
+
const shadowedDefaults = [];
|
|
638
|
+
const localDefault = import_path3.default.join(colorsAndTypeDir, "default.json");
|
|
639
|
+
const packageDefault = packageDataDir ? import_path3.default.join(packageDataDir, "colors-and-type", "default.json") : null;
|
|
640
|
+
if (packageDefault && import_fs3.default.existsSync(localDefault) && import_fs3.default.existsSync(packageDefault) && import_path3.default.resolve(localDefault) !== import_path3.default.resolve(packageDefault)) {
|
|
641
|
+
try {
|
|
642
|
+
const local = JSON.parse(import_fs3.default.readFileSync(localDefault, "utf-8"));
|
|
643
|
+
const shipped = JSON.parse(import_fs3.default.readFileSync(packageDefault, "utf-8"));
|
|
644
|
+
if (!sameContent(local, shipped)) shadowedDefaults.push(localDefault);
|
|
645
|
+
} catch {
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
if (!check) {
|
|
649
|
+
for (const p of legacyPointers) import_fs3.default.unlinkSync(p);
|
|
650
|
+
}
|
|
651
|
+
if (!check) {
|
|
652
|
+
if (recoveredTheme && recoveredThemePath) {
|
|
653
|
+
themesRes.ensureDir();
|
|
654
|
+
import_fs3.default.writeFileSync(recoveredThemePath, JSON.stringify(recoveredTheme, null, 2));
|
|
655
|
+
}
|
|
656
|
+
themesRes.ensureDir();
|
|
657
|
+
themesRes.setProductionName(production.slug);
|
|
658
|
+
}
|
|
659
|
+
return {
|
|
660
|
+
status: check ? "planned" : "healed",
|
|
661
|
+
renames,
|
|
662
|
+
production,
|
|
663
|
+
recoveredThemePath: recoveredThemePath && reported(recoveredThemePath),
|
|
664
|
+
workingWritten: workingWritten.map(reported),
|
|
665
|
+
workingKept: workingKept.map(reported),
|
|
666
|
+
deletedFiles: deletedFiles.map(reported),
|
|
667
|
+
deletedPointers: legacyPointers.map(reported),
|
|
668
|
+
keptUserFiles: keptUserFiles.map(reported),
|
|
669
|
+
notThemes: notThemes.map(reported),
|
|
670
|
+
droppedRefs,
|
|
671
|
+
shadowedDefaults: shadowedDefaults.map(reported),
|
|
672
|
+
upgradedThemes: upgradedThemes.map(reported)
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// vite-plugin/files/dataPaths.ts
|
|
677
|
+
var import_fs4 = __toESM(require("fs"), 1);
|
|
678
|
+
var import_path4 = __toESM(require("path"), 1);
|
|
679
|
+
var DEFAULT_DATA_DIR = "src/live-tokens/data";
|
|
680
|
+
var KNOWN_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
681
|
+
"dataDir",
|
|
682
|
+
"colorsAndTypeDir",
|
|
683
|
+
"componentConfigsDir",
|
|
684
|
+
"themesDir",
|
|
685
|
+
"manifestsDir",
|
|
686
|
+
"tokensCssPath"
|
|
687
|
+
]);
|
|
688
|
+
var cached = null;
|
|
689
|
+
function readLiveTokensConfig() {
|
|
690
|
+
if (cached) return cached;
|
|
691
|
+
try {
|
|
692
|
+
const configPath = import_path4.default.resolve("live-tokens.config.json");
|
|
693
|
+
if (!import_fs4.default.existsSync(configPath)) return cached = {};
|
|
694
|
+
const parsed = JSON.parse(import_fs4.default.readFileSync(configPath, "utf-8"));
|
|
695
|
+
if (!parsed || typeof parsed !== "object") return cached = {};
|
|
696
|
+
const unknown = Object.keys(parsed).filter(
|
|
697
|
+
(k) => k !== "$schema" && !KNOWN_CONFIG_KEYS.has(k)
|
|
698
|
+
);
|
|
699
|
+
if (unknown.length > 0) {
|
|
700
|
+
console.warn(
|
|
701
|
+
`[live-tokens] Unknown key(s) in live-tokens.config.json: ${unknown.join(", ")}. Known keys: ${Array.from(KNOWN_CONFIG_KEYS).join(", ")}.`
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
cached = parsed;
|
|
705
|
+
return cached;
|
|
706
|
+
} catch {
|
|
707
|
+
return cached = {};
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
function resolveDataDirs(opts = {}) {
|
|
711
|
+
const fileConfig = readLiveTokensConfig();
|
|
712
|
+
const dataDirRaw = opts.dataDir ?? fileConfig.dataDir ?? DEFAULT_DATA_DIR;
|
|
713
|
+
const dataDir = import_path4.default.resolve(dataDirRaw);
|
|
714
|
+
const sub = (name) => import_path4.default.resolve(dataDir, name);
|
|
715
|
+
return {
|
|
716
|
+
dataDir,
|
|
717
|
+
colorsAndTypeDir: opts.colorsAndTypeDir ? import_path4.default.resolve(opts.colorsAndTypeDir) : fileConfig.colorsAndTypeDir ? import_path4.default.resolve(fileConfig.colorsAndTypeDir) : sub("colors-and-type"),
|
|
718
|
+
componentConfigsDir: opts.componentConfigsDir ? import_path4.default.resolve(opts.componentConfigsDir) : fileConfig.componentConfigsDir ? import_path4.default.resolve(fileConfig.componentConfigsDir) : sub("component-configs"),
|
|
719
|
+
themesDir: opts.themesDir ? import_path4.default.resolve(opts.themesDir) : fileConfig.themesDir ? import_path4.default.resolve(fileConfig.themesDir) : sub("themes"),
|
|
720
|
+
legacyManifestsDir: fileConfig.manifestsDir ? import_path4.default.resolve(fileConfig.manifestsDir) : void 0
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
724
|
+
0 && (module.exports = {
|
|
725
|
+
migrateData,
|
|
726
|
+
readLiveTokensConfig,
|
|
727
|
+
resolveDataDirs
|
|
728
|
+
});
|