basalt-ui 1.21.0 → 1.23.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/AGENTS.md +11 -1
- package/CHANGELOG.md +33 -0
- package/MIGRATING.md +205 -9
- package/README.md +63 -16
- package/agent/rules/basalt-app.md +39 -9
- package/agent/rules/basalt-charts.md +41 -6
- package/agent/rules/basalt-router.md +1 -1
- package/agent/rules/basalt-state.md +4 -4
- package/agent/rules/basalt-tokens.md +25 -4
- package/agent/skills/basalt-app/SKILL.md +4 -3
- package/agent/skills/basalt-charts/SKILL.md +23 -8
- package/agent/templates/DESIGN.md.tpl +3 -1
- package/configs/oxlint-plugin.js +86 -9
- package/configs/oxlint-plugin.test.ts +173 -0
- package/dist/charts/hooks/useBandPlot.d.ts +138 -0
- package/dist/charts/hooks/useBandPlot.d.ts.map +1 -0
- package/dist/charts/hooks/useBandPlot.js +127 -0
- package/dist/charts/index.d.ts +4 -0
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/index.js +14 -0
- package/dist/charts/kinds/BandStrip.d.ts +113 -0
- package/dist/charts/kinds/BandStrip.d.ts.map +1 -0
- package/dist/charts/kinds/BandStrip.js +218 -0
- package/dist/charts/kinds/BandStrip.test.d.ts +2 -0
- package/dist/charts/kinds/BandStrip.test.d.ts.map +1 -0
- package/dist/charts/kinds/Bars.d.ts +5 -1
- package/dist/charts/kinds/Bars.d.ts.map +1 -1
- package/dist/charts/kinds/Bars.js +2 -0
- package/dist/charts/kinds/MirroredBars.d.ts +93 -0
- package/dist/charts/kinds/MirroredBars.d.ts.map +1 -0
- package/dist/charts/kinds/MirroredBars.js +315 -0
- package/dist/charts/kinds/MirroredBars.test.d.ts +2 -0
- package/dist/charts/kinds/MirroredBars.test.d.ts.map +1 -0
- package/dist/charts/kinds/MultiLine.d.ts +5 -1
- package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
- package/dist/charts/kinds/MultiLine.js +2 -0
- package/dist/charts/kinds/StackedArea.d.ts +5 -1
- package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
- package/dist/charts/kinds/StackedArea.js +2 -0
- package/dist/charts/kinds/ZonedLine.d.ts +5 -1
- package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
- package/dist/charts/kinds/ZonedLine.js +2 -0
- package/dist/charts/primitives/CartesianChart.d.ts +18 -2
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
- package/dist/charts/primitives/CartesianChart.js +5 -2
- package/dist/charts/primitives/HatchPattern.d.ts +31 -0
- package/dist/charts/primitives/HatchPattern.d.ts.map +1 -0
- package/dist/charts/primitives/HatchPattern.js +31 -0
- package/dist/cli/index.d.ts +9 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +275 -48
- package/dist/cli/shipped-versions.test.d.ts +2 -0
- package/dist/cli/shipped-versions.test.d.ts.map +1 -0
- package/dist/guard/index.d.ts +67 -0
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +70 -11
- package/dist/vite.d.ts +44 -2
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +71 -26
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/src/charts/hooks/useBandPlot.ts +302 -0
- package/src/charts/index.ts +14 -0
- package/src/charts/kinds/BandStrip.test.tsx +200 -0
- package/src/charts/kinds/BandStrip.tsx +364 -0
- package/src/charts/kinds/Bars.tsx +7 -1
- package/src/charts/kinds/DualPanel.test.tsx +10 -4
- package/src/charts/kinds/MirroredBars.test.tsx +193 -0
- package/src/charts/kinds/MirroredBars.tsx +455 -0
- package/src/charts/kinds/MultiLine.tsx +7 -1
- package/src/charts/kinds/StackedArea.tsx +7 -1
- package/src/charts/kinds/ZonedLine.tsx +7 -1
- package/src/charts/primitives/CartesianChart.test.tsx +86 -4
- package/src/charts/primitives/CartesianChart.tsx +28 -3
- package/src/charts/primitives/HatchPattern.tsx +55 -0
- package/src/cli/check-theme.test.ts +35 -0
- package/src/cli/help.test.ts +5 -1
- package/src/cli/index.ts +552 -79
- package/src/cli/shipped-versions.test.ts +83 -0
- package/src/cli/toolchain-wiring.test.ts +362 -6
- package/src/cli/waiver-audit.test.ts +88 -4
- package/src/guard/check-source.test.ts +293 -0
- package/src/guard/index.ts +209 -20
- package/src/vite.test.ts +112 -0
- package/src/vite.ts +147 -31
package/dist/cli/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import {
|
|
3
4
|
existsSync,
|
|
@@ -14,9 +15,11 @@ import {
|
|
|
14
15
|
checkSource,
|
|
15
16
|
DEFAULT_GUARD_CONFIG,
|
|
16
17
|
GENERATED_HEADER_LINE,
|
|
18
|
+
findAllowAnnotations,
|
|
17
19
|
guardKindRemedy,
|
|
18
20
|
GUARD_RULES,
|
|
19
21
|
guardWaiverHint,
|
|
22
|
+
neutralizeAllowAnnotation,
|
|
20
23
|
TOKENS_ONLY_DISABLED_KINDS,
|
|
21
24
|
unmatchedExemptPatterns
|
|
22
25
|
} from "../guard/index.js";
|
|
@@ -157,6 +160,16 @@ function hasBasaltProject(dir) {
|
|
|
157
160
|
return false;
|
|
158
161
|
}
|
|
159
162
|
}
|
|
163
|
+
function descendantProjects(cwd, depth = 2) {
|
|
164
|
+
if (depth === 0) return [];
|
|
165
|
+
const out = [];
|
|
166
|
+
for (const name of subdirNames(cwd, { skipDotDirs: true })) {
|
|
167
|
+
const dir = resolve(cwd, name);
|
|
168
|
+
if (hasBasaltProject(dir)) out.push(dir);
|
|
169
|
+
else out.push(...descendantProjects(dir, depth - 1));
|
|
170
|
+
}
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
160
173
|
function resolveProjectDir(cwd) {
|
|
161
174
|
const override = process.env["BASALT_CWD"];
|
|
162
175
|
if (override !== void 0 && override.length > 0) {
|
|
@@ -164,7 +177,8 @@ function resolveProjectDir(cwd) {
|
|
|
164
177
|
return { dir, relocatedFrom: dir === cwd ? null : cwd, ambiguous: null };
|
|
165
178
|
}
|
|
166
179
|
if (hasBasaltProject(cwd)) return { dir: cwd, relocatedFrom: null, ambiguous: null };
|
|
167
|
-
const
|
|
180
|
+
const declared = collectWorkspacePackages(cwd).packages.filter((pkg) => pkg.dir !== cwd && hasBasaltProject(pkg.dir)).map((pkg) => pkg.dir);
|
|
181
|
+
const candidates = declared.length > 0 ? declared : descendantProjects(cwd);
|
|
168
182
|
if (candidates.length === 1) {
|
|
169
183
|
return { dir: candidates[0], relocatedFrom: cwd, ambiguous: null };
|
|
170
184
|
}
|
|
@@ -219,6 +233,13 @@ function appShellFiles(rootAbs) {
|
|
|
219
233
|
out.push(...walkSourceFiles(resolve(appDir, "public")));
|
|
220
234
|
return out;
|
|
221
235
|
}
|
|
236
|
+
const PLAIN_JSON_HINT_PATH = "manifest.json";
|
|
237
|
+
function waiverHintFor(relPath, profile) {
|
|
238
|
+
if (profile !== "tokens-only" || !relPath.endsWith(".webmanifest")) {
|
|
239
|
+
return guardWaiverHint(relPath);
|
|
240
|
+
}
|
|
241
|
+
return `${guardWaiverHint(PLAIN_JSON_HINT_PATH)} (basaltAppPlugin would emit the file instead, but it needs basalt's Vite/React layer, which a tokens-only consumer has opted out of.)`;
|
|
242
|
+
}
|
|
222
243
|
function checkTheme(invocationCwd = process.cwd(), flags = []) {
|
|
223
244
|
if (conflictingProfileFlags(flags)) {
|
|
224
245
|
console.error(
|
|
@@ -229,7 +250,7 @@ function checkTheme(invocationCwd = process.cwd(), flags = []) {
|
|
|
229
250
|
const project = resolveProjectDir(invocationCwd);
|
|
230
251
|
if (project.ambiguous !== null) {
|
|
231
252
|
console.error(
|
|
232
|
-
`\u2716 basalt-ui check-theme: no basalt config at ${invocationCwd}, and ${project.ambiguous.length}
|
|
253
|
+
`\u2716 basalt-ui check-theme: no basalt config at ${invocationCwd}, and ${project.ambiguous.length} packages below it carry one (${project.ambiguous.map((d) => relativePosix(invocationCwd, d)).join(", ")}) \u2014 run it from one of them, or set BASALT_CWD to pick.`
|
|
233
254
|
);
|
|
234
255
|
return 1;
|
|
235
256
|
}
|
|
@@ -329,7 +350,9 @@ function checkTheme(invocationCwd = process.cwd(), flags = []) {
|
|
|
329
350
|
`);
|
|
330
351
|
}
|
|
331
352
|
const presentKinds = [...new Set(findings.map((f) => f.kind))].toSorted();
|
|
332
|
-
const waiverHints = [
|
|
353
|
+
const waiverHints = [
|
|
354
|
+
...new Set(findings.map((f) => waiverHintFor(f.relPath, profile)))
|
|
355
|
+
].toSorted();
|
|
333
356
|
console.error(["Fix:", ...presentKinds.map(guardKindRemedy), ...waiverHints].join(" "));
|
|
334
357
|
if (findings.some((f) => SERIES_MODULE_HINT_RE.test(f.relPath))) {
|
|
335
358
|
console.error(
|
|
@@ -338,20 +361,89 @@ function checkTheme(invocationCwd = process.cwd(), flags = []) {
|
|
|
338
361
|
}
|
|
339
362
|
return errors.length > 0 ? 1 : 0;
|
|
340
363
|
}
|
|
341
|
-
const AUDIT_NEUTRALIZED_TOKEN = "basalt-audit-neutralized";
|
|
342
364
|
function findingKey(f) {
|
|
343
365
|
return `${f.relPath}:${f.line}:${f.kind}`;
|
|
344
366
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
367
|
+
function resolveToolBin(dir, name) {
|
|
368
|
+
let current = dir;
|
|
369
|
+
for (; ; ) {
|
|
370
|
+
const candidate = resolve(current, "node_modules/.bin", name);
|
|
371
|
+
if (existsSync(candidate)) return candidate;
|
|
372
|
+
const parent = resolve(current, "..");
|
|
373
|
+
if (parent === current) break;
|
|
374
|
+
current = parent;
|
|
375
|
+
}
|
|
376
|
+
const probe = spawnSync(name, ["--version"], { stdio: "ignore", timeout: 1e4 });
|
|
377
|
+
return probe.error === void 0 && probe.status === 0 ? name : null;
|
|
378
|
+
}
|
|
379
|
+
function diagnosticCounts(diagnostics, filename) {
|
|
380
|
+
const counts = /* @__PURE__ */ new Map();
|
|
381
|
+
for (const d of diagnostics) {
|
|
382
|
+
if (d.filename !== filename) continue;
|
|
383
|
+
const code = typeof d.code === "string" ? d.code : "";
|
|
384
|
+
const rule = /^basalt\((.+)\)$/.exec(code)?.[1];
|
|
385
|
+
if (rule === void 0) continue;
|
|
386
|
+
const line = d.labels?.[0]?.span?.line;
|
|
387
|
+
const key = `${typeof line === "number" ? line : 0}:${rule}`;
|
|
388
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
389
|
+
}
|
|
390
|
+
return counts;
|
|
391
|
+
}
|
|
392
|
+
function probePluginRules(cwd, guardCfg, probes, sources) {
|
|
393
|
+
if (probes.length === 0) return /* @__PURE__ */ new Map();
|
|
394
|
+
const bin = resolveToolBin(cwd, "oxlint");
|
|
395
|
+
if (bin === null) return null;
|
|
396
|
+
const written = [];
|
|
397
|
+
const probePaths = /* @__PURE__ */ new Map();
|
|
398
|
+
try {
|
|
399
|
+
for (const probe of probes) {
|
|
400
|
+
const probed = neutralizeAllowAnnotation(sources.get(probe.rel) ?? "", probe.line, guardCfg);
|
|
401
|
+
const dot = probe.rel.lastIndexOf(".");
|
|
402
|
+
const rel = dot === -1 ? `${probe.rel}.basalt-audit-${probe.slot}` : `${probe.rel.slice(0, dot)}.basalt-audit-${probe.slot}${probe.rel.slice(dot)}`;
|
|
403
|
+
const abs = resolve(cwd, rel);
|
|
404
|
+
if (existsSync(abs)) continue;
|
|
405
|
+
writeFileSync(abs, probed, "utf8");
|
|
406
|
+
written.push(abs);
|
|
407
|
+
probePaths.set(probe.slot, rel);
|
|
408
|
+
}
|
|
409
|
+
if (probePaths.size === 0) return null;
|
|
410
|
+
const targets = [...new Set(probes.map((p) => p.rel)), ...probePaths.values()];
|
|
411
|
+
const run2 = spawnSync(bin, ["--format=json", "--no-error-on-unmatched-pattern", ...targets], {
|
|
412
|
+
cwd,
|
|
413
|
+
encoding: "utf8",
|
|
414
|
+
timeout: 12e4,
|
|
415
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
416
|
+
});
|
|
417
|
+
if (run2.error !== void 0 || typeof run2.stdout !== "string") return null;
|
|
418
|
+
let diagnostics;
|
|
419
|
+
try {
|
|
420
|
+
diagnostics = JSON.parse(run2.stdout).diagnostics ?? [];
|
|
421
|
+
} catch {
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
424
|
+
const verdicts = /* @__PURE__ */ new Map();
|
|
425
|
+
for (const probe of probes) {
|
|
426
|
+
const probeRel = probePaths.get(probe.slot);
|
|
427
|
+
if (probeRel === void 0) continue;
|
|
428
|
+
const before = diagnosticCounts(diagnostics, probe.rel);
|
|
429
|
+
const after = diagnosticCounts(diagnostics, probeRel);
|
|
430
|
+
const revealed = [];
|
|
431
|
+
for (const [key, count] of after) {
|
|
432
|
+
if (count <= (before.get(key) ?? 0)) continue;
|
|
433
|
+
const [line = "", rule = ""] = key.split(":");
|
|
434
|
+
revealed.push(`${rule}@${line}`);
|
|
435
|
+
}
|
|
436
|
+
verdicts.set(probe.slot, revealed.toSorted());
|
|
437
|
+
}
|
|
438
|
+
return verdicts;
|
|
439
|
+
} finally {
|
|
440
|
+
for (const abs of written) {
|
|
441
|
+
try {
|
|
442
|
+
unlinkSync(abs);
|
|
443
|
+
} catch {
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
355
447
|
}
|
|
356
448
|
function auditAllows(cwd, cfg, guardCfg, scanned) {
|
|
357
449
|
const token = guardCfg.allowComment;
|
|
@@ -363,6 +455,7 @@ basalt-ui check-theme --audit-allows \u2014 ${cwd}
|
|
|
363
455
|
let outOfReach = 0;
|
|
364
456
|
let unaccountable = 0;
|
|
365
457
|
const waiverLines = [];
|
|
458
|
+
const pluginProbes = [];
|
|
366
459
|
const sources = /* @__PURE__ */ new Map();
|
|
367
460
|
for (const rel of scanned) sources.set(rel, readFileSync(resolve(cwd, rel), "utf8"));
|
|
368
461
|
for (const rel of scanned) {
|
|
@@ -375,31 +468,60 @@ basalt-ui check-theme --audit-allows \u2014 ${cwd}
|
|
|
375
468
|
const unscopedAt = new Map(
|
|
376
469
|
baseline.filter((f) => f.kind === "theme-allow-unscoped").map((f) => [f.line, f.token])
|
|
377
470
|
);
|
|
378
|
-
const
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const note = unscopedAt.get(
|
|
471
|
+
for (const site of findAllowAnnotations(text, rel, guardCfg)) {
|
|
472
|
+
const revealed = checkSource(
|
|
473
|
+
neutralizeAllowAnnotation(text, site.line, guardCfg),
|
|
474
|
+
rel,
|
|
475
|
+
guardCfg
|
|
476
|
+
).filter((f) => f.kind !== "theme-allow-unscoped" && !baselineKeys.has(findingKey(f))).map((f) => `${f.kind}@${f.line}`);
|
|
477
|
+
const note = unscopedAt.get(site.line);
|
|
385
478
|
if (note !== void 0) unaccountable++;
|
|
386
|
-
const
|
|
479
|
+
const label = ` ${rel}:${site.line}`.padEnd(52);
|
|
387
480
|
const suffix = note === void 0 ? "" : ` [${note}]`;
|
|
388
|
-
const ids = annotationRuleIds((line ?? "").slice((line ?? "").indexOf(token) + token.length));
|
|
389
481
|
if (revealed.length > 0) {
|
|
390
482
|
live++;
|
|
391
|
-
waiverLines.push(`${
|
|
392
|
-
|
|
483
|
+
waiverLines.push(`${label} suppresses ${[...new Set(revealed)].join(", ")}${suffix}`);
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
if (site.pluginRules.length > 0 && site.guardKinds.length === 0) {
|
|
487
|
+
pluginProbes.push({
|
|
488
|
+
slot: waiverLines.length,
|
|
489
|
+
rel,
|
|
490
|
+
line: site.line,
|
|
491
|
+
ids: site.pluginRules,
|
|
492
|
+
site: label,
|
|
493
|
+
suffix
|
|
494
|
+
});
|
|
495
|
+
waiverLines.push("");
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
if (site.guardKinds.length === 0 && site.unknownRules.length > 0) {
|
|
393
499
|
outOfReach++;
|
|
394
500
|
waiverLines.push(
|
|
395
|
-
`${
|
|
501
|
+
`${label} scoped to ${site.unknownRules.join(", ")} \u2014 names no guard kind and no plugin rule, so this audit cannot judge it (most likely a typo, which theme-allow-unscoped reports)${suffix}`
|
|
396
502
|
);
|
|
397
|
-
|
|
398
|
-
dead++;
|
|
399
|
-
waiverLines.push(`${site} SUPPRESSES NOTHING \u2014 dead, delete it${suffix}`);
|
|
503
|
+
continue;
|
|
400
504
|
}
|
|
505
|
+
dead++;
|
|
506
|
+
waiverLines.push(`${label} SUPPRESSES NOTHING \u2014 dead, delete it${suffix}`);
|
|
401
507
|
}
|
|
402
508
|
}
|
|
509
|
+
const pluginVerdicts = probePluginRules(cwd, guardCfg, pluginProbes, sources);
|
|
510
|
+
for (const probe of pluginProbes) {
|
|
511
|
+
const revealed = pluginVerdicts?.get(probe.slot);
|
|
512
|
+
if (revealed === void 0) {
|
|
513
|
+
outOfReach++;
|
|
514
|
+
waiverLines[probe.slot] = `${probe.site} scoped to ${probe.ids.join(", ")} \u2014 an oxlint plugin rule, and oxlint could not be run here, so this audit cannot judge it${probe.suffix}`;
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
if (revealed.length > 0) {
|
|
518
|
+
live++;
|
|
519
|
+
waiverLines[probe.slot] = `${probe.site} suppresses ${revealed.join(", ")} (oxlint)${probe.suffix}`;
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
dead++;
|
|
523
|
+
waiverLines[probe.slot] = `${probe.site} SUPPRESSES NOTHING \u2014 dead, delete it (proved by re-running oxlint over the file with this annotation neutralized)${probe.suffix}`;
|
|
524
|
+
}
|
|
403
525
|
lines.push(`${token} annotations (${waiverLines.length}):`);
|
|
404
526
|
lines.push(...waiverLines.length === 0 ? [" (none)"] : waiverLines);
|
|
405
527
|
const exemptLines = [];
|
|
@@ -452,7 +574,11 @@ basalt.exemptRules entries (${exemptCount}):`);
|
|
|
452
574
|
lines.push(...exemptLines.length === 0 ? [" (none)"] : exemptLines);
|
|
453
575
|
lines.push(
|
|
454
576
|
`
|
|
455
|
-
${live} live, ${dead} dead, ${outOfReach}
|
|
577
|
+
${live} live, ${dead} dead, ${outOfReach} unjudgeable, ${unaccountable} unaccountable (reported as theme-allow-unscoped by a normal run).`
|
|
578
|
+
);
|
|
579
|
+
const includes = cfg.include ?? [];
|
|
580
|
+
lines.push(
|
|
581
|
+
`Scope: the ${scanned.length} file(s) check-theme scans \u2014 everything under basalt.roots (${resolveRoots(cfg).join(", ")}), plus each root's sibling index.html and public/ tree, ` + (includes.length === 0 ? "plus anything named in basalt.include (none). " : `plus basalt.include (${includes.join(", ")}). `) + "A waiver in a file none of those reach is not audited \u2014 widen roots, or name it in basalt.include, or accept that nothing polices that file."
|
|
456
582
|
);
|
|
457
583
|
if (dead > 0) {
|
|
458
584
|
lines.push(
|
|
@@ -746,6 +872,16 @@ function migrateLegacyOxfmt(cwd, pkgRoot, manifest) {
|
|
|
746
872
|
const shipped = readSource(pkgRoot, "configs/oxfmt.json");
|
|
747
873
|
if (shipped !== null && onDisk === shipped) unlinkSync(legacyAbs);
|
|
748
874
|
}
|
|
875
|
+
const DESIGN_VERSION_LINE = /^(> Managed by basalt-ui) \(\d+\.\d+\.\d+\)\./m;
|
|
876
|
+
function migrateDesignVersionLine(cwd) {
|
|
877
|
+
const dest = resolve(cwd, "DESIGN.md");
|
|
878
|
+
const onDisk = readIfExists(dest);
|
|
879
|
+
if (onDisk === null || !DESIGN_VERSION_LINE.test(onDisk)) return;
|
|
880
|
+
writeFileEnsuringDir(
|
|
881
|
+
dest,
|
|
882
|
+
onDisk.replace(DESIGN_VERSION_LINE, "$1 \u2014 run `basalt-ui doctor` for the version.")
|
|
883
|
+
);
|
|
884
|
+
}
|
|
749
885
|
function writeFileEnsuringDir(abs, content) {
|
|
750
886
|
mkdirSync(dirname(abs), { recursive: true });
|
|
751
887
|
writeFileSync(abs, content);
|
|
@@ -969,6 +1105,38 @@ function inspectLefthookSeam(repoRoot) {
|
|
|
969
1105
|
if (entry === void 0) return { kind: "unwired", file };
|
|
970
1106
|
return existsSync(resolve(repoRoot, entry)) ? { kind: "ok", file, entry } : { kind: "broken", file, entry };
|
|
971
1107
|
}
|
|
1108
|
+
const LEFTHOOK_GUARD_RUN = /^\s*run:\s*.*\bcheck-theme\b/m;
|
|
1109
|
+
function lefthookDump(repoRoot) {
|
|
1110
|
+
const localBin = resolve(repoRoot, "node_modules/.bin/lefthook");
|
|
1111
|
+
const bin = existsSync(localBin) ? localBin : "lefthook";
|
|
1112
|
+
try {
|
|
1113
|
+
const result = spawnSync(bin, ["dump"], {
|
|
1114
|
+
cwd: repoRoot,
|
|
1115
|
+
encoding: "utf8",
|
|
1116
|
+
timeout: 1e4,
|
|
1117
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1118
|
+
});
|
|
1119
|
+
if (result.error !== void 0 || result.status !== 0) return null;
|
|
1120
|
+
return result.stdout;
|
|
1121
|
+
} catch {
|
|
1122
|
+
return null;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
function inspectLefthookGate(repoRoot) {
|
|
1126
|
+
const seam = inspectLefthookSeam(repoRoot);
|
|
1127
|
+
if (seam.kind === "no-file") return { kind: "no-file" };
|
|
1128
|
+
if (seam.kind === "ok") return { kind: "extends-ok", file: seam.file, entry: seam.entry };
|
|
1129
|
+
if (seam.kind === "broken") {
|
|
1130
|
+
return { kind: "extends-broken", file: seam.file, entry: seam.entry };
|
|
1131
|
+
}
|
|
1132
|
+
const dump = lefthookDump(repoRoot);
|
|
1133
|
+
if (dump !== null) {
|
|
1134
|
+
return LEFTHOOK_GUARD_RUN.test(dump) ? { kind: "wired", file: seam.file, proof: "dump" } : { kind: "absent", file: seam.file };
|
|
1135
|
+
}
|
|
1136
|
+
const raw = readIfExists(resolve(repoRoot, seam.file)) ?? "";
|
|
1137
|
+
if (LEFTHOOK_GUARD_RUN.test(raw)) return { kind: "wired", file: seam.file, proof: "config" };
|
|
1138
|
+
return { kind: "advisory", file: seam.file };
|
|
1139
|
+
}
|
|
972
1140
|
function mergeOxlintExtends(cwd, presetPath) {
|
|
973
1141
|
const abs = resolve(cwd, ".oxlintrc.json");
|
|
974
1142
|
const raw = readIfExists(abs);
|
|
@@ -1131,15 +1299,60 @@ function readOxlintPresetPlugins(pkgRoot) {
|
|
|
1131
1299
|
return [];
|
|
1132
1300
|
}
|
|
1133
1301
|
}
|
|
1134
|
-
function
|
|
1302
|
+
function findManifestAbove(dir) {
|
|
1303
|
+
let current = resolve(dir, "..");
|
|
1304
|
+
for (; ; ) {
|
|
1305
|
+
if (existsSync(resolve(current, MANIFEST_PATH))) return current;
|
|
1306
|
+
const parent = resolve(current, "..");
|
|
1307
|
+
if (parent === current) return null;
|
|
1308
|
+
current = parent;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
function sync(opts = {}, invocationCwd = process.cwd()) {
|
|
1312
|
+
const syncFlags = opts.flags ?? [];
|
|
1313
|
+
if (conflictingProfileFlags(syncFlags)) {
|
|
1314
|
+
console.error("basalt-ui sync: --tokens-only and --framework are alternatives \u2014 pass one.");
|
|
1315
|
+
return 1;
|
|
1316
|
+
}
|
|
1317
|
+
const project = resolveProjectDir(invocationCwd);
|
|
1318
|
+
if (project.ambiguous !== null) {
|
|
1319
|
+
console.error(
|
|
1320
|
+
`\u2716 basalt-ui sync: no basalt config at ${invocationCwd}, and ${project.ambiguous.length} packages below it carry one (${project.ambiguous.map((d) => relativePosix(invocationCwd, d)).join(", ")}) \u2014 run it from one of them, or set BASALT_CWD to pick.`
|
|
1321
|
+
);
|
|
1322
|
+
return 1;
|
|
1323
|
+
}
|
|
1324
|
+
const cwd = project.dir;
|
|
1325
|
+
if (project.relocatedFrom !== null) {
|
|
1326
|
+
console.log(
|
|
1327
|
+
`basalt-ui sync: no basalt config at ${project.relocatedFrom} \u2014 running in ${relativePosix(project.relocatedFrom, cwd)}, where it lives.`
|
|
1328
|
+
);
|
|
1329
|
+
}
|
|
1330
|
+
if (declaredProfile(readBasaltConfig(cwd), syncFlags) === "tokens-only") {
|
|
1331
|
+
console.log(
|
|
1332
|
+
`basalt-ui sync: ${MANIFEST_PATH}: n/a \u2014 a tokens-only consumer has no scaffold to reconcile. The token layer is refreshed by re-running \`basalt-ui tokens:css\`, and \`tokens:css --check\` is its drift gate. Pass --framework to force the full profile.`
|
|
1333
|
+
);
|
|
1334
|
+
return 0;
|
|
1335
|
+
}
|
|
1336
|
+
if (!existsSync(resolve(cwd, MANIFEST_PATH))) {
|
|
1337
|
+
const elsewhere = findManifestAbove(cwd);
|
|
1338
|
+
const wouldWrite = managedFiles(resolvePeerFlags(cwd, {}), resolvePlacement(cwd)).length;
|
|
1339
|
+
console.error(
|
|
1340
|
+
`\u2716 basalt-ui sync: no ${MANIFEST_PATH} at ${cwd} \u2014 refusing to scaffold. \`sync\` refreshes an EXISTING basalt install; creating one is \`basalt-ui init\`'s decision, and continuing here would write ${wouldWrite} managed file(s) into this directory.` + (elsewhere === null ? " No manifest exists at any ancestor either \u2014 run `basalt-ui init` here if this package really is meant to be a consumer." : ` This repo's install is at ${relativePosix(cwd, elsewhere)} (${elsewhere}) \u2014 run sync there, or set BASALT_CWD to it.`)
|
|
1341
|
+
);
|
|
1342
|
+
return 1;
|
|
1343
|
+
}
|
|
1135
1344
|
const rootsState = reconcileRoots(cwd, { write: opts.check !== true });
|
|
1136
1345
|
const ctx = renderContext(cwd);
|
|
1137
1346
|
const manifest = readManifest(cwd);
|
|
1138
|
-
if (!opts.check)
|
|
1347
|
+
if (!opts.check) {
|
|
1348
|
+
migrateLegacyOxfmt(cwd, ctx.pkgRoot, manifest);
|
|
1349
|
+
migrateDesignVersionLine(cwd);
|
|
1350
|
+
}
|
|
1139
1351
|
const peers = resolvePeerFlags(cwd, {});
|
|
1140
1352
|
const placement = resolvePlacement(cwd);
|
|
1141
1353
|
const files = managedFiles(peers, placement);
|
|
1142
1354
|
let updated = 0;
|
|
1355
|
+
let created = 0;
|
|
1143
1356
|
let recreated = 0;
|
|
1144
1357
|
let skippedDrift = 0;
|
|
1145
1358
|
let staleForCheck = 0;
|
|
@@ -1151,10 +1364,12 @@ function sync(opts = {}, cwd = process.cwd()) {
|
|
|
1151
1364
|
missingSources.push(file.source);
|
|
1152
1365
|
continue;
|
|
1153
1366
|
}
|
|
1367
|
+
const tracked = manifest.files[file.dest] !== void 0;
|
|
1154
1368
|
if (file.mode === "seed") {
|
|
1155
1369
|
if (state.current === null && !opts.check) {
|
|
1156
1370
|
manifest.files[file.dest] = writeUnit(file, cwd, state.desired);
|
|
1157
|
-
recreated++;
|
|
1371
|
+
if (tracked) recreated++;
|
|
1372
|
+
else created++;
|
|
1158
1373
|
}
|
|
1159
1374
|
continue;
|
|
1160
1375
|
}
|
|
@@ -1172,8 +1387,9 @@ function sync(opts = {}, cwd = process.cwd()) {
|
|
|
1172
1387
|
staleForCheck++;
|
|
1173
1388
|
if (opts.check) continue;
|
|
1174
1389
|
manifest.files[file.dest] = writeUnit(file, cwd, state.desired);
|
|
1175
|
-
if (kind
|
|
1176
|
-
else
|
|
1390
|
+
if (kind !== "missing") updated++;
|
|
1391
|
+
else if (tracked) recreated++;
|
|
1392
|
+
else created++;
|
|
1177
1393
|
}
|
|
1178
1394
|
if (!placement.isPackageRepoRoot) {
|
|
1179
1395
|
console.log(
|
|
@@ -1222,7 +1438,7 @@ function sync(opts = {}, cwd = process.cwd()) {
|
|
|
1222
1438
|
writeFileEnsuringDir(resolve(cwd, MANIFEST_PATH), `${JSON.stringify(manifest, null, 2)}
|
|
1223
1439
|
`);
|
|
1224
1440
|
console.log(
|
|
1225
|
-
`basalt-ui sync: ${updated} updated, ${recreated} recreated, ${skippedDrift} skipped (drift).`
|
|
1441
|
+
`basalt-ui sync: ${updated} updated, ${created} created, ${recreated} recreated, ${skippedDrift} skipped (drift).`
|
|
1226
1442
|
);
|
|
1227
1443
|
if (driftLines.length > 0) {
|
|
1228
1444
|
console.log("Locally-edited files were skipped (run with --force to overwrite):");
|
|
@@ -1454,7 +1670,7 @@ function doctor(invocationCwd = process.cwd(), flags = []) {
|
|
|
1454
1670
|
`
|
|
1455
1671
|
basalt-ui doctor \u2014 ${invocationCwd}
|
|
1456
1672
|
|
|
1457
|
-
\u2716 no basalt config at ${invocationCwd}, and ${project.ambiguous.length}
|
|
1673
|
+
\u2716 no basalt config at ${invocationCwd}, and ${project.ambiguous.length} packages below it carry one (${project.ambiguous.map((d) => relativePosix(invocationCwd, d)).join(", ")}) \u2014 run doctor from one of them, or set BASALT_CWD to pick.
|
|
1458
1674
|
|
|
1459
1675
|
1 hard failure(s), 0 warning(s).
|
|
1460
1676
|
`
|
|
@@ -1630,22 +1846,30 @@ basalt-ui doctor \u2014 ${cwd}
|
|
|
1630
1846
|
}
|
|
1631
1847
|
}
|
|
1632
1848
|
const repoRoot = findRepoRoot(cwd);
|
|
1633
|
-
const
|
|
1849
|
+
const lefthookGate = profile === "tokens-only" ? { kind: "n/a" } : inspectLefthookGate(repoRoot);
|
|
1634
1850
|
const lefthookCorrect = shippedAssetPath(install, repoRoot, "configs/lefthook.yml");
|
|
1635
|
-
if (
|
|
1851
|
+
if (lefthookGate.kind === "n/a") {
|
|
1636
1852
|
pass("lefthook-preset: n/a \u2014 a tokens-only consumer wires its own hooks");
|
|
1637
|
-
} else if (
|
|
1853
|
+
} else if (lefthookGate.kind === "no-file") {
|
|
1638
1854
|
pass(`lefthook-preset: n/a \u2014 no lefthook config at ${repoRoot}`);
|
|
1639
|
-
} else if (
|
|
1640
|
-
|
|
1641
|
-
|
|
1855
|
+
} else if (lefthookGate.kind === "extends-ok") {
|
|
1856
|
+
pass(`${lefthookGate.file} extends the shipped lefthook preset (${lefthookGate.entry})`);
|
|
1857
|
+
} else if (lefthookGate.kind === "wired") {
|
|
1858
|
+
pass(
|
|
1859
|
+
`lefthook-preset: ${lefthookGate.file} does not extend the shipped preset, but a pre-commit command runs check-theme directly \u2014 the gate exists (read from ` + (lefthookGate.proof === "dump" ? "`lefthook dump`, so extends/include/root: are all resolved)." : "the config text; `lefthook dump` was not runnable here, so an `include:` or a remote config was not consulted).")
|
|
1642
1860
|
);
|
|
1643
|
-
} else if (
|
|
1861
|
+
} else if (lefthookGate.kind === "extends-broken") {
|
|
1644
1862
|
fail(
|
|
1645
|
-
`${
|
|
1863
|
+
`${lefthookGate.file} extends "${lefthookGate.entry}", which does not exist (${resolve(repoRoot, lefthookGate.entry)}) \u2014 lefthook merges a missing extends target into ZERO commands and still exits 0, so this repo has no pre-commit gate and \`lefthook dump\` looks clean. Repoint it at "${lefthookCorrect}".`
|
|
1864
|
+
);
|
|
1865
|
+
} else if (lefthookGate.kind === "absent") {
|
|
1866
|
+
warn(
|
|
1867
|
+
`${lefthookGate.file}: \`lefthook dump\` resolves the merged config and NO pre-commit command runs check-theme \u2014 the theme guard is not gating commits. Either add "extends: [${lefthookCorrect}]", or add your own command running \`bunx basalt-ui check-theme\` (with \`root:\` if it must run in a subdirectory).`
|
|
1646
1868
|
);
|
|
1647
1869
|
} else {
|
|
1648
|
-
|
|
1870
|
+
warn(
|
|
1871
|
+
`${lefthookGate.file} names no basalt gate and \`lefthook dump\` could not be run here, so this check cannot tell a missing gate from one wired through an \`include:\` or a remote config it never read \u2014 treat it as advisory. If the guard really is unwired, add "extends: [${lefthookCorrect}]" or your own command running \`bunx basalt-ui check-theme\`.`
|
|
1872
|
+
);
|
|
1649
1873
|
}
|
|
1650
1874
|
const publicDir = resolve(cwd, "public");
|
|
1651
1875
|
if (profile === "framework" && existsSync(publicDir)) {
|
|
@@ -2017,7 +2241,7 @@ async function guardHook(cwd = process.cwd()) {
|
|
|
2017
2241
|
}
|
|
2018
2242
|
return 0;
|
|
2019
2243
|
}
|
|
2020
|
-
const USAGE = "Usage: basalt-ui <init [--with-router] [--with-query] [--merge-lint]
|
|
2244
|
+
const USAGE = "Usage: basalt-ui <init [--with-router] [--with-query] [--merge-lint] |\n sync [--force] [--check] [--tokens-only|--framework] |\n check-theme [--audit-allows] | check-coverage | info [--json] |\n doctor [--tokens-only|--framework] | guard-hook | tokens:css | fonts:css | help>\n\ncheck-theme [--tokens-only|--framework] [--audit-allows]\n --audit-allows reports instead of scanning: every `theme-allow` annotation and every\n `basalt.exemptRules` entry, with what each one still suppresses \u2014 proved by re-running the\n guard with that one waiver neutralized, not by reading its text. Exits 1 on a waiver that\n suppresses nothing (dead), which is what makes it usable as a CI gate.\n\ntokens:css [--out <path>] [--check] [--selector-attribute <attr> | --selector-class <class>]\n [--light-class <class>] [--dark-value <v>] [--light-value <v>]\n [--default-scheme <dark|light|none>] [--media-fallback] [--only <core|all>]\n [--no-legacy-aliases]\n Emit the --vx-* stylesheet (stdout unless --out). Defaults reproduce basalt-ui/tokens.css.\n --selector-class emits `:root.dark` instead of an attribute selector (the Tailwind convention).\n --check writes nothing and exits 1 when --out differs from what would be emitted (a CI gate).\n --no-legacy-aliases drops the deprecated camelCase spellings (--vx-accentFill and friends),\n which are emitted by default as aliases of the canonical kebab-case names.\n\nfonts:css [--out <path>] [--check]\n Emit the shipped --basalt-font-* stacks as plain CSS \u2014 the typeface half of the token layer,\n otherwise reachable only by importing styles.css.\n\ndoctor [--tokens-only|--framework]\n Auto-detects a tokens-only consumer (no manifest + no @mantine/core) and checks only what\n applies. A check that cannot RUN is reported as SKIPPED and exits non-zero.\n\nsync [--force] [--check] [--tokens-only|--framework]\n Refreshes an EXISTING install; it never creates one (that is init). A tokens-only consumer\n has no scaffold to reconcile, so sync reports n/a and exits 0 there \u2014 as doctor does.\n\ncheck-theme / doctor / sync all resolve their project the same way: they honour BASALT_CWD, and\nrelocate to the single package below the cwd carrying a basalt config when invoked from a repo\nroot that has none \u2014 several carrying one is ambiguous and exits 1 in ALL THREE.\n--tokens-only and --framework are alternatives; passing both is an error.\n\nEvery subcommand accepts --help / -h to print this message and exit without running.";
|
|
2021
2245
|
function run(argv, cwd = process.cwd()) {
|
|
2022
2246
|
const [cmd, ...flags] = argv;
|
|
2023
2247
|
if (cmd === "help" || cmd === "--help" || cmd === "-h" || flags.includes("--help") || flags.includes("-h")) {
|
|
@@ -2032,7 +2256,10 @@ function run(argv, cwd = process.cwd()) {
|
|
|
2032
2256
|
mergeLint: flags.includes("--merge-lint")
|
|
2033
2257
|
});
|
|
2034
2258
|
case "sync":
|
|
2035
|
-
return sync(
|
|
2259
|
+
return sync(
|
|
2260
|
+
{ force: flags.includes("--force"), check: flags.includes("--check"), flags },
|
|
2261
|
+
cwd
|
|
2262
|
+
);
|
|
2036
2263
|
case "check-theme":
|
|
2037
2264
|
return checkTheme(cwd, flags);
|
|
2038
2265
|
case "check-coverage":
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shipped-versions.test.d.ts","sourceRoot":"","sources":["../../src/cli/shipped-versions.test.ts"],"names":[],"mappings":""}
|
package/dist/guard/index.d.ts
CHANGED
|
@@ -28,6 +28,17 @@ export type UnmatchedExemptPattern = {
|
|
|
28
28
|
* typo'd kind name is an exemption for a rule that does not exist.
|
|
29
29
|
*/
|
|
30
30
|
export declare function unmatchedExemptPatterns(cfg: GuardConfig, scannedRelPaths: readonly string[]): UnmatchedExemptPattern[];
|
|
31
|
+
/**
|
|
32
|
+
* The oxlint plugin's rule ids. Not guard kinds — they can never suppress a `checkSource` finding —
|
|
33
|
+
* but they ARE valid ids in a `theme-allow`, so an annotation scoped to one of them must parse as
|
|
34
|
+
* accountable rather than be reported as unscoped. Kept as a literal list because the plugin is a
|
|
35
|
+
* standalone `.js` file this module must not import (see the plugin's own header).
|
|
36
|
+
*
|
|
37
|
+
* Exported for `check-theme --audit-allows`: an annotation naming one of these is outside the
|
|
38
|
+
* guard's reach, and judging it needs a `oxlint` run rather than a `checkSource` one. Keep in step
|
|
39
|
+
* with the plugin's own `KNOWN_RULE_IDS`; `configs/oxlint-plugin.test.ts` asserts the two agree.
|
|
40
|
+
*/
|
|
41
|
+
export declare const PLUGIN_RULE_IDS: ReadonlySet<string>;
|
|
31
42
|
/**
|
|
32
43
|
* The exact first line of every stylesheet the CLI emits — the contract between `basalt-ui
|
|
33
44
|
* tokens:css` / `fonts:css` and this scanner, and the single source of truth for it (`src/cli`
|
|
@@ -262,4 +273,60 @@ export declare function guardWaiverHint(relPath: string): string;
|
|
|
262
273
|
* if (findings.some((f) => f.kind === 'raw-hex')) { ... }
|
|
263
274
|
*/
|
|
264
275
|
export declare function checkSource(text: string, relPath: string, cfg: GuardConfig): Finding[];
|
|
276
|
+
/**
|
|
277
|
+
* One `theme-allow` annotation as WRITTEN, classified by whose reach its ids fall in.
|
|
278
|
+
*
|
|
279
|
+
* `guardKinds` is what `checkSource` can judge by re-running itself with the annotation
|
|
280
|
+
* neutralized. `pluginRules` is what only an `oxlint` run can judge. `unknownRules` names no rule
|
|
281
|
+
* at all. All three empty with `bare: true` is the legacy blanket form.
|
|
282
|
+
*/
|
|
283
|
+
export type AllowAnnotationSite = {
|
|
284
|
+
/** 1-based line the annotation is written on. */
|
|
285
|
+
readonly line: number;
|
|
286
|
+
/** `'file'` for the `theme-allow-file` declaration form, `'line'` otherwise. */
|
|
287
|
+
readonly scope: 'line' | 'file';
|
|
288
|
+
/** Every id the annotation names that resolves to a real rule, `basalt/` prefix stripped. */
|
|
289
|
+
readonly rules: readonly string[];
|
|
290
|
+
/** The subset of `rules` `checkSource` owns. */
|
|
291
|
+
readonly guardKinds: readonly GuardKind[];
|
|
292
|
+
/** The subset of `rules` the oxlint plugin owns — outside `checkSource`'s reach. */
|
|
293
|
+
readonly pluginRules: readonly string[];
|
|
294
|
+
/** Words that occupied the id slot but name no rule. Their presence makes the parse fail closed. */
|
|
295
|
+
readonly unknownRules: readonly string[];
|
|
296
|
+
/** A written reason follows the ids. */
|
|
297
|
+
readonly hasReason: boolean;
|
|
298
|
+
/** The legacy blanket form — no ids at all, known or unknown. Only covers anything at line scope. */
|
|
299
|
+
readonly bare: boolean;
|
|
300
|
+
/** The source line, verbatim. */
|
|
301
|
+
readonly text: string;
|
|
302
|
+
};
|
|
303
|
+
/**
|
|
304
|
+
* Every allow annotation in one file, with the ids it names classified by reach.
|
|
305
|
+
*
|
|
306
|
+
* Pure, and it shares `collectAllowAnnotations` with {@link checkSource} — so a caller enumerating
|
|
307
|
+
* annotations sees exactly the set the scan honours, rather than a second regex that can drift from
|
|
308
|
+
* it. `--audit-allows` carried such a mirror and it was already one alternation behind.
|
|
309
|
+
*
|
|
310
|
+
* A file-scoped declaration appears once, at the line it is written on.
|
|
311
|
+
*
|
|
312
|
+
* @example
|
|
313
|
+
* for (const site of findAllowAnnotations(text, rel, cfg)) {
|
|
314
|
+
* if (site.pluginRules.length > 0) probeWithOxlint(neutralizeAllowAnnotation(text, site.line, cfg))
|
|
315
|
+
* }
|
|
316
|
+
*/
|
|
317
|
+
export declare function findAllowAnnotations(text: string, relPath: string, cfg: GuardConfig): AllowAnnotationSite[];
|
|
318
|
+
/** The token a neutralized annotation is rewritten to. Shares no substring with `theme-allow`. */
|
|
319
|
+
export declare const NEUTRALIZED_ALLOW_TOKEN = "basalt-audit-neutralized";
|
|
320
|
+
/**
|
|
321
|
+
* `text` with the allow token on ONE (1-based) line rewritten to {@link NEUTRALIZED_ALLOW_TOKEN},
|
|
322
|
+
* leaving every other annotation intact.
|
|
323
|
+
*
|
|
324
|
+
* The probe half of an audit: re-scan the result and the findings that appear are exactly what that
|
|
325
|
+
* one annotation suppresses. Shipped rather than left to each caller so the guard probe and the
|
|
326
|
+
* oxlint probe neutralize identically — a `--audit-allows` verdict that differs between the two
|
|
327
|
+
* halves by a substitution detail is worse than no verdict.
|
|
328
|
+
*
|
|
329
|
+
* A line with no token comes back unchanged.
|
|
330
|
+
*/
|
|
331
|
+
export declare function neutralizeAllowAnnotation(text: string, line: number, cfg: GuardConfig): string;
|
|
265
332
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guard/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE7E,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,CAAA;AAyb9D,8EAA8E;AAC9E,eAAO,MAAM,oBAAoB,EAAE,WAoBlC,CAAA;AAmJD,sGAAsG;AACtG,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,UAAU,CAAA;CAC7C,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,WAAW,EAChB,eAAe,EAAE,SAAS,MAAM,EAAE,GACjC,sBAAsB,EAAE,CAc1B;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guard/index.ts"],"names":[],"mappings":"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"}
|