elcrm 1.1.38 → 1.1.39
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
CHANGED
|
@@ -1304,10 +1304,10 @@ function inspectPkgCss(pkgName, cwd) {
|
|
|
1304
1304
|
return null;
|
|
1305
1305
|
const pkg = readPkgJson(root);
|
|
1306
1306
|
const exp = pkg?.exports;
|
|
1307
|
-
const abs = (
|
|
1307
|
+
const abs = (rel) => rel ? join5(root, rel.replace(/^\.\//, "")) : undefined;
|
|
1308
1308
|
const fileIfExists = (key) => {
|
|
1309
|
-
const
|
|
1310
|
-
const a = abs(
|
|
1309
|
+
const rel = exportPath(exp, key);
|
|
1310
|
+
const a = abs(rel);
|
|
1311
1311
|
return a && existsSync5(a) ? a : undefined;
|
|
1312
1312
|
};
|
|
1313
1313
|
return {
|
|
@@ -1330,10 +1330,10 @@ function resolveElcrmCssImport(spec, cwd) {
|
|
|
1330
1330
|
if (!root)
|
|
1331
1331
|
return null;
|
|
1332
1332
|
const pkg = readPkgJson(root);
|
|
1333
|
-
const
|
|
1334
|
-
if (!
|
|
1333
|
+
const rel = exportPath(pkg?.exports, `./${sub}`);
|
|
1334
|
+
if (!rel)
|
|
1335
1335
|
return null;
|
|
1336
|
-
const abs = join5(root,
|
|
1336
|
+
const abs = join5(root, rel.replace(/^\.\//, ""));
|
|
1337
1337
|
return existsSync5(abs) ? abs : null;
|
|
1338
1338
|
}
|
|
1339
1339
|
function pruneBrokenElcrmImports(css, cwd) {
|
|
@@ -1628,6 +1628,8 @@ function checkElcrmTokenCoverage(options) {
|
|
|
1628
1628
|
const used = new Set;
|
|
1629
1629
|
for (const file of styleFiles) {
|
|
1630
1630
|
const css = readFileSync7(file, "utf8");
|
|
1631
|
+
for (const k of parseCustomProps(css).keys())
|
|
1632
|
+
defined.add(k);
|
|
1631
1633
|
for (const m of css.matchAll(/var\(\s*(--[a-zA-Z0-9-]+)/g)) {
|
|
1632
1634
|
used.add(m[1]);
|
|
1633
1635
|
}
|
|
@@ -1640,6 +1642,9 @@ function checkElcrmTokenCoverage(options) {
|
|
|
1640
1642
|
continue;
|
|
1641
1643
|
if (/^--tooltip-arrow-/.test(token))
|
|
1642
1644
|
continue;
|
|
1645
|
+
if (token === "--alpha-color" || token === "--preview-color" || token === "--swatch") {
|
|
1646
|
+
continue;
|
|
1647
|
+
}
|
|
1643
1648
|
gaps.push({ pkg: pkgName, token });
|
|
1644
1649
|
}
|
|
1645
1650
|
}
|
|
@@ -1757,7 +1762,7 @@ async function migrateSocketServer(cwd, dry) {
|
|
|
1757
1762
|
pkg.dependencies["@elcrm/server"] = ver;
|
|
1758
1763
|
}
|
|
1759
1764
|
}
|
|
1760
|
-
if (!dry && changes.some((
|
|
1765
|
+
if (!dry && changes.some((c) => c.file === "package.json")) {
|
|
1761
1766
|
writePackageJson(pkg, cwd);
|
|
1762
1767
|
}
|
|
1763
1768
|
}
|
|
@@ -2199,25 +2204,25 @@ function sliceAttrValue(attrs, eqIndex) {
|
|
|
2199
2204
|
let brace = 0;
|
|
2200
2205
|
let quote = null;
|
|
2201
2206
|
while (i < attrs.length) {
|
|
2202
|
-
const
|
|
2207
|
+
const c = attrs[i];
|
|
2203
2208
|
if (quote) {
|
|
2204
|
-
if (
|
|
2209
|
+
if (c === "\\" && quote === '"') {
|
|
2205
2210
|
i += 2;
|
|
2206
2211
|
continue;
|
|
2207
2212
|
}
|
|
2208
|
-
if (
|
|
2213
|
+
if (c === quote)
|
|
2209
2214
|
quote = null;
|
|
2210
2215
|
i++;
|
|
2211
2216
|
continue;
|
|
2212
2217
|
}
|
|
2213
|
-
if (
|
|
2214
|
-
quote =
|
|
2218
|
+
if (c === '"' || c === "'") {
|
|
2219
|
+
quote = c;
|
|
2215
2220
|
i++;
|
|
2216
2221
|
continue;
|
|
2217
2222
|
}
|
|
2218
|
-
if (
|
|
2223
|
+
if (c === "{")
|
|
2219
2224
|
brace++;
|
|
2220
|
-
else if (
|
|
2225
|
+
else if (c === "}") {
|
|
2221
2226
|
brace--;
|
|
2222
2227
|
if (brace === 0) {
|
|
2223
2228
|
i++;
|
|
@@ -2476,8 +2481,8 @@ async function migrateFrontAll(cwd, dry) {
|
|
|
2476
2481
|
const all = [];
|
|
2477
2482
|
for (const name of FRONT_MIGRATE_ORDER) {
|
|
2478
2483
|
const part = await FRONT_MIGRATIONS[name](cwd, dry);
|
|
2479
|
-
for (const
|
|
2480
|
-
all.push({ file:
|
|
2484
|
+
for (const c of part) {
|
|
2485
|
+
all.push({ file: c.file, detail: `[${name}] ${c.detail}` });
|
|
2481
2486
|
}
|
|
2482
2487
|
}
|
|
2483
2488
|
return all;
|
|
@@ -2591,12 +2596,12 @@ import { resolve } from "path";
|
|
|
2591
2596
|
import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync16, statSync as statSync5 } from "fs";
|
|
2592
2597
|
import { join as join8, relative as relative2 } from "path";
|
|
2593
2598
|
var SKIP = new Set(["node_modules", "dist", ".git", "coverage", ".bun"]);
|
|
2594
|
-
function isThemeTokenFile(
|
|
2595
|
-
const n =
|
|
2599
|
+
function isThemeTokenFile(rel) {
|
|
2600
|
+
const n = rel.replace(/\\/g, "/");
|
|
2596
2601
|
return /(?:^|\/)(?:theme(?:-light|-dark)?|elcrm)\.css$/.test(n);
|
|
2597
2602
|
}
|
|
2598
|
-
function isGeneratedIcons(
|
|
2599
|
-
return /icons\.generated\.(tsx?|jsx?)$/.test(
|
|
2603
|
+
function isGeneratedIcons(rel) {
|
|
2604
|
+
return /icons\.generated\.(tsx?|jsx?)$/.test(rel.replace(/\\/g, "/"));
|
|
2600
2605
|
}
|
|
2601
2606
|
var HARD_HEX_RE = /#[0-9a-fA-F]{3,8}\b/;
|
|
2602
2607
|
var HARD_RGB_RE = /\b(?:rgb|rgba|hsl|hsla)\s*\(/i;
|
|
@@ -2739,14 +2744,14 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2739
2744
|
}
|
|
2740
2745
|
for (const file of files) {
|
|
2741
2746
|
const text = readFileSync16(file, "utf8");
|
|
2742
|
-
const
|
|
2743
|
-
const skipHardColor = isLib || isThemeTokenFile(
|
|
2747
|
+
const rel = relative2(cwd, file);
|
|
2748
|
+
const skipHardColor = isLib || isThemeTokenFile(rel) || isGeneratedIcons(rel);
|
|
2744
2749
|
if (DEPRECATED_SOCKET_IMPORT_RE.test(text)) {
|
|
2745
2750
|
issues.push({
|
|
2746
2751
|
level: "error",
|
|
2747
2752
|
code: "deprecated-import",
|
|
2748
2753
|
message: "\u0438\u043C\u043F\u043E\u0440\u0442 @elcrm/socket/server \u0438\u043B\u0438 socket-server",
|
|
2749
|
-
file:
|
|
2754
|
+
file: rel,
|
|
2750
2755
|
fixable: true
|
|
2751
2756
|
});
|
|
2752
2757
|
}
|
|
@@ -2758,13 +2763,13 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2758
2763
|
level: "error",
|
|
2759
2764
|
code: "themes-css",
|
|
2760
2765
|
message: "import \u2026/themes.css \u0443\u0441\u0442\u0430\u0440\u0435\u043B \u2014 \u0442\u043E\u043A\u0435\u043D\u044B \u0437\u0430\u0434\u0430\u0451\u0442 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 (elcrm-theme / theme.css)",
|
|
2761
|
-
file:
|
|
2766
|
+
file: rel,
|
|
2762
2767
|
line
|
|
2763
2768
|
});
|
|
2764
2769
|
}
|
|
2765
2770
|
if (LEGACY_PASSKEY_IMPORT_RE.test(text) && LEGACY_PASSKEY_SYMBOL_RE.test(text)) {
|
|
2766
|
-
const
|
|
2767
|
-
|
|
2771
|
+
const lines = text.split(/\r?\n/);
|
|
2772
|
+
lines.forEach((line, i) => {
|
|
2768
2773
|
if (/\bcreatePasskey\b/.test(line) || /\bauthenticateWithPasskey\b/.test(line)) {
|
|
2769
2774
|
if (pkg.name === "@elcrm/passkey")
|
|
2770
2775
|
return;
|
|
@@ -2772,7 +2777,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2772
2777
|
level: "error",
|
|
2773
2778
|
code: "legacy-passkey-api",
|
|
2774
2779
|
message: "createPasskey / authenticateWithPasskey \u043D\u0435 \u044D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u044E\u0442\u0441\u044F \u2014 createPasskeyClient",
|
|
2775
|
-
file:
|
|
2780
|
+
file: rel,
|
|
2776
2781
|
line: i + 1
|
|
2777
2782
|
});
|
|
2778
2783
|
}
|
|
@@ -2791,19 +2796,19 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2791
2796
|
level: "error",
|
|
2792
2797
|
code: "native-html-input",
|
|
2793
2798
|
message: "\u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0439 <input|textarea|select> \u2014 @elcrm/form (elcrm migrate native-html)",
|
|
2794
|
-
file:
|
|
2799
|
+
file: rel,
|
|
2795
2800
|
line: i + 1,
|
|
2796
2801
|
fixable: true
|
|
2797
2802
|
});
|
|
2798
2803
|
}
|
|
2799
2804
|
}
|
|
2800
|
-
if (!/(^|\/)pages\/Auth\.tsx$/.test(
|
|
2805
|
+
if (!/(^|\/)pages\/Auth\.tsx$/.test(rel.replace(/\\/g, "/")) && /(?:^|\s)native(?:\s|$|=|\/|>)/.test(line) && !/\bnavigator\b|\bnativeEvent\b|\bcreateNative/.test(line) && !/['"`]native['"`]/.test(line) && !(/\binstallMode\b/.test(line) && /\bnative\b/.test(line))) {
|
|
2801
2806
|
if (pkg.name !== "@elcrm/form") {
|
|
2802
2807
|
issues.push({
|
|
2803
2808
|
level: "warn",
|
|
2804
2809
|
code: "form-native-prop",
|
|
2805
2810
|
message: "prop native \u0443 \u043F\u043E\u043B\u044F \u0444\u043E\u0440\u043C\u044B \u2014 \u0443\u0431\u0435\u0440\u0438\u0442\u0435 (elcrm migrate form-native)",
|
|
2806
|
-
file:
|
|
2811
|
+
file: rel,
|
|
2807
2812
|
line: i + 1,
|
|
2808
2813
|
fixable: true
|
|
2809
2814
|
});
|
|
@@ -2814,7 +2819,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2814
2819
|
level: "warn",
|
|
2815
2820
|
code: "size-legacy",
|
|
2816
2821
|
message: 'size="sm"|"md" \u0443\u0441\u0442\u0430\u0440\u0435\u043B\u043E \u2014 "s"|"m" (elcrm migrate size-sml)',
|
|
2817
|
-
file:
|
|
2822
|
+
file: rel,
|
|
2818
2823
|
line: i + 1,
|
|
2819
2824
|
fixable: true
|
|
2820
2825
|
});
|
|
@@ -2824,7 +2829,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2824
2829
|
level: "warn",
|
|
2825
2830
|
code: "modal-add",
|
|
2826
2831
|
message: "Modal.Add \u2014 Modal.Create + Open (elcrm migrate modal-create)",
|
|
2827
|
-
file:
|
|
2832
|
+
file: rel,
|
|
2828
2833
|
line: i + 1,
|
|
2829
2834
|
fixable: true
|
|
2830
2835
|
});
|
|
@@ -2834,7 +2839,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2834
2839
|
level: "error",
|
|
2835
2840
|
code: "field-border-shorthand",
|
|
2836
2841
|
message: "field-border hover/focus/disabled \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0446\u0432\u0435\u0442 (elcrm migrate field-border)",
|
|
2837
|
-
file:
|
|
2842
|
+
file: rel,
|
|
2838
2843
|
line: i + 1,
|
|
2839
2844
|
fixable: true
|
|
2840
2845
|
});
|
|
@@ -2844,7 +2849,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2844
2849
|
level: "warn",
|
|
2845
2850
|
code: "form-token-legacy",
|
|
2846
2851
|
message: "legacy padding/shadow-\u0442\u043E\u043A\u0435\u043D \u2192 --field-padding* / --popup-shadow (elcrm migrate form-tokens)",
|
|
2847
|
-
file:
|
|
2852
|
+
file: rel,
|
|
2848
2853
|
line: i + 1,
|
|
2849
2854
|
fixable: true
|
|
2850
2855
|
});
|
|
@@ -2854,7 +2859,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2854
2859
|
level: "warn",
|
|
2855
2860
|
code: "components-token-legacy",
|
|
2856
2861
|
message: "legacy \u0442\u043E\u043A\u0435\u043D @elcrm/components \u2192 --shell-* (elcrm migrate components)",
|
|
2857
|
-
file:
|
|
2862
|
+
file: rel,
|
|
2858
2863
|
line: i + 1,
|
|
2859
2864
|
fixable: true
|
|
2860
2865
|
});
|
|
@@ -2864,7 +2869,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2864
2869
|
level: "error",
|
|
2865
2870
|
code: "css-orphan-mix",
|
|
2866
2871
|
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",
|
|
2867
|
-
file:
|
|
2872
|
+
file: rel,
|
|
2868
2873
|
line: i + 1,
|
|
2869
2874
|
fixable: true
|
|
2870
2875
|
});
|
|
@@ -2877,7 +2882,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2877
2882
|
level: "warn",
|
|
2878
2883
|
code: "components-stack",
|
|
2879
2884
|
message: "Block/Row/Column \u0443\u0441\u0442\u0430\u0440\u0435\u043B\u0438 \u2014 Stack (elcrm migrate components)",
|
|
2880
|
-
file:
|
|
2885
|
+
file: rel,
|
|
2881
2886
|
line: i + 1,
|
|
2882
2887
|
fixable: true
|
|
2883
2888
|
});
|
|
@@ -2888,7 +2893,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2888
2893
|
level: "warn",
|
|
2889
2894
|
code: "components-value",
|
|
2890
2895
|
message: "activeKey/defaultActiveKey \u2192 value/defaultValue (elcrm migrate components)",
|
|
2891
|
-
file:
|
|
2896
|
+
file: rel,
|
|
2892
2897
|
line: i + 1,
|
|
2893
2898
|
fixable: true
|
|
2894
2899
|
});
|
|
@@ -2900,7 +2905,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2900
2905
|
level: "warn",
|
|
2901
2906
|
code: "hardcoded-color",
|
|
2902
2907
|
message: why,
|
|
2903
|
-
file:
|
|
2908
|
+
file: rel,
|
|
2904
2909
|
line: i + 1
|
|
2905
2910
|
});
|
|
2906
2911
|
}
|
|
@@ -3290,7 +3295,7 @@ function walkFiles2(root, dir, out) {
|
|
|
3290
3295
|
function scanCodeFile(root, file, text) {
|
|
3291
3296
|
const findings = [];
|
|
3292
3297
|
const lines = text.split(/\r?\n/);
|
|
3293
|
-
const
|
|
3298
|
+
const rel = relative3(root, file) || file;
|
|
3294
3299
|
for (const rule of CODE_RULES) {
|
|
3295
3300
|
lines.forEach((line, i) => {
|
|
3296
3301
|
rule.test.lastIndex = 0;
|
|
@@ -3301,7 +3306,7 @@ function scanCodeFile(root, file, text) {
|
|
|
3301
3306
|
findings.push({
|
|
3302
3307
|
ruleId: rule.id,
|
|
3303
3308
|
severity: rule.severity,
|
|
3304
|
-
file:
|
|
3309
|
+
file: rel,
|
|
3305
3310
|
line: i + 1,
|
|
3306
3311
|
match: (m?.[0] ?? line).trim().slice(0, 120),
|
|
3307
3312
|
message: rule.message,
|
|
@@ -3314,7 +3319,7 @@ function scanCodeFile(root, file, text) {
|
|
|
3314
3319
|
}
|
|
3315
3320
|
function scanPackageJson(root, file, text) {
|
|
3316
3321
|
const findings = [];
|
|
3317
|
-
const
|
|
3322
|
+
const rel = relative3(root, file) || file;
|
|
3318
3323
|
let pkg;
|
|
3319
3324
|
try {
|
|
3320
3325
|
pkg = JSON.parse(text);
|
|
@@ -3327,7 +3332,7 @@ function scanPackageJson(root, file, text) {
|
|
|
3327
3332
|
findings.push({
|
|
3328
3333
|
ruleId: `pkg-${name}`,
|
|
3329
3334
|
severity: "error",
|
|
3330
|
-
file:
|
|
3335
|
+
file: rel,
|
|
3331
3336
|
line: 1,
|
|
3332
3337
|
match: `"${name}": "${deps[name]}"`,
|
|
3333
3338
|
message: `\u0417\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u044C ${name} \u2192 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 @elcrm/server (+ subpath)`,
|
|
@@ -3340,7 +3345,7 @@ function scanPackageJson(root, file, text) {
|
|
|
3340
3345
|
findings.push({
|
|
3341
3346
|
ruleId: "pkg-need-server",
|
|
3342
3347
|
severity: "error",
|
|
3343
|
-
file:
|
|
3348
|
+
file: rel,
|
|
3344
3349
|
line: 1,
|
|
3345
3350
|
match: "missing @elcrm/server",
|
|
3346
3351
|
message: "\u041D\u0443\u0436\u043D\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u044C @elcrm/server",
|
|
@@ -3792,8 +3797,8 @@ async function cmdMigrate(parsed) {
|
|
|
3792
3797
|
if (hasFlag(parsed, "list") || parsed.positionals[0] === "list") {
|
|
3793
3798
|
console.log("\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u043C\u0438\u0433\u0440\u0430\u0446\u0438\u0438:");
|
|
3794
3799
|
console.log(" front | ui \u043F\u0430\u043A\u0435\u0442 \u0444\u0440\u043E\u043D\u0442\u043E\u0432\u044B\u0445 \u043C\u0438\u0433\u0440\u0430\u0446\u0438\u0439:");
|
|
3795
|
-
for (const
|
|
3796
|
-
console.log(` - ${
|
|
3800
|
+
for (const name of FRONT_MIGRATE_ORDER) {
|
|
3801
|
+
console.log(` - ${name}`);
|
|
3797
3802
|
}
|
|
3798
3803
|
console.log(" socket-server (\u0442\u0430\u043A\u0436\u0435 \u0432 front)");
|
|
3799
3804
|
return;
|
|
@@ -3819,8 +3824,8 @@ async function cmdMigrate(parsed) {
|
|
|
3819
3824
|
console.log("\u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439 \u043D\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F.");
|
|
3820
3825
|
return;
|
|
3821
3826
|
}
|
|
3822
|
-
for (const
|
|
3823
|
-
console.log(` ${
|
|
3827
|
+
for (const c of changes) {
|
|
3828
|
+
console.log(` ${c.file}: ${c.detail}`);
|
|
3824
3829
|
}
|
|
3825
3830
|
console.log(dry ? `
|
|
3826
3831
|
--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.` : `
|
|
@@ -4192,8 +4197,8 @@ function emitKitManifest(cwd) {
|
|
|
4192
4197
|
throw new Error(`elcrm kit emit \u2014 \u043F\u0430\u043A\u0435\u0442 ${pkg.name} \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F (\u043D\u0443\u0436\u0435\u043D components|form)`);
|
|
4193
4198
|
}
|
|
4194
4199
|
const distDir = join15(cwd, "dist");
|
|
4195
|
-
const components = scanDistComponents(distDir, pkg.name).map((
|
|
4196
|
-
...
|
|
4200
|
+
const components = scanDistComponents(distDir, pkg.name).map((c) => ({
|
|
4201
|
+
...c,
|
|
4197
4202
|
importFrom: pkg.name
|
|
4198
4203
|
}));
|
|
4199
4204
|
return {
|
|
@@ -4750,14 +4755,14 @@ async function cmdCss(parsed) {
|
|
|
4750
4755
|
console.log(`${dry || checkOnly ? "[check/dry] " : ""}\u041F\u0430\u043A\u0435\u0442\u044B: ${names.join(", ")}`);
|
|
4751
4756
|
try {
|
|
4752
4757
|
if (checkOnly) {
|
|
4753
|
-
const
|
|
4754
|
-
console.log(`\u041A\u0430\u0442\u0430\u043B\u043E\u0433 \u0441\u0442\u0438\u043B\u0435\u0439: ${
|
|
4755
|
-
if (!
|
|
4758
|
+
const cov = checkElcrmTokenCoverage({ cwd, pkgNames: names });
|
|
4759
|
+
console.log(`\u041A\u0430\u0442\u0430\u043B\u043E\u0433 \u0441\u0442\u0438\u043B\u0435\u0439: ${cov.styleDir ?? "(\u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D)"} \xB7 \u043F\u0440\u043E\u0432\u0435\u0440\u0435\u043D\u043E var(): ${cov.checked}`);
|
|
4760
|
+
if (!cov.gaps.length) {
|
|
4756
4761
|
console.log(c.green("\u041F\u043E\u043A\u0440\u044B\u0442\u0438\u0435 \u0442\u043E\u043A\u0435\u043D\u043E\u0432 OK."));
|
|
4757
4762
|
return;
|
|
4758
4763
|
}
|
|
4759
|
-
console.error(`${c.red("\u041F\u0440\u043E\u0431\u0435\u043B\u044B:")} ${
|
|
4760
|
-
for (const g of
|
|
4764
|
+
console.error(`${c.red("\u041F\u0440\u043E\u0431\u0435\u043B\u044B:")} ${cov.gaps.length} (\u043D\u0435\u0442 \u0432 theme*/\u043F\u0430\u043A\u0435\u0442\u0435 light|dark|tokens)`);
|
|
4765
|
+
for (const g of cov.gaps) {
|
|
4761
4766
|
console.error(` ${c.dim(g.pkg)} ${g.token}`);
|
|
4762
4767
|
}
|
|
4763
4768
|
process.exit(1);
|
|
@@ -4853,7 +4858,7 @@ function scan(cwd) {
|
|
|
4853
4858
|
const files = projectCodeRoots(cwd).flatMap((r) => walkCodeFiles(r));
|
|
4854
4859
|
for (const file of files) {
|
|
4855
4860
|
const text = readFileSync27(file, "utf8");
|
|
4856
|
-
const
|
|
4861
|
+
const rel = relative4(cwd, file);
|
|
4857
4862
|
const lines = text.split(/\r?\n/);
|
|
4858
4863
|
lines.forEach((line, i) => {
|
|
4859
4864
|
const n = i + 1;
|
|
@@ -4864,7 +4869,7 @@ function scan(cwd) {
|
|
|
4864
4869
|
level: "warn",
|
|
4865
4870
|
code: "size-legacy",
|
|
4866
4871
|
message: 'size="sm"|"md" \u2192 "s"|"m"',
|
|
4867
|
-
file:
|
|
4872
|
+
file: rel,
|
|
4868
4873
|
line: n,
|
|
4869
4874
|
fix: "elcrm migrate size-sml"
|
|
4870
4875
|
});
|
|
@@ -4874,7 +4879,7 @@ function scan(cwd) {
|
|
|
4874
4879
|
level: "warn",
|
|
4875
4880
|
code: "modal-add",
|
|
4876
4881
|
message: "Modal.Add \u2014 \u043F\u0440\u0435\u0434\u043F\u043E\u0447\u0442\u0438\u0442\u0435\u043B\u0435\u043D Modal.Create + Open",
|
|
4877
|
-
file:
|
|
4882
|
+
file: rel,
|
|
4878
4883
|
line: n,
|
|
4879
4884
|
fix: "elcrm migrate modal-create"
|
|
4880
4885
|
});
|
|
@@ -4884,7 +4889,7 @@ function scan(cwd) {
|
|
|
4884
4889
|
level: "error",
|
|
4885
4890
|
code: "native-html-input",
|
|
4886
4891
|
message: "\u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0439 <input|textarea|select> \u2192 @elcrm/form",
|
|
4887
|
-
file:
|
|
4892
|
+
file: rel,
|
|
4888
4893
|
line: n,
|
|
4889
4894
|
fix: "elcrm migrate native-html"
|
|
4890
4895
|
});
|
|
@@ -4894,7 +4899,7 @@ function scan(cwd) {
|
|
|
4894
4899
|
level: "warn",
|
|
4895
4900
|
code: "form-native-prop",
|
|
4896
4901
|
message: "prop native \u0443 \u043F\u043E\u043B\u044F \u0444\u043E\u0440\u043C\u044B \u2014 \u0443\u0431\u0435\u0440\u0438\u0442\u0435",
|
|
4897
|
-
file:
|
|
4902
|
+
file: rel,
|
|
4898
4903
|
line: n,
|
|
4899
4904
|
fix: "elcrm migrate form-native"
|
|
4900
4905
|
});
|
|
@@ -4904,7 +4909,7 @@ function scan(cwd) {
|
|
|
4904
4909
|
level: "info",
|
|
4905
4910
|
code: "modal-date-key",
|
|
4906
4911
|
message: "key={Date.now()} \u0443 \u043C\u043E\u0434\u0430\u043B\u043A\u0438 \u2014 Create \u0437\u0430\u0434\u0430\u0451\u0442 \u0441\u0442\u0430\u0431\u0438\u043B\u044C\u043D\u044B\u0439 name",
|
|
4907
|
-
file:
|
|
4912
|
+
file: rel,
|
|
4908
4913
|
line: n
|
|
4909
4914
|
});
|
|
4910
4915
|
}
|
|
@@ -4913,17 +4918,17 @@ function scan(cwd) {
|
|
|
4913
4918
|
level: "error",
|
|
4914
4919
|
code: "field-border-shorthand",
|
|
4915
4920
|
message: "hover/focus border \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0446\u0432\u0435\u0442, \u043D\u0435 shorthand",
|
|
4916
|
-
file:
|
|
4921
|
+
file: rel,
|
|
4917
4922
|
line: n,
|
|
4918
4923
|
fix: "elcrm migrate field-border"
|
|
4919
4924
|
});
|
|
4920
4925
|
}
|
|
4921
|
-
if (/!important/.test(line) && /drag|file-upload|DragDrop/i.test(
|
|
4926
|
+
if (/!important/.test(line) && /drag|file-upload|DragDrop/i.test(rel + line)) {
|
|
4922
4927
|
out.push({
|
|
4923
4928
|
level: "info",
|
|
4924
4929
|
code: "dragdrop-important",
|
|
4925
4930
|
message: '!important \u0443 DragDrop \u2014 layout="fill"|"overlay" \u0432 @elcrm/form',
|
|
4926
|
-
file:
|
|
4931
|
+
file: rel,
|
|
4927
4932
|
line: n
|
|
4928
4933
|
});
|
|
4929
4934
|
}
|
|
@@ -4932,7 +4937,7 @@ function scan(cwd) {
|
|
|
4932
4937
|
level: "warn",
|
|
4933
4938
|
code: "react-global",
|
|
4934
4939
|
message: "globalThis.React \u0445\u0430\u043A \u2014 migrate legacy-hacks / \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u0435 modal",
|
|
4935
|
-
file:
|
|
4940
|
+
file: rel,
|
|
4936
4941
|
line: n,
|
|
4937
4942
|
fix: "elcrm migrate legacy-hacks"
|
|
4938
4943
|
});
|
|
@@ -4942,7 +4947,7 @@ function scan(cwd) {
|
|
|
4942
4947
|
level: "error",
|
|
4943
4948
|
code: "form-alias",
|
|
4944
4949
|
message: "\u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0439 \u0430\u043B\u0438\u0430\u0441 @elcrm/form (ProgressField/OtpField/\u2026) \u2192 \u043A\u0430\u043D\u043E\u043D",
|
|
4945
|
-
file:
|
|
4950
|
+
file: rel,
|
|
4946
4951
|
line: n,
|
|
4947
4952
|
fix: "elcrm migrate form-aliases"
|
|
4948
4953
|
});
|
package/package.json
CHANGED
|
@@ -107,6 +107,7 @@ import type { PricingPlan, HealthmapData, NavTreeItem } from "@elcrm/components"
|
|
|
107
107
|
|
|
108
108
|
- `--layout-height` — высота каркаса `Layout` при `fixed` (по умолчанию `100dvh`).
|
|
109
109
|
- `--layout-padding` / `--layout-margin` / `--layout-max-width` — отступы и макс. ширина корня Layout (`0` / `none` = на весь вьюпорт).
|
|
110
|
+
- `--layout-main-padding` — padding у `<main>` (`.slm`): сверху/снизу между шапкой и контентом (`0` по умолчанию; например `16px 0`).
|
|
110
111
|
- `--header-border` — рамка Header (shorthand: все стороны и толщина). Только снизу: `none` + линия через `--header-shadow`.
|
|
111
112
|
- `--header-nav-justify` — выравнивание `nav` в шапке (`flex-start` / `center` / `flex-end`).
|
|
112
113
|
- `<Toolbar size="s" width="l" align="start">` — один размер для Search / `*Field` / Button / Dropdown. `width="s"` — ряд по контенту. Свой `size` у ребёнка важнее.
|
|
@@ -243,6 +244,7 @@ elcrm cursor
|
|
|
243
244
|
| `--item-column-title-size` | geometry | `var(--shell-font-size)` |
|
|
244
245
|
| `--layout-gap` | geometry | `0` |
|
|
245
246
|
| `--layout-height` | geometry | `100dvh` |
|
|
247
|
+
| `--layout-main-padding` | geometry | `0` |
|
|
246
248
|
| `--layout-main-radius` | geometry | `0` |
|
|
247
249
|
| `--layout-margin` | geometry | `0` |
|
|
248
250
|
| `--layout-max-width` | geometry | `none` |
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
--control-height-l: 48px;
|
|
29
29
|
--control-radius: 10px;
|
|
30
30
|
--control-font-size: 15px;
|
|
31
|
+
--control-font-size-s: 0.8125rem;
|
|
31
32
|
--field-height: var(--control-height);
|
|
32
33
|
--field-width: 100%;
|
|
33
34
|
/* единый padding капсулы (size s|m|l → через --field-height) */
|
|
@@ -69,6 +70,8 @@
|
|
|
69
70
|
--layout-main-background: transparent;
|
|
70
71
|
--layout-main-shadow: none;
|
|
71
72
|
--layout-main-border: none;
|
|
73
|
+
/* padding <main>: сверху/снизу между шапкой и контентом */
|
|
74
|
+
--layout-main-padding: 0;
|
|
72
75
|
/* none — на всю ширину; иначе например 1440px */
|
|
73
76
|
--layout-max-width: none;
|
|
74
77
|
--elcrm-z-popover: 1000;
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
--control-height-l: 48px;
|
|
29
29
|
--control-radius: 10px;
|
|
30
30
|
--control-font-size: 15px;
|
|
31
|
+
--control-font-size-s: 0.8125rem;
|
|
31
32
|
--field-height: var(--control-height);
|
|
32
33
|
--field-width: 100%;
|
|
33
34
|
/* единый padding капсулы (size s|m|l → через --field-height) */
|
|
@@ -69,6 +70,8 @@
|
|
|
69
70
|
--layout-main-background: transparent;
|
|
70
71
|
--layout-main-shadow: none;
|
|
71
72
|
--layout-main-border: none;
|
|
73
|
+
/* padding <main>: сверху/снизу между шапкой и контентом */
|
|
74
|
+
--layout-main-padding: 0;
|
|
72
75
|
/* none — на всю ширину; иначе например 1440px */
|
|
73
76
|
--layout-max-width: none;
|
|
74
77
|
--elcrm-z-popover: 1000;
|