elcrm 1.1.36 → 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/README.md +1 -0
- package/dist/index.js +503 -137
- package/dist/vite/check-tokens.js +2 -2
- package/package.json +1 -1
- package/templates/elcrm-cursor/rules/elcrm-lib.mdc +9 -0
- package/templates/elcrm-cursor/rules/elcrm-packages.mdc +2 -0
- package/templates/elcrm-docs/ALERT.elCRM.md +26 -0
- package/templates/elcrm-docs/API.elCRM.md +7 -0
- package/templates/elcrm-docs/BUTTON.elCRM.md +7 -0
- package/templates/elcrm-docs/CLI.elCRM.md +23 -2
- package/templates/elcrm-docs/COMPONENTS.elCRM.md +216 -1
- package/templates/elcrm-docs/FORM.elCRM.md +140 -0
- package/templates/elcrm-docs/ICONS.elCRM.md +7 -0
- package/templates/elcrm-docs/MODAL.elCRM.md +7 -0
- package/templates/elcrm-docs/NOTICE.elCRM.md +73 -0
- package/templates/elcrm-docs/NOTIFICATIONS.elCRM.md +35 -0
- package/templates/elcrm-docs/PASSKEY.elCRM.md +7 -0
- package/templates/elcrm-docs/ROUTER.elCRM.md +7 -0
- package/templates/elcrm-docs/SEARCH.elCRM.md +88 -0
- package/templates/elcrm-docs/SERVER.elCRM.md +7 -0
- package/templates/elcrm-docs/SOCKET.elCRM.md +7 -0
- package/templates/elcrm-docs/TOOLTIP.elCRM.md +7 -0
- package/templates/elcrm-docs/generated/tokens.json +3429 -0
- package/templates/orbit/web/package.json +4 -2
- package/templates/orbit/web/src/style/theme.css +3 -0
- package/templates/panel/web/package.json +4 -2
- package/templates/panel/web/src/style/theme.css +3 -0
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// @bun
|
|
3
3
|
|
|
4
4
|
// src/index.ts
|
|
5
|
-
import { readFileSync as
|
|
6
|
-
import { dirname as
|
|
5
|
+
import { readFileSync as readFileSync30 } from "fs";
|
|
6
|
+
import { dirname as dirname5, join as join27 } from "path";
|
|
7
7
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
8
8
|
|
|
9
9
|
// src/parseArgs.ts
|
|
@@ -40,7 +40,8 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
40
40
|
"web",
|
|
41
41
|
"access",
|
|
42
42
|
"tag",
|
|
43
|
-
"otp"
|
|
43
|
+
"otp",
|
|
44
|
+
"pkgs"
|
|
44
45
|
]);
|
|
45
46
|
if (valueOpts.has(body)) {
|
|
46
47
|
options[body] = next;
|
|
@@ -1247,11 +1248,6 @@ function isColorToken(name, value) {
|
|
|
1247
1248
|
return true;
|
|
1248
1249
|
return false;
|
|
1249
1250
|
}
|
|
1250
|
-
function isButtonShadowNoise(name, value) {
|
|
1251
|
-
if (!/^--button-.+-shadow(-(hover|active))?$/.test(name))
|
|
1252
|
-
return false;
|
|
1253
|
-
return /^none$/i.test(value.trim());
|
|
1254
|
-
}
|
|
1255
1251
|
function listCssFiles(dir, acc = []) {
|
|
1256
1252
|
if (!existsSync5(dir))
|
|
1257
1253
|
return acc;
|
|
@@ -1308,10 +1304,10 @@ function inspectPkgCss(pkgName, cwd) {
|
|
|
1308
1304
|
return null;
|
|
1309
1305
|
const pkg = readPkgJson(root);
|
|
1310
1306
|
const exp = pkg?.exports;
|
|
1311
|
-
const abs = (
|
|
1307
|
+
const abs = (rel) => rel ? join5(root, rel.replace(/^\.\//, "")) : undefined;
|
|
1312
1308
|
const fileIfExists = (key) => {
|
|
1313
|
-
const
|
|
1314
|
-
const a = abs(
|
|
1309
|
+
const rel = exportPath(exp, key);
|
|
1310
|
+
const a = abs(rel);
|
|
1315
1311
|
return a && existsSync5(a) ? a : undefined;
|
|
1316
1312
|
};
|
|
1317
1313
|
return {
|
|
@@ -1334,10 +1330,10 @@ function resolveElcrmCssImport(spec, cwd) {
|
|
|
1334
1330
|
if (!root)
|
|
1335
1331
|
return null;
|
|
1336
1332
|
const pkg = readPkgJson(root);
|
|
1337
|
-
const
|
|
1338
|
-
if (!
|
|
1333
|
+
const rel = exportPath(pkg?.exports, `./${sub}`);
|
|
1334
|
+
if (!rel)
|
|
1339
1335
|
return null;
|
|
1340
|
-
const abs = join5(root,
|
|
1336
|
+
const abs = join5(root, rel.replace(/^\.\//, ""));
|
|
1341
1337
|
return existsSync5(abs) ? abs : null;
|
|
1342
1338
|
}
|
|
1343
1339
|
function pruneBrokenElcrmImports(css, cwd) {
|
|
@@ -1359,16 +1355,17 @@ function addDef(acc, seen, pkg, bucket, name, value) {
|
|
|
1359
1355
|
seen.add(key);
|
|
1360
1356
|
acc.push({ name, value, bucket, pkg });
|
|
1361
1357
|
}
|
|
1362
|
-
function
|
|
1363
|
-
|
|
1364
|
-
if (!root)
|
|
1365
|
-
return [];
|
|
1366
|
-
const files = [
|
|
1358
|
+
function pkgTokenCssFiles(root) {
|
|
1359
|
+
return [
|
|
1367
1360
|
...listCssFiles(join5(root, "dist")),
|
|
1361
|
+
...listCssFiles(join5(root, "src/lib")),
|
|
1368
1362
|
...listCssFiles(join5(root, "src/lib/styles")),
|
|
1369
1363
|
...listCssFiles(join5(root, "src/style")),
|
|
1370
1364
|
join5(root, "test/main.css")
|
|
1371
1365
|
].filter((f) => existsSync5(f));
|
|
1366
|
+
}
|
|
1367
|
+
function collectTokensFromPkgRoot(root, pkg) {
|
|
1368
|
+
const files = pkgTokenCssFiles(root);
|
|
1372
1369
|
const acc = [];
|
|
1373
1370
|
const seen = new Set;
|
|
1374
1371
|
for (const file of files) {
|
|
@@ -1379,14 +1376,14 @@ function collectPkgTokens(pkgName, cwd) {
|
|
|
1379
1376
|
const color = isColorToken(name, value);
|
|
1380
1377
|
if (kind === "geometry") {
|
|
1381
1378
|
if (color) {
|
|
1382
|
-
addDef(acc, seen,
|
|
1383
|
-
addDef(acc, seen,
|
|
1379
|
+
addDef(acc, seen, pkg, "light", name, value);
|
|
1380
|
+
addDef(acc, seen, pkg, "dark", name, value);
|
|
1384
1381
|
} else {
|
|
1385
|
-
addDef(acc, seen,
|
|
1382
|
+
addDef(acc, seen, pkg, "geometry", name, value);
|
|
1386
1383
|
}
|
|
1387
1384
|
continue;
|
|
1388
1385
|
}
|
|
1389
|
-
addDef(acc, seen,
|
|
1386
|
+
addDef(acc, seen, pkg, color ? kind : "geometry", name, value);
|
|
1390
1387
|
}
|
|
1391
1388
|
continue;
|
|
1392
1389
|
}
|
|
@@ -1398,19 +1395,25 @@ function collectPkgTokens(pkgName, cwd) {
|
|
|
1398
1395
|
const color = isColorToken(name, value);
|
|
1399
1396
|
if (bucket === "geometry") {
|
|
1400
1397
|
if (color) {
|
|
1401
|
-
addDef(acc, seen,
|
|
1402
|
-
addDef(acc, seen,
|
|
1398
|
+
addDef(acc, seen, pkg, "light", name, value);
|
|
1399
|
+
addDef(acc, seen, pkg, "dark", name, value);
|
|
1403
1400
|
} else {
|
|
1404
|
-
addDef(acc, seen,
|
|
1401
|
+
addDef(acc, seen, pkg, "geometry", name, value);
|
|
1405
1402
|
}
|
|
1406
1403
|
continue;
|
|
1407
1404
|
}
|
|
1408
|
-
addDef(acc, seen,
|
|
1405
|
+
addDef(acc, seen, pkg, color ? bucket : "geometry", name, value);
|
|
1409
1406
|
}
|
|
1410
1407
|
});
|
|
1411
1408
|
}
|
|
1412
1409
|
return acc;
|
|
1413
1410
|
}
|
|
1411
|
+
function collectPkgTokens(pkgName, cwd) {
|
|
1412
|
+
const root = resolvePkgRoot(pkgName, cwd);
|
|
1413
|
+
if (!root)
|
|
1414
|
+
return [];
|
|
1415
|
+
return collectTokensFromPkgRoot(root, pkgName);
|
|
1416
|
+
}
|
|
1414
1417
|
function existingTokenNames(css) {
|
|
1415
1418
|
return new Set(parseCustomProps(css).keys());
|
|
1416
1419
|
}
|
|
@@ -1544,7 +1547,7 @@ function syncElcrmCss(options) {
|
|
|
1544
1547
|
continue;
|
|
1545
1548
|
let css = readFileSync7(file, "utf8");
|
|
1546
1549
|
const have = existingTokenNames(css);
|
|
1547
|
-
const missing = allDefs.filter((d) => d.bucket === bucket && !have.has(d.name) && !d.name.startsWith("--search-") && !TOKEN_DEPRECATED.has(d.name) && !
|
|
1550
|
+
const missing = allDefs.filter((d) => d.bucket === bucket && !have.has(d.name) && !d.name.startsWith("--search-") && !TOKEN_DEPRECATED.has(d.name) && !(bucket === "geometry" && pkgsWithTokens.has(d.pkg)));
|
|
1548
1551
|
const uniq = [];
|
|
1549
1552
|
const seen = new Set;
|
|
1550
1553
|
for (const d of missing) {
|
|
@@ -1592,31 +1595,60 @@ function syncElcrmCss(options) {
|
|
|
1592
1595
|
}
|
|
1593
1596
|
return { styleDir, added, imports, removedImports, skippedPkgs };
|
|
1594
1597
|
}
|
|
1595
|
-
function
|
|
1596
|
-
const
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1598
|
+
function checkElcrmTokenCoverage(options) {
|
|
1599
|
+
const styleDir = findStyleDir(options.cwd);
|
|
1600
|
+
const defined = new Set;
|
|
1601
|
+
if (styleDir) {
|
|
1602
|
+
for (const name of ["theme.css", "theme-light.css", "theme-dark.css"]) {
|
|
1603
|
+
const file = join5(styleDir, name);
|
|
1604
|
+
if (!existsSync5(file))
|
|
1605
|
+
continue;
|
|
1606
|
+
for (const k of parseCustomProps(readFileSync7(file, "utf8")).keys()) {
|
|
1607
|
+
defined.add(k);
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
const gaps = [];
|
|
1612
|
+
let checked = 0;
|
|
1613
|
+
for (const pkgName of options.pkgNames) {
|
|
1614
|
+
const exp = inspectPkgCss(pkgName, options.cwd);
|
|
1615
|
+
if (!exp)
|
|
1616
|
+
continue;
|
|
1617
|
+
for (const d of collectPkgTokens(pkgName, options.cwd)) {
|
|
1618
|
+
defined.add(d.name);
|
|
1619
|
+
}
|
|
1620
|
+
const styleFiles = [
|
|
1621
|
+
exp.style,
|
|
1622
|
+
exp.tokens,
|
|
1623
|
+
exp.light,
|
|
1624
|
+
exp.dark,
|
|
1625
|
+
...listCssFiles(join5(exp.root, "dist")).filter((f) => /index\.css$|style\.css$|\.module\.css$/i.test(f)),
|
|
1626
|
+
...listCssFiles(join5(exp.root, "src/lib")).filter((f) => /\.css$/i.test(f))
|
|
1627
|
+
].filter((f) => Boolean(f && existsSync5(f)));
|
|
1628
|
+
const used = new Set;
|
|
1629
|
+
for (const file of styleFiles) {
|
|
1630
|
+
const css = readFileSync7(file, "utf8");
|
|
1631
|
+
for (const k of parseCustomProps(css).keys())
|
|
1632
|
+
defined.add(k);
|
|
1633
|
+
for (const m of css.matchAll(/var\(\s*(--[a-zA-Z0-9-]+)/g)) {
|
|
1634
|
+
used.add(m[1]);
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
checked += used.size;
|
|
1638
|
+
for (const token of [...used].sort()) {
|
|
1639
|
+
if (TOKEN_DEPRECATED.has(token))
|
|
1640
|
+
continue;
|
|
1641
|
+
if (defined.has(token))
|
|
1642
|
+
continue;
|
|
1643
|
+
if (/^--tooltip-arrow-/.test(token))
|
|
1644
|
+
continue;
|
|
1645
|
+
if (token === "--alpha-color" || token === "--preview-color" || token === "--swatch") {
|
|
1646
|
+
continue;
|
|
1647
|
+
}
|
|
1648
|
+
gaps.push({ pkg: pkgName, token });
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
return { styleDir, gaps, checked };
|
|
1620
1652
|
}
|
|
1621
1653
|
|
|
1622
1654
|
// src/lib/migrate/socket-server.ts
|
|
@@ -1730,7 +1762,7 @@ async function migrateSocketServer(cwd, dry) {
|
|
|
1730
1762
|
pkg.dependencies["@elcrm/server"] = ver;
|
|
1731
1763
|
}
|
|
1732
1764
|
}
|
|
1733
|
-
if (!dry && changes.some((
|
|
1765
|
+
if (!dry && changes.some((c) => c.file === "package.json")) {
|
|
1734
1766
|
writePackageJson(pkg, cwd);
|
|
1735
1767
|
}
|
|
1736
1768
|
}
|
|
@@ -2172,25 +2204,25 @@ function sliceAttrValue(attrs, eqIndex) {
|
|
|
2172
2204
|
let brace = 0;
|
|
2173
2205
|
let quote = null;
|
|
2174
2206
|
while (i < attrs.length) {
|
|
2175
|
-
const
|
|
2207
|
+
const c = attrs[i];
|
|
2176
2208
|
if (quote) {
|
|
2177
|
-
if (
|
|
2209
|
+
if (c === "\\" && quote === '"') {
|
|
2178
2210
|
i += 2;
|
|
2179
2211
|
continue;
|
|
2180
2212
|
}
|
|
2181
|
-
if (
|
|
2213
|
+
if (c === quote)
|
|
2182
2214
|
quote = null;
|
|
2183
2215
|
i++;
|
|
2184
2216
|
continue;
|
|
2185
2217
|
}
|
|
2186
|
-
if (
|
|
2187
|
-
quote =
|
|
2218
|
+
if (c === '"' || c === "'") {
|
|
2219
|
+
quote = c;
|
|
2188
2220
|
i++;
|
|
2189
2221
|
continue;
|
|
2190
2222
|
}
|
|
2191
|
-
if (
|
|
2223
|
+
if (c === "{")
|
|
2192
2224
|
brace++;
|
|
2193
|
-
else if (
|
|
2225
|
+
else if (c === "}") {
|
|
2194
2226
|
brace--;
|
|
2195
2227
|
if (brace === 0) {
|
|
2196
2228
|
i++;
|
|
@@ -2449,8 +2481,8 @@ async function migrateFrontAll(cwd, dry) {
|
|
|
2449
2481
|
const all = [];
|
|
2450
2482
|
for (const name of FRONT_MIGRATE_ORDER) {
|
|
2451
2483
|
const part = await FRONT_MIGRATIONS[name](cwd, dry);
|
|
2452
|
-
for (const
|
|
2453
|
-
all.push({ file:
|
|
2484
|
+
for (const c of part) {
|
|
2485
|
+
all.push({ file: c.file, detail: `[${name}] ${c.detail}` });
|
|
2454
2486
|
}
|
|
2455
2487
|
}
|
|
2456
2488
|
return all;
|
|
@@ -2564,12 +2596,12 @@ import { resolve } from "path";
|
|
|
2564
2596
|
import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync16, statSync as statSync5 } from "fs";
|
|
2565
2597
|
import { join as join8, relative as relative2 } from "path";
|
|
2566
2598
|
var SKIP = new Set(["node_modules", "dist", ".git", "coverage", ".bun"]);
|
|
2567
|
-
function isThemeTokenFile(
|
|
2568
|
-
const n =
|
|
2599
|
+
function isThemeTokenFile(rel) {
|
|
2600
|
+
const n = rel.replace(/\\/g, "/");
|
|
2569
2601
|
return /(?:^|\/)(?:theme(?:-light|-dark)?|elcrm)\.css$/.test(n);
|
|
2570
2602
|
}
|
|
2571
|
-
function isGeneratedIcons(
|
|
2572
|
-
return /icons\.generated\.(tsx?|jsx?)$/.test(
|
|
2603
|
+
function isGeneratedIcons(rel) {
|
|
2604
|
+
return /icons\.generated\.(tsx?|jsx?)$/.test(rel.replace(/\\/g, "/"));
|
|
2573
2605
|
}
|
|
2574
2606
|
var HARD_HEX_RE = /#[0-9a-fA-F]{3,8}\b/;
|
|
2575
2607
|
var HARD_RGB_RE = /\b(?:rgb|rgba|hsl|hsla)\s*\(/i;
|
|
@@ -2712,14 +2744,14 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2712
2744
|
}
|
|
2713
2745
|
for (const file of files) {
|
|
2714
2746
|
const text = readFileSync16(file, "utf8");
|
|
2715
|
-
const
|
|
2716
|
-
const skipHardColor = isLib || isThemeTokenFile(
|
|
2747
|
+
const rel = relative2(cwd, file);
|
|
2748
|
+
const skipHardColor = isLib || isThemeTokenFile(rel) || isGeneratedIcons(rel);
|
|
2717
2749
|
if (DEPRECATED_SOCKET_IMPORT_RE.test(text)) {
|
|
2718
2750
|
issues.push({
|
|
2719
2751
|
level: "error",
|
|
2720
2752
|
code: "deprecated-import",
|
|
2721
2753
|
message: "\u0438\u043C\u043F\u043E\u0440\u0442 @elcrm/socket/server \u0438\u043B\u0438 socket-server",
|
|
2722
|
-
file:
|
|
2754
|
+
file: rel,
|
|
2723
2755
|
fixable: true
|
|
2724
2756
|
});
|
|
2725
2757
|
}
|
|
@@ -2731,13 +2763,13 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2731
2763
|
level: "error",
|
|
2732
2764
|
code: "themes-css",
|
|
2733
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)",
|
|
2734
|
-
file:
|
|
2766
|
+
file: rel,
|
|
2735
2767
|
line
|
|
2736
2768
|
});
|
|
2737
2769
|
}
|
|
2738
2770
|
if (LEGACY_PASSKEY_IMPORT_RE.test(text) && LEGACY_PASSKEY_SYMBOL_RE.test(text)) {
|
|
2739
|
-
const
|
|
2740
|
-
|
|
2771
|
+
const lines = text.split(/\r?\n/);
|
|
2772
|
+
lines.forEach((line, i) => {
|
|
2741
2773
|
if (/\bcreatePasskey\b/.test(line) || /\bauthenticateWithPasskey\b/.test(line)) {
|
|
2742
2774
|
if (pkg.name === "@elcrm/passkey")
|
|
2743
2775
|
return;
|
|
@@ -2745,7 +2777,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2745
2777
|
level: "error",
|
|
2746
2778
|
code: "legacy-passkey-api",
|
|
2747
2779
|
message: "createPasskey / authenticateWithPasskey \u043D\u0435 \u044D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u0443\u044E\u0442\u0441\u044F \u2014 createPasskeyClient",
|
|
2748
|
-
file:
|
|
2780
|
+
file: rel,
|
|
2749
2781
|
line: i + 1
|
|
2750
2782
|
});
|
|
2751
2783
|
}
|
|
@@ -2764,19 +2796,19 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2764
2796
|
level: "error",
|
|
2765
2797
|
code: "native-html-input",
|
|
2766
2798
|
message: "\u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0439 <input|textarea|select> \u2014 @elcrm/form (elcrm migrate native-html)",
|
|
2767
|
-
file:
|
|
2799
|
+
file: rel,
|
|
2768
2800
|
line: i + 1,
|
|
2769
2801
|
fixable: true
|
|
2770
2802
|
});
|
|
2771
2803
|
}
|
|
2772
2804
|
}
|
|
2773
|
-
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))) {
|
|
2774
2806
|
if (pkg.name !== "@elcrm/form") {
|
|
2775
2807
|
issues.push({
|
|
2776
2808
|
level: "warn",
|
|
2777
2809
|
code: "form-native-prop",
|
|
2778
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)",
|
|
2779
|
-
file:
|
|
2811
|
+
file: rel,
|
|
2780
2812
|
line: i + 1,
|
|
2781
2813
|
fixable: true
|
|
2782
2814
|
});
|
|
@@ -2787,7 +2819,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2787
2819
|
level: "warn",
|
|
2788
2820
|
code: "size-legacy",
|
|
2789
2821
|
message: 'size="sm"|"md" \u0443\u0441\u0442\u0430\u0440\u0435\u043B\u043E \u2014 "s"|"m" (elcrm migrate size-sml)',
|
|
2790
|
-
file:
|
|
2822
|
+
file: rel,
|
|
2791
2823
|
line: i + 1,
|
|
2792
2824
|
fixable: true
|
|
2793
2825
|
});
|
|
@@ -2797,7 +2829,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2797
2829
|
level: "warn",
|
|
2798
2830
|
code: "modal-add",
|
|
2799
2831
|
message: "Modal.Add \u2014 Modal.Create + Open (elcrm migrate modal-create)",
|
|
2800
|
-
file:
|
|
2832
|
+
file: rel,
|
|
2801
2833
|
line: i + 1,
|
|
2802
2834
|
fixable: true
|
|
2803
2835
|
});
|
|
@@ -2807,7 +2839,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2807
2839
|
level: "error",
|
|
2808
2840
|
code: "field-border-shorthand",
|
|
2809
2841
|
message: "field-border hover/focus/disabled \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0446\u0432\u0435\u0442 (elcrm migrate field-border)",
|
|
2810
|
-
file:
|
|
2842
|
+
file: rel,
|
|
2811
2843
|
line: i + 1,
|
|
2812
2844
|
fixable: true
|
|
2813
2845
|
});
|
|
@@ -2817,7 +2849,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2817
2849
|
level: "warn",
|
|
2818
2850
|
code: "form-token-legacy",
|
|
2819
2851
|
message: "legacy padding/shadow-\u0442\u043E\u043A\u0435\u043D \u2192 --field-padding* / --popup-shadow (elcrm migrate form-tokens)",
|
|
2820
|
-
file:
|
|
2852
|
+
file: rel,
|
|
2821
2853
|
line: i + 1,
|
|
2822
2854
|
fixable: true
|
|
2823
2855
|
});
|
|
@@ -2827,7 +2859,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2827
2859
|
level: "warn",
|
|
2828
2860
|
code: "components-token-legacy",
|
|
2829
2861
|
message: "legacy \u0442\u043E\u043A\u0435\u043D @elcrm/components \u2192 --shell-* (elcrm migrate components)",
|
|
2830
|
-
file:
|
|
2862
|
+
file: rel,
|
|
2831
2863
|
line: i + 1,
|
|
2832
2864
|
fixable: true
|
|
2833
2865
|
});
|
|
@@ -2837,7 +2869,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2837
2869
|
level: "error",
|
|
2838
2870
|
code: "css-orphan-mix",
|
|
2839
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",
|
|
2840
|
-
file:
|
|
2872
|
+
file: rel,
|
|
2841
2873
|
line: i + 1,
|
|
2842
2874
|
fixable: true
|
|
2843
2875
|
});
|
|
@@ -2850,7 +2882,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2850
2882
|
level: "warn",
|
|
2851
2883
|
code: "components-stack",
|
|
2852
2884
|
message: "Block/Row/Column \u0443\u0441\u0442\u0430\u0440\u0435\u043B\u0438 \u2014 Stack (elcrm migrate components)",
|
|
2853
|
-
file:
|
|
2885
|
+
file: rel,
|
|
2854
2886
|
line: i + 1,
|
|
2855
2887
|
fixable: true
|
|
2856
2888
|
});
|
|
@@ -2861,7 +2893,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2861
2893
|
level: "warn",
|
|
2862
2894
|
code: "components-value",
|
|
2863
2895
|
message: "activeKey/defaultActiveKey \u2192 value/defaultValue (elcrm migrate components)",
|
|
2864
|
-
file:
|
|
2896
|
+
file: rel,
|
|
2865
2897
|
line: i + 1,
|
|
2866
2898
|
fixable: true
|
|
2867
2899
|
});
|
|
@@ -2873,7 +2905,7 @@ function collectFrontIssues(cwd, pkg) {
|
|
|
2873
2905
|
level: "warn",
|
|
2874
2906
|
code: "hardcoded-color",
|
|
2875
2907
|
message: why,
|
|
2876
|
-
file:
|
|
2908
|
+
file: rel,
|
|
2877
2909
|
line: i + 1
|
|
2878
2910
|
});
|
|
2879
2911
|
}
|
|
@@ -3263,7 +3295,7 @@ function walkFiles2(root, dir, out) {
|
|
|
3263
3295
|
function scanCodeFile(root, file, text) {
|
|
3264
3296
|
const findings = [];
|
|
3265
3297
|
const lines = text.split(/\r?\n/);
|
|
3266
|
-
const
|
|
3298
|
+
const rel = relative3(root, file) || file;
|
|
3267
3299
|
for (const rule of CODE_RULES) {
|
|
3268
3300
|
lines.forEach((line, i) => {
|
|
3269
3301
|
rule.test.lastIndex = 0;
|
|
@@ -3274,7 +3306,7 @@ function scanCodeFile(root, file, text) {
|
|
|
3274
3306
|
findings.push({
|
|
3275
3307
|
ruleId: rule.id,
|
|
3276
3308
|
severity: rule.severity,
|
|
3277
|
-
file:
|
|
3309
|
+
file: rel,
|
|
3278
3310
|
line: i + 1,
|
|
3279
3311
|
match: (m?.[0] ?? line).trim().slice(0, 120),
|
|
3280
3312
|
message: rule.message,
|
|
@@ -3287,7 +3319,7 @@ function scanCodeFile(root, file, text) {
|
|
|
3287
3319
|
}
|
|
3288
3320
|
function scanPackageJson(root, file, text) {
|
|
3289
3321
|
const findings = [];
|
|
3290
|
-
const
|
|
3322
|
+
const rel = relative3(root, file) || file;
|
|
3291
3323
|
let pkg;
|
|
3292
3324
|
try {
|
|
3293
3325
|
pkg = JSON.parse(text);
|
|
@@ -3300,7 +3332,7 @@ function scanPackageJson(root, file, text) {
|
|
|
3300
3332
|
findings.push({
|
|
3301
3333
|
ruleId: `pkg-${name}`,
|
|
3302
3334
|
severity: "error",
|
|
3303
|
-
file:
|
|
3335
|
+
file: rel,
|
|
3304
3336
|
line: 1,
|
|
3305
3337
|
match: `"${name}": "${deps[name]}"`,
|
|
3306
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)`,
|
|
@@ -3313,7 +3345,7 @@ function scanPackageJson(root, file, text) {
|
|
|
3313
3345
|
findings.push({
|
|
3314
3346
|
ruleId: "pkg-need-server",
|
|
3315
3347
|
severity: "error",
|
|
3316
|
-
file:
|
|
3348
|
+
file: rel,
|
|
3317
3349
|
line: 1,
|
|
3318
3350
|
match: "missing @elcrm/server",
|
|
3319
3351
|
message: "\u041D\u0443\u0436\u043D\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u044C @elcrm/server",
|
|
@@ -3765,8 +3797,8 @@ async function cmdMigrate(parsed) {
|
|
|
3765
3797
|
if (hasFlag(parsed, "list") || parsed.positionals[0] === "list") {
|
|
3766
3798
|
console.log("\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u043C\u0438\u0433\u0440\u0430\u0446\u0438\u0438:");
|
|
3767
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:");
|
|
3768
|
-
for (const
|
|
3769
|
-
console.log(` - ${
|
|
3800
|
+
for (const name of FRONT_MIGRATE_ORDER) {
|
|
3801
|
+
console.log(` - ${name}`);
|
|
3770
3802
|
}
|
|
3771
3803
|
console.log(" socket-server (\u0442\u0430\u043A\u0436\u0435 \u0432 front)");
|
|
3772
3804
|
return;
|
|
@@ -3792,8 +3824,8 @@ async function cmdMigrate(parsed) {
|
|
|
3792
3824
|
console.log("\u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439 \u043D\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F.");
|
|
3793
3825
|
return;
|
|
3794
3826
|
}
|
|
3795
|
-
for (const
|
|
3796
|
-
console.log(` ${
|
|
3827
|
+
for (const c of changes) {
|
|
3828
|
+
console.log(` ${c.file}: ${c.detail}`);
|
|
3797
3829
|
}
|
|
3798
3830
|
console.log(dry ? `
|
|
3799
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.` : `
|
|
@@ -4165,8 +4197,8 @@ function emitKitManifest(cwd) {
|
|
|
4165
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)`);
|
|
4166
4198
|
}
|
|
4167
4199
|
const distDir = join15(cwd, "dist");
|
|
4168
|
-
const components = scanDistComponents(distDir, pkg.name).map((
|
|
4169
|
-
...
|
|
4200
|
+
const components = scanDistComponents(distDir, pkg.name).map((c) => ({
|
|
4201
|
+
...c,
|
|
4170
4202
|
importFrom: pkg.name
|
|
4171
4203
|
}));
|
|
4172
4204
|
return {
|
|
@@ -4332,6 +4364,7 @@ var ALL_ELCRM_DOCS = [
|
|
|
4332
4364
|
"TOOLTIP.elCRM.md",
|
|
4333
4365
|
"ICONS.elCRM.md",
|
|
4334
4366
|
"FORM.elCRM.md",
|
|
4367
|
+
"SEARCH.elCRM.md",
|
|
4335
4368
|
"COMPONENTS.elCRM.md",
|
|
4336
4369
|
"SERVER.elCRM.md"
|
|
4337
4370
|
];
|
|
@@ -4356,6 +4389,9 @@ import {
|
|
|
4356
4389
|
writeFileSync as writeFileSync9
|
|
4357
4390
|
} from "fs";
|
|
4358
4391
|
import { dirname as dirname3, join as join18 } from "path";
|
|
4392
|
+
function bundledDir(...parts) {
|
|
4393
|
+
return join18(packageRoot(), "templates", ...parts);
|
|
4394
|
+
}
|
|
4359
4395
|
function writeScaffoldFile(dest, body, opts) {
|
|
4360
4396
|
if (opts.dry)
|
|
4361
4397
|
return "dry";
|
|
@@ -4715,16 +4751,24 @@ async function cmdCss(parsed) {
|
|
|
4715
4751
|
return;
|
|
4716
4752
|
}
|
|
4717
4753
|
const dry = hasFlag(parsed, "dry");
|
|
4718
|
-
|
|
4754
|
+
const checkOnly = hasFlag(parsed, "check");
|
|
4755
|
+
console.log(`${dry || checkOnly ? "[check/dry] " : ""}\u041F\u0430\u043A\u0435\u0442\u044B: ${names.join(", ")}`);
|
|
4719
4756
|
try {
|
|
4757
|
+
if (checkOnly) {
|
|
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) {
|
|
4761
|
+
console.log(c.green("\u041F\u043E\u043A\u0440\u044B\u0442\u0438\u0435 \u0442\u043E\u043A\u0435\u043D\u043E\u0432 OK."));
|
|
4762
|
+
return;
|
|
4763
|
+
}
|
|
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) {
|
|
4766
|
+
console.error(` ${c.dim(g.pkg)} ${g.token}`);
|
|
4767
|
+
}
|
|
4768
|
+
process.exit(1);
|
|
4769
|
+
}
|
|
4720
4770
|
const result = syncElcrmCss({ cwd, pkgNames: names, dry });
|
|
4721
4771
|
console.log(`\u041A\u0430\u0442\u0430\u043B\u043E\u0433 \u0441\u0442\u0438\u043B\u0435\u0439: ${result.styleDir}`);
|
|
4722
|
-
const stripped = stripButtonShadowNoiseFromTheme(result.styleDir, dry);
|
|
4723
|
-
if (stripped.length) {
|
|
4724
|
-
console.log(` ${dry ? "[dry] " : ""}${c.yellow("\u2212")} theme.css: \u0443\u0431\u0440\u0430\u043D\u043E ${stripped.length} button-shadow (none)`);
|
|
4725
|
-
for (const t of stripped)
|
|
4726
|
-
console.log(` ${c.dim(t)}`);
|
|
4727
|
-
}
|
|
4728
4772
|
let total = 0;
|
|
4729
4773
|
for (const [file, tokens] of Object.entries(result.added)) {
|
|
4730
4774
|
if (!tokens.length) {
|
|
@@ -4763,6 +4807,17 @@ css-sanitize: \u043F\u043E\u0447\u0438\u043D\u0435\u043D\u043E ${cleaned.length}
|
|
|
4763
4807
|
for (const ch of cleaned)
|
|
4764
4808
|
console.log(` ${ch.file}: ${ch.detail}`);
|
|
4765
4809
|
}
|
|
4810
|
+
const cov = checkElcrmTokenCoverage({ cwd, pkgNames: names });
|
|
4811
|
+
if (cov.gaps.length) {
|
|
4812
|
+
console.log(`
|
|
4813
|
+
${c.yellow("\u26A0")} \u043F\u043E\u043A\u0440\u044B\u0442\u0438\u0435: ${cov.gaps.length} \u043F\u0440\u043E\u0431\u0435\u043B(\u043E\u0432) \u2014 \u0441\u043C. elcrm css --check`);
|
|
4814
|
+
for (const g of cov.gaps.slice(0, 12)) {
|
|
4815
|
+
console.log(` ${c.dim(g.pkg)} ${g.token}`);
|
|
4816
|
+
}
|
|
4817
|
+
if (cov.gaps.length > 12) {
|
|
4818
|
+
console.log(` ${c.dim(`\u2026 \u0435\u0449\u0451 ${cov.gaps.length - 12}`)}`);
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4766
4821
|
} catch (e) {
|
|
4767
4822
|
console.error(e instanceof Error ? e.message : e);
|
|
4768
4823
|
process.exit(1);
|
|
@@ -4803,7 +4858,7 @@ function scan(cwd) {
|
|
|
4803
4858
|
const files = projectCodeRoots(cwd).flatMap((r) => walkCodeFiles(r));
|
|
4804
4859
|
for (const file of files) {
|
|
4805
4860
|
const text = readFileSync27(file, "utf8");
|
|
4806
|
-
const
|
|
4861
|
+
const rel = relative4(cwd, file);
|
|
4807
4862
|
const lines = text.split(/\r?\n/);
|
|
4808
4863
|
lines.forEach((line, i) => {
|
|
4809
4864
|
const n = i + 1;
|
|
@@ -4814,7 +4869,7 @@ function scan(cwd) {
|
|
|
4814
4869
|
level: "warn",
|
|
4815
4870
|
code: "size-legacy",
|
|
4816
4871
|
message: 'size="sm"|"md" \u2192 "s"|"m"',
|
|
4817
|
-
file:
|
|
4872
|
+
file: rel,
|
|
4818
4873
|
line: n,
|
|
4819
4874
|
fix: "elcrm migrate size-sml"
|
|
4820
4875
|
});
|
|
@@ -4824,7 +4879,7 @@ function scan(cwd) {
|
|
|
4824
4879
|
level: "warn",
|
|
4825
4880
|
code: "modal-add",
|
|
4826
4881
|
message: "Modal.Add \u2014 \u043F\u0440\u0435\u0434\u043F\u043E\u0447\u0442\u0438\u0442\u0435\u043B\u0435\u043D Modal.Create + Open",
|
|
4827
|
-
file:
|
|
4882
|
+
file: rel,
|
|
4828
4883
|
line: n,
|
|
4829
4884
|
fix: "elcrm migrate modal-create"
|
|
4830
4885
|
});
|
|
@@ -4834,7 +4889,7 @@ function scan(cwd) {
|
|
|
4834
4889
|
level: "error",
|
|
4835
4890
|
code: "native-html-input",
|
|
4836
4891
|
message: "\u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0439 <input|textarea|select> \u2192 @elcrm/form",
|
|
4837
|
-
file:
|
|
4892
|
+
file: rel,
|
|
4838
4893
|
line: n,
|
|
4839
4894
|
fix: "elcrm migrate native-html"
|
|
4840
4895
|
});
|
|
@@ -4844,7 +4899,7 @@ function scan(cwd) {
|
|
|
4844
4899
|
level: "warn",
|
|
4845
4900
|
code: "form-native-prop",
|
|
4846
4901
|
message: "prop native \u0443 \u043F\u043E\u043B\u044F \u0444\u043E\u0440\u043C\u044B \u2014 \u0443\u0431\u0435\u0440\u0438\u0442\u0435",
|
|
4847
|
-
file:
|
|
4902
|
+
file: rel,
|
|
4848
4903
|
line: n,
|
|
4849
4904
|
fix: "elcrm migrate form-native"
|
|
4850
4905
|
});
|
|
@@ -4854,7 +4909,7 @@ function scan(cwd) {
|
|
|
4854
4909
|
level: "info",
|
|
4855
4910
|
code: "modal-date-key",
|
|
4856
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",
|
|
4857
|
-
file:
|
|
4912
|
+
file: rel,
|
|
4858
4913
|
line: n
|
|
4859
4914
|
});
|
|
4860
4915
|
}
|
|
@@ -4863,17 +4918,17 @@ function scan(cwd) {
|
|
|
4863
4918
|
level: "error",
|
|
4864
4919
|
code: "field-border-shorthand",
|
|
4865
4920
|
message: "hover/focus border \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0446\u0432\u0435\u0442, \u043D\u0435 shorthand",
|
|
4866
|
-
file:
|
|
4921
|
+
file: rel,
|
|
4867
4922
|
line: n,
|
|
4868
4923
|
fix: "elcrm migrate field-border"
|
|
4869
4924
|
});
|
|
4870
4925
|
}
|
|
4871
|
-
if (/!important/.test(line) && /drag|file-upload|DragDrop/i.test(
|
|
4926
|
+
if (/!important/.test(line) && /drag|file-upload|DragDrop/i.test(rel + line)) {
|
|
4872
4927
|
out.push({
|
|
4873
4928
|
level: "info",
|
|
4874
4929
|
code: "dragdrop-important",
|
|
4875
4930
|
message: '!important \u0443 DragDrop \u2014 layout="fill"|"overlay" \u0432 @elcrm/form',
|
|
4876
|
-
file:
|
|
4931
|
+
file: rel,
|
|
4877
4932
|
line: n
|
|
4878
4933
|
});
|
|
4879
4934
|
}
|
|
@@ -4882,7 +4937,7 @@ function scan(cwd) {
|
|
|
4882
4937
|
level: "warn",
|
|
4883
4938
|
code: "react-global",
|
|
4884
4939
|
message: "globalThis.React \u0445\u0430\u043A \u2014 migrate legacy-hacks / \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u0435 modal",
|
|
4885
|
-
file:
|
|
4940
|
+
file: rel,
|
|
4886
4941
|
line: n,
|
|
4887
4942
|
fix: "elcrm migrate legacy-hacks"
|
|
4888
4943
|
});
|
|
@@ -4892,7 +4947,7 @@ function scan(cwd) {
|
|
|
4892
4947
|
level: "error",
|
|
4893
4948
|
code: "form-alias",
|
|
4894
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",
|
|
4895
|
-
file:
|
|
4950
|
+
file: rel,
|
|
4896
4951
|
line: n,
|
|
4897
4952
|
fix: "elcrm migrate form-aliases"
|
|
4898
4953
|
});
|
|
@@ -5170,34 +5225,339 @@ async function cmdKit(parsed) {
|
|
|
5170
5225
|
process.exit(1);
|
|
5171
5226
|
}
|
|
5172
5227
|
|
|
5228
|
+
// src/commands/hub.ts
|
|
5229
|
+
import { resolve as resolve14 } from "path";
|
|
5230
|
+
|
|
5231
|
+
// src/lib/docsHub.ts
|
|
5232
|
+
import {
|
|
5233
|
+
existsSync as existsSync20,
|
|
5234
|
+
mkdirSync as mkdirSync6,
|
|
5235
|
+
readdirSync as readdirSync12,
|
|
5236
|
+
readFileSync as readFileSync28,
|
|
5237
|
+
writeFileSync as writeFileSync12
|
|
5238
|
+
} from "fs";
|
|
5239
|
+
import { dirname as dirname4, join as join25, resolve as resolve13 } from "path";
|
|
5240
|
+
var HUB_START = "<!-- elcrm-hub-tokens:start -->";
|
|
5241
|
+
var HUB_END = "<!-- elcrm-hub-tokens:end -->";
|
|
5242
|
+
var PKG_TO_DOC = {
|
|
5243
|
+
"@elcrm/alert": "ALERT.elCRM.md",
|
|
5244
|
+
"@elcrm/api": "API.elCRM.md",
|
|
5245
|
+
"@elcrm/button": "BUTTON.elCRM.md",
|
|
5246
|
+
"@elcrm/components": "COMPONENTS.elCRM.md",
|
|
5247
|
+
"@elcrm/form": "FORM.elCRM.md",
|
|
5248
|
+
"@elcrm/icons": "ICONS.elCRM.md",
|
|
5249
|
+
"@elcrm/modal": "MODAL.elCRM.md",
|
|
5250
|
+
"@elcrm/notice": "NOTICE.elCRM.md",
|
|
5251
|
+
"@elcrm/notifications": "NOTIFICATIONS.elCRM.md",
|
|
5252
|
+
"@elcrm/passkey": "PASSKEY.elCRM.md",
|
|
5253
|
+
"@elcrm/router": "ROUTER.elCRM.md",
|
|
5254
|
+
"@elcrm/search": "SEARCH.elCRM.md",
|
|
5255
|
+
"@elcrm/server": "SERVER.elCRM.md",
|
|
5256
|
+
"@elcrm/socket": "SOCKET.elCRM.md",
|
|
5257
|
+
"@elcrm/tooltip": "TOOLTIP.elCRM.md"
|
|
5258
|
+
};
|
|
5259
|
+
function findPkgsRoot(from, override) {
|
|
5260
|
+
if (override?.trim()) {
|
|
5261
|
+
const p = resolve13(override.trim());
|
|
5262
|
+
return existsSync20(join25(p, "elCRM.cli", "package.json")) ? p : null;
|
|
5263
|
+
}
|
|
5264
|
+
const env = process.env.ELCRM_PKGS_DIR?.trim();
|
|
5265
|
+
if (env && existsSync20(join25(env, "elCRM.cli", "package.json"))) {
|
|
5266
|
+
return resolve13(env);
|
|
5267
|
+
}
|
|
5268
|
+
let dir = resolve13(from);
|
|
5269
|
+
for (let i = 0;i < 8; i++) {
|
|
5270
|
+
if (existsSync20(join25(dir, "elCRM.cli", "package.json")))
|
|
5271
|
+
return dir;
|
|
5272
|
+
if (existsSync20(join25(dir, "package.json"))) {
|
|
5273
|
+
try {
|
|
5274
|
+
const n = JSON.parse(readFileSync28(join25(dir, "package.json"), "utf8")).name;
|
|
5275
|
+
if (n === "elcrm" && existsSync20(join25(dir, "..", "elCRM.notice"))) {
|
|
5276
|
+
return resolve13(join25(dir, ".."));
|
|
5277
|
+
}
|
|
5278
|
+
} catch {}
|
|
5279
|
+
}
|
|
5280
|
+
const parent = join25(dir, "..");
|
|
5281
|
+
if (parent === dir)
|
|
5282
|
+
break;
|
|
5283
|
+
dir = parent;
|
|
5284
|
+
}
|
|
5285
|
+
return null;
|
|
5286
|
+
}
|
|
5287
|
+
function listHubPackages(pkgsRoot) {
|
|
5288
|
+
const out = [];
|
|
5289
|
+
for (const name of readdirSync12(pkgsRoot)) {
|
|
5290
|
+
if (!name.startsWith("elCRM."))
|
|
5291
|
+
continue;
|
|
5292
|
+
const dir = join25(pkgsRoot, name);
|
|
5293
|
+
const pkgFile = join25(dir, "package.json");
|
|
5294
|
+
if (!existsSync20(pkgFile))
|
|
5295
|
+
continue;
|
|
5296
|
+
let pkg;
|
|
5297
|
+
try {
|
|
5298
|
+
pkg = JSON.parse(readFileSync28(pkgFile, "utf8"));
|
|
5299
|
+
} catch {
|
|
5300
|
+
continue;
|
|
5301
|
+
}
|
|
5302
|
+
if (!pkg.name?.startsWith("@elcrm/"))
|
|
5303
|
+
continue;
|
|
5304
|
+
const doc = PKG_TO_DOC[pkg.name] ?? null;
|
|
5305
|
+
out.push({
|
|
5306
|
+
name: pkg.name,
|
|
5307
|
+
version: pkg.version ?? "0.0.0",
|
|
5308
|
+
dir,
|
|
5309
|
+
doc,
|
|
5310
|
+
tokens: collectTokensFromPkgRoot(dir, pkg.name)
|
|
5311
|
+
});
|
|
5312
|
+
}
|
|
5313
|
+
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
5314
|
+
}
|
|
5315
|
+
function formatHubTokenBlock(pkg) {
|
|
5316
|
+
const rows = [...pkg.tokens].sort((a, b) => a.bucket === b.bucket ? a.name.localeCompare(b.name) : a.bucket.localeCompare(b.bucket)).map((t) => `| \`${t.name}\` | ${t.bucket} | \`${t.value.replace(/\|/g, "\\|")}\` |`);
|
|
5317
|
+
const table = rows.length ? `| \u0422\u043E\u043A\u0435\u043D | \u0421\u043B\u043E\u0439 | \u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 |
|
|
5318
|
+
| --- | --- | --- |
|
|
5319
|
+
${rows.join(`
|
|
5320
|
+
`)}` : "_\u0412 \u043F\u0430\u043A\u0435\u0442\u0435 \u043D\u0435\u0442 CSS-\u0442\u043E\u043A\u0435\u043D\u043E\u0432 (\u0438\u043B\u0438 \u0442\u043E\u043B\u044C\u043A\u043E runtime var)._";
|
|
5321
|
+
return `${HUB_START}
|
|
5322
|
+
\u0410\u0432\u0442\u043E\u0442\u0430\u0431\u043B\u0438\u0446\u0430: \`elcrm hub collect\` \xB7 **${pkg.name}@${pkg.version}**. \u041D\u0435 \u043F\u0440\u0430\u0432\u0438\u0442\u044C \u0440\u0443\u043A\u0430\u043C\u0438.
|
|
5323
|
+
|
|
5324
|
+
${table}
|
|
5325
|
+
|
|
5326
|
+
${HUB_END}
|
|
5327
|
+
`;
|
|
5328
|
+
}
|
|
5329
|
+
function injectHubTokens(markdown, pkg) {
|
|
5330
|
+
const block = formatHubTokenBlock(pkg).trimEnd() + `
|
|
5331
|
+
`;
|
|
5332
|
+
let next = markdown.replace(/<!--\s*\u041F\u0430\u043A\u0435\u0442:\s*(@elcrm\/[a-z0-9-]+)(?:@[^.\s]+)?\s*\.?\s*-->/i, `<!-- \u041F\u0430\u043A\u0435\u0442: ${pkg.name}@${pkg.version}. -->`);
|
|
5333
|
+
if (next.includes(HUB_START) && next.includes(HUB_END)) {
|
|
5334
|
+
return next.replace(new RegExp(`${HUB_START}[\\s\\S]*?${HUB_END}\\n?`), block);
|
|
5335
|
+
}
|
|
5336
|
+
return `${next.trimEnd()}
|
|
5337
|
+
|
|
5338
|
+
${block}`;
|
|
5339
|
+
}
|
|
5340
|
+
function collectIntoCliTemplates(pkgs, cliRoot, dry = false) {
|
|
5341
|
+
const written = [];
|
|
5342
|
+
for (const pkg of pkgs) {
|
|
5343
|
+
if (!pkg.doc)
|
|
5344
|
+
continue;
|
|
5345
|
+
const file = join25(cliRoot, "templates", "elcrm-docs", pkg.doc);
|
|
5346
|
+
if (!existsSync20(file))
|
|
5347
|
+
continue;
|
|
5348
|
+
const prev = readFileSync28(file, "utf8");
|
|
5349
|
+
const next = injectHubTokens(prev, pkg);
|
|
5350
|
+
if (next !== prev && !dry)
|
|
5351
|
+
writeFileSync12(file, next, "utf8");
|
|
5352
|
+
written.push({ file: pkg.doc, tokens: pkg.tokens.length });
|
|
5353
|
+
}
|
|
5354
|
+
const snap = {
|
|
5355
|
+
generatedAt: new Date().toISOString(),
|
|
5356
|
+
packages: pkgs.map((p) => ({
|
|
5357
|
+
name: p.name,
|
|
5358
|
+
version: p.version,
|
|
5359
|
+
tokens: p.tokens.map((t) => ({
|
|
5360
|
+
name: t.name,
|
|
5361
|
+
value: t.value,
|
|
5362
|
+
bucket: t.bucket
|
|
5363
|
+
}))
|
|
5364
|
+
}))
|
|
5365
|
+
};
|
|
5366
|
+
const snapFile = join25(cliRoot, "templates", "elcrm-docs", "generated", "tokens.json");
|
|
5367
|
+
if (!dry) {
|
|
5368
|
+
mkdirSync6(dirname4(snapFile), { recursive: true });
|
|
5369
|
+
writeFileSync12(snapFile, `${JSON.stringify(snap, null, 2)}
|
|
5370
|
+
`, "utf8");
|
|
5371
|
+
}
|
|
5372
|
+
written.push({ file: "generated/tokens.json", tokens: pkgs.length });
|
|
5373
|
+
return written;
|
|
5374
|
+
}
|
|
5375
|
+
function checkHubDocs(pkgs, cliRoot) {
|
|
5376
|
+
const gaps = [];
|
|
5377
|
+
for (const pkg of pkgs) {
|
|
5378
|
+
if (!pkg.doc || !pkg.tokens.length)
|
|
5379
|
+
continue;
|
|
5380
|
+
const file = join25(cliRoot, "templates", "elcrm-docs", pkg.doc);
|
|
5381
|
+
if (!existsSync20(file)) {
|
|
5382
|
+
for (const t of pkg.tokens)
|
|
5383
|
+
gaps.push({ pkg: pkg.name, token: t.name });
|
|
5384
|
+
continue;
|
|
5385
|
+
}
|
|
5386
|
+
const md = readFileSync28(file, "utf8");
|
|
5387
|
+
const names = new Set(pkg.tokens.map((t) => t.name));
|
|
5388
|
+
for (const name of names) {
|
|
5389
|
+
if (!md.includes(name))
|
|
5390
|
+
gaps.push({ pkg: pkg.name, token: name });
|
|
5391
|
+
}
|
|
5392
|
+
}
|
|
5393
|
+
return gaps;
|
|
5394
|
+
}
|
|
5395
|
+
function pushHubToElui(opts) {
|
|
5396
|
+
const dry = opts.dry ?? false;
|
|
5397
|
+
const apiDir = findEluiApiDir(opts.cwd, opts.apiDir);
|
|
5398
|
+
const webDir = findEluiWebDir(opts.cwd, opts.webDir);
|
|
5399
|
+
const docsDir = bundledDir("elcrm-docs");
|
|
5400
|
+
const out = {};
|
|
5401
|
+
if (!dry) {
|
|
5402
|
+
saveKitPathsConfig(opts.cwd, {
|
|
5403
|
+
...apiDir ? { apiDir } : {},
|
|
5404
|
+
...webDir ? { webDir } : {}
|
|
5405
|
+
}, true);
|
|
5406
|
+
}
|
|
5407
|
+
if (apiDir) {
|
|
5408
|
+
const dest = join25(apiDir, "src/kit/package-tokens.json");
|
|
5409
|
+
const src = join25(docsDir, "generated", "tokens.json");
|
|
5410
|
+
if (existsSync20(src) && !dry) {
|
|
5411
|
+
writeFileSync12(dest, readFileSync28(src, "utf8"), "utf8");
|
|
5412
|
+
}
|
|
5413
|
+
out.api = dest;
|
|
5414
|
+
}
|
|
5415
|
+
if (webDir) {
|
|
5416
|
+
const destDir = join25(webDir, "docs", "elcrm");
|
|
5417
|
+
if (!dry)
|
|
5418
|
+
mkdirSync6(destDir, { recursive: true });
|
|
5419
|
+
for (const name of readdirSync12(docsDir)) {
|
|
5420
|
+
if (!name.endsWith(".md") && name !== "generated")
|
|
5421
|
+
continue;
|
|
5422
|
+
const from = join25(docsDir, name);
|
|
5423
|
+
if (name === "generated") {
|
|
5424
|
+
const gdest = join25(destDir, "generated");
|
|
5425
|
+
if (!dry)
|
|
5426
|
+
mkdirSync6(gdest, { recursive: true });
|
|
5427
|
+
for (const g of readdirSync12(from)) {
|
|
5428
|
+
if (!dry) {
|
|
5429
|
+
writeFileSync12(join25(gdest, g), readFileSync28(join25(from, g), "utf8"));
|
|
5430
|
+
}
|
|
5431
|
+
}
|
|
5432
|
+
continue;
|
|
5433
|
+
}
|
|
5434
|
+
if (!dry) {
|
|
5435
|
+
writeFileSync12(join25(destDir, name), readFileSync28(from, "utf8"), "utf8");
|
|
5436
|
+
}
|
|
5437
|
+
}
|
|
5438
|
+
out.web = destDir;
|
|
5439
|
+
}
|
|
5440
|
+
return out;
|
|
5441
|
+
}
|
|
5442
|
+
function cliPackageRoot(from) {
|
|
5443
|
+
const pkgs = findPkgsRoot(from);
|
|
5444
|
+
if (!pkgs)
|
|
5445
|
+
return null;
|
|
5446
|
+
const cli = join25(pkgs, "elCRM.cli");
|
|
5447
|
+
return existsSync20(join25(cli, "package.json")) ? cli : null;
|
|
5448
|
+
}
|
|
5449
|
+
|
|
5450
|
+
// src/commands/hub.ts
|
|
5451
|
+
function showHelp() {
|
|
5452
|
+
console.log(`elcrm hub \u2014 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u044F: \u043F\u0430\u043A\u0435\u0442\u044B \u2192 CLI \u2192 elUI
|
|
5453
|
+
|
|
5454
|
+
\u041D\u0435 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u044B\u0439 \u0441\u0435\u0440\u0432\u0435\u0440. \u0425\u0430\u0431 = \u044D\u0442\u043E\u0442 \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0439 (elCRM.cli/templates).
|
|
5455
|
+
|
|
5456
|
+
collect [--pkgs=\u2026] [--dry]
|
|
5457
|
+
\u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C tokens/light/dark \u0441\u043E\u0441\u0435\u0434\u043D\u0438\u0445 @elcrm/* \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044C
|
|
5458
|
+
\u0430\u0432\u0442\u043E\u0442\u0430\u0431\u043B\u0438\u0446\u044B \u0432 templates/elcrm-docs/*.elCRM.md
|
|
5459
|
+
|
|
5460
|
+
check [--pkgs=\u2026]
|
|
5461
|
+
\u041A\u0430\u0436\u0434\u044B\u0439 \u0442\u043E\u043A\u0435\u043D \u043F\u0430\u043A\u0435\u0442\u0430 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u0432 \u0448\u043F\u0430\u0440\u0433\u0430\u043B\u043A\u0435 CLI
|
|
5462
|
+
|
|
5463
|
+
push [--api=\u2026] [--web=\u2026] [--dry]
|
|
5464
|
+
\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0448\u043F\u0430\u0440\u0433\u0430\u043B\u043A\u0438 \u0432 elUI.web/docs/elcrm
|
|
5465
|
+
\u0438 tokens.json \u0432 elUI.api/src/kit/package-tokens.json
|
|
5466
|
+
|
|
5467
|
+
(\u0431\u0435\u0437 \u043F\u043E\u0434\u043A\u043E\u043C\u0430\u043D\u0434\u044B) collect \u2192 check \u2192 push
|
|
5468
|
+
|
|
5469
|
+
\u041E\u0434\u0438\u043D \u0440\u0430\u0437:
|
|
5470
|
+
elcrm kit config --api=/path/to/elUI.api --web=/path/to/elUI.web --global
|
|
5471
|
+
|
|
5472
|
+
\u041F\u043E\u0441\u043B\u0435 \u043F\u0440\u0430\u0432\u043A\u0438 \u043F\u0430\u043A\u0435\u0442\u0430:
|
|
5473
|
+
cd elCRM.cli && bun run hub
|
|
5474
|
+
# API/\u043C\u043E\u0436\u043D\u043E-\u043D\u0435\u043B\u044C\u0437\u044F \u2014 \u0440\u0443\u043A\u0430\u043C\u0438 \u0432 templates/elcrm-docs/<\u041F\u0410\u041A\u0415\u0422>.elCRM.md
|
|
5475
|
+
`);
|
|
5476
|
+
}
|
|
5477
|
+
async function cmdHub(parsed) {
|
|
5478
|
+
const sub = parsed.positionals[0] || "all";
|
|
5479
|
+
if (sub === "help" || hasFlag(parsed, "help", "h")) {
|
|
5480
|
+
showHelp();
|
|
5481
|
+
return;
|
|
5482
|
+
}
|
|
5483
|
+
const cwd = resolve14(parsed.options.dir || process.cwd());
|
|
5484
|
+
const dry = hasFlag(parsed, "dry");
|
|
5485
|
+
const pkgsRoot = findPkgsRoot(cwd, parsed.options.pkgs);
|
|
5486
|
+
const cliRoot = cliPackageRoot(cwd) ?? packageRoot();
|
|
5487
|
+
if (!pkgsRoot) {
|
|
5488
|
+
console.error("\u041D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D \u043A\u0430\u0442\u0430\u043B\u043E\u0433 \u043F\u0430\u043A\u0435\u0442\u043E\u0432 (elCRM.cli \u0440\u044F\u0434\u043E\u043C \u0441 elCRM.notice). \u0417\u0430\u0434\u0430\u0439\u0442\u0435 --pkgs=\u2026 \u0438\u043B\u0438 ELCRM_PKGS_DIR.");
|
|
5489
|
+
process.exit(1);
|
|
5490
|
+
}
|
|
5491
|
+
const pkgs = listHubPackages(pkgsRoot);
|
|
5492
|
+
console.log(`${dry ? "[dry] " : ""}hub: ${pkgs.length} \u043F\u0430\u043A\u0435\u0442\u043E\u0432 \u0432 ${pkgsRoot}`);
|
|
5493
|
+
const runCollect = sub === "all" || sub === "collect";
|
|
5494
|
+
const runCheck = sub === "all" || sub === "check";
|
|
5495
|
+
const runPush = sub === "all" || sub === "push";
|
|
5496
|
+
if (runCollect) {
|
|
5497
|
+
const files = collectIntoCliTemplates(pkgs, cliRoot, dry);
|
|
5498
|
+
for (const f of files) {
|
|
5499
|
+
console.log(` ${c.green("+")} ${f.file} (${f.tokens})`);
|
|
5500
|
+
}
|
|
5501
|
+
}
|
|
5502
|
+
if (runCheck) {
|
|
5503
|
+
const gaps = checkHubDocs(pkgs, cliRoot);
|
|
5504
|
+
if (gaps.length) {
|
|
5505
|
+
console.error(`${c.red("hub check:")} ${gaps.length} \u0442\u043E\u043A\u0435\u043D(\u043E\u0432) \u043D\u0435\u0442 \u0432 \u0448\u043F\u0430\u0440\u0433\u0430\u043B\u043A\u0435`);
|
|
5506
|
+
for (const g of gaps.slice(0, 40)) {
|
|
5507
|
+
console.error(` ${c.dim(g.pkg)} ${g.token}`);
|
|
5508
|
+
}
|
|
5509
|
+
if (gaps.length > 40)
|
|
5510
|
+
console.error(` \u2026 \u0435\u0449\u0451 ${gaps.length - 40}`);
|
|
5511
|
+
process.exit(1);
|
|
5512
|
+
}
|
|
5513
|
+
console.log(c.green("hub check: OK"));
|
|
5514
|
+
}
|
|
5515
|
+
if (runPush) {
|
|
5516
|
+
const dest = pushHubToElui({
|
|
5517
|
+
cliRoot,
|
|
5518
|
+
cwd,
|
|
5519
|
+
apiDir: parsed.options.api,
|
|
5520
|
+
webDir: parsed.options.web,
|
|
5521
|
+
dry
|
|
5522
|
+
});
|
|
5523
|
+
if (dest.api)
|
|
5524
|
+
console.log(` ${c.green("\u2192")} elUI.api ${dest.api}`);
|
|
5525
|
+
if (dest.web)
|
|
5526
|
+
console.log(` ${c.green("\u2192")} elUI.web ${dest.web}`);
|
|
5527
|
+
if (!dest.api && !dest.web) {
|
|
5528
|
+
console.warn(c.yellow("elUI \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D. elcrm kit config --api=\u2026 --web=\u2026 --global"));
|
|
5529
|
+
}
|
|
5530
|
+
}
|
|
5531
|
+
}
|
|
5532
|
+
|
|
5173
5533
|
// src/commands/publish.ts
|
|
5174
|
-
import { copyFileSync, existsSync as
|
|
5175
|
-
import { join as
|
|
5534
|
+
import { copyFileSync, existsSync as existsSync21, readFileSync as readFileSync29, unlinkSync, writeFileSync as writeFileSync13 } from "fs";
|
|
5535
|
+
import { join as join26, resolve as resolve15 } from "path";
|
|
5176
5536
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
5177
5537
|
var PUBLIC_NAME = "package.public.json";
|
|
5178
5538
|
var PKG_NAME = "package.json";
|
|
5179
5539
|
var BACKUP_NAME = ".package.json.elcrm-publish.bak";
|
|
5180
5540
|
async function cmdPublish(parsed) {
|
|
5181
|
-
const cwd =
|
|
5541
|
+
const cwd = resolve15(process.cwd(), parsed.options.dir || ".");
|
|
5182
5542
|
const dry = hasFlag(parsed, "dry");
|
|
5183
5543
|
const noCheck = hasFlag(parsed, "no-check", "noCheck");
|
|
5184
|
-
const pkgPath =
|
|
5185
|
-
const publicPath =
|
|
5186
|
-
const backupPath =
|
|
5187
|
-
if (!
|
|
5544
|
+
const pkgPath = join26(cwd, PKG_NAME);
|
|
5545
|
+
const publicPath = join26(cwd, PUBLIC_NAME);
|
|
5546
|
+
const backupPath = join26(cwd, BACKUP_NAME);
|
|
5547
|
+
if (!existsSync21(pkgPath)) {
|
|
5188
5548
|
throw new Error(`\u041D\u0435\u0442 ${PKG_NAME} \u0432 ${cwd}`);
|
|
5189
5549
|
}
|
|
5190
5550
|
const local = readPackageJson(cwd);
|
|
5191
5551
|
if (!local?.name || !local.version) {
|
|
5192
5552
|
throw new Error(`${PKG_NAME}: \u043D\u0443\u0436\u043D\u044B \u043F\u043E\u043B\u044F name \u0438 version`);
|
|
5193
5553
|
}
|
|
5194
|
-
if (!
|
|
5554
|
+
if (!existsSync21(publicPath)) {
|
|
5195
5555
|
await publishPlain(cwd, local, parsed, dry, noCheck);
|
|
5196
5556
|
return;
|
|
5197
5557
|
}
|
|
5198
5558
|
let pub;
|
|
5199
5559
|
try {
|
|
5200
|
-
pub = JSON.parse(
|
|
5560
|
+
pub = JSON.parse(readFileSync29(publicPath, "utf8"));
|
|
5201
5561
|
} catch {
|
|
5202
5562
|
throw new Error(`${PUBLIC_NAME}: \u043D\u0435\u0432\u0430\u043B\u0438\u0434\u043D\u044B\u0439 JSON`);
|
|
5203
5563
|
}
|
|
@@ -5218,10 +5578,10 @@ async function cmdPublish(parsed) {
|
|
|
5218
5578
|
console.log("[publish] --dry: \u043F\u043E\u0434\u043C\u0435\u043D\u0430 \u0438 publish \u043D\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u043B\u0438\u0441\u044C");
|
|
5219
5579
|
return;
|
|
5220
5580
|
}
|
|
5221
|
-
const originalBytes =
|
|
5581
|
+
const originalBytes = readFileSync29(pkgPath);
|
|
5222
5582
|
copyFileSync(pkgPath, backupPath);
|
|
5223
|
-
const indent = detectIndent2(
|
|
5224
|
-
|
|
5583
|
+
const indent = detectIndent2(readFileSync29(publicPath, "utf8"));
|
|
5584
|
+
writeFileSync13(pkgPath, JSON.stringify(pub, null, indent) + `
|
|
5225
5585
|
`, "utf8");
|
|
5226
5586
|
let publishStatus = 1;
|
|
5227
5587
|
try {
|
|
@@ -5235,8 +5595,8 @@ async function cmdPublish(parsed) {
|
|
|
5235
5595
|
console.error(r.error.message);
|
|
5236
5596
|
}
|
|
5237
5597
|
} finally {
|
|
5238
|
-
|
|
5239
|
-
if (
|
|
5598
|
+
writeFileSync13(pkgPath, originalBytes);
|
|
5599
|
+
if (existsSync21(backupPath)) {
|
|
5240
5600
|
try {
|
|
5241
5601
|
unlinkSync(backupPath);
|
|
5242
5602
|
} catch {}
|
|
@@ -5343,13 +5703,13 @@ function detectIndent2(jsonText) {
|
|
|
5343
5703
|
|
|
5344
5704
|
// src/index.ts
|
|
5345
5705
|
function cliVersion() {
|
|
5346
|
-
const here =
|
|
5706
|
+
const here = dirname5(fileURLToPath2(import.meta.url));
|
|
5347
5707
|
for (const p of [
|
|
5348
|
-
|
|
5349
|
-
|
|
5708
|
+
join27(here, "..", "package.json"),
|
|
5709
|
+
join27(here, "package.json")
|
|
5350
5710
|
]) {
|
|
5351
5711
|
try {
|
|
5352
|
-
const v = JSON.parse(
|
|
5712
|
+
const v = JSON.parse(readFileSync30(p, "utf8")).version;
|
|
5353
5713
|
if (typeof v === "string" && v)
|
|
5354
5714
|
return v;
|
|
5355
5715
|
} catch {}
|
|
@@ -5359,7 +5719,7 @@ function cliVersion() {
|
|
|
5359
5719
|
function showVersion() {
|
|
5360
5720
|
console.log(`elcrm ${cliVersion()}`);
|
|
5361
5721
|
}
|
|
5362
|
-
function
|
|
5722
|
+
function showHelp2() {
|
|
5363
5723
|
console.log(`elcrm \u2014 CLI \u0434\u043B\u044F \u044D\u043A\u043E\u0441\u0438\u0441\u0442\u0435\u043C\u044B @elcrm/*
|
|
5364
5724
|
|
|
5365
5725
|
\u0415\u0436\u0435\u0434\u043D\u0435\u0432\u043D\u044B\u0439 \u0446\u0438\u043A\u043B:
|
|
@@ -5374,9 +5734,9 @@ function showHelp() {
|
|
|
5374
5734
|
--fix = doctor --fix (migrate + css)
|
|
5375
5735
|
--test = elcrm test
|
|
5376
5736
|
|
|
5377
|
-
css [--dry] [--dir=\u2026]
|
|
5737
|
+
css [--dry] [--check] [--dir=\u2026]
|
|
5378
5738
|
\u0422\u043E\u043A\u0435\u043D\u044B \u2192 theme*.css; elcrm.css: +\u0440\u0430\u0431\u043E\u0447\u0438\u0435 @import, \u2212\u0431\u0438\u0442\u044B\u0435 (\u043D\u0435\u0442 \u0444\u0430\u0439\u043B\u0430 \u0432 \u043F\u0430\u043A\u0435\u0442\u0435)
|
|
5379
|
-
\u0417\u0430\u0442\u0435\u043C css-sanitize
|
|
5739
|
+
\u0417\u0430\u0442\u0435\u043C css-sanitize. --check: \u043F\u043E\u043A\u0440\u044B\u0442\u0438\u0435 var(--*) \u0431\u0435\u0437 \u0437\u0430\u043F\u0438\u0441\u0438 (exit 1)
|
|
5380
5740
|
|
|
5381
5741
|
docs [--dry] [--keep] [--dir=\u2026] [--lib]
|
|
5382
5742
|
docs/*.elCRM.md (\u0448\u043F\u0430\u0440\u0433\u0430\u043B\u043A\u0438 \u043F\u0430\u043A\u0435\u0442\u043E\u0432)
|
|
@@ -5391,6 +5751,9 @@ function showHelp() {
|
|
|
5391
5751
|
sync \u2014 manifest \u2192 elUI.api/src/kit/manifests + reseed
|
|
5392
5752
|
pull \u2014 emit + sync (postbuild \u043F\u0430\u043A\u0435\u0442\u0430)
|
|
5393
5753
|
|
|
5754
|
+
hub [collect|check|push] [--pkgs=\u2026] [--api=\u2026] [--web=\u2026] [--dry]
|
|
5755
|
+
\u043F\u0430\u043A\u0435\u0442\u044B @elcrm/* \u2192 \u0448\u043F\u0430\u0440\u0433\u0430\u043B\u043A\u0438 CLI \u2192 elUI (\u0431\u0435\u0437 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u0433\u043E \u0441\u0435\u0440\u0432\u0435\u0440\u0430)
|
|
5756
|
+
|
|
5394
5757
|
migrate <name> [--dry] | migrate --list
|
|
5395
5758
|
front|ui = \u043F\u0430\u043A\u0435\u0442 \u043C\u0438\u0433\u0440\u0430\u0446\u0438\u0439 (aliases, form-native, native-html, tokens, \u2026)
|
|
5396
5759
|
\u043F\u043E \u043E\u0434\u043D\u043E\u0439: form-aliases, form-native, native-html, form-tokens, components,
|
|
@@ -5437,7 +5800,7 @@ async function main() {
|
|
|
5437
5800
|
return;
|
|
5438
5801
|
}
|
|
5439
5802
|
if (hasFlag(parsed, "help", "h") || parsed.command === "help" || !parsed.command) {
|
|
5440
|
-
|
|
5803
|
+
showHelp2();
|
|
5441
5804
|
return;
|
|
5442
5805
|
}
|
|
5443
5806
|
if (hasFlag(parsed, "dev")) {
|
|
@@ -5483,6 +5846,9 @@ async function main() {
|
|
|
5483
5846
|
case "kit":
|
|
5484
5847
|
await cmdKit(parsed);
|
|
5485
5848
|
break;
|
|
5849
|
+
case "hub":
|
|
5850
|
+
await cmdHub(parsed);
|
|
5851
|
+
break;
|
|
5486
5852
|
case "publish":
|
|
5487
5853
|
await cmdPublish(parsed);
|
|
5488
5854
|
break;
|