@shivaedev/quality 0.11.0 → 0.12.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/CHANGELOG.md +13 -0
- package/README.md +4 -1
- package/dist/imports/fences/evaluate.d.ts.map +1 -1
- package/dist/imports/fences/evaluate.js +2 -1
- package/dist/imports/fences/evaluate.js.map +1 -1
- package/dist/rules/imports/fences.d.ts.map +1 -1
- package/dist/rules/imports/fences.js +1 -1
- package/dist/rules/imports/fences.js.map +1 -1
- package/dist/rules/suppressions/no-inline.js +2 -2
- package/dist/rules/suppressions/no-inline.js.map +1 -1
- package/package.json +5 -4
- package/src/imports/fences/evaluate.ts +2 -1
- package/src/rules/imports/fences.ts +2 -1
- package/src/rules/suppressions/no-inline.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.12.0 - 2026-10-05
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- `imports/fences` skips test files: a file the `tests/*` rules read as a test, `*.test.ts` or `*.spec.ts` with any environment, is never a module a fence holds, so a test beside shipped code may import what it needs. Fences guard shipped code, and a test ships nowhere. Nothing turns this off.
|
|
8
|
+
- `suppressions/no-inline` allows `@ts-expect-error` in `*.typecheck.spec.ts` files too, the type test of a behaviour, exactly as in `*.typecheck.test.ts`.
|
|
9
|
+
|
|
10
|
+
## 0.11.1 - 2026-10-05
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- The optional `vitest` peer dependency requires Vitest 4.1.11, the latest 4.x patch.
|
|
15
|
+
|
|
3
16
|
## 0.11.0 - 2026-10-05
|
|
4
17
|
|
|
5
18
|
### Added
|
package/README.md
CHANGED
|
@@ -124,7 +124,7 @@ Coverage hints (`c8 ignore`, `v8 ignore`, `istanbul ignore`) are allowed: they l
|
|
|
124
124
|
|
|
125
125
|
#### Type tests
|
|
126
126
|
|
|
127
|
-
A type test proves that an API rejects what its types forbid, and TypeScript asserts a compile error only through `@ts-expect-error`, which fails as soon as the error it expects goes away. So `@ts-expect-error`, and no other directive, is allowed in a type test: a file named `*.typecheck.test.ts` or `typecheck.test.ts` (or `.tsx`). The compiler checks these files; [Vitest projects](#vitest-projects) never run them. `@ts-ignore`, `@ts-nocheck` and every linter and formatter directive stay reported in them. A test that must pass a rejected value at run time, to prove the runtime refuses it too, calls the API through `Reflect.apply` instead of a directive.
|
|
127
|
+
A type test proves that an API rejects what its types forbid, and TypeScript asserts a compile error only through `@ts-expect-error`, which fails as soon as the error it expects goes away. So `@ts-expect-error`, and no other directive, is allowed in a type test: a file named `*.typecheck.test.ts`, `*.typecheck.spec.ts` or `typecheck.test.ts` (or `.tsx`). The compiler checks these files; [Vitest projects](#vitest-projects) never run them. `@ts-ignore`, `@ts-nocheck` and every linter and formatter directive stay reported in them. A test that must pass a rejected value at run time, to prove the runtime refuses it too, calls the API through `Reflect.apply` instead of a directive.
|
|
128
128
|
|
|
129
129
|
`suppressions/no-double-cast` finds casts with the TypeScript parser, through parentheses and in either assertion syntax. A single cast is left to the linter, and `as const` is not a cast.
|
|
130
130
|
|
|
@@ -274,6 +274,8 @@ Targets are `packages(...)` (workspace packages by name, with or without their s
|
|
|
274
274
|
|
|
275
275
|
The config does not compile without `demonstratedBy`, and the rule checks the examples against the policy: each is a chain of imports from a file of the repository, which may end in `external(name)`. The illegal example must cross this fence and no other; the legal example must cross none. Every name a fence uses must exist: a package, a folder that holds checked files, a checked file, a subject of the unit. Two fences may not share a name, and each needs a reason. A policy that breaks any of this stops the run. Fences count type imports too.
|
|
276
276
|
|
|
277
|
+
Fences guard shipped code, and a test ships nowhere, so a fence never holds a test file: a `*.test.ts` or `*.spec.ts` file, as the [test rules](#tests) read the name, may import across every fence. There is no option to check them.
|
|
278
|
+
|
|
277
279
|
A finding has its fence's name as its subject, so a registry entry with that subject excuses one file from one fence.
|
|
278
280
|
|
|
279
281
|
### Manifests
|
|
@@ -496,6 +498,7 @@ A test sits beside the code it covers, and its name says what it covers and wher
|
|
|
496
498
|
| `cart/Basket.dom.test.tsx` | `cart/Basket.tsx`, in a DOM | Yes |
|
|
497
499
|
| `cart/checkoutFlow.spec.ts` | A behaviour of the `cart/` folder as a whole, such as a flow across several files | Yes |
|
|
498
500
|
| `cart/checkoutFlow.dom.spec.tsx` | The same, in a DOM | Yes |
|
|
501
|
+
| `cart/checkoutFlow.typecheck.spec.ts` | The types of that behaviour, checked by the compiler | Yes |
|
|
499
502
|
| `cart/totals.test.ts` | No `cart/totals.ts` beside it | No: a `.test` follows a file, and a test of the folder is a `.spec` |
|
|
500
503
|
| `cart/cart.spec.ts` | | No: a `.spec` names a behaviour, so it may not share a stem with a file beside it |
|
|
501
504
|
| `cart/cart.hydration.test.ts` | | No: an aspect gets its own file in the module's folder, or a `.spec` |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../../src/imports/fences/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../../src/imports/fences/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,KAAK,QAAQ,EAAyB,MAAM,YAAY,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAIxC,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;AAEhE,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,SAAS,OAAO,EAAE,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACtB;AAgDD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,GAAG,aAAa,CAY5E"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { testName } from "#naming/testName.ts";
|
|
1
2
|
import { compile } from "./match.js";
|
|
2
3
|
import { labelOf, outgoing, reachedFrom } from "./reach.js";
|
|
3
4
|
import { compileVocabulary } from "./vocabulary.js";
|
|
@@ -43,7 +44,7 @@ export function compileFence(compiler, fence) {
|
|
|
43
44
|
const where = `fence "${fence.name}"`;
|
|
44
45
|
const from = compile(compiler, fence.from, `${where}.from`);
|
|
45
46
|
function importer(path) {
|
|
46
|
-
return from({ kind: "file", path });
|
|
47
|
+
return testName(path) === undefined && from({ kind: "file", path });
|
|
47
48
|
}
|
|
48
49
|
const prohibition = fence.prohibition;
|
|
49
50
|
if (prohibition.kind === "vocabulary") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../../src/imports/fences/evaluate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../../src/imports/fences/evaluate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAiB,OAAO,EAAgB,MAAM,YAAY,CAAC;AAElE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAmB,MAAM,iBAAiB,CAAC;AAWrE,SAAS,MAAM,CAAC,KAAY;IAC3B,OAAO,qBAAqB,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;AAC/D,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAY,EAAE,UAAsB,EAAE,QAA2B,EAAE,IAAgB;IAC7G,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9C,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACzD,OAAO,EAAE,CAAC;IACX,CAAC;IACD,MAAM,OAAO,GAAG,YAAY,OAAO,QAAQ,UAAU,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,aAAa,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IACjH,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAkB,EAAE,KAAY,EAAE,QAAmC,EAAE,KAAa;IAC/G,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC7C,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC;IACjB,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC;IAC5C,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,KAAK,KAAK,CAAC,CAAC;IAChG,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC;IACjB,CAAC;IACD,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACpI,CAAC;AAED,SAAS,cAAc,CAAC,KAAY,EAAE,QAAmC,EAAE,EAAW;IACrF,OAAO,CAAC,KAAK,EAAE,EAAE,CAChB,KAAK,CAAC,KAAK;SACT,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACpD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACxI,CAAC;AAED,SAAS,aAAa,CAAC,KAAY,EAAE,QAAmC,EAAE,EAAW;IACpF,OAAO,CAAC,KAAK,EAAE,EAAE;QAChB,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACxD,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACpD,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,WAAW,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE;YACnG,OAAO,EAAE,KAAK,CAAC,IAAI;SACnB,CAAC,CAAC,CACH,CAAC;IACH,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAkB,EAAE,KAAY;IAC5D,MAAM,KAAK,GAAG,UAAU,KAAK,CAAC,IAAI,GAAG,CAAC;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC;IAC5D,SAAS,QAAQ,CAAC,IAAY;QAC7B,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACtC,IAAI,WAAW,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACvC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;IAClF,CAAC;IACD,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE,GAAG,KAAK,KAAK,CAAC,CAAC;IAC5D,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;AACtI,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fences.d.ts","sourceRoot":"","sources":["../../../src/rules/imports/fences.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAatD,eAAO,MAAM,YAAY;;
|
|
1
|
+
{"version":3,"file":"fences.d.ts","sourceRoot":"","sources":["../../../src/rules/imports/fences.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAatD,eAAO,MAAM,YAAY;;EAavB,CAAC"}
|
|
@@ -17,7 +17,7 @@ export const importFences = defineRule({
|
|
|
17
17
|
const policy = compilePolicy(options.fences, { files: inputs.files, packages: graph.packages });
|
|
18
18
|
return policy.flatMap((compiled) => compiled.evaluate(graph));
|
|
19
19
|
},
|
|
20
|
-
description: "Imports respect the fences the repository declares. Move the code to the side of the fence its imports belong to.",
|
|
20
|
+
description: "Imports of shipped code respect the fences the repository declares; a test file ships nowhere, so no fence holds it. Move the code to the side of the fence its imports belong to.",
|
|
21
21
|
id: "imports/fences",
|
|
22
22
|
options: Schema.toStandardSchemaV1(FencesOptions, { parseOptions: { errors: "all", onExcessProperty: "error" } }),
|
|
23
23
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fences.js","sourceRoot":"","sources":["../../../src/rules/imports/fences.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,SAAS,OAAO,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC;AACjG,CAAC;AAED,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,2BAA2B,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;CAChJ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;IACtC,KAAK,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE;QACvC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,CAAC;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChG,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,CAAC;IACD,WAAW,
|
|
1
|
+
{"version":3,"file":"fences.js","sourceRoot":"","sources":["../../../src/rules/imports/fences.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,SAAS,OAAO,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC;AACjG,CAAC;AAED,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,2BAA2B,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;CAChJ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;IACtC,KAAK,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE;QACvC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,CAAC;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChG,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/D,CAAC;IACD,WAAW,EACV,oLAAoL;IACrL,EAAE,EAAE,gBAAgB;IACpB,OAAO,EAAE,MAAM,CAAC,kBAAkB,CAAC,aAAa,EAAE,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,EAAE,CAAC;CACjH,CAAC,CAAC"}
|
|
@@ -2,7 +2,7 @@ import { defineRule } from "#rule.ts";
|
|
|
2
2
|
import { scanComments } from "#rules/comments/scan.ts";
|
|
3
3
|
import { suppressionIn } from "./directives.js";
|
|
4
4
|
import { STYLESHEET, stylesheetComments } from "./stylesheet-comments.js";
|
|
5
|
-
const TYPE_TEST = /(
|
|
5
|
+
const TYPE_TEST = /(?:(?:^|\/)typecheck\.test|\.typecheck\.(?:test|spec))\.[cm]?[jt]sx?$/u;
|
|
6
6
|
const TYPE_TEST_DIRECTIVE = "@ts-expect-error";
|
|
7
7
|
const sitesIn = (file, comments) => comments.flatMap((comment) => {
|
|
8
8
|
const directive = suppressionIn(comment);
|
|
@@ -18,7 +18,7 @@ function allowed(site) {
|
|
|
18
18
|
}
|
|
19
19
|
export const noInline = defineRule({
|
|
20
20
|
check: async (inputs) => [...inputs.sources.flatMap((file) => sitesIn(file.path, scanComments(file))), ...(await stylesheetSites(inputs))].filter((site) => !allowed(site)),
|
|
21
|
-
description: "A suppression silences a check at one site instead of fixing the cause. Fix the code; where a lint rule truly cannot apply, turn it off for that scope in the Biome config and declare it under suppressions/biome-overrides. A type test asserts a compile error with @ts-expect-error in a *.typecheck.test.ts file.",
|
|
21
|
+
description: "A suppression silences a check at one site instead of fixing the cause. Fix the code; where a lint rule truly cannot apply, turn it off for that scope in the Biome config and declare it under suppressions/biome-overrides. A type test asserts a compile error with @ts-expect-error in a *.typecheck.test.ts or *.typecheck.spec.ts file.",
|
|
22
22
|
id: "suppressions/no-inline",
|
|
23
23
|
registrable: false,
|
|
24
24
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-inline.js","sourceRoot":"","sources":["../../../src/rules/suppressions/no-inline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiC,MAAM,UAAU,CAAC;AACrE,OAAO,EAAsB,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE1E,MAAM,SAAS,GAAG,
|
|
1
|
+
{"version":3,"file":"no-inline.js","sourceRoot":"","sources":["../../../src/rules/suppressions/no-inline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiC,MAAM,UAAU,CAAC;AACrE,OAAO,EAAsB,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE1E,MAAM,SAAS,GAAG,wEAAwE,CAAC;AAE3F,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AAM/C,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,QAAkC,EAAmB,EAAE,CACrF,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IAC5B,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,wBAAwB,SAAS,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;AAC1I,CAAC,CAAC,CAAC;AAEJ,MAAM,eAAe,GAAG,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAc,EAA4B,EAAE;IACpG,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1I,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACnG,CAAC,CAAC;AAEF,SAAS,OAAO,CAAC,IAAU;IAC1B,OAAO,IAAI,CAAC,OAAO,KAAK,mBAAmB,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;IAClC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CACvB,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CACvH,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CACxB;IACF,WAAW,EACV,+UAA+U;IAChV,EAAE,EAAE,wBAAwB;IAC5B,WAAW,EAAE,KAAK;CAClB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/quality",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Repository quality gate with typed rules, a baseline of existing debt and a registry of reasoned exceptions",
|
|
5
5
|
"homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/quality#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"sideEffects": false,
|
|
16
16
|
"type": "module",
|
|
17
17
|
"imports": {
|
|
18
|
-
"#test/*": "./test/*",
|
|
18
|
+
"#test/*": "./src/test-support/*",
|
|
19
19
|
"#*.ts": {
|
|
20
20
|
"source": "./src/*.ts",
|
|
21
21
|
"types": "./dist/*.d.ts",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"src",
|
|
44
44
|
"!src/**/*.test.ts",
|
|
45
45
|
"!src/**/*.spec.ts",
|
|
46
|
+
"!src/**/test-support",
|
|
46
47
|
"tsconfig",
|
|
47
48
|
"CHANGELOG.md",
|
|
48
49
|
"README.md"
|
|
@@ -61,13 +62,13 @@
|
|
|
61
62
|
"@types/node": "24.10.1",
|
|
62
63
|
"@typescript/native": "npm:typescript@7.0.2",
|
|
63
64
|
"effect": "4.0.0-rc.112",
|
|
64
|
-
"vitest": "4.1.
|
|
65
|
+
"vitest": "4.1.11"
|
|
65
66
|
},
|
|
66
67
|
"peerDependencies": {
|
|
67
68
|
"@effect/platform-node": "4.0.0-rc.112",
|
|
68
69
|
"@effect/platform-node-shared": "4.0.0-rc.112",
|
|
69
70
|
"effect": "4.0.0-rc.112",
|
|
70
|
-
"vitest": "4.1.
|
|
71
|
+
"vitest": "4.1.11"
|
|
71
72
|
},
|
|
72
73
|
"peerDependenciesMeta": {
|
|
73
74
|
"vitest": {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ImportEdge, ImportGraph } from "#imports/graph.ts";
|
|
2
|
+
import { testName } from "#naming/testName.ts";
|
|
2
3
|
import type { Finding } from "#rule.ts";
|
|
3
4
|
import { type Compiler, compile, type Matcher } from "./match.ts";
|
|
4
5
|
import type { Fence } from "./model.ts";
|
|
@@ -64,7 +65,7 @@ export function compileFence(compiler: Compiler, fence: Fence): CompiledFence {
|
|
|
64
65
|
const where = `fence "${fence.name}"`;
|
|
65
66
|
const from = compile(compiler, fence.from, `${where}.from`);
|
|
66
67
|
function importer(path: string): boolean {
|
|
67
|
-
return from({ kind: "file", path });
|
|
68
|
+
return testName(path) === undefined && from({ kind: "file", path });
|
|
68
69
|
}
|
|
69
70
|
const prohibition = fence.prohibition;
|
|
70
71
|
if (prohibition.kind === "vocabulary") {
|
|
@@ -21,7 +21,8 @@ export const importFences = defineRule({
|
|
|
21
21
|
const policy = compilePolicy(options.fences, { files: inputs.files, packages: graph.packages });
|
|
22
22
|
return policy.flatMap((compiled) => compiled.evaluate(graph));
|
|
23
23
|
},
|
|
24
|
-
description:
|
|
24
|
+
description:
|
|
25
|
+
"Imports of shipped code respect the fences the repository declares; a test file ships nowhere, so no fence holds it. Move the code to the side of the fence its imports belong to.",
|
|
25
26
|
id: "imports/fences",
|
|
26
27
|
options: Schema.toStandardSchemaV1(FencesOptions, { parseOptions: { errors: "all", onExcessProperty: "error" } }),
|
|
27
28
|
});
|
|
@@ -3,7 +3,7 @@ import { type SourceComment, scanComments } from "#rules/comments/scan.ts";
|
|
|
3
3
|
import { suppressionIn } from "./directives.ts";
|
|
4
4
|
import { STYLESHEET, stylesheetComments } from "./stylesheet-comments.ts";
|
|
5
5
|
|
|
6
|
-
const TYPE_TEST = /(
|
|
6
|
+
const TYPE_TEST = /(?:(?:^|\/)typecheck\.test|\.typecheck\.(?:test|spec))\.[cm]?[jt]sx?$/u;
|
|
7
7
|
|
|
8
8
|
const TYPE_TEST_DIRECTIVE = "@ts-expect-error";
|
|
9
9
|
|
|
@@ -33,7 +33,7 @@ export const noInline = defineRule({
|
|
|
33
33
|
(site) => !allowed(site),
|
|
34
34
|
),
|
|
35
35
|
description:
|
|
36
|
-
"A suppression silences a check at one site instead of fixing the cause. Fix the code; where a lint rule truly cannot apply, turn it off for that scope in the Biome config and declare it under suppressions/biome-overrides. A type test asserts a compile error with @ts-expect-error in a *.typecheck.test.ts file.",
|
|
36
|
+
"A suppression silences a check at one site instead of fixing the cause. Fix the code; where a lint rule truly cannot apply, turn it off for that scope in the Biome config and declare it under suppressions/biome-overrides. A type test asserts a compile error with @ts-expect-error in a *.typecheck.test.ts or *.typecheck.spec.ts file.",
|
|
37
37
|
id: "suppressions/no-inline",
|
|
38
38
|
registrable: false,
|
|
39
39
|
});
|