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