elcrm 1.1.2 → 1.1.4
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 +696 -48
- package/dist/vite/concat-css.js +13 -1
- package/dist/vite/postbuild.js +13 -1
- package/package.json +4 -3
- package/templates/elcrm-cursor/AGENTS.md +3 -1
- package/templates/elcrm-cursor/rules/elcrm-jsdoc.mdc +89 -0
- package/templates/elcrm-cursor/rules/elcrm-lib.mdc +1 -0
- package/templates/elcrm-cursor/rules/elcrm-packages.mdc +2 -2
- package/templates/elcrm-cursor/rules/elcrm-theme.mdc +1 -0
- package/templates/elcrm-cursor/rules/elcrm-tokens.mdc +40 -0
- package/templates/elcrm-cursor/rules/elcrm-ui.mdc +1 -0
- package/templates/elcrm-cursor/rules/elcrm.mdc +1 -1
- package/templates/elcrm-docs/CLI.elCRM.md +3 -3
- package/templates/elcrm-docs/COMPONENTS.elCRM.md +51 -46
- package/templates/panel/web/src/App.tsx +15 -1
- package/templates/panel/web/src/component/Header.tsx +19 -6
- package/templates/panel/web/src/lazyRoute.ts +6 -0
- package/templates/panel/web/src/lib/routeKey.ts +8 -1
- package/templates/panel/web/src/lib/theme.ts +20 -3
- package/templates/panel/web/src/modules/Account/index.tsx +12 -8
- package/templates/panel/web/src/modules/Account/router.sections.ts +5 -3
- package/templates/panel/web/src/modules/Account/sections/Profile.tsx +9 -4
- package/templates/panel/web/src/modules/Account/sections/Sessions.tsx +1 -1
- package/templates/panel/web/src/modules/Home/index.tsx +11 -4
- package/templates/panel/web/src/modules/Home/modal/Demo.tsx +10 -0
- package/templates/panel/web/src/modules/List/index.tsx +12 -11
- package/templates/panel/web/src/modules/List/router.sections.ts +6 -4
- package/templates/panel/web/src/modules/List/sections/Basic.tsx +3 -3
- package/templates/panel/web/src/modules/List/sections/Horizontal.tsx +1 -1
- package/templates/panel/web/src/modules/List/sections/Rows.tsx +6 -3
- package/templates/panel/web/src/modules/Settings/index.tsx +14 -8
- package/templates/panel/web/src/modules/Settings/router.sections.ts +7 -4
- package/templates/panel/web/src/modules/Settings/sections/Appearance.tsx +8 -4
- package/templates/panel/web/src/modules/Settings/sections/General.tsx +5 -1
- package/templates/panel/web/src/modules/Settings/sections/Profile.tsx +5 -1
- package/templates/panel/web/src/pages/Auth.tsx +10 -0
- package/templates/panel/web/src/pages/Main.tsx +7 -1
- package/templates/panel/web/src/state.ts +9 -0
- package/templates/panel/web/src/style/theme-dark.css +18 -87
- package/templates/panel/web/src/style/theme-light.css +18 -87
- package/templates/panel/web/src/style/theme.css +29 -78
package/dist/index.js
CHANGED
|
@@ -533,19 +533,112 @@ var init_form_aliases = __esm(() => {
|
|
|
533
533
|
];
|
|
534
534
|
});
|
|
535
535
|
|
|
536
|
-
// src/lib/migrate/
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
const re = new RegExp(`\\n?[ \\t]*${name.replace(/-/g, "\\-")}\\s*:[^;\\n}]+;?[ \\t]*`, "g");
|
|
536
|
+
// src/lib/migrate/css-decl.ts
|
|
537
|
+
function removeCssDecl(css, name) {
|
|
538
|
+
const re = new RegExp(`\\n?[ \\t]*${name.replace(/-/g, "\\-")}(?![\\w-])\\s*:`, "g");
|
|
540
539
|
let n = 0;
|
|
541
|
-
const
|
|
540
|
+
const ranges = [];
|
|
541
|
+
let m;
|
|
542
|
+
while ((m = re.exec(css)) !== null) {
|
|
543
|
+
const start = m.index;
|
|
544
|
+
let i = m.index + m[0].length;
|
|
545
|
+
let depth = 0;
|
|
546
|
+
while (i < css.length) {
|
|
547
|
+
const ch = css[i];
|
|
548
|
+
if (ch === "(")
|
|
549
|
+
depth++;
|
|
550
|
+
else if (ch === ")")
|
|
551
|
+
depth = Math.max(0, depth - 1);
|
|
552
|
+
else if ((ch === ";" || ch === "}") && depth === 0) {
|
|
553
|
+
if (ch === ";")
|
|
554
|
+
i++;
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
i++;
|
|
558
|
+
}
|
|
559
|
+
let s = start;
|
|
560
|
+
if (s > 0 && css[s - 1] === `
|
|
561
|
+
`)
|
|
562
|
+
s--;
|
|
563
|
+
ranges.push({ start: s, end: i });
|
|
542
564
|
n++;
|
|
543
|
-
|
|
544
|
-
|
|
565
|
+
}
|
|
566
|
+
if (!ranges.length)
|
|
567
|
+
return { next: css, n: 0 };
|
|
568
|
+
let next = css;
|
|
569
|
+
for (let r = ranges.length - 1;r >= 0; r--) {
|
|
570
|
+
const { start, end } = ranges[r];
|
|
571
|
+
next = next.slice(0, start) + next.slice(end);
|
|
572
|
+
}
|
|
545
573
|
return { next: next.replace(/\n{3,}/g, `
|
|
546
574
|
|
|
547
575
|
`), n };
|
|
548
576
|
}
|
|
577
|
+
|
|
578
|
+
// src/lib/migrate/css-sanitize.ts
|
|
579
|
+
import { readFileSync as readFileSync9 } from "fs";
|
|
580
|
+
function stripOrphanColorMix(source) {
|
|
581
|
+
let next = source;
|
|
582
|
+
let hits = 0;
|
|
583
|
+
next = next.replace(ORPHAN_MIX_BLOCK_RE, () => {
|
|
584
|
+
hits++;
|
|
585
|
+
return `
|
|
586
|
+
`;
|
|
587
|
+
});
|
|
588
|
+
const lines = next.split(/\r?\n/);
|
|
589
|
+
const kept = [];
|
|
590
|
+
for (const line of lines) {
|
|
591
|
+
if (/^[ \t]*in\s+(?:srgb|hsl|hwb|lab|lch)\s*,?\s*$/i.test(line) || /^[ \t]*transparent\s*\)\s*;?\s*$/i.test(line) || /^[ \t]*var\([^)]+\)\s*\d+%\s*,?\s*$/i.test(line)) {
|
|
592
|
+
const prev = kept[kept.length - 1] ?? "";
|
|
593
|
+
if (!/color-mix\s*\(\s*$/i.test(prev) && !/color-mix\s*\(/i.test(prev)) {
|
|
594
|
+
hits++;
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
kept.push(line);
|
|
599
|
+
}
|
|
600
|
+
next = kept.join(`
|
|
601
|
+
`).replace(/\n{3,}/g, `
|
|
602
|
+
|
|
603
|
+
`);
|
|
604
|
+
return { next, hits };
|
|
605
|
+
}
|
|
606
|
+
function lineHasOrphanColorMix(line) {
|
|
607
|
+
const t = line.trim();
|
|
608
|
+
if (!t || t.startsWith("/*") || t.startsWith("*"))
|
|
609
|
+
return false;
|
|
610
|
+
if (/^in\s+(?:srgb|hsl|hwb|lab|lch)\b/i.test(t) && !/color-mix\s*\(/i.test(t)) {
|
|
611
|
+
return true;
|
|
612
|
+
}
|
|
613
|
+
if (/^transparent\s*\)\s*;?\s*$/i.test(t))
|
|
614
|
+
return true;
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
async function migrateCssSanitize(cwd, dry) {
|
|
618
|
+
const changes = [];
|
|
619
|
+
const files = projectCodeRoots(cwd).flatMap((r) => walkCodeFiles(r)).filter((f) => f.endsWith(".css"));
|
|
620
|
+
for (const file of files) {
|
|
621
|
+
const raw = readFileSync9(file, "utf8");
|
|
622
|
+
const { next, hits } = stripOrphanColorMix(raw);
|
|
623
|
+
if (hits === 0 || next === raw)
|
|
624
|
+
continue;
|
|
625
|
+
if (writeIfChanged(file, next, dry) || dry) {
|
|
626
|
+
changes.push({
|
|
627
|
+
file: rel(cwd, file),
|
|
628
|
+
detail: `${hits}\xD7 \u0443\u0434\u0430\u043B\u0435\u043D\u044B \u043E\u0441\u0438\u0440\u043E\u0442\u0435\u0432\u0448\u0438\u0435 color-mix/\u0444\u0440\u0430\u0433\u043C\u0435\u043D\u0442\u044B`
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return changes;
|
|
633
|
+
}
|
|
634
|
+
var ORPHAN_MIX_BLOCK_RE;
|
|
635
|
+
var init_css_sanitize = __esm(() => {
|
|
636
|
+
init_walk();
|
|
637
|
+
ORPHAN_MIX_BLOCK_RE = /(?:^|\n)[ \t]*(?:in\s+srgb|in\s+hsl|in\s+hwb|in\s+lab|in\s+lch)[\s\S]*?\n[ \t]*\);?[ \t]*(?=\n|$)/gi;
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
// src/lib/migrate/form-tokens.ts
|
|
641
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
549
642
|
function migrateDatePopupShadowDecl(css) {
|
|
550
643
|
let n = 0;
|
|
551
644
|
let next = css;
|
|
@@ -600,10 +693,13 @@ function rewriteFormTokens(source) {
|
|
|
600
693
|
const stillUsed = new RegExp(`var\\(\\s*${name.replace(/-/g, "\\-")}\\s*`, "i").test(next);
|
|
601
694
|
if (stillUsed)
|
|
602
695
|
continue;
|
|
603
|
-
const rem =
|
|
696
|
+
const rem = removeCssDecl(next, name);
|
|
604
697
|
next = rem.next;
|
|
605
698
|
hits += rem.n;
|
|
606
699
|
}
|
|
700
|
+
const clean = stripOrphanColorMix(next);
|
|
701
|
+
next = clean.next;
|
|
702
|
+
hits += clean.hits;
|
|
607
703
|
return { next, hits };
|
|
608
704
|
}
|
|
609
705
|
async function migrateFormTokens(cwd, dry) {
|
|
@@ -613,7 +709,7 @@ async function migrateFormTokens(cwd, dry) {
|
|
|
613
709
|
const changes = [];
|
|
614
710
|
const files = projectCodeRoots(cwd).flatMap((r) => walkCodeFiles(r)).filter((f) => f.endsWith(".css"));
|
|
615
711
|
for (const file of files) {
|
|
616
|
-
const raw =
|
|
712
|
+
const raw = readFileSync10(file, "utf8");
|
|
617
713
|
const { next, hits } = rewriteFormTokens(raw);
|
|
618
714
|
if (hits === 0 || next === raw)
|
|
619
715
|
continue;
|
|
@@ -642,6 +738,7 @@ var VAR_REPLACEMENTS, DECL_REMOVE, FORM_TOKEN_DEPRECATED, DEPRECATED_VAR_RE, DEP
|
|
|
642
738
|
var init_form_tokens = __esm(() => {
|
|
643
739
|
init_pkg();
|
|
644
740
|
init_walk();
|
|
741
|
+
init_css_sanitize();
|
|
645
742
|
VAR_REPLACEMENTS = [
|
|
646
743
|
[
|
|
647
744
|
/var\(\s*--field-note-padding-top\s*(?:,[^)]+)?\)/gi,
|
|
@@ -688,6 +785,392 @@ var init_form_tokens = __esm(() => {
|
|
|
688
785
|
DEPRECATED_DECL_RE = new RegExp(`(?:${FORM_TOKEN_DEPRECATED.map((n) => n.replace(/-/g, "\\-")).join("|")})\\s*:`);
|
|
689
786
|
});
|
|
690
787
|
|
|
788
|
+
// src/lib/migrate/components.ts
|
|
789
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
790
|
+
function rewriteComponentsCss(source) {
|
|
791
|
+
let next = source;
|
|
792
|
+
let hits = 0;
|
|
793
|
+
for (const [re, to] of VAR_REPLACEMENTS2) {
|
|
794
|
+
next = next.replace(re, () => {
|
|
795
|
+
hits++;
|
|
796
|
+
return to;
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
for (const name of COMPONENTS_TOKEN_DEPRECATED) {
|
|
800
|
+
const stillUsed = new RegExp(`var\\(\\s*${name.replace(/-/g, "\\-")}(?![\\w-])`, "i").test(next);
|
|
801
|
+
if (stillUsed)
|
|
802
|
+
continue;
|
|
803
|
+
const rem = removeCssDecl(next, name);
|
|
804
|
+
next = rem.next;
|
|
805
|
+
hits += rem.n;
|
|
806
|
+
}
|
|
807
|
+
return { next, hits };
|
|
808
|
+
}
|
|
809
|
+
function rewriteImports2(source) {
|
|
810
|
+
let hits = 0;
|
|
811
|
+
let next = source;
|
|
812
|
+
const replaceImportList = (list) => {
|
|
813
|
+
let s = list;
|
|
814
|
+
const before = s;
|
|
815
|
+
s = s.replace(/\bBlock\b/g, "Stack");
|
|
816
|
+
s = s.replace(/\bRow\b/g, "Stack");
|
|
817
|
+
s = s.replace(/\bColumn\b/g, "Stack");
|
|
818
|
+
const parts = s.split(",").map((p) => p.trim()).filter(Boolean);
|
|
819
|
+
const seen = new Set;
|
|
820
|
+
const uniq = [];
|
|
821
|
+
for (const p of parts) {
|
|
822
|
+
const bare = p.replace(/\s+as\s+\w+$/, "").trim();
|
|
823
|
+
if (seen.has(bare)) {
|
|
824
|
+
hits++;
|
|
825
|
+
continue;
|
|
826
|
+
}
|
|
827
|
+
seen.add(bare);
|
|
828
|
+
uniq.push(p);
|
|
829
|
+
}
|
|
830
|
+
if (s !== before || uniq.join(", ") !== list.trim())
|
|
831
|
+
hits++;
|
|
832
|
+
return uniq.join(", ");
|
|
833
|
+
};
|
|
834
|
+
next = next.replace(/import\s*\{([^}]+)\}\s*from\s*["']@elcrm\/components["']/g, (full, list) => {
|
|
835
|
+
if (!/\b(Block|Row|Column)\b/.test(list))
|
|
836
|
+
return full;
|
|
837
|
+
hits++;
|
|
838
|
+
return `import { ${replaceImportList(list)} } from "@elcrm/components"`;
|
|
839
|
+
});
|
|
840
|
+
next = next.replace(/import\s*\{\s*Block\s*\}\s*from\s*["']@elcrm\/components\/Block["']/g, () => {
|
|
841
|
+
hits++;
|
|
842
|
+
return `import { Stack } from "@elcrm/components/Stack"`;
|
|
843
|
+
});
|
|
844
|
+
next = next.replace(/import\s*\{\s*Row\s*\}\s*from\s*["']@elcrm\/components\/Row["']/g, () => {
|
|
845
|
+
hits++;
|
|
846
|
+
return `import { Stack } from "@elcrm/components/Stack"`;
|
|
847
|
+
});
|
|
848
|
+
next = next.replace(/import\s*\{\s*Column\s*\}\s*from\s*["']@elcrm\/components\/Column["']/g, () => {
|
|
849
|
+
hits++;
|
|
850
|
+
return `import { Stack } from "@elcrm/components/Stack"`;
|
|
851
|
+
});
|
|
852
|
+
return { next, hits };
|
|
853
|
+
}
|
|
854
|
+
function rewriteJsx(source) {
|
|
855
|
+
let hits = 0;
|
|
856
|
+
let next = source;
|
|
857
|
+
next = next.replace(/<Block([^>]*?)\srow(\s|\/|>)/g, (_m, attrs, end) => {
|
|
858
|
+
hits++;
|
|
859
|
+
return `<Stack${attrs} direction="row"${end}`;
|
|
860
|
+
});
|
|
861
|
+
next = next.replace(/<\/Block>/g, () => {
|
|
862
|
+
hits++;
|
|
863
|
+
return "</Stack>";
|
|
864
|
+
});
|
|
865
|
+
next = next.replace(/<Block(\s|\/|>)/g, (_m, end) => {
|
|
866
|
+
hits++;
|
|
867
|
+
return `<Stack${end}`;
|
|
868
|
+
});
|
|
869
|
+
next = next.replace(/<Row(\s[^/>]*(?:\/>|>))/g, (_m, rest) => {
|
|
870
|
+
hits++;
|
|
871
|
+
return `<Stack direction="row"${rest}`;
|
|
872
|
+
});
|
|
873
|
+
next = next.replace(/<\/Row>/g, () => {
|
|
874
|
+
hits++;
|
|
875
|
+
return "</Stack>";
|
|
876
|
+
});
|
|
877
|
+
next = next.replace(/<\/Column>/g, () => {
|
|
878
|
+
hits++;
|
|
879
|
+
return "</Stack>";
|
|
880
|
+
});
|
|
881
|
+
next = next.replace(/<Column(\s|\/|>)/g, (_m, end) => {
|
|
882
|
+
hits++;
|
|
883
|
+
return `<Stack${end}`;
|
|
884
|
+
});
|
|
885
|
+
next = next.replace(/\bactiveKey=/g, () => {
|
|
886
|
+
hits++;
|
|
887
|
+
return "value=";
|
|
888
|
+
});
|
|
889
|
+
next = next.replace(/\bdefaultActiveKey=/g, () => {
|
|
890
|
+
hits++;
|
|
891
|
+
return "defaultValue=";
|
|
892
|
+
});
|
|
893
|
+
return { next, hits };
|
|
894
|
+
}
|
|
895
|
+
function rewriteSectionOnChange(source) {
|
|
896
|
+
if (!/\b(NavSections|TabSections)\b/.test(source)) {
|
|
897
|
+
return { next: source, hits: 0 };
|
|
898
|
+
}
|
|
899
|
+
let hits = 0;
|
|
900
|
+
const next = source.replace(/\bonChange=/g, () => {
|
|
901
|
+
hits++;
|
|
902
|
+
return "onValueChange=";
|
|
903
|
+
});
|
|
904
|
+
return { next, hits };
|
|
905
|
+
}
|
|
906
|
+
function rewriteItemKeys(source) {
|
|
907
|
+
if (!/\b(Menu|NavSections|TabSections|MenuItem|NavSectionsItem|TabSectionsItem)\b/.test(source)) {
|
|
908
|
+
return { next: source, hits: 0 };
|
|
909
|
+
}
|
|
910
|
+
let hits = 0;
|
|
911
|
+
const next = source.replace(/(\{\s*)key(\s*:\s*["'`])/g, (_m, a, b) => {
|
|
912
|
+
hits++;
|
|
913
|
+
return `${a}value${b}`;
|
|
914
|
+
});
|
|
915
|
+
const next2 = next.replace(/(\.\s*)key(\s*(?:[,)\]]|;|\s*[=!]==))/g, (full, a, b) => {
|
|
916
|
+
if (/\bt\.key|\bi\.key|item\.key/.test(full) || /t\.key|i\.key/.test(a + "key")) {
|
|
917
|
+
hits++;
|
|
918
|
+
return `${a}value${b}`;
|
|
919
|
+
}
|
|
920
|
+
return full;
|
|
921
|
+
});
|
|
922
|
+
const next3 = next2.replace(/\b(t|i|item)\.key\b/g, (_m, obj) => {
|
|
923
|
+
hits++;
|
|
924
|
+
return `${obj}.value`;
|
|
925
|
+
});
|
|
926
|
+
return { next: next3, hits };
|
|
927
|
+
}
|
|
928
|
+
function rewriteComponentsTsx(source) {
|
|
929
|
+
let hits = 0;
|
|
930
|
+
let next = source;
|
|
931
|
+
const imp = rewriteImports2(next);
|
|
932
|
+
next = imp.next;
|
|
933
|
+
hits += imp.hits;
|
|
934
|
+
const jsx = rewriteJsx(next);
|
|
935
|
+
next = jsx.next;
|
|
936
|
+
hits += jsx.hits;
|
|
937
|
+
const oc = rewriteSectionOnChange(next);
|
|
938
|
+
next = oc.next;
|
|
939
|
+
hits += oc.hits;
|
|
940
|
+
const keys = rewriteItemKeys(next);
|
|
941
|
+
next = keys.next;
|
|
942
|
+
hits += keys.hits;
|
|
943
|
+
return { next, hits };
|
|
944
|
+
}
|
|
945
|
+
function fixStackDirectionSpacing(source) {
|
|
946
|
+
return source.replace(/<Stack direction="row"(\S)/g, `<Stack direction="row" $1`);
|
|
947
|
+
}
|
|
948
|
+
async function migrateComponents(cwd, dry) {
|
|
949
|
+
const pkg = readPackageJson(cwd);
|
|
950
|
+
if (pkg?.name === "@elcrm/components")
|
|
951
|
+
return [];
|
|
952
|
+
const changes = [];
|
|
953
|
+
const files = projectCodeRoots(cwd).flatMap((r) => walkCodeFiles(r));
|
|
954
|
+
for (const file of files) {
|
|
955
|
+
const raw = readFileSync11(file, "utf8");
|
|
956
|
+
let next = raw;
|
|
957
|
+
let hits = 0;
|
|
958
|
+
if (file.endsWith(".css")) {
|
|
959
|
+
const r = rewriteComponentsCss(raw);
|
|
960
|
+
const clean = stripOrphanColorMix(r.next);
|
|
961
|
+
next = clean.next;
|
|
962
|
+
hits = r.hits + clean.hits;
|
|
963
|
+
} else if (/\.(tsx?|jsx?|mdx?)$/.test(file)) {
|
|
964
|
+
const r = rewriteComponentsTsx(raw);
|
|
965
|
+
next = fixStackDirectionSpacing(r.next);
|
|
966
|
+
hits = r.hits;
|
|
967
|
+
} else {
|
|
968
|
+
continue;
|
|
969
|
+
}
|
|
970
|
+
if (hits === 0 || next === raw)
|
|
971
|
+
continue;
|
|
972
|
+
if (writeIfChanged(file, next, dry) || dry) {
|
|
973
|
+
changes.push({
|
|
974
|
+
file: rel(cwd, file),
|
|
975
|
+
detail: `${hits}\xD7 components (Stack / value / shell-tokens)`
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return changes;
|
|
980
|
+
}
|
|
981
|
+
function lineHasDeprecatedComponentsToken(line) {
|
|
982
|
+
const t = line.trim();
|
|
983
|
+
if (!t || t.startsWith("/*") || t.startsWith("*"))
|
|
984
|
+
return false;
|
|
985
|
+
if (DEPRECATED_VAR_RE2.test(t))
|
|
986
|
+
return true;
|
|
987
|
+
if (!DEPRECATED_DECL_RE2.test(t))
|
|
988
|
+
return false;
|
|
989
|
+
if (/:\s*var\(\s*--shell-/.test(t))
|
|
990
|
+
return false;
|
|
991
|
+
return true;
|
|
992
|
+
}
|
|
993
|
+
var VAR_REPLACEMENTS2, COMPONENTS_TOKEN_DEPRECATED, DEPRECATED_VAR_RE2, DEPRECATED_DECL_RE2;
|
|
994
|
+
var init_components = __esm(() => {
|
|
995
|
+
init_pkg();
|
|
996
|
+
init_walk();
|
|
997
|
+
init_css_sanitize();
|
|
998
|
+
VAR_REPLACEMENTS2 = [
|
|
999
|
+
[/var\(\s*--layout-background\s*(?:,[^)]+)?\)/gi, "var(--shell-background-muted)"],
|
|
1000
|
+
[/var\(\s*--header-background\s*(?:,[^)]+)?\)/gi, "var(--shell-background)"],
|
|
1001
|
+
[/var\(\s*--header-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color)"],
|
|
1002
|
+
[/var\(\s*--header-border\s*(?:,[^)]+)?\)/gi, "var(--shell-border)"],
|
|
1003
|
+
[/var\(\s*--footer-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color-muted)"],
|
|
1004
|
+
[/var\(\s*--footer-border\s*(?:,[^)]+)?\)/gi, "var(--shell-border)"],
|
|
1005
|
+
[/var\(\s*--item-background-hover\s*(?:,[^)]+)?\)/gi, "var(--shell-background-hover)"],
|
|
1006
|
+
[/var\(\s*--item-background-active\s*(?:,[^)]+)?\)/gi, "var(--shell-background-selected)"],
|
|
1007
|
+
[/var\(\s*--item-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color)"],
|
|
1008
|
+
[/var\(\s*--card-background\s*(?:,[^)]+)?\)/gi, "var(--shell-background)"],
|
|
1009
|
+
[/var\(\s*--card-border\s*(?:,[^)]+)?\)/gi, "var(--shell-border)"],
|
|
1010
|
+
[/var\(\s*--card-shadow\s*(?:,[^)]+)?\)/gi, "var(--shell-shadow)"],
|
|
1011
|
+
[/var\(\s*--menu-item-background-hover\s*(?:,[^)]+)?\)/gi, "var(--shell-background-hover)"],
|
|
1012
|
+
[/var\(\s*--menu-item-background-active\s*(?:,[^)]+)?\)/gi, "var(--shell-background-selected)"],
|
|
1013
|
+
[/var\(\s*--menu-item-color-active\s*(?:,[^)]+)?\)/gi, "var(--shell-color)"],
|
|
1014
|
+
[/var\(\s*--menu-item-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color-muted)"],
|
|
1015
|
+
[/var\(\s*--loading-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color-muted)"],
|
|
1016
|
+
[/var\(\s*--section-title-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color)"],
|
|
1017
|
+
[/var\(\s*--section-description-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color-muted)"],
|
|
1018
|
+
[/var\(\s*--section-auth-card-background\s*(?:,[^)]+)?\)/gi, "var(--shell-background)"],
|
|
1019
|
+
[/var\(\s*--section-auth-card-border\s*(?:,[^)]+)?\)/gi, "var(--shell-border)"],
|
|
1020
|
+
[/var\(\s*--section-auth-card-shadow\s*(?:,[^)]+)?\)/gi, "var(--shell-shadow)"],
|
|
1021
|
+
[/var\(\s*--section-block-border\s*(?:,[^)]+)?\)/gi, "var(--shell-border)"],
|
|
1022
|
+
[/var\(\s*--nav-sections-label-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color-muted)"],
|
|
1023
|
+
[/var\(\s*--nav-sections-item-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color)"],
|
|
1024
|
+
[/var\(\s*--nav-sections-item-background-hover\s*(?:,[^)]+)?\)/gi, "var(--shell-background-hover)"],
|
|
1025
|
+
[/var\(\s*--nav-sections-item-background-active\s*(?:,[^)]+)?\)/gi, "var(--shell-background-selected)"],
|
|
1026
|
+
[/var\(\s*--nav-sections-accent\s*(?:,[^)]+)?\)/gi, "var(--shell-color-accent)"],
|
|
1027
|
+
[/var\(\s*--nav-sections-icon-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color-muted)"],
|
|
1028
|
+
[/var\(\s*--nav-sections-group-border\s*(?:,[^)]+)?\)/gi, "var(--shell-border)"],
|
|
1029
|
+
[/var\(\s*--nav-sections-footer-border\s*(?:,[^)]+)?\)/gi, "var(--shell-border)"],
|
|
1030
|
+
[/var\(\s*--tab-sections-border\s*(?:,[^)]+)?\)/gi, "var(--shell-border)"],
|
|
1031
|
+
[/var\(\s*--tab-sections-color-active\s*(?:,[^)]+)?\)/gi, "var(--shell-color)"],
|
|
1032
|
+
[/var\(\s*--tab-sections-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color-muted)"],
|
|
1033
|
+
[/var\(\s*--tab-sections-accent\s*(?:,[^)]+)?\)/gi, "var(--shell-color)"],
|
|
1034
|
+
[/var\(\s*--tab-sections-badge-background\s*(?:,[^)]+)?\)/gi, "var(--shell-color-danger)"],
|
|
1035
|
+
[/var\(\s*--brand-color-hover\s*(?:,[^)]+)?\)/gi, "var(--shell-color-accent)"],
|
|
1036
|
+
[/var\(\s*--brand-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color)"],
|
|
1037
|
+
[/var\(\s*--badge-neutral-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color)"],
|
|
1038
|
+
[/var\(\s*--badge-accent-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color-accent)"],
|
|
1039
|
+
[/var\(\s*--badge-success-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color-success)"],
|
|
1040
|
+
[/var\(\s*--badge-danger-color\s*(?:,[^)]+)?\)/gi, "var(--shell-color-danger)"],
|
|
1041
|
+
[/var\(\s*--list-gap\s*(?:,[^)]+)?\)/gi, "var(--shell-gap-sm)"],
|
|
1042
|
+
[/var\(\s*--item-padding\s*(?:,[^)]+)?\)/gi, "var(--shell-padding)"],
|
|
1043
|
+
[/var\(\s*--item-radius\s*(?:,[^)]+)?\)/gi, "var(--shell-radius)"],
|
|
1044
|
+
[/var\(\s*--block-gap\s*(?:,[^)]+)?\)/gi, "var(--shell-gap)"],
|
|
1045
|
+
[/var\(\s*--row-gap\s*(?:,[^)]+)?\)/gi, "var(--shell-gap)"],
|
|
1046
|
+
[/var\(\s*--column-gap\s*(?:,[^)]+)?\)/gi, "var(--shell-gap)"],
|
|
1047
|
+
[/var\(\s*--page-gap\s*(?:,[^)]+)?\)/gi, "var(--shell-gap)"],
|
|
1048
|
+
[/var\(\s*--page-pad\s*(?:,[^)]+)?\)/gi, "var(--shell-padding)"],
|
|
1049
|
+
[/var\(\s*--page-pad-x\s*(?:,[^)]+)?\)/gi, "var(--shell-padding-inline)"],
|
|
1050
|
+
[/var\(\s*--page-pad-y\s*(?:,[^)]+)?\)/gi, "var(--shell-padding-block)"],
|
|
1051
|
+
[/var\(\s*--card-radius\s*(?:,[^)]+)?\)/gi, "var(--shell-radius)"],
|
|
1052
|
+
[/var\(\s*--section-description-size\s*(?:,[^)]+)?\)/gi, "0.95rem"],
|
|
1053
|
+
[/var\(\s*--section-title-size\s*(?:,[^)]+)?\)/gi, "1.5rem"]
|
|
1054
|
+
];
|
|
1055
|
+
COMPONENTS_TOKEN_DEPRECATED = [
|
|
1056
|
+
"--layout-background",
|
|
1057
|
+
"--layout-min-height",
|
|
1058
|
+
"--layout-gap",
|
|
1059
|
+
"--header-background",
|
|
1060
|
+
"--header-color",
|
|
1061
|
+
"--header-border",
|
|
1062
|
+
"--header-padding",
|
|
1063
|
+
"--header-gap",
|
|
1064
|
+
"--footer-background",
|
|
1065
|
+
"--footer-color",
|
|
1066
|
+
"--footer-border",
|
|
1067
|
+
"--footer-padding",
|
|
1068
|
+
"--footer-font-size",
|
|
1069
|
+
"--list-gap",
|
|
1070
|
+
"--list-padding",
|
|
1071
|
+
"--item-background",
|
|
1072
|
+
"--item-background-hover",
|
|
1073
|
+
"--item-background-active",
|
|
1074
|
+
"--item-color",
|
|
1075
|
+
"--item-color-muted",
|
|
1076
|
+
"--item-border",
|
|
1077
|
+
"--item-radius",
|
|
1078
|
+
"--item-padding",
|
|
1079
|
+
"--item-gap",
|
|
1080
|
+
"--card-background",
|
|
1081
|
+
"--card-border",
|
|
1082
|
+
"--card-shadow",
|
|
1083
|
+
"--card-radius",
|
|
1084
|
+
"--card-padding",
|
|
1085
|
+
"--block-gap",
|
|
1086
|
+
"--block-padding",
|
|
1087
|
+
"--row-gap",
|
|
1088
|
+
"--column-gap",
|
|
1089
|
+
"--menu-gap",
|
|
1090
|
+
"--menu-item-radius",
|
|
1091
|
+
"--menu-item-padding",
|
|
1092
|
+
"--menu-item-background",
|
|
1093
|
+
"--menu-item-background-hover",
|
|
1094
|
+
"--menu-item-background-active",
|
|
1095
|
+
"--menu-item-color",
|
|
1096
|
+
"--menu-item-color-active",
|
|
1097
|
+
"--loading-padding",
|
|
1098
|
+
"--loading-color",
|
|
1099
|
+
"--section-gap",
|
|
1100
|
+
"--section-description-size",
|
|
1101
|
+
"--section-icon-gap",
|
|
1102
|
+
"--section-body-gap",
|
|
1103
|
+
"--section-actions-gap",
|
|
1104
|
+
"--section-auth-padding",
|
|
1105
|
+
"--section-auth-card-padding",
|
|
1106
|
+
"--section-auth-card-radius",
|
|
1107
|
+
"--section-block-padding-bottom",
|
|
1108
|
+
"--section-block-margin-bottom",
|
|
1109
|
+
"--section-title-color",
|
|
1110
|
+
"--section-description-color",
|
|
1111
|
+
"--section-auth-card-background",
|
|
1112
|
+
"--section-auth-card-border",
|
|
1113
|
+
"--section-auth-card-shadow",
|
|
1114
|
+
"--section-block-border",
|
|
1115
|
+
"--nav-sections-gap",
|
|
1116
|
+
"--nav-sections-item-radius",
|
|
1117
|
+
"--nav-sections-item-padding",
|
|
1118
|
+
"--nav-sections-label-color",
|
|
1119
|
+
"--nav-sections-item-color",
|
|
1120
|
+
"--nav-sections-item-background-hover",
|
|
1121
|
+
"--nav-sections-item-background-active",
|
|
1122
|
+
"--nav-sections-accent",
|
|
1123
|
+
"--nav-sections-icon-color",
|
|
1124
|
+
"--nav-sections-group-border",
|
|
1125
|
+
"--nav-sections-footer-border",
|
|
1126
|
+
"--tab-sections-gap",
|
|
1127
|
+
"--tab-sections-tab-padding",
|
|
1128
|
+
"--tab-sections-tab-gap",
|
|
1129
|
+
"--tab-sections-badge-size",
|
|
1130
|
+
"--tab-sections-border",
|
|
1131
|
+
"--tab-sections-color",
|
|
1132
|
+
"--tab-sections-color-active",
|
|
1133
|
+
"--tab-sections-accent",
|
|
1134
|
+
"--tab-sections-badge-background",
|
|
1135
|
+
"--tab-sections-badge-color",
|
|
1136
|
+
"--badge-padding",
|
|
1137
|
+
"--badge-radius",
|
|
1138
|
+
"--badge-font-size",
|
|
1139
|
+
"--badge-font-weight",
|
|
1140
|
+
"--badge-border",
|
|
1141
|
+
"--badge-neutral-background",
|
|
1142
|
+
"--badge-neutral-color",
|
|
1143
|
+
"--badge-accent-background",
|
|
1144
|
+
"--badge-accent-color",
|
|
1145
|
+
"--badge-success-background",
|
|
1146
|
+
"--badge-success-color",
|
|
1147
|
+
"--badge-warning-background",
|
|
1148
|
+
"--badge-warning-color",
|
|
1149
|
+
"--badge-danger-background",
|
|
1150
|
+
"--badge-danger-color",
|
|
1151
|
+
"--brand-font-weight",
|
|
1152
|
+
"--brand-letter-spacing",
|
|
1153
|
+
"--brand-color",
|
|
1154
|
+
"--brand-color-hover",
|
|
1155
|
+
"--empty-state-gap",
|
|
1156
|
+
"--empty-state-padding",
|
|
1157
|
+
"--empty-state-icon-gap",
|
|
1158
|
+
"--empty-state-title-size",
|
|
1159
|
+
"--empty-state-description-size",
|
|
1160
|
+
"--empty-state-max-width",
|
|
1161
|
+
"--empty-state-actions-gap",
|
|
1162
|
+
"--empty-state-actions-margin-top",
|
|
1163
|
+
"--radio-group-gap",
|
|
1164
|
+
"--page-pad",
|
|
1165
|
+
"--page-pad-x",
|
|
1166
|
+
"--page-pad-y",
|
|
1167
|
+
"--page-gap",
|
|
1168
|
+
"--card-radius"
|
|
1169
|
+
];
|
|
1170
|
+
DEPRECATED_VAR_RE2 = new RegExp(`var\\(\\s*(?:${COMPONENTS_TOKEN_DEPRECATED.map((n) => n.replace(/-/g, "\\-")).join("|")})(?![\\w-])`, "i");
|
|
1171
|
+
DEPRECATED_DECL_RE2 = new RegExp(`(?:${COMPONENTS_TOKEN_DEPRECATED.map((n) => n.replace(/-/g, "\\-")).join("|")})(?![\\w-])\\s*:`);
|
|
1172
|
+
});
|
|
1173
|
+
|
|
691
1174
|
// src/lib/migrate/front.ts
|
|
692
1175
|
var exports_front = {};
|
|
693
1176
|
__export(exports_front, {
|
|
@@ -714,18 +1197,24 @@ var init_front = __esm(() => {
|
|
|
714
1197
|
init_legacy_hacks();
|
|
715
1198
|
init_form_aliases();
|
|
716
1199
|
init_form_tokens();
|
|
1200
|
+
init_components();
|
|
1201
|
+
init_css_sanitize();
|
|
717
1202
|
FRONT_MIGRATIONS = {
|
|
718
1203
|
"size-sml": migrateSizeSml,
|
|
719
1204
|
"field-border": migrateFieldBorder,
|
|
720
1205
|
"modal-create": migrateModalCreate,
|
|
721
1206
|
"form-aliases": migrateFormAliases,
|
|
722
1207
|
"form-tokens": migrateFormTokens,
|
|
1208
|
+
components: migrateComponents,
|
|
1209
|
+
"css-sanitize": migrateCssSanitize,
|
|
723
1210
|
"legacy-hacks": migrateLegacyReactHack,
|
|
724
1211
|
"socket-server": migrateSocketServer
|
|
725
1212
|
};
|
|
726
1213
|
FRONT_MIGRATE_ORDER = [
|
|
727
1214
|
"form-aliases",
|
|
728
1215
|
"form-tokens",
|
|
1216
|
+
"components",
|
|
1217
|
+
"css-sanitize",
|
|
729
1218
|
"size-sml",
|
|
730
1219
|
"field-border",
|
|
731
1220
|
"modal-create",
|
|
@@ -734,7 +1223,7 @@ var init_front = __esm(() => {
|
|
|
734
1223
|
});
|
|
735
1224
|
|
|
736
1225
|
// src/index.ts
|
|
737
|
-
import { readFileSync as
|
|
1226
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
738
1227
|
import { dirname as dirname4, join as join18 } from "path";
|
|
739
1228
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
740
1229
|
|
|
@@ -854,6 +1343,17 @@ function installDeps(cwd = process.cwd()) {
|
|
|
854
1343
|
});
|
|
855
1344
|
return r.status === 0;
|
|
856
1345
|
}
|
|
1346
|
+
function installGlobalElcrm() {
|
|
1347
|
+
const bun = spawnSync("bun", ["--version"], { encoding: "utf8" });
|
|
1348
|
+
const cmd = bun.status === 0 ? "bun" : "npm";
|
|
1349
|
+
const args = ["i", "-g", "elcrm@latest"];
|
|
1350
|
+
console.log(`CLI: ${cmd} ${args.join(" ")}`);
|
|
1351
|
+
const r = spawnSync(cmd, args, {
|
|
1352
|
+
stdio: "inherit",
|
|
1353
|
+
env: process.env
|
|
1354
|
+
});
|
|
1355
|
+
return r.status === 0;
|
|
1356
|
+
}
|
|
857
1357
|
|
|
858
1358
|
// src/commands/update.ts
|
|
859
1359
|
init_pkg();
|
|
@@ -877,18 +1377,24 @@ var c = {
|
|
|
877
1377
|
|
|
878
1378
|
// src/commands/update.ts
|
|
879
1379
|
init_front();
|
|
1380
|
+
init_css_sanitize();
|
|
880
1381
|
|
|
881
1382
|
// src/lib/cssSync.ts
|
|
882
1383
|
init_form_tokens();
|
|
1384
|
+
init_components();
|
|
883
1385
|
import {
|
|
884
1386
|
existsSync as existsSync6,
|
|
885
1387
|
readdirSync as readdirSync3,
|
|
886
|
-
readFileSync as
|
|
1388
|
+
readFileSync as readFileSync12,
|
|
887
1389
|
statSync as statSync3,
|
|
888
1390
|
writeFileSync as writeFileSync4
|
|
889
1391
|
} from "fs";
|
|
890
1392
|
import { createRequire } from "module";
|
|
891
1393
|
import { dirname, join as join6 } from "path";
|
|
1394
|
+
var TOKEN_DEPRECATED = new Set([
|
|
1395
|
+
...FORM_TOKEN_DEPRECATED,
|
|
1396
|
+
...COMPONENTS_TOKEN_DEPRECATED
|
|
1397
|
+
]);
|
|
892
1398
|
var COLOR_VALUE = /#|rgba?\(|hsla?\(|oklch|oklab|color-mix|lab\(|lch\(|hwb\(/i;
|
|
893
1399
|
var COLOR_NAME = /(?:^|-)(bg|fg|color|fill|track|thumb|overlay|shadow|border|ring|background|placeholder)(?:-|$)/i;
|
|
894
1400
|
var GEOM_VALUE = /(?:^|\s)(\d*\.?\d+)(px|em|rem|%|vh|vw|dvh|ch|ex|s|ms|deg|fr|pt)\b|^[0-9.]+$|ease|linear|none/i;
|
|
@@ -1008,7 +1514,7 @@ function resolvePkgRoot(pkgName, cwd) {
|
|
|
1008
1514
|
}
|
|
1009
1515
|
function readPkgJson(dir) {
|
|
1010
1516
|
try {
|
|
1011
|
-
return JSON.parse(
|
|
1517
|
+
return JSON.parse(readFileSync12(join6(dir, "package.json"), "utf8"));
|
|
1012
1518
|
} catch {
|
|
1013
1519
|
return null;
|
|
1014
1520
|
}
|
|
@@ -1064,7 +1570,7 @@ function collectPkgTokens(pkgName, cwd) {
|
|
|
1064
1570
|
const acc = [];
|
|
1065
1571
|
const seen = new Set;
|
|
1066
1572
|
for (const file of files) {
|
|
1067
|
-
const css =
|
|
1573
|
+
const css = readFileSync12(file, "utf8");
|
|
1068
1574
|
const kind = fileKind(file);
|
|
1069
1575
|
if (kind !== "mixed") {
|
|
1070
1576
|
for (const [name, value] of parseCustomProps(css)) {
|
|
@@ -1232,9 +1738,9 @@ function syncElcrmCss(options) {
|
|
|
1232
1738
|
const file = fileFor(bucket);
|
|
1233
1739
|
if (!existsSync6(file))
|
|
1234
1740
|
continue;
|
|
1235
|
-
let css =
|
|
1741
|
+
let css = readFileSync12(file, "utf8");
|
|
1236
1742
|
const have = existingTokenNames(css);
|
|
1237
|
-
const missing = allDefs.filter((d) => d.bucket === bucket && !have.has(d.name) && !
|
|
1743
|
+
const missing = allDefs.filter((d) => d.bucket === bucket && !have.has(d.name) && !TOKEN_DEPRECATED.has(d.name));
|
|
1238
1744
|
const uniq = [];
|
|
1239
1745
|
const seen = new Set;
|
|
1240
1746
|
for (const d of missing) {
|
|
@@ -1257,7 +1763,7 @@ function syncElcrmCss(options) {
|
|
|
1257
1763
|
writeFileSync4(file, next, "utf8");
|
|
1258
1764
|
}
|
|
1259
1765
|
if (existsSync6(paths.elcrm)) {
|
|
1260
|
-
let css =
|
|
1766
|
+
let css = readFileSync12(paths.elcrm, "utf8");
|
|
1261
1767
|
for (const exp of cssExports) {
|
|
1262
1768
|
const specs = [];
|
|
1263
1769
|
if (exp.light)
|
|
@@ -1284,7 +1790,7 @@ function syncElcrmCss(options) {
|
|
|
1284
1790
|
import { resolve } from "path";
|
|
1285
1791
|
|
|
1286
1792
|
// src/lib/test/detect.ts
|
|
1287
|
-
import { existsSync as existsSync7, readdirSync as readdirSync4, readFileSync as
|
|
1793
|
+
import { existsSync as existsSync7, readdirSync as readdirSync4, readFileSync as readFileSync13, statSync as statSync4 } from "fs";
|
|
1288
1794
|
import { join as join7 } from "path";
|
|
1289
1795
|
function hasElcrmServer(pkg) {
|
|
1290
1796
|
for (const section of [
|
|
@@ -1339,17 +1845,43 @@ function readPkgAt(dir) {
|
|
|
1339
1845
|
if (!existsSync7(path))
|
|
1340
1846
|
return null;
|
|
1341
1847
|
try {
|
|
1342
|
-
return JSON.parse(
|
|
1848
|
+
return JSON.parse(readFileSync13(path, "utf8"));
|
|
1343
1849
|
} catch {
|
|
1344
1850
|
return null;
|
|
1345
1851
|
}
|
|
1346
1852
|
}
|
|
1347
1853
|
|
|
1348
1854
|
// src/lib/test/front.ts
|
|
1349
|
-
import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as
|
|
1855
|
+
import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync14, statSync as statSync5 } from "fs";
|
|
1350
1856
|
import { join as join8, relative as relative2 } from "path";
|
|
1351
1857
|
init_form_tokens();
|
|
1858
|
+
init_components();
|
|
1859
|
+
init_css_sanitize();
|
|
1352
1860
|
var SKIP = new Set(["node_modules", "dist", ".git", "coverage", ".bun"]);
|
|
1861
|
+
function isThemeTokenFile(rel2) {
|
|
1862
|
+
const n = rel2.replace(/\\/g, "/");
|
|
1863
|
+
return /(?:^|\/)(?:theme(?:-light|-dark)?|elcrm)\.css$/.test(n);
|
|
1864
|
+
}
|
|
1865
|
+
function isGeneratedIcons(rel2) {
|
|
1866
|
+
return /icons\.generated\.(tsx?|jsx?)$/.test(rel2.replace(/\\/g, "/"));
|
|
1867
|
+
}
|
|
1868
|
+
var HARD_HEX_RE = /#[0-9a-fA-F]{3,8}\b/;
|
|
1869
|
+
var HARD_RGB_RE = /\b(?:rgb|rgba|hsl|hsla)\s*\(/i;
|
|
1870
|
+
var HARD_NAMED_RE = /(?:^|[;{]\s*|(?:color|background(?:-color)?|border-color|fill|stroke|outline-color)\s*:\s*)(?:white|black|red|blue|navy|gray|grey|silver|whitesmoke)\b/i;
|
|
1871
|
+
var JSX_COLOR_PROP_RE = /\b(?:color|background(?:Color)?|borderColor|fill)\s*=\s*\{?\s*["'](?:#|rgb|hsl|white|black)/i;
|
|
1872
|
+
function lineForColorScan(line) {
|
|
1873
|
+
return line.replace(/var\([^)]*\)/g, "").replace(/url\s*\([^)]*\)/gi, "");
|
|
1874
|
+
}
|
|
1875
|
+
function hardcodedColorReason(line) {
|
|
1876
|
+
const s = lineForColorScan(line);
|
|
1877
|
+
if (HARD_HEX_RE.test(s) || HARD_RGB_RE.test(s) || JSX_COLOR_PROP_RE.test(line)) {
|
|
1878
|
+
return "\u043B\u0438\u0442\u0435\u0440\u0430\u043B \u0446\u0432\u0435\u0442\u0430 \u2014 var(--button-*|--field-*|--item-*|--layout-*) \u0438\u0437 theme";
|
|
1879
|
+
}
|
|
1880
|
+
if (HARD_NAMED_RE.test(s) && !/\btransparent\b|\bcurrentColor\b|\binherit\b/.test(s)) {
|
|
1881
|
+
return "\u0438\u043C\u0435\u043D\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0446\u0432\u0435\u0442 \u2014 \u0442\u043E\u043A\u0435\u043D @elcrm/* / theme";
|
|
1882
|
+
}
|
|
1883
|
+
return null;
|
|
1884
|
+
}
|
|
1353
1885
|
var DEPRECATED_SOCKET_IMPORT_RE = /(?:from\s+|require\s*\(\s*)["']@elcrm\/(?:socket\/server|socket-server)["']/;
|
|
1354
1886
|
var THEMES_CSS_IMPORT_RE = /(?:from\s+|import\s+)["']@elcrm\/[^"']+\/themes\.css["']|import\s+["']@elcrm\/[^"']+\/themes\.css["']/;
|
|
1355
1887
|
var LEGACY_PASSKEY_IMPORT_RE = /(?:from\s+|require\s*\(\s*)["']@elcrm\/passkey["']/;
|
|
@@ -1469,8 +2001,9 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
1469
2001
|
files.push(inSrc);
|
|
1470
2002
|
}
|
|
1471
2003
|
for (const file of files) {
|
|
1472
|
-
const text =
|
|
2004
|
+
const text = readFileSync14(file, "utf8");
|
|
1473
2005
|
const rel2 = relative2(cwd, file);
|
|
2006
|
+
const skipHardColor = isLib || isThemeTokenFile(rel2) || isGeneratedIcons(rel2);
|
|
1474
2007
|
if (DEPRECATED_SOCKET_IMPORT_RE.test(text)) {
|
|
1475
2008
|
issues.push({
|
|
1476
2009
|
level: "error",
|
|
@@ -1576,12 +2109,66 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
1576
2109
|
fixable: true
|
|
1577
2110
|
});
|
|
1578
2111
|
}
|
|
2112
|
+
if (lineHasDeprecatedComponentsToken(line)) {
|
|
2113
|
+
issues.push({
|
|
2114
|
+
level: "warn",
|
|
2115
|
+
code: "components-token-legacy",
|
|
2116
|
+
message: "legacy \u0442\u043E\u043A\u0435\u043D @elcrm/components \u2192 --shell-* (elcrm migrate components)",
|
|
2117
|
+
file: rel2,
|
|
2118
|
+
line: i + 1,
|
|
2119
|
+
fixable: true
|
|
2120
|
+
});
|
|
2121
|
+
}
|
|
2122
|
+
if (lineHasOrphanColorMix(line)) {
|
|
2123
|
+
issues.push({
|
|
2124
|
+
level: "error",
|
|
2125
|
+
code: "css-orphan-mix",
|
|
2126
|
+
message: "\u043E\u0441\u0438\u0440\u043E\u0442\u0435\u0432\u0448\u0438\u0439 \u0445\u0432\u043E\u0441\u0442 color-mix (in srgb\u2026) \u2014 elcrm migrate css-sanitize",
|
|
2127
|
+
file: rel2,
|
|
2128
|
+
line: i + 1,
|
|
2129
|
+
fixable: true
|
|
2130
|
+
});
|
|
2131
|
+
}
|
|
2132
|
+
if (/\b(Block|Row|Column)\b/.test(line) && /@elcrm\/components/.test(text) && /from\s+["']@elcrm\/components/.test(text)) {
|
|
2133
|
+
if (/import\s*\{[^}]*\b(Block|Row|Column)\b/.test(line) || /<\/?(?:Block|Row|Column)\b/.test(line)) {
|
|
2134
|
+
issues.push({
|
|
2135
|
+
level: "warn",
|
|
2136
|
+
code: "components-stack",
|
|
2137
|
+
message: "Block/Row/Column \u0443\u0441\u0442\u0430\u0440\u0435\u043B\u0438 \u2014 Stack (elcrm migrate components)",
|
|
2138
|
+
file: rel2,
|
|
2139
|
+
line: i + 1,
|
|
2140
|
+
fixable: true
|
|
2141
|
+
});
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
if (/\b(activeKey|defaultActiveKey)\s*=/.test(line) && /@elcrm\/components/.test(text)) {
|
|
2145
|
+
issues.push({
|
|
2146
|
+
level: "warn",
|
|
2147
|
+
code: "components-value",
|
|
2148
|
+
message: "activeKey/defaultActiveKey \u2192 value/defaultValue (elcrm migrate components)",
|
|
2149
|
+
file: rel2,
|
|
2150
|
+
line: i + 1,
|
|
2151
|
+
fixable: true
|
|
2152
|
+
});
|
|
2153
|
+
}
|
|
2154
|
+
if (!skipHardColor) {
|
|
2155
|
+
const why = hardcodedColorReason(line);
|
|
2156
|
+
if (why) {
|
|
2157
|
+
issues.push({
|
|
2158
|
+
level: "warn",
|
|
2159
|
+
code: "hardcoded-color",
|
|
2160
|
+
message: why,
|
|
2161
|
+
file: rel2,
|
|
2162
|
+
line: i + 1
|
|
2163
|
+
});
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
1579
2166
|
});
|
|
1580
2167
|
}
|
|
1581
2168
|
return issues;
|
|
1582
2169
|
}
|
|
1583
2170
|
async function runPkgScript(cwd, script) {
|
|
1584
|
-
const pkg = JSON.parse(
|
|
2171
|
+
const pkg = JSON.parse(readFileSync14(join8(cwd, "package.json"), "utf8"));
|
|
1585
2172
|
if (!pkg.scripts?.[script])
|
|
1586
2173
|
return { ran: false, ok: true };
|
|
1587
2174
|
console.log(`\u2192 bun run ${script}`);
|
|
@@ -1624,7 +2211,7 @@ function printIssues(issues, title) {
|
|
|
1624
2211
|
}
|
|
1625
2212
|
|
|
1626
2213
|
// src/lib/test/serverScan.ts
|
|
1627
|
-
import { existsSync as existsSync9, readdirSync as readdirSync6, readFileSync as
|
|
2214
|
+
import { existsSync as existsSync9, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
|
|
1628
2215
|
import { join as join9, relative as relative3 } from "path";
|
|
1629
2216
|
|
|
1630
2217
|
// src/lib/test/serverRules.ts
|
|
@@ -2026,7 +2613,7 @@ function scanServerProject(root) {
|
|
|
2026
2613
|
walkFiles2(root, root, files);
|
|
2027
2614
|
const findings = [];
|
|
2028
2615
|
for (const file of files) {
|
|
2029
|
-
const text =
|
|
2616
|
+
const text = readFileSync15(file, "utf8");
|
|
2030
2617
|
if (file.endsWith("package.json")) {
|
|
2031
2618
|
findings.push(...scanPackageJson(root, file, text));
|
|
2032
2619
|
} else {
|
|
@@ -2136,6 +2723,17 @@ elcrm test: ok`));
|
|
|
2136
2723
|
// src/commands/update.ts
|
|
2137
2724
|
async function cmdUpdate(parsed) {
|
|
2138
2725
|
const cwd = process.cwd();
|
|
2726
|
+
const dry = hasFlag(parsed, "dry");
|
|
2727
|
+
const useCore = hasFlag(parsed, "core");
|
|
2728
|
+
const noInstall = hasFlag(parsed, "no-install");
|
|
2729
|
+
const doFix = hasFlag(parsed, "fix");
|
|
2730
|
+
const doTest = hasFlag(parsed, "test");
|
|
2731
|
+
if (dry) {
|
|
2732
|
+
console.log(`${c.gray("[dry]")} bun/npm i -g elcrm@latest`);
|
|
2733
|
+
} else if (!installGlobalElcrm()) {
|
|
2734
|
+
console.error("\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u044B\u0439 elcrm.");
|
|
2735
|
+
process.exit(1);
|
|
2736
|
+
}
|
|
2139
2737
|
const pkg = readPackageJson(cwd);
|
|
2140
2738
|
if (!pkg) {
|
|
2141
2739
|
console.error("package.json \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D \u0432 \u0442\u0435\u043A\u0443\u0449\u0435\u043C \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0435.");
|
|
@@ -2146,11 +2744,6 @@ async function cmdUpdate(parsed) {
|
|
|
2146
2744
|
console.log("\u0417\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u0435\u0439 @elcrm/* \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u043E.");
|
|
2147
2745
|
return;
|
|
2148
2746
|
}
|
|
2149
|
-
const dry = hasFlag(parsed, "dry");
|
|
2150
|
-
const useCore = hasFlag(parsed, "core");
|
|
2151
|
-
const noInstall = hasFlag(parsed, "no-install");
|
|
2152
|
-
const doFix = hasFlag(parsed, "fix");
|
|
2153
|
-
const doTest = hasFlag(parsed, "test");
|
|
2154
2747
|
const names = uniqueElcrmNames(deps);
|
|
2155
2748
|
console.log(`\u041D\u0430\u0439\u0434\u0435\u043D\u043E @elcrm/*: ${names.length}`);
|
|
2156
2749
|
let versions;
|
|
@@ -2271,6 +2864,12 @@ package.json \u043E\u0431\u043D\u043E\u0432\u043B\u0451\u043D (${changed}).`);
|
|
|
2271
2864
|
if (added === 0 && css.imports.length === 0) {
|
|
2272
2865
|
console.log(" \u0422\u043E\u043A\u0435\u043D\u044B \u0443\u0436\u0435 \u043D\u0430 \u043C\u0435\u0441\u0442\u0435.");
|
|
2273
2866
|
}
|
|
2867
|
+
const cleaned = await migrateCssSanitize(cwd, false);
|
|
2868
|
+
if (cleaned.length) {
|
|
2869
|
+
console.log(" css-sanitize:");
|
|
2870
|
+
for (const ch of cleaned)
|
|
2871
|
+
console.log(` ${ch.file}: ${ch.detail}`);
|
|
2872
|
+
}
|
|
2274
2873
|
} catch (e) {
|
|
2275
2874
|
console.log(` ${c.gray("css sync \u043F\u0440\u043E\u043F\u0443\u0449\u0435\u043D:")} ${e instanceof Error ? e.message : e}`);
|
|
2276
2875
|
}
|
|
@@ -2295,7 +2894,7 @@ import {
|
|
|
2295
2894
|
existsSync as existsSync11,
|
|
2296
2895
|
mkdirSync,
|
|
2297
2896
|
readdirSync as readdirSync7,
|
|
2298
|
-
readFileSync as
|
|
2897
|
+
readFileSync as readFileSync16,
|
|
2299
2898
|
statSync as statSync7,
|
|
2300
2899
|
writeFileSync as writeFileSync5
|
|
2301
2900
|
} from "fs";
|
|
@@ -2339,7 +2938,7 @@ function isEmptyDir(dir) {
|
|
|
2339
2938
|
function writePkgName(pkgPath, name) {
|
|
2340
2939
|
if (!existsSync11(pkgPath))
|
|
2341
2940
|
return;
|
|
2342
|
-
const pkg = JSON.parse(
|
|
2941
|
+
const pkg = JSON.parse(readFileSync16(pkgPath, "utf8"));
|
|
2343
2942
|
pkg.name = name;
|
|
2344
2943
|
pkg.version = pkg.version ?? "0.0.0";
|
|
2345
2944
|
writeFileSync5(pkgPath, JSON.stringify(pkg, null, 2) + `
|
|
@@ -2506,7 +3105,7 @@ async function cmdMigrate(parsed) {
|
|
|
2506
3105
|
console.log(dry ? `
|
|
2507
3106
|
--dry: ${changes.length} \u043F\u043E\u0442\u0435\u043D\u0446\u0438\u0430\u043B\u044C\u043D\u044B\u0445 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439.` : `
|
|
2508
3107
|
\u041F\u0440\u0438\u043C\u0435\u043D\u0435\u043D\u043E: ${changes.length}.`);
|
|
2509
|
-
if (name === "front" || name === "ui" || name === "size-sml" || name === "form-tokens") {
|
|
3108
|
+
if (name === "front" || name === "ui" || name === "size-sml" || name === "form-tokens" || name === "components" || name === "css-sanitize") {
|
|
2510
3109
|
console.log("\u0414\u0430\u043B\u044C\u0448\u0435: elcrm css && elcrm audit");
|
|
2511
3110
|
}
|
|
2512
3111
|
}
|
|
@@ -2701,7 +3300,7 @@ import { resolve as resolve3 } from "path";
|
|
|
2701
3300
|
import {
|
|
2702
3301
|
existsSync as existsSync13,
|
|
2703
3302
|
readdirSync as readdirSync9,
|
|
2704
|
-
readFileSync as
|
|
3303
|
+
readFileSync as readFileSync18,
|
|
2705
3304
|
rmSync,
|
|
2706
3305
|
statSync as statSync8,
|
|
2707
3306
|
writeFileSync as writeFileSync7
|
|
@@ -2709,12 +3308,24 @@ import {
|
|
|
2709
3308
|
import { join as join13 } from "path";
|
|
2710
3309
|
|
|
2711
3310
|
// src/vite/concat-css.ts
|
|
2712
|
-
import { readdirSync as readdirSync8, readFileSync as
|
|
3311
|
+
import { readdirSync as readdirSync8, readFileSync as readFileSync17, writeFileSync as writeFileSync6 } from "fs";
|
|
2713
3312
|
import { join as join12 } from "path";
|
|
3313
|
+
var SKIP_CSS = new Set([
|
|
3314
|
+
"index.css",
|
|
3315
|
+
"tokens.css",
|
|
3316
|
+
"light.css",
|
|
3317
|
+
"dark.css",
|
|
3318
|
+
"themes.css"
|
|
3319
|
+
]);
|
|
2714
3320
|
function concatDistCss(options) {
|
|
2715
3321
|
const outFile = options.outFile ?? "index.css";
|
|
2716
|
-
const
|
|
2717
|
-
|
|
3322
|
+
const skip = new Set([
|
|
3323
|
+
...SKIP_CSS,
|
|
3324
|
+
outFile,
|
|
3325
|
+
...options.skip ?? []
|
|
3326
|
+
]);
|
|
3327
|
+
const files = readdirSync8(options.distDir).filter((f) => f.endsWith(".css") && !skip.has(f)).sort();
|
|
3328
|
+
const css = files.map((f) => readFileSync17(join12(options.distDir, f), "utf8")).join(`
|
|
2718
3329
|
`);
|
|
2719
3330
|
const outPath = join12(options.distDir, outFile);
|
|
2720
3331
|
writeFileSync6(outPath, css);
|
|
@@ -2745,7 +3356,7 @@ function postbuildLib(options) {
|
|
|
2745
3356
|
const flat = join13(dist, `${name}.d.ts`);
|
|
2746
3357
|
const src = existsSync13(impl) ? impl : existsSync13(nestedIndex) ? nestedIndex : null;
|
|
2747
3358
|
if (src) {
|
|
2748
|
-
const text =
|
|
3359
|
+
const text = readFileSync18(src, "utf8").replace(/from ['"]\.\.\/([^'"]+)['"]/g, `from './$1'`);
|
|
2749
3360
|
writeFileSync7(flat, text);
|
|
2750
3361
|
console.log(`[postbuild] types \u2192 ${name}.d.ts`);
|
|
2751
3362
|
}
|
|
@@ -2764,6 +3375,7 @@ async function cmdPostbuild(parsed) {
|
|
|
2764
3375
|
|
|
2765
3376
|
// src/commands/css.ts
|
|
2766
3377
|
init_pkg();
|
|
3378
|
+
init_css_sanitize();
|
|
2767
3379
|
async function cmdCss(parsed) {
|
|
2768
3380
|
const cwd = parsed.options.dir || process.cwd();
|
|
2769
3381
|
const pkg = readPackageJson(cwd);
|
|
@@ -2805,6 +3417,14 @@ async function cmdCss(parsed) {
|
|
|
2805
3417
|
} else if (dry) {
|
|
2806
3418
|
console.log("\u0417\u0430\u043F\u0438\u0441\u044C \u043D\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u043B\u0430\u0441\u044C (--dry).");
|
|
2807
3419
|
}
|
|
3420
|
+
const cleaned = await migrateCssSanitize(cwd, dry);
|
|
3421
|
+
if (cleaned.length) {
|
|
3422
|
+
console.log(dry ? `
|
|
3423
|
+
[dry] css-sanitize: ${cleaned.length} \u0444\u0430\u0439\u043B(\u043E\u0432)` : `
|
|
3424
|
+
css-sanitize: \u043F\u043E\u0447\u0438\u043D\u0435\u043D\u043E ${cleaned.length} \u0444\u0430\u0439\u043B(\u043E\u0432)`);
|
|
3425
|
+
for (const ch of cleaned)
|
|
3426
|
+
console.log(` ${ch.file}: ${ch.detail}`);
|
|
3427
|
+
}
|
|
2808
3428
|
} catch (e) {
|
|
2809
3429
|
console.error(e instanceof Error ? e.message : e);
|
|
2810
3430
|
process.exit(1);
|
|
@@ -2812,12 +3432,14 @@ async function cmdCss(parsed) {
|
|
|
2812
3432
|
}
|
|
2813
3433
|
|
|
2814
3434
|
// src/commands/audit.ts
|
|
2815
|
-
import { existsSync as existsSync14, readFileSync as
|
|
3435
|
+
import { existsSync as existsSync14, readFileSync as readFileSync19 } from "fs";
|
|
2816
3436
|
import { join as join14, relative as relative4 } from "path";
|
|
2817
3437
|
init_pkg();
|
|
2818
3438
|
init_walk();
|
|
2819
3439
|
init_front();
|
|
2820
3440
|
init_form_tokens();
|
|
3441
|
+
init_components();
|
|
3442
|
+
init_css_sanitize();
|
|
2821
3443
|
function scan(cwd) {
|
|
2822
3444
|
const out = [];
|
|
2823
3445
|
const pkg = readPackageJson(cwd);
|
|
@@ -2848,7 +3470,7 @@ function scan(cwd) {
|
|
|
2848
3470
|
}
|
|
2849
3471
|
const files = projectCodeRoots(cwd).flatMap((r) => walkCodeFiles(r));
|
|
2850
3472
|
for (const file of files) {
|
|
2851
|
-
const text =
|
|
3473
|
+
const text = readFileSync19(file, "utf8");
|
|
2852
3474
|
const rel2 = relative4(cwd, file);
|
|
2853
3475
|
const lines = text.split(/\r?\n/);
|
|
2854
3476
|
lines.forEach((line, i) => {
|
|
@@ -2930,7 +3552,7 @@ function scan(cwd) {
|
|
|
2930
3552
|
return false;
|
|
2931
3553
|
if (/theme(-light|-dark)?\.css$/.test(f))
|
|
2932
3554
|
return false;
|
|
2933
|
-
const t =
|
|
3555
|
+
const t = readFileSync19(f, "utf8");
|
|
2934
3556
|
return t.includes("--search-border:") && t.includes("--button-secondary-bg:") && t.includes("transparent");
|
|
2935
3557
|
});
|
|
2936
3558
|
if (toolbarMarkers.length > 1) {
|
|
@@ -2957,7 +3579,7 @@ function scan(cwd) {
|
|
|
2957
3579
|
"theme-dark.css",
|
|
2958
3580
|
"theme.css"
|
|
2959
3581
|
].map((f) => join14(styleDir, f));
|
|
2960
|
-
const themeText = themeFiles.filter(existsSync14).map((f) =>
|
|
3582
|
+
const themeText = themeFiles.filter(existsSync14).map((f) => readFileSync19(f, "utf8")).join(`
|
|
2961
3583
|
`);
|
|
2962
3584
|
if (themeText && !/--popup-shadow\s*:/.test(themeText) && /--date-popup-shadow\s*:|--select-background\s*:/.test(themeText)) {
|
|
2963
3585
|
out.push({
|
|
@@ -2979,7 +3601,7 @@ function scan(cwd) {
|
|
|
2979
3601
|
for (const file of files) {
|
|
2980
3602
|
if (!file.endsWith(".css"))
|
|
2981
3603
|
continue;
|
|
2982
|
-
const text =
|
|
3604
|
+
const text = readFileSync19(file, "utf8");
|
|
2983
3605
|
const relPath = relative4(cwd, file);
|
|
2984
3606
|
const lines = text.split(/\r?\n/);
|
|
2985
3607
|
lines.forEach((line, i) => {
|
|
@@ -2995,6 +3617,26 @@ function scan(cwd) {
|
|
|
2995
3617
|
fix: "elcrm migrate form-tokens"
|
|
2996
3618
|
});
|
|
2997
3619
|
}
|
|
3620
|
+
if (lineHasDeprecatedComponentsToken(line)) {
|
|
3621
|
+
out.push({
|
|
3622
|
+
level: "warn",
|
|
3623
|
+
code: "components-token-legacy",
|
|
3624
|
+
message: "legacy components-\u0442\u043E\u043A\u0435\u043D \u2192 --shell-*",
|
|
3625
|
+
file: relPath,
|
|
3626
|
+
line: i + 1,
|
|
3627
|
+
fix: "elcrm migrate components"
|
|
3628
|
+
});
|
|
3629
|
+
}
|
|
3630
|
+
if (lineHasOrphanColorMix(line)) {
|
|
3631
|
+
out.push({
|
|
3632
|
+
level: "error",
|
|
3633
|
+
code: "css-orphan-mix",
|
|
3634
|
+
message: "\u0431\u0438\u0442\u044B\u0439 CSS: \u0445\u0432\u043E\u0441\u0442 color-mix \u0431\u0435\u0437 \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430 (in srgb / transparent))",
|
|
3635
|
+
file: relPath,
|
|
3636
|
+
line: i + 1,
|
|
3637
|
+
fix: "elcrm migrate css-sanitize"
|
|
3638
|
+
});
|
|
3639
|
+
}
|
|
2998
3640
|
});
|
|
2999
3641
|
}
|
|
3000
3642
|
return out;
|
|
@@ -3108,7 +3750,7 @@ import {
|
|
|
3108
3750
|
existsSync as existsSync15,
|
|
3109
3751
|
mkdirSync as mkdirSync2,
|
|
3110
3752
|
readdirSync as readdirSync10,
|
|
3111
|
-
readFileSync as
|
|
3753
|
+
readFileSync as readFileSync20,
|
|
3112
3754
|
writeFileSync as writeFileSync8
|
|
3113
3755
|
} from "fs";
|
|
3114
3756
|
import { dirname as dirname3, join as join15 } from "path";
|
|
@@ -3126,7 +3768,7 @@ function readBundled(relPath) {
|
|
|
3126
3768
|
if (!existsSync15(full)) {
|
|
3127
3769
|
throw new Error(`\u0428\u0430\u0431\u043B\u043E\u043D \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D: ${relPath}`);
|
|
3128
3770
|
}
|
|
3129
|
-
return
|
|
3771
|
+
return readFileSync20(full, "utf8");
|
|
3130
3772
|
}
|
|
3131
3773
|
|
|
3132
3774
|
// src/commands/docs.ts
|
|
@@ -3153,8 +3795,13 @@ async function cmdDocs(parsed) {
|
|
|
3153
3795
|
|
|
3154
3796
|
// src/commands/cursor.ts
|
|
3155
3797
|
import { join as join17, resolve as resolve5 } from "path";
|
|
3156
|
-
var ALWAYS = ["elcrm.mdc", "elcrm-packages.mdc"];
|
|
3157
|
-
var UI = [
|
|
3798
|
+
var ALWAYS = ["elcrm.mdc", "elcrm-packages.mdc", "elcrm-jsdoc.mdc"];
|
|
3799
|
+
var UI = [
|
|
3800
|
+
"elcrm-ui.mdc",
|
|
3801
|
+
"elcrm-module.mdc",
|
|
3802
|
+
"elcrm-theme.mdc",
|
|
3803
|
+
"elcrm-tokens.mdc"
|
|
3804
|
+
];
|
|
3158
3805
|
var SERVER = ["elcrm-server.mdc", "elcrm-rpc.mdc"];
|
|
3159
3806
|
var LIB = ["elcrm-lib.mdc"];
|
|
3160
3807
|
function writeOne(dest, body, dry, force, label) {
|
|
@@ -3199,7 +3846,7 @@ function cliVersion() {
|
|
|
3199
3846
|
join18(here, "package.json")
|
|
3200
3847
|
]) {
|
|
3201
3848
|
try {
|
|
3202
|
-
const v = JSON.parse(
|
|
3849
|
+
const v = JSON.parse(readFileSync21(p, "utf8")).version;
|
|
3203
3850
|
if (typeof v === "string" && v)
|
|
3204
3851
|
return v;
|
|
3205
3852
|
} catch {}
|
|
@@ -3217,7 +3864,8 @@ function showHelp() {
|
|
|
3217
3864
|
|
|
3218
3865
|
\u041A\u043E\u043C\u0430\u043D\u0434\u044B:
|
|
3219
3866
|
update [--dry] [--core] [--no-install] [--fix] [--test]
|
|
3220
|
-
\
|
|
3867
|
+
CLI (bun i -g elcrm@latest) + \u0432\u0441\u0435 @elcrm/* \u0432 \u043F\u0440\u043E\u0435\u043A\u0442\u0435 \u0434\u043E latest
|
|
3868
|
+
--fix = migrate front; --test = elcrm test
|
|
3221
3869
|
\u0420\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0443\u0435\u0442\u0441\u044F: elcrm update --fix --test
|
|
3222
3870
|
|
|
3223
3871
|
create <name> [--template app|lib|panel] [--no-install]
|
|
@@ -3229,7 +3877,7 @@ function showHelp() {
|
|
|
3229
3877
|
|
|
3230
3878
|
migrate <name> [--dry]
|
|
3231
3879
|
migrate --list
|
|
3232
|
-
\u041C\u0438\u0433\u0440\u0430\u0446\u0438\u0438: front|ui, form-aliases, form-tokens, size-sml, field-border, modal-create, legacy-hacks, socket-server
|
|
3880
|
+
\u041C\u0438\u0433\u0440\u0430\u0446\u0438\u0438: front|ui, form-aliases, form-tokens, components, css-sanitize, size-sml, field-border, modal-create, legacy-hacks, socket-server
|
|
3233
3881
|
|
|
3234
3882
|
audit [--fix] [--dry] [--dir=\u2026]
|
|
3235
3883
|
\u0423\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0439 API + CSS-\u0442\u043E\u043A\u0435\u043D\u044B form (padding-\u0430\u043B\u0438\u0430\u0441\u044B, popup-shadow, border shorthand)
|