digdesign 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +520 -83
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20,6 +20,8 @@ function defaultConfig() {
|
|
|
20
20
|
tsx: true,
|
|
21
21
|
tailwind: {
|
|
22
22
|
css: "src/app/globals.css",
|
|
23
|
+
theme: "src/app/dig-theme.css",
|
|
24
|
+
brand: "src/app/brand.css",
|
|
23
25
|
baseColor: "neutral",
|
|
24
26
|
cssVariables: true
|
|
25
27
|
},
|
|
@@ -273,15 +275,23 @@ async function fetchFromRegistry(url, subject) {
|
|
|
273
275
|
}
|
|
274
276
|
throw new DigError(`\u062F\u0631\u06CC\u0627\u0641\u062A ${subject} \u0646\u0627\u0645\u0648\u0641\u0642 \u0628\u0648\u062F (${response.status}): ${url}`);
|
|
275
277
|
}
|
|
278
|
+
function normalizeType(type) {
|
|
279
|
+
return type.startsWith("registry:") ? `dig:${type.slice("registry:".length)}` : type;
|
|
280
|
+
}
|
|
276
281
|
async function fetchRegistryIndex(registryUrl) {
|
|
277
282
|
const url = `${registryUrl}/r/registry.json`;
|
|
278
283
|
const response = await fetchFromRegistry(url, "\u0641\u0647\u0631\u0633\u062A\u0650 \u0631\u062C\u06CC\u0633\u062A\u0631\u06CC");
|
|
279
|
-
|
|
284
|
+
const index = await response.json();
|
|
285
|
+
for (const item of index.items) item.type = normalizeType(item.type);
|
|
286
|
+
return index;
|
|
280
287
|
}
|
|
281
288
|
async function fetchRegistryItem(nameOrUrl, registryUrl) {
|
|
282
289
|
const url = resolveUrl(nameOrUrl, registryUrl);
|
|
283
290
|
const response = await fetchFromRegistry(url, `\xAB${nameOrUrl}\xBB`);
|
|
284
|
-
|
|
291
|
+
const item = await response.json();
|
|
292
|
+
item.type = normalizeType(item.type);
|
|
293
|
+
for (const file of item.files ?? []) file.type = normalizeType(file.type);
|
|
294
|
+
return item;
|
|
285
295
|
}
|
|
286
296
|
async function resolveRegistryTree(names, registryUrl) {
|
|
287
297
|
const resolved = /* @__PURE__ */ new Map();
|
|
@@ -369,9 +379,12 @@ import path5 from "path";
|
|
|
369
379
|
function toPosixPath(relativePath) {
|
|
370
380
|
return relativePath.split(path5.sep).join("/");
|
|
371
381
|
}
|
|
382
|
+
function targetPathOptions(config) {
|
|
383
|
+
return { tailwindCss: config.tailwind.css, themeCss: config.tailwind.theme };
|
|
384
|
+
}
|
|
372
385
|
function resolveTargetPath(filePath, aliases, options = {}) {
|
|
373
386
|
if (/(?:^|\/)app\/globals\.css$/.test(filePath)) {
|
|
374
|
-
return options.tailwindCss ?? "src/app/globals.css";
|
|
387
|
+
return options.themeCss ?? options.tailwindCss ?? "src/app/globals.css";
|
|
375
388
|
}
|
|
376
389
|
const match = filePath.match(/(?:^|\/)(components|lib|hooks)\/(.*)$/);
|
|
377
390
|
const cleaned = match ? `${match[1]}/${match[2]}` : filePath;
|
|
@@ -406,7 +419,7 @@ async function pickComponents(registryUrl) {
|
|
|
406
419
|
);
|
|
407
420
|
}
|
|
408
421
|
const index = await fetchRegistryIndex(registryUrl);
|
|
409
|
-
const choices = index.items.filter((item) => item.type === "
|
|
422
|
+
const choices = index.items.filter((item) => item.type === "dig:ui").map((item) => ({
|
|
410
423
|
value: item.name,
|
|
411
424
|
label: item.title ? `${item.name} \u2014 ${item.title}` : item.name
|
|
412
425
|
}));
|
|
@@ -435,9 +448,7 @@ async function addCommand(components, options) {
|
|
|
435
448
|
const existing = [];
|
|
436
449
|
for (const item of items.values()) {
|
|
437
450
|
for (const file of item.files) {
|
|
438
|
-
const target = path6.join(cwd, resolveTargetPath(file.path, config.aliases,
|
|
439
|
-
tailwindCss: config.tailwind.css
|
|
440
|
-
}));
|
|
451
|
+
const target = path6.join(cwd, resolveTargetPath(file.path, config.aliases, targetPathOptions(config)));
|
|
441
452
|
if (await pathExists(target)) existing.push(path6.relative(cwd, target));
|
|
442
453
|
}
|
|
443
454
|
}
|
|
@@ -459,12 +470,10 @@ ${existing.length} \u0641\u0627\u06CC\u0644 \u0627\u0632 \u0642\u0628\u0644 \u06
|
|
|
459
470
|
for (const item of items.values()) {
|
|
460
471
|
for (const dep of item.dependencies ?? []) npmDeps.add(dep);
|
|
461
472
|
for (const file of item.files) {
|
|
462
|
-
const target = path6.join(cwd, resolveTargetPath(file.path, config.aliases,
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
const
|
|
466
|
-
const mark = exists ? overwrite ? "~" : "-" : "+";
|
|
467
|
-
const note = exists ? overwrite ? " (\u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC)" : " (\u0631\u062F \u0645\u06CC\u200C\u0634\u0648\u062F\u060C \u0648\u062C\u0648\u062F \u062F\u0627\u0631\u062F)" : "";
|
|
473
|
+
const target = path6.join(cwd, resolveTargetPath(file.path, config.aliases, targetPathOptions(config)));
|
|
474
|
+
const exists2 = await pathExists(target);
|
|
475
|
+
const mark = exists2 ? overwrite ? "~" : "-" : "+";
|
|
476
|
+
const note = exists2 ? overwrite ? " (\u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC)" : " (\u0631\u062F \u0645\u06CC\u200C\u0634\u0648\u062F\u060C \u0648\u062C\u0648\u062F \u062F\u0627\u0631\u062F)" : "";
|
|
468
477
|
console.log(`${mark} ${path6.relative(cwd, target)}${note}`);
|
|
469
478
|
}
|
|
470
479
|
}
|
|
@@ -488,9 +497,7 @@ ${items.size} \u0622\u06CC\u062A\u0645 \u0627\u0632 \u0631\u062C\u06CC\u0633\u06
|
|
|
488
497
|
const writtenFiles = {};
|
|
489
498
|
const writtenContents = {};
|
|
490
499
|
for (const file of item.files) {
|
|
491
|
-
const target = path6.join(cwd, resolveTargetPath(file.path, config.aliases,
|
|
492
|
-
tailwindCss: config.tailwind.css
|
|
493
|
-
}));
|
|
500
|
+
const target = path6.join(cwd, resolveTargetPath(file.path, config.aliases, targetPathOptions(config)));
|
|
494
501
|
if (!overwrite && await pathExists(target)) {
|
|
495
502
|
console.log(`- \u0631\u062F \u0634\u062F (\u0648\u062C\u0648\u062F \u062F\u0627\u0631\u062F): ${path6.relative(cwd, target)}`);
|
|
496
503
|
skipped++;
|
|
@@ -589,9 +596,9 @@ function searchItems(items, query) {
|
|
|
589
596
|
|
|
590
597
|
// src/commands/list.ts
|
|
591
598
|
var TYPE_LABEL = {
|
|
592
|
-
"
|
|
593
|
-
"
|
|
594
|
-
"
|
|
599
|
+
"dig:ui": "\u06A9\u0627\u0645\u067E\u0648\u0646\u0646\u062A",
|
|
600
|
+
"dig:lib": "\u0627\u0628\u0632\u0627\u0631",
|
|
601
|
+
"dig:theme": "\u062A\u0645"
|
|
595
602
|
};
|
|
596
603
|
async function loadItems(cwd) {
|
|
597
604
|
const config = await configExists(cwd) ? await readConfig(cwd) : defaultConfig();
|
|
@@ -600,7 +607,7 @@ async function loadItems(cwd) {
|
|
|
600
607
|
}
|
|
601
608
|
function matchesType(item, type) {
|
|
602
609
|
if (!type) return true;
|
|
603
|
-
const wanted = type.startsWith("
|
|
610
|
+
const wanted = type.startsWith("dig:") ? type : `dig:${type}`;
|
|
604
611
|
return item.type === wanted;
|
|
605
612
|
}
|
|
606
613
|
function printTable(items) {
|
|
@@ -685,8 +692,8 @@ async function readLocalHash(target) {
|
|
|
685
692
|
throw error;
|
|
686
693
|
}
|
|
687
694
|
}
|
|
688
|
-
async function computeFileDrift(cwd, aliases, lockEntry, file) {
|
|
689
|
-
const target = path7.join(cwd, resolveTargetPath(file.path, aliases));
|
|
695
|
+
async function computeFileDrift(cwd, aliases, lockEntry, file, paths) {
|
|
696
|
+
const target = path7.join(cwd, resolveTargetPath(file.path, aliases, paths));
|
|
690
697
|
const relPath = toPosixPath(path7.relative(cwd, target));
|
|
691
698
|
const registryHash = file.hash ?? hashContent(file.content);
|
|
692
699
|
const installedHash = lockEntry?.files[relPath];
|
|
@@ -700,9 +707,9 @@ async function computeFileDrift(cwd, aliases, lockEntry, file) {
|
|
|
700
707
|
};
|
|
701
708
|
}
|
|
702
709
|
async function computeComponentDrift(params) {
|
|
703
|
-
const { cwd, aliases, registryUrl, lockEntry, registryItem } = params;
|
|
710
|
+
const { cwd, aliases, registryUrl, lockEntry, registryItem, paths } = params;
|
|
704
711
|
const files = await Promise.all(
|
|
705
|
-
registryItem.files.map((file) => computeFileDrift(cwd, aliases, lockEntry, file))
|
|
712
|
+
registryItem.files.map((file) => computeFileDrift(cwd, aliases, lockEntry, file, paths))
|
|
706
713
|
);
|
|
707
714
|
return {
|
|
708
715
|
name: registryItem.name,
|
|
@@ -850,7 +857,7 @@ function describeThreeWayConflict(baseContent, localContent, registryContent) {
|
|
|
850
857
|
return `\u0646\u0633\u0628\u062A \u0628\u0647 \u0646\u0633\u062E\u0647\u0654 \u0646\u0635\u0628\u200C\u0634\u062F\u0647 (\u067E\u0627\u06CC\u0647): \u0634\u0645\u0627 ${local.added + local.removed} \u062E\u0637 \u062A\u063A\u06CC\u06CC\u0631 \u062F\u0627\u062F\u0647\u200C\u0627\u06CC\u062F (+${local.added}/-${local.removed})\u060C \u0631\u062C\u06CC\u0633\u062A\u0631\u06CC ${registry.added + registry.removed} \u062E\u0637 \u062A\u063A\u06CC\u06CC\u0631 \u062F\u0627\u062F\u0647 (+${registry.added}/-${registry.removed}). \u062F\u06CC\u06AF \u062E\u0648\u062F\u06A9\u0627\u0631 \u0627\u062F\u063A\u0627\u0645 \u0646\u0645\u06CC\u200C\u06A9\u0646\u062F \u2014 \u062F\u0648 \u062F\u06CC\u0641\u0650 \u0628\u0627\u0644\u0627 \u0631\u0627 \u062F\u0633\u062A\u06CC \u0628\u0631\u0631\u0633\u06CC \u06A9\u0646\u06CC\u062F.`;
|
|
851
858
|
}
|
|
852
859
|
async function computeFileDiffDetails(params) {
|
|
853
|
-
const { cwd, aliases, name, snapshotVersion, file, registryFile } = params;
|
|
860
|
+
const { cwd, aliases, name, snapshotVersion, file, registryFile, paths } = params;
|
|
854
861
|
if (file.status === "up_to_date") return void 0;
|
|
855
862
|
if (file.status === "new_upstream") {
|
|
856
863
|
return {
|
|
@@ -866,7 +873,7 @@ async function computeFileDiffDetails(params) {
|
|
|
866
873
|
note: file.registryHash === file.installedHash ? "\u0641\u0627\u06CC\u0644 \u0628\u0647\u200C\u0635\u0648\u0631\u062A \u0645\u062D\u0644\u06CC \u062D\u0630\u0641 \u0634\u062F\u0647\u061B \u0631\u062C\u06CC\u0633\u062A\u0631\u06CC \u0627\u0632 \u0632\u0645\u0627\u0646 \u0646\u0635\u0628 \u062A\u063A\u06CC\u06CC\u0631\u06CC \u0646\u06A9\u0631\u062F\u0647." : "\u0641\u0627\u06CC\u0644 \u0628\u0647\u200C\u0635\u0648\u0631\u062A \u0645\u062D\u0644\u06CC \u062D\u0630\u0641 \u0634\u062F\u0647 \u0648 \u0631\u062C\u06CC\u0633\u062A\u0631\u06CC \u0647\u0645 \u062A\u063A\u06CC\u06CC\u0631 \u06A9\u0631\u062F\u0647 \u2014 \u0645\u0642\u0627\u06CC\u0633\u0647\u200C\u0627\u06CC \u0628\u0627 \u0641\u0627\u06CC\u0644 \u062D\u0630\u0641\u200C\u0634\u062F\u0647 \u0645\u0645\u06A9\u0646 \u0646\u06CC\u0633\u062A."
|
|
867
874
|
};
|
|
868
875
|
}
|
|
869
|
-
const target = path8.join(cwd, resolveTargetPath(registryFile.path, aliases));
|
|
876
|
+
const target = path8.join(cwd, resolveTargetPath(registryFile.path, aliases, paths));
|
|
870
877
|
const localContent = await readTextFileSafely(target);
|
|
871
878
|
if (localContent === "binary") {
|
|
872
879
|
return {
|
|
@@ -961,6 +968,7 @@ async function diffCommand(components, options) {
|
|
|
961
968
|
const drift = await computeComponentDrift({
|
|
962
969
|
cwd,
|
|
963
970
|
aliases: config.aliases,
|
|
971
|
+
paths: targetPathOptions(config),
|
|
964
972
|
registryUrl: config.registryUrl,
|
|
965
973
|
lockEntry,
|
|
966
974
|
registryItem
|
|
@@ -972,6 +980,7 @@ async function diffCommand(components, options) {
|
|
|
972
980
|
(file, index) => file.status === "up_to_date" ? Promise.resolve(void 0) : computeFileDiffDetails({
|
|
973
981
|
cwd,
|
|
974
982
|
aliases: config.aliases,
|
|
983
|
+
paths: targetPathOptions(config),
|
|
975
984
|
name,
|
|
976
985
|
snapshotVersion: lockEntry?.snapshot?.version,
|
|
977
986
|
file,
|
|
@@ -1655,7 +1664,7 @@ async function generateIntelligenceExport(params) {
|
|
|
1655
1664
|
} catch {
|
|
1656
1665
|
continue;
|
|
1657
1666
|
}
|
|
1658
|
-
if (item.type !== "
|
|
1667
|
+
if (item.type !== "dig:ui") continue;
|
|
1659
1668
|
const scan = await scanRepositoryForComponent({ projectRoot: cwd, component: name });
|
|
1660
1669
|
installedComponents.push({
|
|
1661
1670
|
name,
|
|
@@ -1874,7 +1883,7 @@ async function healthCommand(options) {
|
|
|
1874
1883
|
} catch {
|
|
1875
1884
|
continue;
|
|
1876
1885
|
}
|
|
1877
|
-
if (item.type !== "
|
|
1886
|
+
if (item.type !== "dig:ui") continue;
|
|
1878
1887
|
const scan = await scanRepositoryForComponent({ projectRoot: cwd, component: name });
|
|
1879
1888
|
installedComponents.push({
|
|
1880
1889
|
name,
|
|
@@ -1948,8 +1957,272 @@ async function impactCommand(name, options) {
|
|
|
1948
1957
|
}
|
|
1949
1958
|
|
|
1950
1959
|
// src/commands/init.ts
|
|
1951
|
-
import {
|
|
1960
|
+
import { readFile as readFile8, writeFile as writeFile6 } from "fs/promises";
|
|
1961
|
+
import path12 from "path";
|
|
1962
|
+
|
|
1963
|
+
// src/commands/theme.ts
|
|
1964
|
+
import { access as access5, mkdir as mkdir4, readFile as readFile7, writeFile as writeFile5 } from "fs/promises";
|
|
1965
|
+
import path11 from "path";
|
|
1966
|
+
|
|
1967
|
+
// src/lib/brand-ramp.ts
|
|
1968
|
+
var RAMP_STEPS = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
|
|
1969
|
+
var REFERENCE_L = {
|
|
1970
|
+
50: 96.6,
|
|
1971
|
+
100: 93.1,
|
|
1972
|
+
200: 87.6,
|
|
1973
|
+
300: 79.7,
|
|
1974
|
+
400: 69,
|
|
1975
|
+
500: 60.4,
|
|
1976
|
+
600: 52.9,
|
|
1977
|
+
700: 47.3,
|
|
1978
|
+
800: 41.1,
|
|
1979
|
+
900: 36.9,
|
|
1980
|
+
950: 26.9
|
|
1981
|
+
};
|
|
1982
|
+
var CHROMA_SHAPE = {
|
|
1983
|
+
50: 0.07,
|
|
1984
|
+
100: 0.13,
|
|
1985
|
+
200: 0.25,
|
|
1986
|
+
300: 0.44,
|
|
1987
|
+
400: 0.69,
|
|
1988
|
+
500: 0.89,
|
|
1989
|
+
600: 1,
|
|
1990
|
+
700: 0.92,
|
|
1991
|
+
800: 0.74,
|
|
1992
|
+
900: 0.55,
|
|
1993
|
+
950: 0.34
|
|
1994
|
+
};
|
|
1995
|
+
function parseHex(hex) {
|
|
1996
|
+
const clean = hex.trim().replace(/^#/, "");
|
|
1997
|
+
const full = clean.length === 3 ? [...clean].map((ch) => ch + ch).join("") : clean;
|
|
1998
|
+
if (!/^[0-9a-fA-F]{6}$/.test(full)) {
|
|
1999
|
+
throw new DigError(`\xAB${hex}\xBB \u0631\u0646\u06AF\u0650 \u0647\u06AF\u0632\u0650 \u0645\u0639\u062A\u0628\u0631 \u0646\u06CC\u0633\u062A\u061B \u0645\u062B\u0644\u0627\u064B #2C4C5B \u0628\u062F\u0647\u06CC\u062F.`);
|
|
2000
|
+
}
|
|
2001
|
+
return [0, 2, 4].map((i) => parseInt(full.slice(i, i + 2), 16) / 255);
|
|
2002
|
+
}
|
|
2003
|
+
var toLinear = (v) => v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
|
|
2004
|
+
var fromLinear = (v) => v <= 31308e-7 ? 12.92 * v : 1.055 * v ** (1 / 2.4) - 0.055;
|
|
2005
|
+
function hexToOklch(hex) {
|
|
2006
|
+
const [r, g, b] = parseHex(hex).map(toLinear);
|
|
2007
|
+
const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
|
|
2008
|
+
const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
|
|
2009
|
+
const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
|
|
2010
|
+
const L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s;
|
|
2011
|
+
const A = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;
|
|
2012
|
+
const B = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;
|
|
2013
|
+
const c = Math.sqrt(A * A + B * B);
|
|
2014
|
+
const h = (Math.atan2(B, A) * 180 / Math.PI + 360) % 360;
|
|
2015
|
+
return { l: L * 100, c, h };
|
|
2016
|
+
}
|
|
2017
|
+
function oklchToSrgb({ l, c, h }) {
|
|
2018
|
+
const L = l / 100;
|
|
2019
|
+
const rad = h * Math.PI / 180;
|
|
2020
|
+
const A = c * Math.cos(rad);
|
|
2021
|
+
const B = c * Math.sin(rad);
|
|
2022
|
+
const l_ = (L + 0.3963377774 * A + 0.2158037573 * B) ** 3;
|
|
2023
|
+
const m_ = (L - 0.1055613458 * A - 0.0638541728 * B) ** 3;
|
|
2024
|
+
const s_ = (L - 0.0894841775 * A - 1.291485548 * B) ** 3;
|
|
2025
|
+
return [
|
|
2026
|
+
fromLinear(4.0767416621 * l_ - 3.3077115913 * m_ + 0.2309699292 * s_),
|
|
2027
|
+
fromLinear(-1.2684380046 * l_ + 2.6097574011 * m_ - 0.3413193965 * s_),
|
|
2028
|
+
fromLinear(-0.0041960863 * l_ - 0.7034186147 * m_ + 1.707614701 * s_)
|
|
2029
|
+
];
|
|
2030
|
+
}
|
|
2031
|
+
var inGamut = (rgb) => rgb.every((v) => v >= -5e-4 && v <= 1.0005);
|
|
2032
|
+
function fitGamut(color) {
|
|
2033
|
+
let { c } = color;
|
|
2034
|
+
while (c > 0 && !inGamut(oklchToSrgb({ ...color, c }))) c -= 2e-3;
|
|
2035
|
+
return { ...color, c: Math.max(0, c) };
|
|
2036
|
+
}
|
|
2037
|
+
function relativeLuminance(rgb) {
|
|
2038
|
+
const [r, g, b] = rgb.map((v) => toLinear(Math.min(1, Math.max(0, v))));
|
|
2039
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
2040
|
+
}
|
|
2041
|
+
function contrastWithWhite(color) {
|
|
2042
|
+
return 1.05 / (relativeLuminance(oklchToSrgb(color)) + 0.05);
|
|
2043
|
+
}
|
|
2044
|
+
function formatOklch({ l, c, h }) {
|
|
2045
|
+
return `oklch(${l.toFixed(1)}% ${c.toFixed(3)} ${h.toFixed(1)})`;
|
|
2046
|
+
}
|
|
2047
|
+
function buildBrandRamp(hex) {
|
|
2048
|
+
const base = hexToOklch(hex);
|
|
2049
|
+
const top = 97.5;
|
|
2050
|
+
const bottom = Math.min(26, Math.max(8, base.l * 0.55));
|
|
2051
|
+
const ref600 = REFERENCE_L[600];
|
|
2052
|
+
const steps = {};
|
|
2053
|
+
for (const step of RAMP_STEPS) {
|
|
2054
|
+
if (step === 600) {
|
|
2055
|
+
steps[step] = base;
|
|
2056
|
+
continue;
|
|
2057
|
+
}
|
|
2058
|
+
const ref = REFERENCE_L[step];
|
|
2059
|
+
const l = ref > ref600 ? base.l + (ref - ref600) / (REFERENCE_L[50] - ref600) * (top - base.l) : base.l - (ref600 - ref) / (ref600 - REFERENCE_L[950]) * (base.l - bottom);
|
|
2060
|
+
steps[step] = fitGamut({ l, c: base.c * CHROMA_SHAPE[step], h: base.h });
|
|
2061
|
+
}
|
|
2062
|
+
return { steps, primaryContrast: contrastWithWhite(base) };
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2065
|
+
// src/lib/theme-files.ts
|
|
1952
2066
|
import path10 from "path";
|
|
2067
|
+
function importPath(fromFile, toFile) {
|
|
2068
|
+
const rel = toPosixPath(path10.relative(path10.dirname(fromFile), toFile));
|
|
2069
|
+
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
2070
|
+
}
|
|
2071
|
+
function globalsCss(paths, extraStatements = []) {
|
|
2072
|
+
const lines = [
|
|
2073
|
+
"/* \u0641\u0642\u0637 import. \u062A\u0645 \u062F\u0631 dig-theme.css (\u0645\u0627\u0644\u0650 \u062F\u06CC\u06AF) \u0648 \u0628\u0631\u0646\u062F \u062F\u0631 brand.css (\u0645\u0627\u0644\u0650",
|
|
2074
|
+
" \u067E\u0631\u0648\u0698\u0647) \u0627\u0633\u062A\u061B \u062A\u0631\u062A\u06CC\u0628 \u0645\u0647\u0645 \u0627\u0633\u062A: \u0628\u0631\u0646\u062F \u0628\u0639\u062F \u0627\u0632 \u062A\u0645 \u0645\u06CC\u200C\u0622\u06CC\u062F \u062A\u0627 \u0628\u0631\u0646\u062F\u0647 \u0628\u0627\u0634\u062F. */",
|
|
2075
|
+
`@import "${importPath(paths.css, paths.theme)}";`,
|
|
2076
|
+
...extraStatements,
|
|
2077
|
+
`@import "${importPath(paths.css, paths.brand)}";`,
|
|
2078
|
+
""
|
|
2079
|
+
];
|
|
2080
|
+
return lines.join("\n");
|
|
2081
|
+
}
|
|
2082
|
+
var BRAND_HEADER = `/* ==================================================================== *
|
|
2083
|
+
* \u0628\u0631\u0646\u062F\u0650 \u067E\u0631\u0648\u0698\u0647
|
|
2084
|
+
*
|
|
2085
|
+
* \u0627\u06CC\u0646 \u0641\u0627\u06CC\u0644 \u0645\u0627\u0644\u0650 \u067E\u0631\u0648\u0698\u0647 \u0627\u0633\u062A \u0648 \u062F\u06CC\u06AF \u0647\u06CC\u0686\u200C\u0648\u0642\u062A \u0622\u0646 \u0631\u0627 \u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC \u0646\u0645\u06CC\u200C\u06A9\u0646\u062F\u061B \u062A\u0645\u0650 \u062F\u06CC\u06AF \u062F\u0631
|
|
2086
|
+
* dig-theme.css \u0627\u0633\u062A \u0648 \u0628\u0627 \xABdig update theme\xBB \u0628\u0647\u200C\u0631\u0648\u0632 \u0645\u06CC\u200C\u0634\u0648\u062F.
|
|
2087
|
+
*
|
|
2088
|
+
* \u0686\u0647 \u0686\u06CC\u0632\u06CC \u0627\u06CC\u0646\u062C\u0627 \u0645\u06CC\u200C\u0622\u06CC\u062F:
|
|
2089
|
+
* \u06F1) \u0631\u0645\u067E\u0650 \u0628\u0631\u0646\u062F (--brand-*\u060C \u0644\u0627\u06CC\u0647\u0654 \u06F2)\u061B Shade \u06F6\u06F0\u06F0 \u0647\u0645\u0627\u0646 --primary \u0627\u0633\u062A.
|
|
2090
|
+
* \u06F2) \u0644\u0627\u06CC\u0647\u0654 \u0645\u062D\u0635\u0648\u0644: \u0641\u0642\u0637 \u062A\u0648\u06A9\u0646\u200C\u0647\u0627\u06CC \u0645\u0639\u0646\u0627\u06CC\u06CC\u200C\u0627\u06CC \u06A9\u0647 \u0628\u0627 \u067E\u06CC\u0634\u200C\u0641\u0631\u0636\u0650 \u062F\u06CC\u06AF \u0641\u0631\u0642 \u062F\u0627\u0631\u0646\u062F
|
|
2091
|
+
* (--background\u060C --foreground\u060C --radius\u060C --font-anchor\u060C \u0633\u0627\u06CC\u0647\u200C\u0647\u0627\u060C ...).
|
|
2092
|
+
* \u06F3) \u062A\u0648\u06A9\u0646\u200C\u0647\u0627\u06CC \u062A\u0627\u0632\u0647\u0654 \u062E\u0648\u062F\u0650 \u0645\u062D\u0635\u0648\u0644 \u062F\u0627\u062E\u0644 @theme inline.
|
|
2093
|
+
*
|
|
2094
|
+
* \u0631\u0645\u067E \u0631\u0627 \u0645\u06CC\u200C\u0634\u0648\u062F \u062F\u0648\u0628\u0627\u0631\u0647 \u0627\u0632 \u06CC\u06A9 \u0631\u0646\u06AF \u0633\u0627\u062E\u062A: npx digdesign theme brand "#2C4C5B"
|
|
2095
|
+
* ==================================================================== */
|
|
2096
|
+
`;
|
|
2097
|
+
function brandRampBlock(ramp, hex) {
|
|
2098
|
+
const lines = RAMP_STEPS.map((step) => ` --brand-${step}: ${formatOklch(ramp.steps[step])};`);
|
|
2099
|
+
return `/* dig:brand-ramp-start \u2014 \u0633\u0627\u062E\u062A\u0647\u200C\u0634\u062F\u0647 \u0627\u0632 ${hex.toUpperCase()}\u061B \xABdig theme brand\xBB \u0647\u0645\u06CC\u0646 \u0628\u0644\u0648\u06A9 \u0631\u0627 \u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC \u0645\u06CC\u200C\u06A9\u0646\u062F */
|
|
2100
|
+
:root {
|
|
2101
|
+
${lines.join("\n")}
|
|
2102
|
+
}
|
|
2103
|
+
/* dig:brand-ramp-end */`;
|
|
2104
|
+
}
|
|
2105
|
+
function brandCss(options) {
|
|
2106
|
+
const parts = [BRAND_HEADER];
|
|
2107
|
+
if (options.ramp && options.hex) parts.push(brandRampBlock(options.ramp, options.hex));
|
|
2108
|
+
if (options.body?.trim()) parts.push(options.body.trim());
|
|
2109
|
+
if (!options.ramp && !options.body?.trim()) {
|
|
2110
|
+
parts.push(`/* \u0646\u0645\u0648\u0646\u0647:
|
|
2111
|
+
:root {
|
|
2112
|
+
--brand-600: #2c4c5b;
|
|
2113
|
+
--radius: 0.75rem;
|
|
2114
|
+
}
|
|
2115
|
+
*/`);
|
|
2116
|
+
}
|
|
2117
|
+
return `${parts.join("\n\n")}
|
|
2118
|
+
`;
|
|
2119
|
+
}
|
|
2120
|
+
function replaceBrandRamp(existing, ramp, hex) {
|
|
2121
|
+
const block = brandRampBlock(ramp, hex);
|
|
2122
|
+
const pattern = /\/\* dig:brand-ramp-start[\s\S]*?\/\* dig:brand-ramp-end \*\//;
|
|
2123
|
+
if (pattern.test(existing)) return existing.replace(pattern, block);
|
|
2124
|
+
const headerEnd = existing.indexOf("* ==================================================================== */");
|
|
2125
|
+
if (existing.startsWith("/* ====") && headerEnd !== -1) {
|
|
2126
|
+
const cut = existing.indexOf("\n", headerEnd) + 1;
|
|
2127
|
+
return `${existing.slice(0, cut)}
|
|
2128
|
+
${block}
|
|
2129
|
+
${existing.slice(cut)}`;
|
|
2130
|
+
}
|
|
2131
|
+
return `${block}
|
|
2132
|
+
|
|
2133
|
+
${existing}`;
|
|
2134
|
+
}
|
|
2135
|
+
function stripComments(css) {
|
|
2136
|
+
return css.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
2137
|
+
}
|
|
2138
|
+
function parseCss(css) {
|
|
2139
|
+
const source = stripComments(css);
|
|
2140
|
+
const declarations = [];
|
|
2141
|
+
const statements = [];
|
|
2142
|
+
const stack = [];
|
|
2143
|
+
let buffer = "";
|
|
2144
|
+
let depthParen = 0;
|
|
2145
|
+
const flush = (terminator) => {
|
|
2146
|
+
const text = buffer.trim();
|
|
2147
|
+
buffer = "";
|
|
2148
|
+
if (!text) return;
|
|
2149
|
+
if (text.startsWith("@")) {
|
|
2150
|
+
statements.push({ context: [...stack], text: `${text};` });
|
|
2151
|
+
return;
|
|
2152
|
+
}
|
|
2153
|
+
const colon = text.indexOf(":");
|
|
2154
|
+
if (colon === -1) return;
|
|
2155
|
+
declarations.push({
|
|
2156
|
+
context: [...stack],
|
|
2157
|
+
property: text.slice(0, colon).trim(),
|
|
2158
|
+
value: text.slice(colon + 1).trim().replace(/\s+/g, " ")
|
|
2159
|
+
});
|
|
2160
|
+
void terminator;
|
|
2161
|
+
};
|
|
2162
|
+
for (const ch of source) {
|
|
2163
|
+
if (ch === "(") depthParen++;
|
|
2164
|
+
if (ch === ")") depthParen--;
|
|
2165
|
+
if (depthParen > 0) {
|
|
2166
|
+
buffer += ch;
|
|
2167
|
+
continue;
|
|
2168
|
+
}
|
|
2169
|
+
if (ch === "{") {
|
|
2170
|
+
stack.push(buffer.trim().replace(/\s+/g, " "));
|
|
2171
|
+
buffer = "";
|
|
2172
|
+
} else if (ch === ";") {
|
|
2173
|
+
flush(";");
|
|
2174
|
+
} else if (ch === "}") {
|
|
2175
|
+
flush("}");
|
|
2176
|
+
stack.pop();
|
|
2177
|
+
} else {
|
|
2178
|
+
buffer += ch;
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
return { declarations, statements };
|
|
2182
|
+
}
|
|
2183
|
+
var key = (context, name) => `${context.join(" > ")}|${name}`;
|
|
2184
|
+
function splitTheme(projectCss, digThemeCss) {
|
|
2185
|
+
const project = parseCss(projectCss);
|
|
2186
|
+
const dig = parseCss(digThemeCss);
|
|
2187
|
+
const digValues = new Map(dig.declarations.map((d) => [key(d.context, d.property), d.value]));
|
|
2188
|
+
const digStatements = new Set(dig.statements.map((s) => key(s.context, s.text)));
|
|
2189
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
2190
|
+
let changed = 0;
|
|
2191
|
+
let added = 0;
|
|
2192
|
+
for (const decl of project.declarations) {
|
|
2193
|
+
const k = key(decl.context, decl.property);
|
|
2194
|
+
const digValue = digValues.get(k);
|
|
2195
|
+
if (digValue === decl.value) {
|
|
2196
|
+
overrides.delete(k);
|
|
2197
|
+
continue;
|
|
2198
|
+
}
|
|
2199
|
+
overrides.set(k, decl);
|
|
2200
|
+
}
|
|
2201
|
+
for (const [k] of overrides) {
|
|
2202
|
+
if (digValues.has(k)) changed++;
|
|
2203
|
+
else added++;
|
|
2204
|
+
}
|
|
2205
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2206
|
+
for (const decl of overrides.values()) {
|
|
2207
|
+
const ctx = decl.context.join(" > ");
|
|
2208
|
+
if (!groups.has(ctx)) groups.set(ctx, []);
|
|
2209
|
+
groups.get(ctx).push(decl);
|
|
2210
|
+
}
|
|
2211
|
+
const blocks = [];
|
|
2212
|
+
for (const [, decls] of groups) {
|
|
2213
|
+
const context = decls[0].context;
|
|
2214
|
+
const indent = (level) => " ".repeat(level);
|
|
2215
|
+
const lines = [];
|
|
2216
|
+
context.forEach((selector, level) => lines.push(`${indent(level)}${selector} {`));
|
|
2217
|
+
for (const d of decls) lines.push(`${indent(context.length)}${d.property}: ${d.value};`);
|
|
2218
|
+
for (let level = context.length - 1; level >= 0; level--) lines.push(`${indent(level)}}`);
|
|
2219
|
+
blocks.push(lines.join("\n"));
|
|
2220
|
+
}
|
|
2221
|
+
const extraStatements = project.statements.filter((s) => s.context.length === 0 && !digStatements.has(key(s.context, s.text))).map((s) => s.text);
|
|
2222
|
+
return { body: blocks.join("\n\n"), extraStatements, changed, added };
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
// src/commands/theme.ts
|
|
1953
2226
|
var THEME_ITEM = "theme";
|
|
1954
2227
|
async function readIfExists(target) {
|
|
1955
2228
|
try {
|
|
@@ -1958,36 +2231,192 @@ async function readIfExists(target) {
|
|
|
1958
2231
|
return null;
|
|
1959
2232
|
}
|
|
1960
2233
|
}
|
|
1961
|
-
async function
|
|
2234
|
+
async function exists(target) {
|
|
2235
|
+
try {
|
|
2236
|
+
await access5(target);
|
|
2237
|
+
return true;
|
|
2238
|
+
} catch {
|
|
2239
|
+
return false;
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
function themePaths(config) {
|
|
2243
|
+
const dir = path11.posix.dirname(toPosixPath(config.tailwind.css));
|
|
2244
|
+
return {
|
|
2245
|
+
css: config.tailwind.css,
|
|
2246
|
+
theme: config.tailwind.theme ?? `${dir}/dig-theme.css`,
|
|
2247
|
+
brand: config.tailwind.brand ?? `${dir}/brand.css`
|
|
2248
|
+
};
|
|
2249
|
+
}
|
|
2250
|
+
function isBoilerplateCss(content) {
|
|
2251
|
+
if (content === null) return true;
|
|
2252
|
+
const withoutComments = content.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
2253
|
+
return withoutComments.split("\n").filter((line) => line.trim() && !line.trim().startsWith("@import")).length === 0;
|
|
2254
|
+
}
|
|
2255
|
+
async function fetchTheme(config) {
|
|
1962
2256
|
const item = await fetchRegistryItem(THEME_ITEM, config.registryUrl);
|
|
1963
2257
|
const file = item.files[0];
|
|
1964
|
-
if (!file)
|
|
1965
|
-
|
|
2258
|
+
if (!file) throw new DigError("\u0622\u06CC\u062A\u0645\u0650 \xABtheme\xBB \u062F\u0631 \u0631\u062C\u06CC\u0633\u062A\u0631\u06CC \u0641\u0627\u06CC\u0644\u06CC \u0646\u062F\u0627\u0631\u062F.");
|
|
2259
|
+
return { ...item, content: file.content };
|
|
2260
|
+
}
|
|
2261
|
+
async function recordTheme(cwd, config, themeRel, item) {
|
|
2262
|
+
const lock = await readLock(cwd);
|
|
2263
|
+
const version = item.version ?? "0.0.0";
|
|
2264
|
+
const installedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2265
|
+
const relPath = toPosixPath(themeRel);
|
|
2266
|
+
const snapshot = await writeComponentSnapshot(cwd, THEME_ITEM, version, { [relPath]: item.content });
|
|
2267
|
+
lock.components[THEME_ITEM] = mergeComponentEntry(lock.components[THEME_ITEM], {
|
|
2268
|
+
version: item.version,
|
|
2269
|
+
registryUrl: config.registryUrl,
|
|
2270
|
+
installedAt,
|
|
2271
|
+
writtenFiles: { [relPath]: item.files[0].hash ?? hashContent(item.content) },
|
|
2272
|
+
snapshot: "path" in snapshot ? { version, path: snapshot.path, installedAt } : void 0
|
|
2273
|
+
});
|
|
2274
|
+
await writeLock(lock, cwd);
|
|
2275
|
+
}
|
|
2276
|
+
async function writeText(cwd, rel, content) {
|
|
2277
|
+
const target = path11.join(cwd, rel);
|
|
2278
|
+
await mkdir4(path11.dirname(target), { recursive: true });
|
|
2279
|
+
await writeFile5(target, content, "utf8");
|
|
2280
|
+
}
|
|
2281
|
+
async function installTheme(cwd, config, options) {
|
|
2282
|
+
const paths = themePaths(config);
|
|
2283
|
+
const item = await fetchTheme(config);
|
|
2284
|
+
const ramp = options.brand ? buildBrandRamp(options.brand) : void 0;
|
|
2285
|
+
await writeText(cwd, paths.theme, item.content);
|
|
2286
|
+
console.log(`\u2713 \u062A\u0645\u0650 \u062F\u06CC\u06AF \u062F\u0631 ${paths.theme} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F (\u0645\u0627\u0644\u0650 \u062F\u06CC\u06AF\u061B \u0628\u0627 \xABdig update theme\xBB \u0628\u0647\u200C\u0631\u0648\u0632 \u0645\u06CC\u200C\u0634\u0648\u062F).`);
|
|
2287
|
+
const existingBrand = await readIfExists(path11.join(cwd, paths.brand));
|
|
2288
|
+
if (existingBrand === null) {
|
|
2289
|
+
await writeText(cwd, paths.brand, brandCss({ ramp, hex: options.brand }));
|
|
2290
|
+
console.log(`\u2713 ${paths.brand} \u0633\u0627\u062E\u062A\u0647 \u0634\u062F (\u0645\u0627\u0644\u0650 \u067E\u0631\u0648\u0698\u0647\u061B \u062F\u06CC\u06AF \u0647\u0631\u06AF\u0632 \u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC\u200C\u0627\u0634 \u0646\u0645\u06CC\u200C\u06A9\u0646\u062F).`);
|
|
2291
|
+
} else if (ramp && options.brand) {
|
|
2292
|
+
await writeText(cwd, paths.brand, replaceBrandRamp(existingBrand, ramp, options.brand));
|
|
2293
|
+
console.log(`\u2713 \u0631\u0645\u067E\u0650 \u0628\u0631\u0646\u062F \u062F\u0631 ${paths.brand} \u0627\u0632 ${options.brand} \u0628\u0627\u0632\u0633\u0627\u0632\u06CC \u0634\u062F\u061B \u0628\u0642\u06CC\u0647\u0654 \u0641\u0627\u06CC\u0644 \u062F\u0633\u062A \u0646\u062E\u0648\u0631\u062F.`);
|
|
2294
|
+
} else {
|
|
2295
|
+
console.log(`- ${paths.brand} \u0627\u0632 \u0642\u0628\u0644 \u0647\u0633\u062A\u061B \u062F\u0633\u062A \u0646\u062E\u0648\u0631\u062F.`);
|
|
2296
|
+
}
|
|
2297
|
+
if (ramp) reportContrast(ramp.primaryContrast);
|
|
2298
|
+
const cssTarget = path11.join(cwd, paths.css);
|
|
2299
|
+
const existingCss = await readIfExists(cssTarget);
|
|
2300
|
+
if (!isBoilerplateCss(existingCss) && existingCss !== null) {
|
|
2301
|
+
await writeFile5(`${cssTarget}.backup`, existingCss, "utf8");
|
|
2302
|
+
console.log(` \u0646\u0633\u062E\u0647\u0654 \u0642\u0628\u0644\u06CC\u0650 ${paths.css} \u062F\u0631 ${paths.css}.backup \u0646\u06AF\u0647 \u062F\u0627\u0634\u062A\u0647 \u0634\u062F.`);
|
|
2303
|
+
console.log(` \u0627\u06AF\u0631 \u0622\u0646 \u0641\u0627\u06CC\u0644 \u062A\u0645\u0650 \u0642\u062F\u06CC\u0645\u06CC\u0650 \u062F\u06CC\u06AF \u0628\u0648\u062F\u060C \u0628\u0647\u200C\u062C\u0627\u06CC init \u0627\u0632 \xABdig theme split\xBB \u0627\u0633\u062A\u0641\u0627\u062F\u0647 \u06A9\u0646\u06CC\u062F.`);
|
|
2304
|
+
}
|
|
2305
|
+
await writeText(cwd, paths.css, globalsCss(paths));
|
|
2306
|
+
console.log(`\u2713 ${paths.css} \u0641\u0642\u0637 import \u0634\u062F: \u062A\u0645\u060C \u0633\u067E\u0633 \u0628\u0631\u0646\u062F.`);
|
|
2307
|
+
await recordTheme(cwd, config, paths.theme, item);
|
|
2308
|
+
return item;
|
|
2309
|
+
}
|
|
2310
|
+
function reportContrast(contrast) {
|
|
2311
|
+
const ratio = contrast.toFixed(2);
|
|
2312
|
+
if (contrast >= 4.5) {
|
|
2313
|
+
console.log(` \u06A9\u0646\u062A\u0631\u0627\u0633\u062A\u0650 \u0645\u062A\u0646\u0650 \u0633\u0641\u06CC\u062F \u0631\u0648\u06CC \u0631\u0646\u06AF\u0650 \u0627\u0635\u0644\u06CC: ${ratio} (AA \u0631\u0627 \u0631\u062F \u0645\u06CC\u200C\u06A9\u0646\u062F).`);
|
|
2314
|
+
} else {
|
|
2315
|
+
console.log(
|
|
2316
|
+
` \u26A0 \u06A9\u0646\u062A\u0631\u0627\u0633\u062A\u0650 \u0645\u062A\u0646\u0650 \u0633\u0641\u06CC\u062F \u0631\u0648\u06CC \u0631\u0646\u06AF\u0650 \u0627\u0635\u0644\u06CC ${ratio} \u0627\u0633\u062A\u060C \u06A9\u0645\u062A\u0631 \u0627\u0632 \u06F4.\u06F5 (AA). \u0645\u062A\u0646\u0650 \u062F\u06A9\u0645\u0647\u200C\u0647\u0627\u06CC \u0627\u0635\u0644\u06CC \u062E\u0648\u0627\u0646\u0627 \u0646\u06CC\u0633\u062A\u061B \u0631\u0646\u06AF\u06CC \u062A\u06CC\u0631\u0647\u200C\u062A\u0631 \u0628\u062F\u0647\u06CC\u062F \u06CC\u0627 --primary-foreground \u0631\u0627 \u062F\u0631 brand.css \u062A\u06CC\u0631\u0647 \u06A9\u0646\u06CC\u062F.`
|
|
2317
|
+
);
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
async function requireConfig(cwd) {
|
|
2321
|
+
if (!await configExists(cwd)) {
|
|
2322
|
+
throw new DigError("dig.json \u067E\u06CC\u062F\u0627 \u0646\u0634\u062F\u061B \u0627\u0648\u0644 \xABnpx digdesign init\xBB \u0631\u0627 \u0627\u062C\u0631\u0627 \u06A9\u0646\u06CC\u062F.");
|
|
1966
2323
|
}
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
2324
|
+
return readConfig(cwd);
|
|
2325
|
+
}
|
|
2326
|
+
async function themeSplitCommand(options) {
|
|
2327
|
+
const cwd = process.cwd();
|
|
2328
|
+
const config = await requireConfig(cwd);
|
|
2329
|
+
if (config.tailwind.theme) {
|
|
2330
|
+
console.log(`\u067E\u0631\u0648\u0698\u0647 \u0627\u0632 \u0642\u0628\u0644 \u0633\u0627\u062E\u062A\u0627\u0631\u0650 \u062F\u0648\u0641\u0627\u06CC\u0644\u06CC \u062F\u0627\u0631\u062F (${config.tailwind.theme})\u061B \u06A9\u0627\u0631\u06CC \u0644\u0627\u0632\u0645 \u0646\u06CC\u0633\u062A.`);
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
const paths = themePaths(config);
|
|
2334
|
+
const current = await readIfExists(path11.join(cwd, paths.css));
|
|
2335
|
+
if (current === null || isBoilerplateCss(current)) {
|
|
2336
|
+
throw new DigError(`${paths.css} \u062A\u0645\u06CC \u0646\u062F\u0627\u0631\u062F\u061B \u0628\u0631\u0627\u06CC \u0646\u0635\u0628\u0650 \u062A\u0627\u0632\u0647 \xABdig init\xBB \u0631\u0627 \u0627\u062C\u0631\u0627 \u06A9\u0646\u06CC\u062F.`);
|
|
2337
|
+
}
|
|
2338
|
+
if (await exists(path11.join(cwd, paths.brand))) {
|
|
2339
|
+
throw new DigError(`${paths.brand} \u0627\u0632 \u0642\u0628\u0644 \u0648\u062C\u0648\u062F \u062F\u0627\u0631\u062F\u061B \u0628\u0631\u0627\u06CC \u062C\u0644\u0648\u06AF\u06CC\u0631\u06CC \u0627\u0632 \u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC\u060C \u0627\u0648\u0644 \u062C\u0627\u0628\u0647\u200C\u062C\u0627\u06CC\u0634 \u06A9\u0646\u06CC\u062F.`);
|
|
2340
|
+
}
|
|
2341
|
+
console.log(`\u062F\u0631\u06CC\u0627\u0641\u062A\u0650 \u062A\u0645\u0650 \u062F\u06CC\u06AF \u0627\u0632 ${config.registryUrl} \u2026`);
|
|
2342
|
+
const item = await fetchTheme(config);
|
|
2343
|
+
const split = splitTheme(current, item.content);
|
|
2344
|
+
console.log(`
|
|
2345
|
+
${split.changed} \u062A\u0648\u06A9\u0646\u0650 \u0639\u0648\u0636\u200C\u0634\u062F\u0647 \u0648 ${split.added} \u062A\u0648\u06A9\u0646\u0650 \u062A\u0627\u0632\u0647 \u067E\u06CC\u062F\u0627 \u0634\u062F \u2192 ${paths.brand}`);
|
|
2346
|
+
if (split.extraStatements.length) {
|
|
2347
|
+
console.log(`${split.extraStatements.length} \u062F\u0633\u062A\u0648\u0631\u0650 \u0633\u0637\u062D\u0650 \u0628\u0627\u0644\u0627 \u062F\u0631 ${paths.css} \u0645\u06CC\u200C\u0645\u0627\u0646\u062F:`);
|
|
2348
|
+
for (const statement of split.extraStatements) console.log(` ${statement}`);
|
|
2349
|
+
}
|
|
2350
|
+
if (options.dryRun) {
|
|
1971
2351
|
console.log(`
|
|
1972
|
-
${
|
|
2352
|
+
\u067E\u06CC\u0634\u200C\u0646\u0645\u0627\u06CC\u0634\u0650 ${paths.brand} (\u0686\u06CC\u0632\u06CC \u0646\u0648\u0634\u062A\u0647 \u0646\u0634\u062F):
|
|
2353
|
+
`);
|
|
2354
|
+
console.log(split.body || "(\u062E\u0627\u0644\u06CC: \u067E\u0631\u0648\u0698\u0647 \u0686\u06CC\u0632\u06CC \u062F\u0631 \u062A\u0645 \u0639\u0648\u0636 \u0646\u06A9\u0631\u062F\u0647)");
|
|
2355
|
+
return;
|
|
2356
|
+
}
|
|
2357
|
+
await writeFile5(path11.join(cwd, `${paths.css}.backup`), current, "utf8");
|
|
2358
|
+
await writeText(cwd, paths.theme, item.content);
|
|
2359
|
+
await writeText(cwd, paths.brand, brandCss({ body: split.body }));
|
|
2360
|
+
await writeText(cwd, paths.css, globalsCss(paths, split.extraStatements));
|
|
2361
|
+
await writeConfig(
|
|
2362
|
+
{ ...config, tailwind: { ...config.tailwind, theme: paths.theme, brand: paths.brand } },
|
|
2363
|
+
cwd
|
|
2364
|
+
);
|
|
2365
|
+
await recordTheme(cwd, config, paths.theme, item);
|
|
2366
|
+
console.log(`
|
|
2367
|
+
\u2713 ${paths.theme} (\u062A\u0645\u0650 \u062F\u06CC\u06AF)\u060C ${paths.brand} (\u0628\u0631\u0646\u062F) \u0648 ${paths.css} (\u0641\u0642\u0637 import) \u0646\u0648\u0634\u062A\u0647 \u0634\u062F.`);
|
|
2368
|
+
console.log(` \u0646\u0633\u062E\u0647\u0654 \u0642\u0628\u0644\u06CC: ${paths.css}.backup`);
|
|
2369
|
+
console.log(
|
|
2370
|
+
` \u062A\u0641\u0627\u0648\u062A\u200C\u0647\u0627 \u0628\u0627 \u0622\u062E\u0631\u06CC\u0646 \u062A\u0645\u0650 \u062F\u06CC\u06AF \u0645\u0642\u0627\u06CC\u0633\u0647 \u0634\u062F\u0646\u062F\u061B \u0627\u06AF\u0631 \u067E\u0631\u0648\u0698\u0647 \u0646\u0633\u062E\u0647\u0654 \u0642\u062F\u06CC\u0645\u06CC\u200C\u062A\u0631\u06CC \u0627\u0632 \u062A\u0645 \u062F\u0627\u0634\u062A\u060C \u0645\u0645\u06A9\u0646 \u0627\u0633\u062A \u0686\u0646\u062F \u0645\u0642\u062F\u0627\u0631\u0650 \u0642\u062F\u06CC\u0645\u06CC\u0650 \u062F\u06CC\u06AF \u0647\u0645 \u0628\u0647 ${paths.brand} \u0631\u0641\u062A\u0647 \u0628\u0627\u0634\u062F. \u06CC\u06A9 \u0646\u06AF\u0627\u0647 \u0628\u0647 \u0622\u0646 \u0628\u06CC\u0646\u062F\u0627\u0632\u06CC\u062F.`
|
|
2371
|
+
);
|
|
2372
|
+
}
|
|
2373
|
+
async function themeBrandCommand(hex) {
|
|
2374
|
+
const cwd = process.cwd();
|
|
2375
|
+
const config = await requireConfig(cwd);
|
|
2376
|
+
if (!config.tailwind.theme) {
|
|
2377
|
+
throw new DigError("\u0627\u06CC\u0646 \u067E\u0631\u0648\u0698\u0647 \u0647\u0646\u0648\u0632 brand.css \u0646\u062F\u0627\u0631\u062F\u061B \u0627\u0648\u0644 \xABdig theme split\xBB \u0631\u0627 \u0627\u062C\u0631\u0627 \u06A9\u0646\u06CC\u062F.");
|
|
2378
|
+
}
|
|
2379
|
+
const paths = themePaths(config);
|
|
2380
|
+
const ramp = buildBrandRamp(hex);
|
|
2381
|
+
const existing = await readIfExists(path11.join(cwd, paths.brand)) ?? brandCss({});
|
|
2382
|
+
const next = replaceBrandRamp(existing, ramp, hex);
|
|
2383
|
+
await writeText(cwd, paths.brand, next);
|
|
2384
|
+
console.log(`\u2713 \u0631\u0645\u067E\u0650 \u0628\u0631\u0646\u062F \u062F\u0631 ${paths.brand} \u0627\u0632 ${hex} \u0633\u0627\u062E\u062A\u0647 \u0634\u062F (Shade \u06F6\u06F0\u06F0 = \u0631\u0646\u06AF\u0650 \u062F\u0627\u062F\u0647\u200C\u0634\u062F\u0647).`);
|
|
2385
|
+
reportContrast(ramp.primaryContrast);
|
|
2386
|
+
const outside = next.replace(/\/\* dig:brand-ramp-start[\s\S]*?\/\* dig:brand-ramp-end \*\//, "");
|
|
2387
|
+
const shadowing = outside.match(/--brand-\d+\s*:/g);
|
|
2388
|
+
if (shadowing) {
|
|
2389
|
+
console.log(
|
|
2390
|
+
` \u26A0 ${shadowing.length} \u0627\u0639\u0644\u0627\u0646\u0650 --brand-* \u0628\u06CC\u0631\u0648\u0646 \u0627\u0632 \u0628\u0644\u0648\u06A9\u0650 \u0631\u0645\u067E \u062F\u0631 ${paths.brand} \u0647\u0633\u062A \u0648 \u0628\u0631 \u0622\u0646 \u0628\u0631\u0646\u062F\u0647 \u0645\u06CC\u200C\u0634\u0648\u062F\u061B \u0627\u06AF\u0631 \u0631\u0645\u067E\u0650 \u062A\u0627\u0632\u0647 \u0631\u0627 \u0645\u06CC\u200C\u062E\u0648\u0627\u0647\u06CC\u062F\u060C \u0622\u0646\u200C\u0647\u0627 \u0631\u0627 \u067E\u0627\u06A9 \u06A9\u0646\u06CC\u062F.`
|
|
2391
|
+
);
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2395
|
+
// src/commands/init.ts
|
|
2396
|
+
async function readIfExists2(target) {
|
|
2397
|
+
try {
|
|
2398
|
+
return await readFile8(target, "utf8");
|
|
2399
|
+
} catch {
|
|
2400
|
+
return null;
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
async function writeTheme(config, cwd, options) {
|
|
2404
|
+
const paths = themePaths(config);
|
|
2405
|
+
const existing = await readIfExists2(path12.join(cwd, paths.css));
|
|
2406
|
+
if (!isBoilerplateCss(existing) && !options.yes) {
|
|
2407
|
+
console.log(`
|
|
2408
|
+
${paths.css} \u0627\u0632 \u0642\u0628\u0644 \u0645\u062D\u062A\u0648\u0627 \u062F\u0627\u0631\u062F.`);
|
|
2409
|
+
console.log(` \u0627\u06AF\u0631 \u062A\u0645\u0650 \u0642\u062F\u06CC\u0645\u06CC\u0650 \u062F\u06CC\u06AF \u0627\u0633\u062A\u060C \u0628\u0647\u200C\u062C\u0627\u06CC \u0627\u06CC\u0646 \u0627\u0632 \xABdig theme split\xBB \u0627\u0633\u062A\u0641\u0627\u062F\u0647 \u06A9\u0646\u06CC\u062F \u062A\u0627 \u0628\u0631\u0646\u062F\u062A\u0627\u0646 \u062D\u0641\u0638 \u0634\u0648\u062F.`);
|
|
1973
2410
|
const overwrite = await confirm(
|
|
1974
|
-
"\u0628\u0627 \u062A\
|
|
2411
|
+
"\u0628\u0627 \u0633\u0627\u062E\u062A\u0627\u0631\u0650 \u062A\u0627\u0632\u0647 (\u0641\u0642\u0637 import) \u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC \u0634\u0648\u062F\u061F (\u0646\u0633\u062E\u0647\u0654 \u0641\u0639\u0644\u06CC \u06A9\u0646\u0627\u0631\u0634 \u0628\u0647\u200C\u0639\u0646\u0648\u0627\u0646 .backup \u0645\u06CC\u200C\u0645\u0627\u0646\u062F)",
|
|
1975
2412
|
false
|
|
1976
2413
|
);
|
|
1977
2414
|
if (!overwrite) {
|
|
1978
|
-
console.log(
|
|
1979
|
-
`- \u062A\u0645 \u0646\u0648\u0634\u062A\u0647 \u0646\u0634\u062F. \u0628\u0631\u0627\u06CC \u0646\u0648\u0634\u062A\u0646\u0634 \u0628\u0639\u062F\u0627\u064B: dig add ${THEME_ITEM} --overwrite`
|
|
1980
|
-
);
|
|
2415
|
+
console.log(`- \u062A\u0645 \u0646\u0648\u0634\u062A\u0647 \u0646\u0634\u062F. \u0628\u0639\u062F\u0627\u064B: dig init \u06CC\u0627 dig theme split`);
|
|
1981
2416
|
return "skipped";
|
|
1982
2417
|
}
|
|
1983
2418
|
}
|
|
1984
|
-
|
|
1985
|
-
await writeFile5(`${target}.backup`, existing, "utf8");
|
|
1986
|
-
console.log(` \u0646\u0633\u062E\u0647\u0654 \u0642\u0628\u0644\u06CC \u062F\u0631 ${config.tailwind.css}.backup \u0646\u06AF\u0647 \u062F\u0627\u0634\u062A\u0647 \u0634\u062F.`);
|
|
1987
|
-
}
|
|
1988
|
-
await mkdir4(path10.dirname(target), { recursive: true });
|
|
1989
|
-
await writeFile5(target, file.content, "utf8");
|
|
1990
|
-
console.log(`\u2713 \u062A\u0645 \u062F\u0631 ${config.tailwind.css} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F.`);
|
|
2419
|
+
const item = await installTheme(cwd, config, { brand: options.brand });
|
|
1991
2420
|
if (item.dependencies?.length) {
|
|
1992
2421
|
const pm = await detectPackageManager(cwd);
|
|
1993
2422
|
console.log(`
|
|
@@ -1998,8 +2427,8 @@ ${config.tailwind.css} \u0627\u0632 \u0642\u0628\u0644 \u0645\u062D\u062A\u0648\
|
|
|
1998
2427
|
}
|
|
1999
2428
|
async function applyRtl(cwd) {
|
|
2000
2429
|
for (const candidate of ["src/app/layout.tsx", "app/layout.tsx"]) {
|
|
2001
|
-
const target =
|
|
2002
|
-
const source = await
|
|
2430
|
+
const target = path12.join(cwd, candidate);
|
|
2431
|
+
const source = await readIfExists2(target);
|
|
2003
2432
|
if (source === null) continue;
|
|
2004
2433
|
if (/<html[^>]*\sdir=/.test(source)) {
|
|
2005
2434
|
console.log(`- ${candidate} \u0627\u0632 \u0642\u0628\u0644 dir \u062F\u0627\u0631\u062F\u061B \u062F\u0633\u062A \u0646\u062E\u0648\u0631\u062F.`);
|
|
@@ -2011,7 +2440,7 @@ async function applyRtl(cwd) {
|
|
|
2011
2440
|
match[0],
|
|
2012
2441
|
`<html${match[1]} dir="rtl">`.replace(/\s+dir="rtl">$/, ' dir="rtl">')
|
|
2013
2442
|
);
|
|
2014
|
-
await
|
|
2443
|
+
await writeFile6(target, updated, "utf8");
|
|
2015
2444
|
console.log(`\u2713 dir="rtl" \u0628\u0647 ${candidate} \u0627\u0636\u0627\u0641\u0647 \u0634\u062F.`);
|
|
2016
2445
|
return;
|
|
2017
2446
|
}
|
|
@@ -2032,23 +2461,24 @@ async function initCommand(options) {
|
|
|
2032
2461
|
const config = options.yes ? base : {
|
|
2033
2462
|
...base,
|
|
2034
2463
|
rtl: await confirm("\u067E\u0631\u0648\u0698\u0647 \u0631\u0627\u0633\u062A\u200C\u0628\u0647\u200C\u0686\u067E (RTL) \u0627\u0633\u062A\u061F", base.rtl),
|
|
2035
|
-
tailwind: {
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
)
|
|
2041
|
-
}
|
|
2464
|
+
tailwind: await (async () => {
|
|
2465
|
+
const css = await ask("\u0645\u0633\u06CC\u0631 \u0641\u0627\u06CC\u0644 CSS \u0627\u0635\u0644\u06CC \u062A\u06CC\u0644\u0648\u06CC\u0646\u062F\u061F", base.tailwind.css);
|
|
2466
|
+
const dir = path12.posix.dirname(css.split(path12.sep).join("/"));
|
|
2467
|
+
return { ...base.tailwind, css, theme: `${dir}/dig-theme.css`, brand: `${dir}/brand.css` };
|
|
2468
|
+
})()
|
|
2042
2469
|
};
|
|
2043
2470
|
await writeConfig(config, cwd);
|
|
2044
|
-
console.log(`\u2713 ${
|
|
2045
|
-
const
|
|
2471
|
+
console.log(`\u2713 ${path12.join(cwd, "dig.json")} \u0646\u0648\u0634\u062A\u0647 \u0634\u062F.`);
|
|
2472
|
+
const theme2 = await writeTheme(config, cwd, options);
|
|
2046
2473
|
if (config.rtl) {
|
|
2047
2474
|
await applyRtl(cwd);
|
|
2048
2475
|
}
|
|
2049
2476
|
console.log("\n\u0622\u0645\u0627\u062F\u0647 \u0627\u0633\u062A. \u0642\u062F\u0645 \u0628\u0639\u062F\u06CC:");
|
|
2050
2477
|
console.log(" dig add button");
|
|
2051
|
-
if (
|
|
2478
|
+
if (theme2 === "written") {
|
|
2479
|
+
console.log("\n\u0628\u0631\u0646\u062F \u0648 \u0634\u062E\u0635\u06CC\u200C\u0633\u0627\u0632\u06CC \u0641\u0642\u0637 \u062F\u0631 brand.css\u061B \u062A\u0645\u0650 \u062F\u06CC\u06AF \u0628\u0627 \xABdig update theme\xBB \u0628\u0647\u200C\u0631\u0648\u0632 \u0645\u06CC\u200C\u0634\u0648\u062F.");
|
|
2480
|
+
}
|
|
2481
|
+
if (theme2 === "skipped") {
|
|
2052
2482
|
console.log(
|
|
2053
2483
|
`
|
|
2054
2484
|
\u26A0 \u0628\u062F\u0648\u0646 \u062A\u0645\u060C \u06A9\u0627\u0645\u067E\u0648\u0646\u0646\u062A\u200C\u0647\u0627 \u0646\u0635\u0628 \u0645\u06CC\u200C\u0634\u0648\u0646\u062F \u0648\u0644\u06CC \u0628\u06CC\u200C\u0638\u0627\u0647\u0631 \u0645\u06CC\u200C\u0645\u0627\u0646\u0646\u062F (\u0631\u0646\u06AF\u060C \u0634\u0639\u0627\u0639 \u0648 \u0633\u0627\u06CC\u0647 \u0627\u0632 \u062A\u0648\u06A9\u0646 \u0645\u06CC\u200C\u0622\u06CC\u0646\u062F).`
|
|
@@ -2057,8 +2487,8 @@ async function initCommand(options) {
|
|
|
2057
2487
|
}
|
|
2058
2488
|
|
|
2059
2489
|
// src/lib/migration-apply.ts
|
|
2060
|
-
import { readFile as
|
|
2061
|
-
import
|
|
2490
|
+
import { readFile as readFile9, writeFile as writeFile7 } from "fs/promises";
|
|
2491
|
+
import path13 from "path";
|
|
2062
2492
|
|
|
2063
2493
|
// src/lib/migration-strategy.ts
|
|
2064
2494
|
var TextReplaceStrategy = class {
|
|
@@ -2135,7 +2565,7 @@ function looksBinary2(buffer) {
|
|
|
2135
2565
|
async function readTextFileSafely2(target) {
|
|
2136
2566
|
let buffer;
|
|
2137
2567
|
try {
|
|
2138
|
-
buffer = await
|
|
2568
|
+
buffer = await readFile9(target);
|
|
2139
2569
|
} catch (error) {
|
|
2140
2570
|
if (error.code === "ENOENT") return void 0;
|
|
2141
2571
|
throw error;
|
|
@@ -2157,7 +2587,7 @@ function summarizeMigration(migration) {
|
|
|
2157
2587
|
return void 0;
|
|
2158
2588
|
}
|
|
2159
2589
|
async function planOrApplyMigrations(params) {
|
|
2160
|
-
const { cwd, aliases, registryUrl, lock, registryItem, dryRun } = params;
|
|
2590
|
+
const { cwd, aliases, registryUrl, lock, registryItem, dryRun, paths } = params;
|
|
2161
2591
|
const name = registryItem.name;
|
|
2162
2592
|
const lockEntry = lock.components[name];
|
|
2163
2593
|
if (!lockEntry) {
|
|
@@ -2180,8 +2610,8 @@ async function planOrApplyMigrations(params) {
|
|
|
2180
2610
|
};
|
|
2181
2611
|
}
|
|
2182
2612
|
const fileTargets = registryItem.files.map((file) => {
|
|
2183
|
-
const target =
|
|
2184
|
-
return { relPath: toPosixPath(
|
|
2613
|
+
const target = path13.join(cwd, resolveTargetPath(file.path, aliases, paths));
|
|
2614
|
+
return { relPath: toPosixPath(path13.relative(cwd, target)), target };
|
|
2185
2615
|
});
|
|
2186
2616
|
const currentContents = /* @__PURE__ */ new Map();
|
|
2187
2617
|
for (const ft of fileTargets) {
|
|
@@ -2247,12 +2677,12 @@ async function planOrApplyMigrations(params) {
|
|
|
2247
2677
|
const written = [];
|
|
2248
2678
|
try {
|
|
2249
2679
|
for (const item of pending) {
|
|
2250
|
-
await
|
|
2680
|
+
await writeFile7(item.target, item.newContent, "utf8");
|
|
2251
2681
|
written.push(item);
|
|
2252
2682
|
}
|
|
2253
2683
|
} catch (error) {
|
|
2254
2684
|
for (const item of written) {
|
|
2255
|
-
await
|
|
2685
|
+
await writeFile7(item.target, item.originalContent, "utf8");
|
|
2256
2686
|
}
|
|
2257
2687
|
return {
|
|
2258
2688
|
name,
|
|
@@ -2389,6 +2819,7 @@ async function runApplyOrDryRun(components, options, dryRun) {
|
|
|
2389
2819
|
const result = await planOrApplyMigrations({
|
|
2390
2820
|
cwd,
|
|
2391
2821
|
aliases: config.aliases,
|
|
2822
|
+
paths: targetPathOptions(config),
|
|
2392
2823
|
registryUrl: config.registryUrl,
|
|
2393
2824
|
lock,
|
|
2394
2825
|
registryItem,
|
|
@@ -2546,7 +2977,7 @@ ${message}`);
|
|
|
2546
2977
|
}
|
|
2547
2978
|
const summary = intelligence.components.find((c) => c.name === component);
|
|
2548
2979
|
if (!summary) {
|
|
2549
|
-
const message = `\xAB${component}\xBB \u062F\u0631 \u062F\u0627\u062F\u0647\u0654 \u0647\u0648\u0634\u0645\u0646\u062F\u06CC\u0650 \u0641\u0639\u0644\u06CC \u0646\u06CC\u0633\u062A (\u0634\u0627\u06CC\u062F \u0627\u0632 \u0646\u0648\u0639\u0650
|
|
2980
|
+
const message = `\xAB${component}\xBB \u062F\u0631 \u062F\u0627\u062F\u0647\u0654 \u0647\u0648\u0634\u0645\u0646\u062F\u06CC\u0650 \u0641\u0639\u0644\u06CC \u0646\u06CC\u0633\u062A (\u0634\u0627\u06CC\u062F \u0627\u0632 \u0646\u0648\u0639\u0650 dig:lib \u0628\u0627\u0634\u062F\u060C \u0646\u0647 UI).`;
|
|
2550
2981
|
if (options.json) {
|
|
2551
2982
|
console.log(JSON.stringify({ component, status: "no-data", message }, null, 2));
|
|
2552
2983
|
} else {
|
|
@@ -2863,8 +3294,8 @@ ${entry.migrationHint}`);
|
|
|
2863
3294
|
}
|
|
2864
3295
|
|
|
2865
3296
|
// src/lib/update.ts
|
|
2866
|
-
import { mkdir as mkdir5, readFile as
|
|
2867
|
-
import
|
|
3297
|
+
import { mkdir as mkdir5, readFile as readFile10, rm as rm2, writeFile as writeFile8 } from "fs/promises";
|
|
3298
|
+
import path14 from "path";
|
|
2868
3299
|
function safeFileIndexes(drift) {
|
|
2869
3300
|
const indexes = [];
|
|
2870
3301
|
drift.files.forEach((file, index) => {
|
|
@@ -2873,7 +3304,7 @@ function safeFileIndexes(drift) {
|
|
|
2873
3304
|
});
|
|
2874
3305
|
return indexes;
|
|
2875
3306
|
}
|
|
2876
|
-
async function applySafeFiles(cwd, aliases, drift, registryItem, dryRun) {
|
|
3307
|
+
async function applySafeFiles(cwd, aliases, drift, registryItem, dryRun, paths) {
|
|
2877
3308
|
const actions = new Array(drift.files.length).fill("skipped");
|
|
2878
3309
|
const safeIndexes = safeFileIndexes(drift);
|
|
2879
3310
|
if (dryRun) {
|
|
@@ -2884,7 +3315,7 @@ async function applySafeFiles(cwd, aliases, drift, registryItem, dryRun) {
|
|
|
2884
3315
|
for (const index of safeIndexes) {
|
|
2885
3316
|
const file = drift.files[index];
|
|
2886
3317
|
const registryFile = registryItem.files[index];
|
|
2887
|
-
const target =
|
|
3318
|
+
const target = path14.join(cwd, resolveTargetPath(registryFile.path, aliases, paths));
|
|
2888
3319
|
const isNewFile = file.status === "new_upstream";
|
|
2889
3320
|
pending.push({
|
|
2890
3321
|
index,
|
|
@@ -2892,14 +3323,14 @@ async function applySafeFiles(cwd, aliases, drift, registryItem, dryRun) {
|
|
|
2892
3323
|
newContent: registryFile.content,
|
|
2893
3324
|
newHash: registryFile.hash ?? hashContent(registryFile.content),
|
|
2894
3325
|
isNewFile,
|
|
2895
|
-
originalContent: isNewFile ? void 0 : await
|
|
3326
|
+
originalContent: isNewFile ? void 0 : await readFile10(target, "utf8")
|
|
2896
3327
|
});
|
|
2897
3328
|
}
|
|
2898
3329
|
const written = [];
|
|
2899
3330
|
try {
|
|
2900
3331
|
for (const item of pending) {
|
|
2901
|
-
if (item.isNewFile) await mkdir5(
|
|
2902
|
-
await
|
|
3332
|
+
if (item.isNewFile) await mkdir5(path14.dirname(item.target), { recursive: true });
|
|
3333
|
+
await writeFile8(item.target, item.newContent, "utf8");
|
|
2903
3334
|
written.push(item);
|
|
2904
3335
|
}
|
|
2905
3336
|
} catch (error) {
|
|
@@ -2907,7 +3338,7 @@ async function applySafeFiles(cwd, aliases, drift, registryItem, dryRun) {
|
|
|
2907
3338
|
if (item.isNewFile) {
|
|
2908
3339
|
await rm2(item.target, { force: true });
|
|
2909
3340
|
} else {
|
|
2910
|
-
await
|
|
3341
|
+
await writeFile8(item.target, item.originalContent, "utf8");
|
|
2911
3342
|
}
|
|
2912
3343
|
}
|
|
2913
3344
|
return { actions, writtenHashes: {}, rollbackError: error.message };
|
|
@@ -2932,7 +3363,7 @@ async function applySafeFiles(cwd, aliases, drift, registryItem, dryRun) {
|
|
|
2932
3363
|
return { actions, writtenHashes, snapshotPath: snapshotResult.path };
|
|
2933
3364
|
}
|
|
2934
3365
|
async function updateComponent(params) {
|
|
2935
|
-
const { cwd, aliases, registryUrl, lock, registryItem, dryRun = false } = params;
|
|
3366
|
+
const { cwd, aliases, registryUrl, lock, registryItem, dryRun = false, paths } = params;
|
|
2936
3367
|
const name = registryItem.name;
|
|
2937
3368
|
const lockEntry = lock.components[name];
|
|
2938
3369
|
if (!lockEntry) {
|
|
@@ -2943,9 +3374,10 @@ async function updateComponent(params) {
|
|
|
2943
3374
|
aliases,
|
|
2944
3375
|
registryUrl,
|
|
2945
3376
|
lockEntry,
|
|
2946
|
-
registryItem
|
|
3377
|
+
registryItem,
|
|
3378
|
+
paths
|
|
2947
3379
|
});
|
|
2948
|
-
const { actions, writtenHashes, rollbackError, snapshotPath, snapshotError } = await applySafeFiles(cwd, aliases, drift, registryItem, dryRun);
|
|
3380
|
+
const { actions, writtenHashes, rollbackError, snapshotPath, snapshotError } = await applySafeFiles(cwd, aliases, drift, registryItem, dryRun, paths);
|
|
2949
3381
|
if (rollbackError) {
|
|
2950
3382
|
return {
|
|
2951
3383
|
name,
|
|
@@ -3009,6 +3441,7 @@ async function updateCommand(components, options) {
|
|
|
3009
3441
|
const result = await updateComponent({
|
|
3010
3442
|
cwd,
|
|
3011
3443
|
aliases: config.aliases,
|
|
3444
|
+
paths: targetPathOptions(config),
|
|
3012
3445
|
registryUrl: config.registryUrl,
|
|
3013
3446
|
lock,
|
|
3014
3447
|
registryItem,
|
|
@@ -3140,6 +3573,7 @@ ${result.name}`);
|
|
|
3140
3573
|
const details = await computeFileDiffDetails({
|
|
3141
3574
|
cwd,
|
|
3142
3575
|
aliases: config.aliases,
|
|
3576
|
+
paths: targetPathOptions(config),
|
|
3143
3577
|
name: result.name,
|
|
3144
3578
|
snapshotVersion,
|
|
3145
3579
|
file,
|
|
@@ -3196,14 +3630,17 @@ ${result.name}`);
|
|
|
3196
3630
|
}
|
|
3197
3631
|
|
|
3198
3632
|
// src/lib/version.ts
|
|
3199
|
-
var CLI_VERSION = "0.
|
|
3633
|
+
var CLI_VERSION = "0.4.0";
|
|
3200
3634
|
|
|
3201
3635
|
// src/index.ts
|
|
3202
3636
|
var program = new Command();
|
|
3203
3637
|
program.name("dig").description("CLI \u0631\u0633\u0645\u06CC \u062F\u06CC\u0632\u0627\u06CC\u0646 \u0633\u06CC\u0633\u062A\u0645 \u062F\u06CC\u06AF").version(CLI_VERSION);
|
|
3204
3638
|
program.command("init").description(
|
|
3205
3639
|
'\u0631\u0627\u0647\u200C\u0627\u0646\u062F\u0627\u0632\u06CC \u062F\u06CC\u06AF \u062F\u0631 \u067E\u0631\u0648\u0698\u0647: dig.json\u060C \u062A\u0645 \u0648 \u062A\u0648\u06A9\u0646\u200C\u0647\u0627\u060C \u0648 dir="rtl"'
|
|
3206
|
-
).option("--yes", "\u067E\u0627\u0633\u062E \u067E\u06CC\u0634\u200C\u0641\u0631\u0636 \u0628\u0647 \u0647\u0645\u0647\u0654 \u0633\u0648\u0627\u0644\u0627\u062A", false).action(initCommand);
|
|
3640
|
+
).option("--yes", "\u067E\u0627\u0633\u062E \u067E\u06CC\u0634\u200C\u0641\u0631\u0636 \u0628\u0647 \u0647\u0645\u0647\u0654 \u0633\u0648\u0627\u0644\u0627\u062A", false).option("--brand <hex>", "\u0633\u0627\u062E\u062A\u0646\u0650 \u0631\u0645\u067E\u0650 \u0628\u0631\u0646\u062F \u0627\u0632 \u06CC\u06A9 \u0631\u0646\u06AF (\u0631\u0648\u06CC Shade \u06F6\u06F0\u06F0 \u0645\u06CC\u200C\u0646\u0634\u06CC\u0646\u062F)\u060C \u0645\u062B\u0644 #2C4C5B").action(initCommand);
|
|
3641
|
+
var theme = program.command("theme").description("\u062A\u0645 \u0648 \u0628\u0631\u0646\u062F: \u062C\u062F\u0627 \u06A9\u0631\u062F\u0646\u0650 \u062A\u0645\u0650 \u062F\u06CC\u06AF \u0627\u0632 \u0628\u0631\u0646\u062F\u0650 \u067E\u0631\u0648\u0698\u0647");
|
|
3642
|
+
theme.command("split").description("\u067E\u0631\u0648\u0698\u0647\u0654 \u0642\u062F\u06CC\u0645\u06CC \u0631\u0627 \u0628\u0647 \u0633\u0627\u062E\u062A\u0627\u0631\u0650 \u062F\u0648\u0641\u0627\u06CC\u0644\u06CC \u0645\u06CC\u200C\u0628\u0631\u062F (dig-theme.css \u0645\u0627\u0644\u0650 \u062F\u06CC\u06AF\u060C brand.css \u0645\u0627\u0644\u0650 \u067E\u0631\u0648\u0698\u0647)").option("--dry-run", "\u0641\u0642\u0637 \u0646\u0634\u0627\u0646 \u0628\u062F\u0647 \u0686\u0647 \u0686\u06CC\u0632\u06CC \u0628\u0647 brand.css \u0645\u06CC\u200C\u0631\u0648\u062F\u060C \u0686\u06CC\u0632\u06CC \u0646\u0646\u0648\u06CC\u0633", false).action(themeSplitCommand);
|
|
3643
|
+
theme.command("brand").description("\u0631\u0645\u067E\u0650 \u0628\u0631\u0646\u062F \u0631\u0627 \u062F\u0631 brand.css \u0627\u0632 \u06CC\u06A9 \u0631\u0646\u06AF \u0645\u06CC\u200C\u0633\u0627\u0632\u062F\u061B \u0628\u0642\u06CC\u0647\u0654 \u0641\u0627\u06CC\u0644 \u062F\u0633\u062A \u0646\u0645\u06CC\u200C\u062E\u0648\u0631\u062F").argument("<hex>", "\u0631\u0646\u06AF\u0650 \u0627\u0635\u0644\u06CC\u0650 \u0628\u0631\u0646\u062F\u060C \u0645\u062B\u0644 #2C4C5B").action(themeBrandCommand);
|
|
3207
3644
|
program.command("add").description("\u0627\u0641\u0632\u0648\u062F\u0646 \u06CC\u06A9 \u06CC\u0627 \u0686\u0646\u062F \u06A9\u0627\u0645\u067E\u0648\u0646\u0646\u062A \u0627\u0632 \u0631\u062C\u06CC\u0633\u062A\u0631\u06CC \u062F\u06CC\u06AF").argument("[components...]", "\u0646\u0627\u0645 \u06A9\u0627\u0645\u067E\u0648\u0646\u0646\u062A\u200C\u0647\u0627 (\u0645\u062B\u0644 button) \u06CC\u0627 \u0622\u062F\u0631\u0633 \u0631\u062C\u06CC\u0633\u062A\u0631\u06CC\u061B \u0628\u062F\u0648\u0646 \u0622\u0631\u06AF\u0648\u0645\u0627\u0646 \u0641\u0647\u0631\u0633\u062A \u0631\u0627 \u0646\u0634\u0627\u0646 \u0645\u06CC\u200C\u062F\u0647\u062F").option("--overwrite", "\u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC \u0641\u0627\u06CC\u0644\u200C\u0647\u0627\u06CC \u0645\u0648\u062C\u0648\u062F", false).option("-y, --yes", "\u0628\u062F\u0648\u0646 \u067E\u0631\u0633\u0634\u060C \u0641\u0627\u06CC\u0644\u200C\u0647\u0627\u06CC \u0645\u0648\u062C\u0648\u062F \u0631\u0627 \u0628\u0627\u0632\u0646\u0648\u06CC\u0633\u06CC \u06A9\u0646", false).option("--dry-run", "\u0641\u0642\u0637 \u0646\u0634\u0627\u0646 \u0628\u062F\u0647 \u0686\u0647 \u0641\u0627\u06CC\u0644\u200C\u0647\u0627\u06CC\u06CC \u0646\u0648\u0634\u062A\u0647 \u0645\u06CC\u200C\u0634\u0648\u062F\u060C \u0686\u06CC\u0632\u06CC \u0646\u0646\u0648\u06CC\u0633", false).option("--no-install", "\u0641\u0642\u0637 \u0641\u0627\u06CC\u0644\u200C\u0647\u0627 \u0631\u0627 \u0628\u0646\u0648\u06CC\u0633\u060C \u0648\u0627\u0628\u0633\u062A\u06AF\u06CC\u200C\u0647\u0627 \u0631\u0627 \u0646\u0635\u0628 \u0646\u06A9\u0646").action(addCommand);
|
|
3208
3645
|
program.command("list").description("\u0641\u0647\u0631\u0633\u062A \u0622\u06CC\u062A\u0645\u200C\u0647\u0627\u06CC \u0631\u062C\u06CC\u0633\u062A\u0631\u06CC \u062F\u06CC\u06AF").option("--type <type>", "\u0641\u06CC\u0644\u062A\u0631 \u0646\u0648\u0639: ui\u060C lib \u06CC\u0627 theme").option("--json", "\u062E\u0631\u0648\u062C\u06CC JSON \u0628\u0631\u0627\u06CC \u0627\u0633\u06A9\u0631\u06CC\u067E\u062A/\u0627\u0628\u0632\u0627\u0631", false).action(listCommand);
|
|
3209
3646
|
program.command("search").description("\u062C\u0633\u062A\u062C\u0648\u06CC \u06A9\u0627\u0645\u067E\u0648\u0646\u0646\u062A \u062F\u0631 \u0631\u062C\u06CC\u0633\u062A\u0631\u06CC\u060C \u0628\u0627 \u0646\u0627\u0645 \u0641\u0627\u0631\u0633\u06CC \u06CC\u0627 \u0627\u0646\u06AF\u0644\u06CC\u0633\u06CC").argument("<query>", "\u0639\u0628\u0627\u0631\u062A \u062C\u0633\u062A\u062C\u0648").option("--json", "\u062E\u0631\u0648\u062C\u06CC JSON \u0628\u0631\u0627\u06CC \u0627\u0633\u06A9\u0631\u06CC\u067E\u062A/\u0627\u0628\u0632\u0627\u0631", false).action(searchCommand);
|