@fairfox/polly 0.47.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -14
- package/dist/src/background/index.d.ts +1 -0
- package/dist/src/background/index.js +65 -2
- package/dist/src/background/index.js.map +8 -7
- package/dist/src/background/message-router.js.map +4 -4
- package/dist/src/client/index.js.map +2 -2
- package/dist/src/elysia/index.js.map +1 -1
- package/dist/src/index.js.map +6 -6
- package/dist/src/mesh-node.js.map +3 -3
- package/dist/src/mesh.js +49 -17
- package/dist/src/mesh.js.map +13 -13
- package/dist/src/peer.js +16 -10
- package/dist/src/peer.js.map +7 -7
- package/dist/src/shared/adapters/index.js.map +3 -3
- package/dist/src/shared/lib/context-helpers.js.map +4 -4
- package/dist/src/shared/lib/mesh-client.d.ts +31 -9
- package/dist/src/shared/lib/mesh-network-adapter.d.ts +22 -5
- package/dist/src/shared/lib/mesh-webrtc-adapter.d.ts +24 -1
- package/dist/src/shared/lib/message-bus.js.map +4 -4
- package/dist/src/shared/lib/resource.js.map +3 -3
- package/dist/src/shared/lib/state.js.map +3 -3
- package/dist/src/shared/state/app-state.js.map +3 -3
- package/dist/tools/quality/src/cli.js +217 -74
- package/dist/tools/quality/src/cli.js.map +9 -8
- package/dist/tools/quality/src/index.js +217 -74
- package/dist/tools/quality/src/index.js.map +9 -8
- package/dist/tools/quality/src/plugins/cliche-checks.d.ts +16 -0
- package/dist/tools/quality/src/plugins/core.d.ts +1 -1
- package/dist/tools/test/src/browser/index.js.map +1 -1
- package/dist/tools/test/src/browser/run.js.map +1 -1
- package/dist/tools/verify/src/cli.js +2 -2
- package/dist/tools/verify/src/cli.js.map +8 -8
- package/dist/tools/verify/src/config.js.map +2 -2
- package/dist/tools/visualize/src/cli.js.map +3 -3
- package/package.json +2 -1
|
@@ -1455,15 +1455,157 @@ async function runAttest(opts) {
|
|
|
1455
1455
|
};
|
|
1456
1456
|
}
|
|
1457
1457
|
// tools/quality/src/config.ts
|
|
1458
|
-
import { join as
|
|
1458
|
+
import { join as join11 } from "node:path";
|
|
1459
1459
|
|
|
1460
1460
|
// tools/quality/src/plugins/core.ts
|
|
1461
|
-
import { join as
|
|
1461
|
+
import { join as join10 } from "node:path";
|
|
1462
1462
|
import { Glob as Glob5 } from "bun";
|
|
1463
1463
|
|
|
1464
|
-
// tools/quality/src/plugins/
|
|
1464
|
+
// tools/quality/src/plugins/cliche-checks.ts
|
|
1465
1465
|
import { readdir as readdir3 } from "node:fs/promises";
|
|
1466
1466
|
import { join as join6, relative as relative3 } from "node:path";
|
|
1467
|
+
var SKIP_DIRS_DEFAULT = ["node_modules", ".git", "dist", ".bun", ".cache", "build", "coverage"];
|
|
1468
|
+
var DEFAULT_CODE_ZONES = ["src", "tools", "cli", "scripts", "recipes", "examples"];
|
|
1469
|
+
var DEFAULT_CODE_EXTENSIONS = [".ts", ".tsx"];
|
|
1470
|
+
var BANNER_RE = /^\s*\/\/.*(?:[=]{5,}|[-]{10,}|[─━═]{3,})/;
|
|
1471
|
+
var DECORATIVE_EMOJI_RE = /[\u{1F680}\u{2728}\u{1F3AF}\u{1F389}\u{26A1}\u{1F4E6}\u{1F9E9}]/u;
|
|
1472
|
+
var MARKETING_RE = /\b(comprehensive|robust|elegantly?|seamless(ly)?|leverages?|utili[sz]es?|ensures? that)\b/i;
|
|
1473
|
+
var NOTE_PREFIX_RE = /^\s*\/\/\s*(Note|Important|Warning|TIP|NB)\s*:/;
|
|
1474
|
+
var COMMENTED_CODE_RE = /^\s*\/\/\s+(import|const|let|var|function|class|return|if|for|while|export)\b/;
|
|
1475
|
+
var ALLOW_LINE_RE = /\/\/\s*audit-allow:\s*([\w-]+)/;
|
|
1476
|
+
function isLineAllowed(line, kind) {
|
|
1477
|
+
const match = line.match(ALLOW_LINE_RE);
|
|
1478
|
+
return match !== null && match[1] === kind;
|
|
1479
|
+
}
|
|
1480
|
+
function matchesExtension(name, extensions) {
|
|
1481
|
+
const dotIdx = name.lastIndexOf(".");
|
|
1482
|
+
if (dotIdx < 0)
|
|
1483
|
+
return false;
|
|
1484
|
+
return extensions.has(name.slice(dotIdx));
|
|
1485
|
+
}
|
|
1486
|
+
async function walkFilesByExt(dir, skipDirs, extensions, out) {
|
|
1487
|
+
let entries;
|
|
1488
|
+
try {
|
|
1489
|
+
entries = await readdir3(dir, { withFileTypes: true });
|
|
1490
|
+
} catch {
|
|
1491
|
+
return;
|
|
1492
|
+
}
|
|
1493
|
+
for (const entry of entries) {
|
|
1494
|
+
const fullPath = join6(dir, entry.name);
|
|
1495
|
+
if (entry.isDirectory()) {
|
|
1496
|
+
if (skipDirs.has(entry.name) || entry.name.startsWith("."))
|
|
1497
|
+
continue;
|
|
1498
|
+
await walkFilesByExt(fullPath, skipDirs, extensions, out);
|
|
1499
|
+
} else if (entry.isFile() && matchesExtension(entry.name, extensions)) {
|
|
1500
|
+
out.push(fullPath);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
function resolveCliche(cfg) {
|
|
1505
|
+
const c = cfg ?? {};
|
|
1506
|
+
return {
|
|
1507
|
+
zones: c.zones ?? DEFAULT_CODE_ZONES,
|
|
1508
|
+
skipDirs: new Set(c.skipDirs ?? SKIP_DIRS_DEFAULT),
|
|
1509
|
+
allowFiles: new Set(c.allowFiles ?? []),
|
|
1510
|
+
extensions: new Set(c.extensions ?? DEFAULT_CODE_EXTENSIONS)
|
|
1511
|
+
};
|
|
1512
|
+
}
|
|
1513
|
+
async function collectClicheFiles(rootDir, cfg) {
|
|
1514
|
+
const { zones, skipDirs, allowFiles, extensions } = resolveCliche(cfg);
|
|
1515
|
+
const files = [];
|
|
1516
|
+
for (const zone of zones) {
|
|
1517
|
+
await walkFilesByExt(join6(rootDir, zone), skipDirs, extensions, files);
|
|
1518
|
+
}
|
|
1519
|
+
return { files, allowFiles };
|
|
1520
|
+
}
|
|
1521
|
+
function scanFile2(content, rel, pattern, allowKind) {
|
|
1522
|
+
const out = [];
|
|
1523
|
+
const lines = content.split(`
|
|
1524
|
+
`);
|
|
1525
|
+
for (let i = 0;i < lines.length; i++) {
|
|
1526
|
+
const line = lines[i] ?? "";
|
|
1527
|
+
if (pattern.test(line) && !isLineAllowed(line, allowKind)) {
|
|
1528
|
+
out.push(`${rel}:${i + 1}: ${line.trim()}`);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
return out;
|
|
1532
|
+
}
|
|
1533
|
+
function makeClicheCheck(id, description, pattern, allowKind) {
|
|
1534
|
+
return {
|
|
1535
|
+
id,
|
|
1536
|
+
description,
|
|
1537
|
+
filesRead: async (cfg, root) => {
|
|
1538
|
+
const { files, allowFiles } = await collectClicheFiles(root, cfg);
|
|
1539
|
+
return files.filter((p) => !allowFiles.has(relative3(root, p)));
|
|
1540
|
+
},
|
|
1541
|
+
run: async ({ rootDir, config }) => {
|
|
1542
|
+
const { files, allowFiles } = await collectClicheFiles(rootDir, config);
|
|
1543
|
+
const violations = [];
|
|
1544
|
+
for (const filePath of files) {
|
|
1545
|
+
const rel = relative3(rootDir, filePath);
|
|
1546
|
+
if (allowFiles.has(rel))
|
|
1547
|
+
continue;
|
|
1548
|
+
const content = await Bun.file(filePath).text();
|
|
1549
|
+
violations.push(...scanFile2(content, rel, pattern, allowKind));
|
|
1550
|
+
}
|
|
1551
|
+
return { ok: violations.length === 0, messages: violations };
|
|
1552
|
+
}
|
|
1553
|
+
};
|
|
1554
|
+
}
|
|
1555
|
+
var noBanners = makeClicheCheck("polly:no-banners", "Ban decorative comment dividers (// ─────, // =====, // ----------)", BANNER_RE, "banner");
|
|
1556
|
+
var noDecorativeEmoji = makeClicheCheck("polly:no-decorative-emoji", "Ban a small set of Unicode emoji used as decorative flair in source", DECORATIVE_EMOJI_RE, "emoji");
|
|
1557
|
+
var noNotePrefix = makeClicheCheck("polly:no-note-prefix", "Ban `// Note:` / `// Important:` / `// Warning:` / `// TIP:` / `// NB:` comment prefixes", NOTE_PREFIX_RE, "note-prefix");
|
|
1558
|
+
var noCommentedCode = makeClicheCheck("polly:no-commented-code", "Ban single-line commented-out source (lines starting with `// import|const|let|...`)", COMMENTED_CODE_RE, "commented-code");
|
|
1559
|
+
var DEFAULT_MARKETING_ZONES = [...DEFAULT_CODE_ZONES, "docs"];
|
|
1560
|
+
var DEFAULT_MARKETING_EXTENSIONS = [".ts", ".tsx", ".md"];
|
|
1561
|
+
function resolveMarketing(cfg) {
|
|
1562
|
+
const c = cfg ?? {};
|
|
1563
|
+
return {
|
|
1564
|
+
zones: c.zones ?? DEFAULT_MARKETING_ZONES,
|
|
1565
|
+
skipDirs: new Set(c.skipDirs ?? SKIP_DIRS_DEFAULT),
|
|
1566
|
+
allowFiles: new Set(c.allowFiles ?? []),
|
|
1567
|
+
extensions: new Set(c.extensions ?? DEFAULT_MARKETING_EXTENSIONS)
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
var noMarketing = {
|
|
1571
|
+
id: "polly:no-marketing",
|
|
1572
|
+
description: 'Ban marketing language ("comprehensive / robust / seamless / leverages / ensures that") in source and docs',
|
|
1573
|
+
filesRead: async (cfg, root) => {
|
|
1574
|
+
const { zones, skipDirs, extensions, allowFiles } = resolveMarketing(cfg);
|
|
1575
|
+
const out = [];
|
|
1576
|
+
for (const zone of zones) {
|
|
1577
|
+
await walkFilesByExt(join6(root, zone), skipDirs, extensions, out);
|
|
1578
|
+
}
|
|
1579
|
+
return out.filter((p) => !allowFiles.has(relative3(root, p)));
|
|
1580
|
+
},
|
|
1581
|
+
run: async ({ rootDir, config }) => {
|
|
1582
|
+
const { zones, skipDirs, extensions, allowFiles } = resolveMarketing(config);
|
|
1583
|
+
const violations = [];
|
|
1584
|
+
for (const zone of zones) {
|
|
1585
|
+
const files = [];
|
|
1586
|
+
await walkFilesByExt(join6(rootDir, zone), skipDirs, extensions, files);
|
|
1587
|
+
for (const filePath of files) {
|
|
1588
|
+
const rel = relative3(rootDir, filePath);
|
|
1589
|
+
if (allowFiles.has(rel))
|
|
1590
|
+
continue;
|
|
1591
|
+
const content = await Bun.file(filePath).text();
|
|
1592
|
+
violations.push(...scanFile2(content, rel, MARKETING_RE, "no-marketing"));
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
return { ok: violations.length === 0, messages: violations };
|
|
1596
|
+
}
|
|
1597
|
+
};
|
|
1598
|
+
var clicheCoreChecks = [
|
|
1599
|
+
noBanners,
|
|
1600
|
+
noDecorativeEmoji,
|
|
1601
|
+
noMarketing,
|
|
1602
|
+
noNotePrefix,
|
|
1603
|
+
noCommentedCode
|
|
1604
|
+
];
|
|
1605
|
+
|
|
1606
|
+
// tools/quality/src/plugins/core-checks.ts
|
|
1607
|
+
import { readdir as readdir4 } from "node:fs/promises";
|
|
1608
|
+
import { join as join7, relative as relative4 } from "node:path";
|
|
1467
1609
|
async function semgrepInstalled() {
|
|
1468
1610
|
const which = Bun.spawn(["which", "semgrep"], { stdout: "ignore", stderr: "ignore" });
|
|
1469
1611
|
await which.exited;
|
|
@@ -1522,7 +1664,7 @@ function isTestFile(rel) {
|
|
|
1522
1664
|
function resolveTargetZone(specifier, fromFile, rootDir) {
|
|
1523
1665
|
if (!specifier.startsWith(".") && !specifier.startsWith("/"))
|
|
1524
1666
|
return null;
|
|
1525
|
-
const fromDir =
|
|
1667
|
+
const fromDir = relative4(rootDir, fromFile).split("/").slice(0, -1).join("/");
|
|
1526
1668
|
const segments = `${fromDir}/${specifier}`.split("/");
|
|
1527
1669
|
const resolved = [];
|
|
1528
1670
|
for (const seg of segments) {
|
|
@@ -1539,12 +1681,12 @@ function resolveTargetZone(specifier, fromFile, rootDir) {
|
|
|
1539
1681
|
async function collectScannableFiles(dir, skipDirs, out) {
|
|
1540
1682
|
let entries;
|
|
1541
1683
|
try {
|
|
1542
|
-
entries = await
|
|
1684
|
+
entries = await readdir4(dir, { withFileTypes: true });
|
|
1543
1685
|
} catch {
|
|
1544
1686
|
return;
|
|
1545
1687
|
}
|
|
1546
1688
|
for (const entry of entries) {
|
|
1547
|
-
const fullPath =
|
|
1689
|
+
const fullPath = join7(dir, entry.name);
|
|
1548
1690
|
if (entry.isDirectory()) {
|
|
1549
1691
|
if (!skipDirs.has(entry.name))
|
|
1550
1692
|
await collectScannableFiles(fullPath, skipDirs, out);
|
|
@@ -1586,7 +1728,7 @@ function scanLineForBoundary(line, ctx) {
|
|
|
1586
1728
|
return out;
|
|
1587
1729
|
}
|
|
1588
1730
|
function scanFileForBoundaryViolations(filePath, content, rootDir, zone, bans) {
|
|
1589
|
-
const rel =
|
|
1731
|
+
const rel = relative4(rootDir, filePath);
|
|
1590
1732
|
const lines = content.split(`
|
|
1591
1733
|
`);
|
|
1592
1734
|
const out = [];
|
|
@@ -1610,9 +1752,9 @@ var boundaries = {
|
|
|
1610
1752
|
const skipDirs = new Set(c.skipDirs ?? DEFAULT_BOUNDARIES.skipDirs ?? []);
|
|
1611
1753
|
const out = [];
|
|
1612
1754
|
for (const zone of c.zones ?? DEFAULT_BOUNDARIES.zones ?? []) {
|
|
1613
|
-
await collectScannableFiles(
|
|
1755
|
+
await collectScannableFiles(join7(root, zone), skipDirs, out);
|
|
1614
1756
|
}
|
|
1615
|
-
return out.filter((p) => !isTestFile(
|
|
1757
|
+
return out.filter((p) => !isTestFile(relative4(root, p)));
|
|
1616
1758
|
},
|
|
1617
1759
|
run: async ({ rootDir, config }) => {
|
|
1618
1760
|
const c = { ...DEFAULT_BOUNDARIES, ...config ?? {} };
|
|
@@ -1622,12 +1764,12 @@ var boundaries = {
|
|
|
1622
1764
|
const all = [];
|
|
1623
1765
|
for (const zone of zones) {
|
|
1624
1766
|
const files = [];
|
|
1625
|
-
await collectScannableFiles(
|
|
1767
|
+
await collectScannableFiles(join7(rootDir, zone), skipDirs, files);
|
|
1626
1768
|
const fromBans = bans[zone] ?? [];
|
|
1627
1769
|
if (fromBans.length === 0)
|
|
1628
1770
|
continue;
|
|
1629
1771
|
for (const filePath of files) {
|
|
1630
|
-
if (isTestFile(
|
|
1772
|
+
if (isTestFile(relative4(rootDir, filePath)))
|
|
1631
1773
|
continue;
|
|
1632
1774
|
const content = await Bun.file(filePath).text();
|
|
1633
1775
|
all.push(...scanFileForBoundaryViolations(filePath, content, rootDir, zone, fromBans));
|
|
@@ -1707,9 +1849,9 @@ var serverImports = {
|
|
|
1707
1849
|
const allow = new Set(c.allowFiles ?? []);
|
|
1708
1850
|
const out = [];
|
|
1709
1851
|
for (const p of c.browserPaths ?? DEFAULT_SERVER_IMPORTS.browserPaths) {
|
|
1710
|
-
await collectScannableFiles(
|
|
1852
|
+
await collectScannableFiles(join7(root, p), skipDirs, out);
|
|
1711
1853
|
}
|
|
1712
|
-
return out.filter((p) => !isExcludedFromServerCheck(
|
|
1854
|
+
return out.filter((p) => !isExcludedFromServerCheck(relative4(root, p), allow));
|
|
1713
1855
|
},
|
|
1714
1856
|
run: async ({ rootDir, config }) => {
|
|
1715
1857
|
const c = config ?? {};
|
|
@@ -1719,9 +1861,9 @@ var serverImports = {
|
|
|
1719
1861
|
const violations = [];
|
|
1720
1862
|
for (const p of c.browserPaths ?? DEFAULT_SERVER_IMPORTS.browserPaths) {
|
|
1721
1863
|
const files = [];
|
|
1722
|
-
await collectScannableFiles(
|
|
1864
|
+
await collectScannableFiles(join7(rootDir, p), skipDirs, files);
|
|
1723
1865
|
for (const filePath of files) {
|
|
1724
|
-
const rel =
|
|
1866
|
+
const rel = relative4(rootDir, filePath);
|
|
1725
1867
|
if (isExcludedFromServerCheck(rel, allow))
|
|
1726
1868
|
continue;
|
|
1727
1869
|
const content = await Bun.file(filePath).text();
|
|
@@ -1738,10 +1880,10 @@ var additionalCoreChecks = [
|
|
|
1738
1880
|
];
|
|
1739
1881
|
|
|
1740
1882
|
// tools/quality/src/plugins/extra-checks.ts
|
|
1741
|
-
import { readdir as
|
|
1742
|
-
import { join as
|
|
1883
|
+
import { readdir as readdir5 } from "node:fs/promises";
|
|
1884
|
+
import { join as join8, relative as relative5 } from "node:path";
|
|
1743
1885
|
import { Glob as Glob3 } from "bun";
|
|
1744
|
-
var
|
|
1886
|
+
var SKIP_DIRS_DEFAULT2 = ["node_modules", ".git", "dist", ".bun", ".cache"];
|
|
1745
1887
|
function isCommentLine2(trimmed) {
|
|
1746
1888
|
return trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*");
|
|
1747
1889
|
}
|
|
@@ -1751,12 +1893,12 @@ function isTestFile2(rel) {
|
|
|
1751
1893
|
async function walkScannableFiles(dir, skipDirs, out) {
|
|
1752
1894
|
let entries;
|
|
1753
1895
|
try {
|
|
1754
|
-
entries = await
|
|
1896
|
+
entries = await readdir5(dir, { withFileTypes: true });
|
|
1755
1897
|
} catch {
|
|
1756
1898
|
return;
|
|
1757
1899
|
}
|
|
1758
1900
|
for (const entry of entries) {
|
|
1759
|
-
const fullPath =
|
|
1901
|
+
const fullPath = join8(dir, entry.name);
|
|
1760
1902
|
if (entry.isDirectory()) {
|
|
1761
1903
|
if (!skipDirs.has(entry.name))
|
|
1762
1904
|
await walkScannableFiles(fullPath, skipDirs, out);
|
|
@@ -1792,7 +1934,7 @@ var DEFAULT_FORBIDDEN = {
|
|
|
1792
1934
|
"Date-handling libraries (use Date or built-ins)": ["moment", "moment-timezone"]
|
|
1793
1935
|
},
|
|
1794
1936
|
zones: ["src", "tools", "cli", "scripts"],
|
|
1795
|
-
skipDirs:
|
|
1937
|
+
skipDirs: SKIP_DIRS_DEFAULT2
|
|
1796
1938
|
};
|
|
1797
1939
|
var IMPORT_REGEX2 = /(?:import|export)\s+.*?from\s+['"]([^'"]+)['"]|require\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
1798
1940
|
function lookupBanned(specifier, banned) {
|
|
@@ -1841,9 +1983,9 @@ var forbiddenDeps = {
|
|
|
1841
1983
|
const skipDirs = new Set(c.skipDirs ?? DEFAULT_FORBIDDEN.skipDirs);
|
|
1842
1984
|
const out = [];
|
|
1843
1985
|
for (const z of c.zones ?? DEFAULT_FORBIDDEN.zones) {
|
|
1844
|
-
await walkScannableFiles(
|
|
1986
|
+
await walkScannableFiles(join8(root, z), skipDirs, out);
|
|
1845
1987
|
}
|
|
1846
|
-
return out.filter((p) => !isTestFile2(
|
|
1988
|
+
return out.filter((p) => !isTestFile2(relative5(root, p)));
|
|
1847
1989
|
},
|
|
1848
1990
|
run: async ({ rootDir, config }) => {
|
|
1849
1991
|
const c = config ?? {};
|
|
@@ -1852,9 +1994,9 @@ var forbiddenDeps = {
|
|
|
1852
1994
|
const violations = [];
|
|
1853
1995
|
for (const z of c.zones ?? DEFAULT_FORBIDDEN.zones) {
|
|
1854
1996
|
const files = [];
|
|
1855
|
-
await walkScannableFiles(
|
|
1997
|
+
await walkScannableFiles(join8(rootDir, z), skipDirs, files);
|
|
1856
1998
|
for (const filePath of files) {
|
|
1857
|
-
const rel =
|
|
1999
|
+
const rel = relative5(rootDir, filePath);
|
|
1858
2000
|
if (isTestFile2(rel))
|
|
1859
2001
|
continue;
|
|
1860
2002
|
violations.push(...await scanFileForForbidden(filePath, rel, banned));
|
|
@@ -1867,7 +2009,7 @@ var DEFAULT_NO_STATE_HOOKS = {
|
|
|
1867
2009
|
banned: ["useState", "useReducer", "useSignal"],
|
|
1868
2010
|
allowedFiles: [],
|
|
1869
2011
|
zones: ["src", "tools", "cli", "scripts"],
|
|
1870
|
-
skipDirs:
|
|
2012
|
+
skipDirs: SKIP_DIRS_DEFAULT2
|
|
1871
2013
|
};
|
|
1872
2014
|
function escapeForAlternation(name) {
|
|
1873
2015
|
return name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -1892,10 +2034,10 @@ var noStateHooks = {
|
|
|
1892
2034
|
const allowed = c.allowedFiles ?? DEFAULT_NO_STATE_HOOKS.allowedFiles;
|
|
1893
2035
|
const out = [];
|
|
1894
2036
|
for (const z of c.zones ?? DEFAULT_NO_STATE_HOOKS.zones) {
|
|
1895
|
-
await walkScannableFiles(
|
|
2037
|
+
await walkScannableFiles(join8(root, z), skipDirs, out);
|
|
1896
2038
|
}
|
|
1897
2039
|
return out.filter((p) => {
|
|
1898
|
-
const rel =
|
|
2040
|
+
const rel = relative5(root, p);
|
|
1899
2041
|
return !isTestFile2(rel) && !isAllowedByGlob(rel, allowed);
|
|
1900
2042
|
});
|
|
1901
2043
|
},
|
|
@@ -1910,9 +2052,9 @@ var noStateHooks = {
|
|
|
1910
2052
|
const violations = [];
|
|
1911
2053
|
for (const z of c.zones ?? DEFAULT_NO_STATE_HOOKS.zones) {
|
|
1912
2054
|
const files = [];
|
|
1913
|
-
await walkScannableFiles(
|
|
2055
|
+
await walkScannableFiles(join8(rootDir, z), skipDirs, files);
|
|
1914
2056
|
for (const filePath of files) {
|
|
1915
|
-
const rel =
|
|
2057
|
+
const rel = relative5(rootDir, filePath);
|
|
1916
2058
|
if (isTestFile2(rel) || isAllowedByGlob(rel, allowed))
|
|
1917
2059
|
continue;
|
|
1918
2060
|
violations.push(...await scanFileForHookCalls(filePath, rel, regex));
|
|
@@ -1941,7 +2083,7 @@ var DEFAULT_TYPOGRAPHIC = {
|
|
|
1941
2083
|
typographicZone: [],
|
|
1942
2084
|
straightZone: [],
|
|
1943
2085
|
zones: ["src", "tools", "cli", "scripts"],
|
|
1944
|
-
skipDirs:
|
|
2086
|
+
skipDirs: SKIP_DIRS_DEFAULT2
|
|
1945
2087
|
};
|
|
1946
2088
|
function fileMatchesAnyGlob(rel, globs) {
|
|
1947
2089
|
for (const g of globs) {
|
|
@@ -1958,7 +2100,7 @@ var typographicQuotes = {
|
|
|
1958
2100
|
const skipDirs = new Set(c.skipDirs ?? DEFAULT_TYPOGRAPHIC.skipDirs);
|
|
1959
2101
|
const out = [];
|
|
1960
2102
|
for (const z of c.zones ?? DEFAULT_TYPOGRAPHIC.zones) {
|
|
1961
|
-
await walkScannableFiles(
|
|
2103
|
+
await walkScannableFiles(join8(root, z), skipDirs, out);
|
|
1962
2104
|
}
|
|
1963
2105
|
return out;
|
|
1964
2106
|
},
|
|
@@ -1992,9 +2134,9 @@ async function runTypographicScan(rootDir, c, tz, sz) {
|
|
|
1992
2134
|
const violations = [];
|
|
1993
2135
|
for (const z of c.zones ?? DEFAULT_TYPOGRAPHIC.zones) {
|
|
1994
2136
|
const files = [];
|
|
1995
|
-
await walkScannableFiles(
|
|
2137
|
+
await walkScannableFiles(join8(rootDir, z), skipDirs, files);
|
|
1996
2138
|
for (const filePath of files) {
|
|
1997
|
-
const rel =
|
|
2139
|
+
const rel = relative5(rootDir, filePath);
|
|
1998
2140
|
const inT = fileMatchesAnyGlob(rel, tz);
|
|
1999
2141
|
const inS = fileMatchesAnyGlob(rel, sz);
|
|
2000
2142
|
if (!inT && !inS)
|
|
@@ -2011,10 +2153,10 @@ var extraCoreChecks = [
|
|
|
2011
2153
|
];
|
|
2012
2154
|
|
|
2013
2155
|
// tools/quality/src/plugins/import-checks.ts
|
|
2014
|
-
import { readdir as
|
|
2015
|
-
import { join as
|
|
2156
|
+
import { readdir as readdir6 } from "node:fs/promises";
|
|
2157
|
+
import { join as join9, relative as relative6 } from "node:path";
|
|
2016
2158
|
import { Glob as Glob4 } from "bun";
|
|
2017
|
-
var
|
|
2159
|
+
var SKIP_DIRS_DEFAULT3 = ["node_modules", ".git", "dist", ".bun", ".cache"];
|
|
2018
2160
|
function isCommentLine3(trimmed) {
|
|
2019
2161
|
return trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*");
|
|
2020
2162
|
}
|
|
@@ -2024,12 +2166,12 @@ function isTestFile3(rel) {
|
|
|
2024
2166
|
async function walkScannableFiles2(dir, skipDirs, out) {
|
|
2025
2167
|
let entries;
|
|
2026
2168
|
try {
|
|
2027
|
-
entries = await
|
|
2169
|
+
entries = await readdir6(dir, { withFileTypes: true });
|
|
2028
2170
|
} catch {
|
|
2029
2171
|
return;
|
|
2030
2172
|
}
|
|
2031
2173
|
for (const entry of entries) {
|
|
2032
|
-
const fullPath =
|
|
2174
|
+
const fullPath = join9(dir, entry.name);
|
|
2033
2175
|
if (entry.isDirectory()) {
|
|
2034
2176
|
if (!skipDirs.has(entry.name))
|
|
2035
2177
|
await walkScannableFiles2(fullPath, skipDirs, out);
|
|
@@ -2062,7 +2204,7 @@ var DEFAULT_RELATIVE = {
|
|
|
2062
2204
|
maxDepth: 1,
|
|
2063
2205
|
allowedFiles: [],
|
|
2064
2206
|
zones: ["src", "tools", "cli", "scripts"],
|
|
2065
|
-
skipDirs:
|
|
2207
|
+
skipDirs: SKIP_DIRS_DEFAULT3
|
|
2066
2208
|
};
|
|
2067
2209
|
function relativeDepth(specifier) {
|
|
2068
2210
|
if (!specifier.startsWith(".."))
|
|
@@ -2102,10 +2244,10 @@ var relativeImports = {
|
|
|
2102
2244
|
const allowed = c.allowedFiles ?? DEFAULT_RELATIVE.allowedFiles;
|
|
2103
2245
|
const out = [];
|
|
2104
2246
|
for (const z of c.zones ?? DEFAULT_RELATIVE.zones) {
|
|
2105
|
-
await walkScannableFiles2(
|
|
2247
|
+
await walkScannableFiles2(join9(root, z), skipDirs, out);
|
|
2106
2248
|
}
|
|
2107
2249
|
return out.filter((p) => {
|
|
2108
|
-
const rel =
|
|
2250
|
+
const rel = relative6(root, p);
|
|
2109
2251
|
return !isTestFile3(rel) && !isAllowedByGlob2(rel, allowed);
|
|
2110
2252
|
});
|
|
2111
2253
|
},
|
|
@@ -2117,9 +2259,9 @@ var relativeImports = {
|
|
|
2117
2259
|
const violations = [];
|
|
2118
2260
|
for (const z of c.zones ?? DEFAULT_RELATIVE.zones) {
|
|
2119
2261
|
const files = [];
|
|
2120
|
-
await walkScannableFiles2(
|
|
2262
|
+
await walkScannableFiles2(join9(rootDir, z), skipDirs, files);
|
|
2121
2263
|
for (const filePath of files) {
|
|
2122
|
-
const rel =
|
|
2264
|
+
const rel = relative6(rootDir, filePath);
|
|
2123
2265
|
if (isTestFile3(rel) || isAllowedByGlob2(rel, allowed))
|
|
2124
2266
|
continue;
|
|
2125
2267
|
violations.push(...await scanFileForRelativeViolations(filePath, rel, maxDepth));
|
|
@@ -2134,16 +2276,16 @@ var DEFAULT_TSCONFIG_PATHS = {
|
|
|
2134
2276
|
};
|
|
2135
2277
|
async function findTsconfigs(rootDir, names) {
|
|
2136
2278
|
const out = [];
|
|
2137
|
-
const skipDirs = new Set(
|
|
2279
|
+
const skipDirs = new Set(SKIP_DIRS_DEFAULT3);
|
|
2138
2280
|
async function walk(dir) {
|
|
2139
2281
|
let entries;
|
|
2140
2282
|
try {
|
|
2141
|
-
entries = await
|
|
2283
|
+
entries = await readdir6(dir, { withFileTypes: true });
|
|
2142
2284
|
} catch {
|
|
2143
2285
|
return;
|
|
2144
2286
|
}
|
|
2145
2287
|
for (const entry of entries) {
|
|
2146
|
-
const fullPath =
|
|
2288
|
+
const fullPath = join9(dir, entry.name);
|
|
2147
2289
|
if (entry.isDirectory()) {
|
|
2148
2290
|
if (!skipDirs.has(entry.name))
|
|
2149
2291
|
await walk(fullPath);
|
|
@@ -2172,14 +2314,14 @@ var tsconfigPaths = {
|
|
|
2172
2314
|
try {
|
|
2173
2315
|
parsed = JSON.parse(stripped);
|
|
2174
2316
|
} catch {
|
|
2175
|
-
violations.push(`${
|
|
2317
|
+
violations.push(`${relative6(rootDir, tsconfigPath)}: failed to parse as JSON`);
|
|
2176
2318
|
continue;
|
|
2177
2319
|
}
|
|
2178
2320
|
const paths = parsed.compilerOptions?.paths ?? {};
|
|
2179
2321
|
for (const alias of Object.keys(paths)) {
|
|
2180
2322
|
if (allowed.has(alias))
|
|
2181
2323
|
continue;
|
|
2182
|
-
violations.push(`${
|
|
2324
|
+
violations.push(`${relative6(rootDir, tsconfigPath)}: paths["${alias}"] is set`);
|
|
2183
2325
|
}
|
|
2184
2326
|
}
|
|
2185
2327
|
return { ok: violations.length === 0, messages: violations };
|
|
@@ -2189,7 +2331,7 @@ var DEFAULT_NO_RAW_HTTP = {
|
|
|
2189
2331
|
banned: ["fetch", "XMLHttpRequest", "axios"],
|
|
2190
2332
|
allowedFiles: [],
|
|
2191
2333
|
zones: ["src"],
|
|
2192
|
-
skipDirs:
|
|
2334
|
+
skipDirs: SKIP_DIRS_DEFAULT3
|
|
2193
2335
|
};
|
|
2194
2336
|
function buildBannedCallRegex(banned) {
|
|
2195
2337
|
const alts = banned.map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
|
|
@@ -2222,10 +2364,10 @@ var noRawHttp = {
|
|
|
2222
2364
|
const allowed = cfg.allowedFiles ?? DEFAULT_NO_RAW_HTTP.allowedFiles;
|
|
2223
2365
|
const out = [];
|
|
2224
2366
|
for (const z of cfg.zones ?? DEFAULT_NO_RAW_HTTP.zones) {
|
|
2225
|
-
await walkScannableFiles2(
|
|
2367
|
+
await walkScannableFiles2(join9(root, z), skipDirs, out);
|
|
2226
2368
|
}
|
|
2227
2369
|
return out.filter((p) => {
|
|
2228
|
-
const rel =
|
|
2370
|
+
const rel = relative6(root, p);
|
|
2229
2371
|
return !isTestFile3(rel) && !isAllowedByGlob2(rel, allowed);
|
|
2230
2372
|
});
|
|
2231
2373
|
},
|
|
@@ -2241,9 +2383,9 @@ var noRawHttp = {
|
|
|
2241
2383
|
const violations = [];
|
|
2242
2384
|
for (const z of c.zones ?? DEFAULT_NO_RAW_HTTP.zones) {
|
|
2243
2385
|
const files = [];
|
|
2244
|
-
await walkScannableFiles2(
|
|
2386
|
+
await walkScannableFiles2(join9(rootDir, z), skipDirs, files);
|
|
2245
2387
|
for (const filePath of files) {
|
|
2246
|
-
const rel =
|
|
2388
|
+
const rel = relative6(rootDir, filePath);
|
|
2247
2389
|
if (isTestFile3(rel) || isAllowedByGlob2(rel, allowed))
|
|
2248
2390
|
continue;
|
|
2249
2391
|
violations.push(...await scanFileForRawHttp(filePath, rel, c.canonicalClient, bannedRegex));
|
|
@@ -2282,7 +2424,7 @@ var types = {
|
|
|
2282
2424
|
return [];
|
|
2283
2425
|
},
|
|
2284
2426
|
run: async ({ rootDir, config }) => {
|
|
2285
|
-
const patterns =
|
|
2427
|
+
const patterns = config?.workspaces ?? ["packages/*", "."];
|
|
2286
2428
|
const packages = await findWorkspaces(rootDir, patterns);
|
|
2287
2429
|
if (packages.length === 0)
|
|
2288
2430
|
return { ok: true, messages: ["no workspace packages found"] };
|
|
@@ -2308,7 +2450,7 @@ function aggregateTypesResults(packages, results, rootDir) {
|
|
|
2308
2450
|
if (!pkg || !r || r.ok)
|
|
2309
2451
|
continue;
|
|
2310
2452
|
ok = false;
|
|
2311
|
-
appendTscFailure(messages,
|
|
2453
|
+
appendTscFailure(messages, relative6(rootDir, pkg) || ".", r.output);
|
|
2312
2454
|
}
|
|
2313
2455
|
return { ok, messages };
|
|
2314
2456
|
}
|
|
@@ -2388,10 +2530,10 @@ var secrets = {
|
|
|
2388
2530
|
const c = cfg ?? {};
|
|
2389
2531
|
if (!c.configPath)
|
|
2390
2532
|
return [];
|
|
2391
|
-
return [
|
|
2533
|
+
return [join10(root, c.configPath)];
|
|
2392
2534
|
},
|
|
2393
2535
|
cacheKeyExtras: (cfg) => ({
|
|
2394
|
-
noGit:
|
|
2536
|
+
noGit: cfg?.noGit === false ? "false" : "true"
|
|
2395
2537
|
}),
|
|
2396
2538
|
run: async ({ rootDir, config }) => {
|
|
2397
2539
|
const cfg = config ?? {};
|
|
@@ -2420,8 +2562,8 @@ var gitignoreCrossCheck = {
|
|
|
2420
2562
|
filesRead: (cfg, root) => {
|
|
2421
2563
|
const c = cfg ?? {};
|
|
2422
2564
|
return [
|
|
2423
|
-
|
|
2424
|
-
|
|
2565
|
+
join10(root, c.tomlPath ?? ".gitleaks.toml"),
|
|
2566
|
+
join10(root, c.gitignorePath ?? ".gitignore")
|
|
2425
2567
|
];
|
|
2426
2568
|
},
|
|
2427
2569
|
run: async ({ rootDir, config }) => {
|
|
@@ -2442,7 +2584,7 @@ var gitignoreCrossCheck = {
|
|
|
2442
2584
|
};
|
|
2443
2585
|
}
|
|
2444
2586
|
};
|
|
2445
|
-
var POLLY_CORE_VERSION = "0.
|
|
2587
|
+
var POLLY_CORE_VERSION = "0.48.0";
|
|
2446
2588
|
var pollyCorePlugin = {
|
|
2447
2589
|
name: "polly",
|
|
2448
2590
|
version: POLLY_CORE_VERSION,
|
|
@@ -2453,14 +2595,15 @@ var pollyCorePlugin = {
|
|
|
2453
2595
|
gitignoreCrossCheck,
|
|
2454
2596
|
...additionalCoreChecks,
|
|
2455
2597
|
...extraCoreChecks,
|
|
2456
|
-
...importCoreChecks
|
|
2598
|
+
...importCoreChecks,
|
|
2599
|
+
...clicheCoreChecks
|
|
2457
2600
|
]
|
|
2458
2601
|
};
|
|
2459
2602
|
|
|
2460
2603
|
// tools/quality/src/config.ts
|
|
2461
2604
|
var DEFAULT_PATHS = ["polly.config.ts", "polly.config.js", "polly.config.mjs"];
|
|
2462
2605
|
async function loadQualityConfig(rootDir, explicitPath) {
|
|
2463
|
-
const candidates = explicitPath ? [explicitPath] : DEFAULT_PATHS.map((p) =>
|
|
2606
|
+
const candidates = explicitPath ? [explicitPath] : DEFAULT_PATHS.map((p) => join11(rootDir, p));
|
|
2464
2607
|
for (const path of candidates) {
|
|
2465
2608
|
if (!await Bun.file(path).exists())
|
|
2466
2609
|
continue;
|
|
@@ -2476,10 +2619,10 @@ async function loadQualityConfig(rootDir, explicitPath) {
|
|
|
2476
2619
|
return { plugins: [pollyCorePlugin] };
|
|
2477
2620
|
}
|
|
2478
2621
|
// tools/quality/src/plugins/polly-ui.ts
|
|
2479
|
-
import { readdir as
|
|
2480
|
-
import { join as
|
|
2622
|
+
import { readdir as readdir7 } from "node:fs/promises";
|
|
2623
|
+
import { join as join12, relative as relative7 } from "node:path";
|
|
2481
2624
|
import { Glob as Glob6 } from "bun";
|
|
2482
|
-
var
|
|
2625
|
+
var SKIP_DIRS_DEFAULT4 = ["node_modules", ".git", "dist", ".bun", ".cache"];
|
|
2483
2626
|
function isCommentLine4(trimmed) {
|
|
2484
2627
|
return trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*");
|
|
2485
2628
|
}
|
|
@@ -2493,12 +2636,12 @@ function isAllowedByGlob3(rel, globs) {
|
|
|
2493
2636
|
async function walkScannableFiles3(dir, skipDirs, exts, out) {
|
|
2494
2637
|
let entries;
|
|
2495
2638
|
try {
|
|
2496
|
-
entries = await
|
|
2639
|
+
entries = await readdir7(dir, { withFileTypes: true });
|
|
2497
2640
|
} catch {
|
|
2498
2641
|
return;
|
|
2499
2642
|
}
|
|
2500
2643
|
for (const entry of entries) {
|
|
2501
|
-
const fullPath =
|
|
2644
|
+
const fullPath = join12(dir, entry.name);
|
|
2502
2645
|
if (entry.isDirectory()) {
|
|
2503
2646
|
if (!skipDirs.has(entry.name))
|
|
2504
2647
|
await walkScannableFiles3(fullPath, skipDirs, exts, out);
|
|
@@ -2597,7 +2740,7 @@ var DEFAULT_NO_INLINE_HANDLERS = {
|
|
|
2597
2740
|
],
|
|
2598
2741
|
allowedFiles: [],
|
|
2599
2742
|
zones: ["src"],
|
|
2600
|
-
skipDirs:
|
|
2743
|
+
skipDirs: SKIP_DIRS_DEFAULT4
|
|
2601
2744
|
};
|
|
2602
2745
|
function escapeRegex(name) {
|
|
2603
2746
|
return name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -2633,10 +2776,10 @@ var noInlineHandlers = {
|
|
|
2633
2776
|
const allowed = c.allowedFiles ?? DEFAULT_NO_INLINE_HANDLERS.allowedFiles;
|
|
2634
2777
|
const out = [];
|
|
2635
2778
|
for (const z of c.zones ?? DEFAULT_NO_INLINE_HANDLERS.zones) {
|
|
2636
|
-
await walkScannableFiles3(
|
|
2779
|
+
await walkScannableFiles3(join12(root, z), skipDirs, [".tsx"], out);
|
|
2637
2780
|
}
|
|
2638
2781
|
return out.filter((p) => {
|
|
2639
|
-
const rel =
|
|
2782
|
+
const rel = relative7(root, p);
|
|
2640
2783
|
return !isTestFile4(rel) && !isAllowedByGlob3(rel, allowed);
|
|
2641
2784
|
});
|
|
2642
2785
|
},
|
|
@@ -2651,9 +2794,9 @@ var noInlineHandlers = {
|
|
|
2651
2794
|
const violations = [];
|
|
2652
2795
|
for (const z of c.zones ?? DEFAULT_NO_INLINE_HANDLERS.zones) {
|
|
2653
2796
|
const files = [];
|
|
2654
|
-
await walkScannableFiles3(
|
|
2797
|
+
await walkScannableFiles3(join12(rootDir, z), skipDirs, [".tsx"], files);
|
|
2655
2798
|
for (const filePath of files) {
|
|
2656
|
-
const rel =
|
|
2799
|
+
const rel = relative7(rootDir, filePath);
|
|
2657
2800
|
if (isTestFile4(rel) || isAllowedByGlob3(rel, allowed))
|
|
2658
2801
|
continue;
|
|
2659
2802
|
violations.push(...await scanFileForInlineHandlers(filePath, rel, regex));
|
|
@@ -2903,4 +3046,4 @@ switch (subcommand) {
|
|
|
2903
3046
|
}
|
|
2904
3047
|
process.exit(exitCode);
|
|
2905
3048
|
|
|
2906
|
-
//# debugId=
|
|
3049
|
+
//# debugId=C337428BF011F4B264756E2164756E21
|