no-mistakes 0.41.0 → 0.43.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.
@@ -8,6 +8,7 @@ import type {
8
8
  } from "./named-query-types";
9
9
  import type { PlaywrightOptions, PlaywrightRelatedOptions } from "./report-types";
10
10
  import type {
11
+ CheckOptions,
11
12
  ProjectOptions,
12
13
  SymbolsListOptions,
13
14
  SymbolsSignatureImpactOptions,
@@ -25,7 +26,7 @@ type BatchedReactUsagesOptions = Pick<
25
26
  "root" | "tsconfig" | "config" | "targets" | "include"
26
27
  > &
27
28
  Required<Pick<ProjectOptions, "target">>;
28
- type BatchedCheckOptions = Pick<ProjectOptions, "root" | "tsconfig" | "config">;
29
+ type BatchedCheckOptions = Pick<CheckOptions, "root" | "tsconfig" | "config" | "includeSuppressed">;
29
30
 
30
31
  export type AnalyzeProjectReportRequest =
31
32
  | ({ type: "dependencies" | "dependents" | "related"; id?: string } & BatchedTraverseOptions)
@@ -0,0 +1,57 @@
1
+ import type { QueueCheckFinding } from "./queue-report-types";
2
+ import type { ReactViolation } from "./react-report-types";
3
+
4
+ export interface CheckReport {
5
+ react: ReactViolation[];
6
+ queues: QueueCheckFinding[];
7
+ rules: RuleFinding[];
8
+ integration: IntegrationFinding[];
9
+ codebase: UniqueExportFinding[];
10
+ warnings: string[];
11
+ advisories: RuleFinding[];
12
+ /** Present when `includeSuppressed` is requested; empty when no directives matched. */
13
+ suppressed?: SuppressedFinding[];
14
+ }
15
+
16
+ export interface SuppressedFinding {
17
+ domain: "react" | "queues" | "rules" | "filesystem" | "integration" | "codebase" | "advisories";
18
+ rule: string;
19
+ file: string;
20
+ /** File containing the suppression directive. */
21
+ sourceFile: string;
22
+ line?: number;
23
+ reason: string;
24
+ directive: {
25
+ kind: "file" | "line" | "nextLine";
26
+ line: number;
27
+ };
28
+ }
29
+
30
+ export interface RuleFinding {
31
+ rule: string;
32
+ file: string;
33
+ line: number;
34
+ message: string;
35
+ import?: string;
36
+ target?: string;
37
+ }
38
+
39
+ export interface IntegrationFinding {
40
+ framework: string;
41
+ suite: string;
42
+ file: string;
43
+ line: number;
44
+ testName?: string;
45
+ describePath?: string[];
46
+ integration?: string;
47
+ message: string;
48
+ }
49
+
50
+ export interface UniqueExportFinding {
51
+ rule: string;
52
+ file: string;
53
+ line: number;
54
+ exportName: string;
55
+ exportKind: string;
56
+ message: string;
57
+ }
package/ci-types.d.ts CHANGED
@@ -115,11 +115,18 @@ export interface ImpactedChecksTiming {
115
115
  duration_ms: number;
116
116
  }
117
117
 
118
+ export interface ImpactedChecksEmptyResult {
119
+ code: "no-changed-files" | "no-impacted-checks";
120
+ message: string;
121
+ }
122
+
118
123
  export interface ImpactedChecksReport {
119
124
  changed_files: string[];
120
125
  checks: CheckCommand[];
121
126
  warnings: Array<{ type: string; message: string; file: string }>;
122
127
  fallback_triggered: boolean;
128
+ /** Present only when no changed files or impacted checks were found. */
129
+ empty_result?: ImpactedChecksEmptyResult;
123
130
  /** Present only when `timings: true` was requested. */
124
131
  timings?: ImpactedChecksTiming[];
125
132
  }
@@ -0,0 +1,86 @@
1
+ export type FetchSourceType =
2
+ | "page"
3
+ | "layout"
4
+ | "loading"
5
+ | "error"
6
+ | "template"
7
+ | "route"
8
+ | "module";
9
+
10
+ export type CacheKind =
11
+ | "none"
12
+ | "fetch-cache"
13
+ | "fetch-next-revalidate"
14
+ | "fetch-next-tags"
15
+ | "react-cache"
16
+ | "cache"
17
+ | "unstable-cache";
18
+
19
+ export interface FetchOccurrence {
20
+ path: string;
21
+ rawPath: string;
22
+ method: string;
23
+ file: string;
24
+ line: number;
25
+ side: "server" | "client";
26
+ rsc: boolean;
27
+ cached: boolean;
28
+ cacheKind: CacheKind;
29
+ cachedFunction?: string;
30
+ dynamic: boolean;
31
+ unsupported: boolean;
32
+ functionName?: string;
33
+ conditional: boolean;
34
+ inPromiseAll: boolean;
35
+ errorHandled: boolean;
36
+ sourceType: FetchSourceType;
37
+ }
38
+
39
+ export interface FetchRouteReport {
40
+ route: string;
41
+ file: string;
42
+ apiCalls: FetchOccurrence[];
43
+ }
44
+
45
+ export interface FetchSummary {
46
+ totalRoutes: number;
47
+ routesWithApiCalls: number;
48
+ totalApiCalls: number;
49
+ uniqueApiCalls: number;
50
+ duplicateApiCalls: number;
51
+ dynamicApiCalls: number;
52
+ cachedApiCalls: number;
53
+ clientApiCalls: number;
54
+ serverApiCalls: number;
55
+ rscApiCalls: number;
56
+ conditionalApiCalls: number;
57
+ parallelApiCalls: number;
58
+ errorHandledApiCalls: number;
59
+ }
60
+
61
+ export interface FetchReport {
62
+ summary: FetchSummary;
63
+ routes: FetchRouteReport[];
64
+ duplicates: DuplicateApiCall[];
65
+ unsupported: UnsupportedApiCall[];
66
+ }
67
+
68
+ export interface DuplicateApiCall {
69
+ key: string;
70
+ count: number;
71
+ occurrences: ApiCallOccurrence[];
72
+ }
73
+
74
+ export interface ApiCallOccurrence {
75
+ route: string;
76
+ file: string;
77
+ line: number;
78
+ }
79
+
80
+ export interface UnsupportedApiCall {
81
+ route: string;
82
+ file: string;
83
+ line: number;
84
+ reason: string;
85
+ rawPath: string;
86
+ }
package/index.d.ts CHANGED
@@ -4,11 +4,13 @@ import type {
4
4
  AnalyzeProjectResult,
5
5
  CallSitesOptions,
6
6
  CallSitesResult,
7
+ CheckOptions,
7
8
  DeadExportsOptions,
8
9
  DeadExportsResult,
9
10
  DependencyResult,
10
11
  ExportsOfOptions,
11
12
  ExportsOfResult,
13
+ FetchReport,
12
14
  FetchesOptions,
13
15
  FlowOptions,
14
16
  FlowReport,
@@ -19,11 +21,15 @@ import type {
19
21
  MermaidValidationOptions,
20
22
  MermaidValidationResult,
21
23
  ResolveCheckOptions,
24
+ ResolveCheckFilesOptions,
22
25
  ResolveCheckResult,
26
+ ResolveCheckBatchResult,
23
27
  GraphEdge,
24
28
  PlaywrightOptions,
25
29
  PlaywrightRelatedOptions,
26
30
  ProjectOptions,
31
+ QueueCheckFinding,
32
+ QueueEdge,
27
33
  QueueReport,
28
34
  ReactComponentFacts,
29
35
  ReactUsagesReport,
@@ -86,9 +92,12 @@ export function callSites(
86
92
  export function resolveCheck(
87
93
  options: WithInvocationOptions<ResolveCheckOptions>,
88
94
  ): Promise<ResolveCheckResult>;
89
- export function fetches(options?: WithInvocationOptions<FetchesOptions>): Promise<unknown>;
95
+ export function resolveCheck(
96
+ options: WithInvocationOptions<ResolveCheckFilesOptions>,
97
+ ): Promise<ResolveCheckBatchResult>;
98
+ export function fetches(options?: WithInvocationOptions<FetchesOptions>): Promise<FetchReport>;
90
99
  export function flow(options: WithInvocationOptions<FlowOptions>): Promise<FlowReport>;
91
- export function check(options?: WithInvocationOptions<ProjectOptions>): Promise<CheckReport>;
100
+ export function check(options?: WithInvocationOptions<CheckOptions>): Promise<CheckReport>;
92
101
  export function validateMermaidMarkdown(
93
102
  options: WithInvocationOptions<MermaidValidationOptions>,
94
103
  ): Promise<MermaidValidationResult>;
@@ -122,9 +131,11 @@ export function playwrightTests(
122
131
  options?: WithInvocationOptions<PlaywrightOptions>,
123
132
  ): Promise<unknown>;
124
133
  export function queues(options?: WithInvocationOptions<ProjectOptions>): Promise<QueueReport>;
125
- export function queueEdges(options?: WithInvocationOptions<ProjectOptions>): Promise<GraphEdge[]>;
126
- export function queueRelated(options: WithInvocationOptions<ProjectOptions>): Promise<GraphEdge[]>;
127
- export function queueCheck(options?: WithInvocationOptions<ProjectOptions>): Promise<unknown[]>;
134
+ export function queueEdges(options?: WithInvocationOptions<ProjectOptions>): Promise<QueueEdge[]>;
135
+ export function queueRelated(options: WithInvocationOptions<ProjectOptions>): Promise<QueueEdge[]>;
136
+ export function queueCheck(
137
+ options?: WithInvocationOptions<ProjectOptions>,
138
+ ): Promise<QueueCheckFinding[]>;
128
139
  export function serverRoutes(
129
140
  options?: WithInvocationOptions<ProjectOptions>,
130
141
  ): Promise<ServerRoutesReport>;
package/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
 
3
- const native = require("./bin/no-mistakes.node");
3
+ // CI real-addon tests point this at the freshly compiled cdylib without
4
+ // overwriting the package's checked-in install placeholder.
5
+ const native = require(process.env.NO_MISTAKES_TEST_NAPI_ADDON_PATH || "./bin/no-mistakes.node");
4
6
  const planning = require("./planning");
5
7
  const { createWorkflowTopologyIndex } = require("./workflow-topology-index");
6
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "no-mistakes",
3
- "version": "0.41.0",
3
+ "version": "0.43.0",
4
4
  "description": "Static codebase analysis tools for TS/JS dependencies, dependents, and symbols",
5
5
  "license": "MIT",
6
6
  "repository": {
package/planning.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- const native = require("./bin/no-mistakes.node");
3
+ const native = require(process.env.NO_MISTAKES_TEST_NAPI_ADDON_PATH || "./bin/no-mistakes.node");
4
4
 
5
5
  async function callJson(fn, options) {
6
6
  return JSON.parse(await fn(JSON.stringify(options || {})));
package/query-types.d.ts CHANGED
@@ -96,13 +96,28 @@ export interface CallSitesResult {
96
96
  callSites: CallSite[];
97
97
  }
98
98
 
99
- export type ResolveCheckOptions = QueryFileOptions;
99
+ /** Single-file form of `resolveCheck`; cannot be combined with `files`. */
100
+ export type ResolveCheckOptions = QueryFileOptions & {
101
+ files?: never;
102
+ };
103
+
104
+ /** Batch form of `resolveCheck`; `files` always returns the batch schema. */
105
+ export interface ResolveCheckFilesOptions {
106
+ /** A nonempty list of TS/JS files to check. */
107
+ files: [string, ...string[]];
108
+ /** Mutually exclusive with `files`. */
109
+ file?: never;
110
+ /** Project root. Defaults to the current working directory. */
111
+ root?: string;
112
+ /** Path to tsconfig.json for alias resolution. Searched upward if omitted. */
113
+ tsconfig?: string;
114
+ }
100
115
 
101
116
  export type ImportResolutionStatus = "resolved" | "unresolved" | "external";
102
117
 
103
118
  export interface ResolveCheckImport {
104
119
  specifier: string;
105
- kind: "static" | "type" | "dynamic" | "require";
120
+ kind: "static" | "type" | "dynamic" | "require" | "require-resolve";
106
121
  status: ImportResolutionStatus;
107
122
  /** Root-relative resolved target, when the import resolves locally. */
108
123
  resolved?: string;
@@ -114,3 +129,9 @@ export interface ResolveCheckResult {
114
129
  imports: ResolveCheckImport[];
115
130
  unresolved: string[];
116
131
  }
132
+
133
+ export interface ResolveCheckBatchResult {
134
+ allResolve: boolean;
135
+ unresolvedFiles: string[];
136
+ results: ResolveCheckResult[];
137
+ }
@@ -0,0 +1,62 @@
1
+ export interface QueueReport {
2
+ producers: QueueProducer[];
3
+ workers: QueueWorker[];
4
+ jobs: QueueJobNode[];
5
+ edges: QueueEdge[];
6
+ diagnostics: QueueDiagnostic[];
7
+ check: QueueCheckFinding[];
8
+ }
9
+
10
+ export interface QueueJobNode {
11
+ queueFile: string;
12
+ queueName: string;
13
+ job: string;
14
+ }
15
+
16
+ export interface QueueProducer {
17
+ file: string;
18
+ line: number;
19
+ queueFile: string | null;
20
+ queueName: string | null;
21
+ job: string | null;
22
+ rawJob: string | null;
23
+ library: string | null;
24
+ }
25
+
26
+ export interface QueueWorker {
27
+ file: string;
28
+ line: number;
29
+ processorFile: string | null;
30
+ queueFile: string | null;
31
+ queueName: string | null;
32
+ jobs: string[];
33
+ wildcard: boolean;
34
+ library: string | null;
35
+ }
36
+
37
+ export type QueueEdgeKind = "queue-enqueue" | "queue-worker";
38
+
39
+ export interface QueueEdge {
40
+ from: string;
41
+ to: string;
42
+ kind: QueueEdgeKind;
43
+ }
44
+
45
+ export type QueueDiagnosticSeverity = "warning" | "error";
46
+
47
+ export interface QueueDiagnostic {
48
+ severity: QueueDiagnosticSeverity;
49
+ file: string;
50
+ line: number;
51
+ message: string;
52
+ }
53
+
54
+ export interface QueueCheckFinding {
55
+ kind: string;
56
+ file: string;
57
+ line: number;
58
+ queueFile: string | null;
59
+ queueName: string | null;
60
+ job: string | null;
61
+ message: string;
62
+ }
@@ -0,0 +1,62 @@
1
+ export interface ReactComponentFacts {
2
+ name: string;
3
+ file: string;
4
+ environment: "server" | "client" | "shared" | "unknown";
5
+ hasState: boolean;
6
+ hasProps: boolean;
7
+ passesProps: boolean;
8
+ usesMemo: boolean;
9
+ usesContextProvider: boolean;
10
+ usesSuspense: boolean;
11
+ fetches: ReactFetchCall[];
12
+ dependencies: string[];
13
+ children: ReactComponentRef[];
14
+ inheritedFromChildren?: ReactAggregatedFacts;
15
+ }
16
+
17
+ export interface ReactFetchCall {
18
+ file: string;
19
+ exportedName: string | null;
20
+ shape: string | null;
21
+ }
22
+
23
+ export interface ReactComponentRef {
24
+ name: string;
25
+ file: string;
26
+ }
27
+
28
+ export interface ReactAggregatedFacts {
29
+ hasState: boolean;
30
+ hasProps: boolean;
31
+ passesProps: boolean;
32
+ usesMemo: boolean;
33
+ usesContextProvider: boolean;
34
+ usesSuspense: boolean;
35
+ hasFetch: boolean;
36
+ }
37
+
38
+ export interface ReactViolation {
39
+ component: string;
40
+ file: string;
41
+ rule: string;
42
+ detail: string | null;
43
+ }
44
+
45
+ export interface ReactCallsite {
46
+ file: string;
47
+ line: number;
48
+ component: string;
49
+ props: string[];
50
+ hasSpread: boolean;
51
+ }
52
+
53
+ export interface ReactUsagesReport {
54
+ target: { file: string; symbol?: string };
55
+ callsites: ReactCallsite[];
56
+ /** Story files importing the target. Omitted when `props`/`tests`-only `include`. */
57
+ stories?: string[];
58
+ /** Test files importing the target. */
59
+ tests?: string[];
60
+ /** Exported prop type/interface names declared in the target file. */
61
+ propTypes?: string[];
62
+ }
package/report-types.d.ts CHANGED
@@ -1,3 +1,8 @@
1
+ export * from "./check-report-types";
2
+ export * from "./fetch-report-types";
3
+ export * from "./queue-report-types";
4
+ export * from "./react-report-types";
5
+
1
6
  export interface PlaywrightOptions {
2
7
  /** Project root. Defaults to the current working directory. */
3
8
  root?: string;
@@ -22,25 +27,6 @@ export interface PlaywrightRelatedOptions extends PlaywrightOptions {
22
27
  files: string[];
23
28
  }
24
29
 
25
- export interface CheckReport {
26
- react: ReactViolation[];
27
- queues: unknown[];
28
- rules: unknown[];
29
- integration: unknown[];
30
- codebase: unknown[];
31
- warnings: string[];
32
- advisories: unknown[];
33
- }
34
-
35
- export interface QueueReport {
36
- producers: unknown[];
37
- workers: unknown[];
38
- jobs: unknown[];
39
- edges: unknown[];
40
- diagnostics: unknown[];
41
- check: unknown[];
42
- }
43
-
44
30
  export interface GraphEdge {
45
31
  from: string;
46
32
  to: string;
@@ -118,112 +104,3 @@ export interface ServerRoutesReport {
118
104
  edges: unknown[];
119
105
  diagnostics: unknown[];
120
106
  }
121
-
122
- export type FetchSourceType =
123
- | "page"
124
- | "layout"
125
- | "loading"
126
- | "error"
127
- | "template"
128
- | "route"
129
- | "module";
130
-
131
- export type CacheKind =
132
- | "none"
133
- | "fetch-cache"
134
- | "fetch-next-revalidate"
135
- | "fetch-next-tags"
136
- | "react-cache"
137
- | "cache"
138
- | "unstable-cache";
139
-
140
- export interface FetchOccurrence {
141
- path: string;
142
- rawPath: string;
143
- method: string;
144
- file: string;
145
- line: number;
146
- side: "server" | "client";
147
- rsc: boolean;
148
- cached: boolean;
149
- cacheKind: CacheKind;
150
- cachedFunction?: string;
151
- dynamic: boolean;
152
- unsupported: boolean;
153
- functionName?: string;
154
- conditional: boolean;
155
- inPromiseAll: boolean;
156
- errorHandled: boolean;
157
- sourceType: FetchSourceType;
158
- }
159
-
160
- export interface FetchRouteReport {
161
- route: string;
162
- file: string;
163
- apiCalls: FetchOccurrence[];
164
- }
165
-
166
- export interface FetchSummary {
167
- totalRoutes: number;
168
- routesWithApiCalls: number;
169
- totalApiCalls: number;
170
- uniqueApiCalls: number;
171
- duplicateApiCalls: number;
172
- dynamicApiCalls: number;
173
- cachedApiCalls: number;
174
- clientApiCalls: number;
175
- serverApiCalls: number;
176
- rscApiCalls: number;
177
- conditionalApiCalls: number;
178
- parallelApiCalls: number;
179
- errorHandledApiCalls: number;
180
- }
181
-
182
- export interface FetchReport {
183
- summary: FetchSummary;
184
- routes: FetchRouteReport[];
185
- duplicates: unknown[];
186
- unsupported: unknown[];
187
- }
188
-
189
- export interface ReactComponentFacts {
190
- name: string;
191
- file: string;
192
- environment: "server" | "client" | "shared" | "unknown";
193
- hasState: boolean;
194
- hasProps: boolean;
195
- passesProps: boolean;
196
- usesMemo: boolean;
197
- usesContextProvider: boolean;
198
- usesSuspense: boolean;
199
- fetches: unknown[];
200
- dependencies: string[];
201
- children: unknown[];
202
- inheritedFromChildren?: unknown;
203
- }
204
-
205
- export interface ReactViolation {
206
- component: string;
207
- file: string;
208
- rule: string;
209
- detail?: string;
210
- }
211
-
212
- export interface ReactCallsite {
213
- file: string;
214
- line: number;
215
- component: string;
216
- props: string[];
217
- hasSpread: boolean;
218
- }
219
-
220
- export interface ReactUsagesReport {
221
- target: { file: string; symbol?: string };
222
- callsites: ReactCallsite[];
223
- /** Story files importing the target. Omitted when `props`/`tests`-only `include`. */
224
- stories?: string[];
225
- /** Test files importing the target. */
226
- tests?: string[];
227
- /** Exported prop type/interface names declared in the target file. */
228
- propTypes?: string[];
229
- }
package/test-types.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import type { SymbolEntrypoint } from "./traversal-types";
2
2
 
3
- export interface TestsPlanOptions {
4
- framework?: "vitest" | "playwright" | "dotnet" | "swift";
3
+ type TestPlanFramework = "vitest" | "playwright" | "dotnet" | "swift";
4
+
5
+ interface TestsPlanOptionsBase {
6
+ framework?: TestPlanFramework;
5
7
  /** Project root. Defaults to the current working directory. */
6
8
  root?: string;
7
9
  /** Path to the no-mistakes config file (e.g. .no-mistakes.yml). Auto-discovered in root if omitted. */
@@ -26,6 +28,29 @@ export interface TestsPlanOptions {
26
28
  globalConfigFallback?: boolean;
27
29
  }
28
30
 
31
+ /**
32
+ * Options for `testsPlan()`. Direct-owner plans intentionally bypass normal
33
+ * test-plan policy, so their incompatible options are rejected at compile time.
34
+ */
35
+ export type TestsPlanOptions =
36
+ | (Omit<
37
+ TestsPlanOptionsBase,
38
+ "framework" | "limitPercent" | "limitFiles" | "globalConfigFallback"
39
+ > & {
40
+ /** Select changed framework-owned tests plus tests one reverse graph edge away. */
41
+ directTestOwner: true;
42
+ framework: TestPlanFramework;
43
+ /** Direct-owner selection is bounded to changed files; use testsImpact for explicit entrypoints. */
44
+ entrypoints?: never;
45
+ limitPercent?: never;
46
+ limitFiles?: never;
47
+ globalConfigFallback?: never;
48
+ })
49
+ | (TestsPlanOptionsBase & {
50
+ /** Set to true only with an explicit framework and without policy overrides. */
51
+ directTestOwner?: false;
52
+ });
53
+
29
54
  export interface TestsImpactOptions {
30
55
  /** Project root. Defaults to the current working directory. */
31
56
  root?: string;
@@ -207,3 +207,8 @@ export interface ProjectOptions {
207
207
  /** `reactUsages` `--include` spec: comma-separated `stories,tests,props`. */
208
208
  include?: string;
209
209
  }
210
+
211
+ export interface CheckOptions extends ProjectOptions {
212
+ /** Add deterministic accounting for findings hidden by no-mistakes directives. */
213
+ includeSuppressed?: boolean;
214
+ }