@ksmv/ui-checks 0.3.0 → 0.3.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.1 - 2026-09-30
4
+
5
+ - **O CLI volta a rodar quando é chamado por um link simbólico.** Na 0.3.0 e anteriores, pelo `npx`, por um script npm ou pelo `node_modules/.bin` no Linux e no macOS, e em qualquer sistema quando `node_modules` é um link ou uma junção, o comando não executava nada e saía com código `0`: uma verificação verde que não tinha acontecido. A detecção do ponto de entrada passa a comparar os caminhos reais. **Quem roda o verificador num CI Linux deve atualizar e conferir que o passo de fato imprime o relatório.**
6
+ - **Um `#` que não inicia um nome deixa de travar a análise.** Um arquivo TypeScript ou TSX com `#` dentro de uma expressão regular literal, como `/^#\/rota/`, fazia a varredura nunca terminar, até o processo esgotar a memória. A varredura agora sempre avança. Um `#` solto que não compila continua sendo erro operacional de parse (saída 2).
7
+
3
8
  ## 0.3.0 - 2026-09-30
4
9
 
5
10
  - **Regra `components/override`**, opt-in pelo bloco `components` da configuração. Num componente da biblioteca, ajuste de encaixe por `className` ou `style` (margem, largura, item de flex/grid, posição, visibilidade, alinhamento do texto) é livre; ajuste de aparência ou de arranjo interno exige `data-ui-override="motivo"` no mesmo elemento. Classes fora do catálogo contam como aparência. `className` ou `style` que o checker não consegue ler e props repassadas depois de `className`/`style` também exigem a marca.
package/dist/cli.d.ts CHANGED
@@ -1,2 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  export declare function main(argv?: string[]): Promise<import("./result.js").ExitCode>;
3
+ /**
4
+ * Whether this module is the script Node was started with. Compared by real
5
+ * path: through a symbolic link (npm's `.bin` on POSIX, a linked node_modules)
6
+ * `process.argv[1]` names the link while `import.meta.url` names the file, and
7
+ * comparing them as written made the CLI do nothing and exit 0.
8
+ */
9
+ export declare function isEntryPoint(scriptPath: string | undefined, moduleUrl: string): boolean;
package/dist/cli.js CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
+ import { realpathSync } from "node:fs";
2
3
  import { readFile } from "node:fs/promises";
3
4
  import { resolve } from "node:path";
4
- import { pathToFileURL } from "node:url";
5
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
6
  import { approveBaselineGrowth, baselineFor, validateBaseline, writeBaselineFile, } from "./baseline.js";
6
7
  import { applyConfiguredSuppressions } from "./governance.js";
7
8
  import { formatHumanReport, formatJsonReport, } from "./result.js";
@@ -169,9 +170,23 @@ export async function main(argv = process.argv.slice(2)) {
169
170
  return 2;
170
171
  }
171
172
  }
172
- const entryPoint = process.argv[1]
173
- ? pathToFileURL(resolve(process.argv[1])).href
174
- : undefined;
175
- if (entryPoint === import.meta.url) {
173
+ /**
174
+ * Whether this module is the script Node was started with. Compared by real
175
+ * path: through a symbolic link (npm's `.bin` on POSIX, a linked node_modules)
176
+ * `process.argv[1]` names the link while `import.meta.url` names the file, and
177
+ * comparing them as written made the CLI do nothing and exit 0.
178
+ */
179
+ export function isEntryPoint(scriptPath, moduleUrl) {
180
+ if (!scriptPath)
181
+ return false;
182
+ try {
183
+ return (realpathSync.native(resolve(scriptPath)) ===
184
+ realpathSync.native(fileURLToPath(moduleUrl)));
185
+ }
186
+ catch {
187
+ return false;
188
+ }
189
+ }
190
+ if (isEntryPoint(process.argv[1], import.meta.url)) {
176
191
  process.exitCode = await main();
177
192
  }
package/dist/scan.js CHANGED
@@ -24,6 +24,19 @@ function scanTypeScript(content, path) {
24
24
  const uncovered = [];
25
25
  let kind = scanner.scan();
26
26
  while (kind !== SyntaxKind.EndOfFile) {
27
+ // This scan has no parser behind it, so a "#" that starts no name (the one
28
+ // in /#/, read here as a division) comes back as a zero-width token and
29
+ // the scanner stays where it was. Read it as the hash it is; if a token
30
+ // still has no width, step over one character so the scan always ends.
31
+ if (scanner.getTokenEnd() <= scanner.getTokenStart()) {
32
+ if (kind === SyntaxKind.PrivateIdentifier)
33
+ kind = scanner.reScanHashToken();
34
+ if (scanner.getTokenEnd() <= scanner.getTokenStart()) {
35
+ scanner.resetTokenState(scanner.getTokenStart() + 1);
36
+ kind = scanner.scan();
37
+ continue;
38
+ }
39
+ }
27
40
  tokens.push({
28
41
  end: scanner.getTokenEnd(),
29
42
  kind,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ksmv/ui-checks",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Static and computed quality checks for semantic UI token contracts.",
5
5
  "keywords": ["accessibility", "design-tokens", "quality", "static-analysis"],
6
6
  "license": "Apache-2.0",