no-mistakes 0.84.2 → 0.86.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/analyze-project-types.d.ts +8 -7
- package/check-report-types.d.ts +49 -0
- package/declared-payload-types.d.ts +19 -0
- package/index-ci-infra.d.ts +6 -0
- package/index.js +8 -1
- package/index.mjs +1 -0
- package/invocation-types.d.ts +9 -3
- package/named-query-types.d.ts +1 -1
- package/package.json +6 -5
- package/planning-artifact-inputs.js +68 -0
- package/planning.js +12 -63
- package/postgres-insert-types.d.ts +3 -0
- package/postgres-procedural-types.d.ts +25 -0
- package/postgres-query-statement-types.d.ts +3 -1
- package/postgres-query-types.d.ts +16 -0
- package/query-types.d.ts +28 -4
- package/test-audit-types.d.ts +100 -0
- package/test-types.d.ts +9 -0
- package/traversal-types.d.ts +2 -0
- package/types.d.ts +2 -0
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
CiTopologyOptions,
|
|
5
|
-
ImpactedChecksOptions,
|
|
6
|
-
} from "./ci-types";
|
|
1
|
+
import type { TestsAuditOptions } from "./test-audit-types";
|
|
2
|
+
import type { CiTopologyOptions } from "./workflow-topology-types";
|
|
3
|
+
import type { CiEnvOptions, CiImpactOptions, ImpactedChecksOptions } from "./ci-types";
|
|
7
4
|
import type { FetchesOptions, FlowOptions } from "./flow-types";
|
|
8
5
|
import type { ImportUsagesOptions } from "./import-usage-types";
|
|
9
6
|
import type { MermaidValidationOptions } from "./mermaid-types";
|
|
@@ -60,7 +57,10 @@ type BatchedReactUsagesOptions = Pick<
|
|
|
60
57
|
"root" | "tsconfig" | "config" | "targets" | "include"
|
|
61
58
|
> &
|
|
62
59
|
Required<Pick<ProjectOptions, "target">>;
|
|
63
|
-
type BatchedCheckOptions = Pick<
|
|
60
|
+
type BatchedCheckOptions = Pick<
|
|
61
|
+
CheckOptions,
|
|
62
|
+
"root" | "tsconfig" | "config" | "includeSuppressed" | "includeRunnerConfigDeadlines"
|
|
63
|
+
>;
|
|
64
64
|
type BatchedQueryFileOptions<T> = Omit<T, "root" | "tsconfig">;
|
|
65
65
|
type BatchedRootConfigOptions<T> = Omit<T, "root" | "config">;
|
|
66
66
|
type BatchedRootTsConfigOptions<T> = Omit<T, "root" | "tsconfig" | "config">;
|
|
@@ -115,6 +115,7 @@ export type AnalyzeProjectReportRequest =
|
|
|
115
115
|
| ({ type: "fetches"; id?: string } & BatchedRootConfigOptions<FetchesOptions>)
|
|
116
116
|
| ({ type: "dataPw"; id?: string } & BatchedRootConfigOptions<DataPwOptions>)
|
|
117
117
|
| ({ type: "registryExtension"; id?: string } & Omit<RegistryExtensionOptions, "root">)
|
|
118
|
+
| ({ type: "testsAudit"; id?: string } & TestsAuditOptions)
|
|
118
119
|
| ({ type: "testsPlan"; id?: string } & BatchedRootTsConfigOptions<TestsPlanOptions>)
|
|
119
120
|
| ({ type: "testsImpact"; id?: string } & BatchedRootTsConfigOptions<TestsImpactOptions>)
|
|
120
121
|
| ({ type: "testsTargets"; id?: string } & Omit<TestsTargetsOptions, "root" | "config">)
|
package/check-report-types.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export interface CheckReport {
|
|
|
6
6
|
queues: QueueCheckFinding[];
|
|
7
7
|
rules: RuleFinding[];
|
|
8
8
|
integration: IntegrationFinding[];
|
|
9
|
+
/** Present only when requested; declaration evidence, not runtime closure. */
|
|
10
|
+
runnerConfigDeadlines?: RunnerConfigDeadlineEvidence[];
|
|
9
11
|
codebase: UniqueExportFinding[];
|
|
10
12
|
warnings: string[];
|
|
11
13
|
advisories: RuleFinding[];
|
|
@@ -55,3 +57,50 @@ export interface UniqueExportFinding {
|
|
|
55
57
|
exportKind: string;
|
|
56
58
|
message: string;
|
|
57
59
|
}
|
|
60
|
+
|
|
61
|
+
export type RunnerDeadlineStatus = "notRequested" | "prepared" | "failed";
|
|
62
|
+
export interface RunnerConfigDeadlineEvidence {
|
|
63
|
+
framework: "playwright" | "vitest";
|
|
64
|
+
status: RunnerDeadlineStatus;
|
|
65
|
+
configs: ConfigDeadlineEvidence[];
|
|
66
|
+
}
|
|
67
|
+
export type ConfigDeadlineEvidence =
|
|
68
|
+
| { status: "prepared"; config: string; projects: ProjectDeadlineEvidence[] }
|
|
69
|
+
| { status: "failed"; config: string; error: string };
|
|
70
|
+
export interface ProjectDeadlineEvidence {
|
|
71
|
+
config: string | null;
|
|
72
|
+
workspace: boolean;
|
|
73
|
+
policyName: string | null;
|
|
74
|
+
runnerProjectArg: string | null;
|
|
75
|
+
scope: string | null;
|
|
76
|
+
case: DeclaredDeadlineSlot;
|
|
77
|
+
hook: DeclaredDeadlineSlot;
|
|
78
|
+
fixture: DeclaredDeadlineSlot;
|
|
79
|
+
}
|
|
80
|
+
export type DeclaredDeadlineSlot =
|
|
81
|
+
| { status: "absent" }
|
|
82
|
+
| { status: "known"; milliseconds: number; provenance: DeadlineProvenance }
|
|
83
|
+
| { status: "unknown"; reason: DeclaredDeadlineUnknownReason; provenance: DeadlineProvenance };
|
|
84
|
+
export type DeclaredDeadlineUnknownReason =
|
|
85
|
+
| "expression"
|
|
86
|
+
| "nonFinite"
|
|
87
|
+
| "opaqueSpread"
|
|
88
|
+
| "opaqueTestObject"
|
|
89
|
+
| "computedProperty"
|
|
90
|
+
| "unresolvedExtends"
|
|
91
|
+
| "unresolvedInheritance"
|
|
92
|
+
| "unprovedConfigRoot"
|
|
93
|
+
| "accessor"
|
|
94
|
+
| "unsupportedConfigCall"
|
|
95
|
+
| "unprovedBinding";
|
|
96
|
+
export interface DeadlineProvenance {
|
|
97
|
+
/** Request-root-relative slash path; outside-root sources retain their path. */
|
|
98
|
+
path: string;
|
|
99
|
+
/** Half-open source byte offsets, never line numbers; null when unavailable. */
|
|
100
|
+
span: [number, number] | null;
|
|
101
|
+
inheritedThrough: DeadlineInheritanceEvidence[];
|
|
102
|
+
}
|
|
103
|
+
export interface DeadlineInheritanceEvidence {
|
|
104
|
+
path: string;
|
|
105
|
+
project: string | null;
|
|
106
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Options for the configured `declared-payload-compatibility` check rule. */
|
|
2
|
+
export interface DeclaredPayloadCompatibilityOptions {
|
|
3
|
+
contracts?: DeclaredPayloadContract[];
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/** Producer declarations must accept only values accepted by the consumer. */
|
|
7
|
+
export interface DeclaredPayloadContract {
|
|
8
|
+
name: string;
|
|
9
|
+
producer: DeclaredPayloadSchema;
|
|
10
|
+
consumer: DeclaredPayloadSchema;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** A visible JSON document selected explicitly; no runtime adoption is inferred. */
|
|
14
|
+
export interface DeclaredPayloadSchema {
|
|
15
|
+
/** Root-relative path within this rule application's visible file scope. */
|
|
16
|
+
file: string;
|
|
17
|
+
/** RFC 6901 JSON pointer; omitted or empty selects the whole document. */
|
|
18
|
+
pointer?: string;
|
|
19
|
+
}
|
package/index-ci-infra.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ import type {
|
|
|
28
28
|
SwiftOptions,
|
|
29
29
|
SwiftTestTargetRow,
|
|
30
30
|
TestForRow,
|
|
31
|
+
TestAuditReport,
|
|
32
|
+
TestsAuditOptions,
|
|
31
33
|
WithInvocationOptions,
|
|
32
34
|
WorkflowTopology,
|
|
33
35
|
WorkflowTopologyIndex,
|
|
@@ -73,3 +75,7 @@ export function swiftTestTargets(
|
|
|
73
75
|
options: WithInvocationOptions<SwiftOptions & { file: string }>,
|
|
74
76
|
): Promise<SwiftTestTargetRow[]>;
|
|
75
77
|
export function version(): Promise<string>;
|
|
78
|
+
|
|
79
|
+
export function testsAudit(
|
|
80
|
+
options: WithInvocationOptions<TestsAuditOptions>,
|
|
81
|
+
): Promise<TestAuditReport>;
|
package/index.js
CHANGED
|
@@ -66,7 +66,13 @@ const jsonApis = createJsonApis({
|
|
|
66
66
|
symbols: "symbolsJson",
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
const CAMELIZE_REPORTS = new Set([
|
|
69
|
+
const CAMELIZE_REPORTS = new Set([
|
|
70
|
+
"testsAudit",
|
|
71
|
+
"testsPlan",
|
|
72
|
+
"testsImpact",
|
|
73
|
+
"testsTargets",
|
|
74
|
+
"testsGraph",
|
|
75
|
+
]);
|
|
70
76
|
const acquirePlanningArtifactLock = createPlanningArtifactLock(native);
|
|
71
77
|
|
|
72
78
|
async function analyzeProject(options = {}) {
|
|
@@ -163,6 +169,7 @@ module.exports.serverRouteEdges = planning.serverRouteEdges;
|
|
|
163
169
|
module.exports.serverRouteList = planning.serverRouteList;
|
|
164
170
|
module.exports.serverRouteRelated = planning.serverRouteRelated;
|
|
165
171
|
module.exports.serverRoutes = planning.serverRoutes;
|
|
172
|
+
module.exports.testsAudit = planning.testsAudit;
|
|
166
173
|
module.exports.testsGraph = planning.testsGraph;
|
|
167
174
|
module.exports.testsImpact = planning.testsImpact;
|
|
168
175
|
module.exports.testsPlan = planning.testsPlan;
|
package/index.mjs
CHANGED
package/invocation-types.d.ts
CHANGED
|
@@ -2,13 +2,19 @@
|
|
|
2
2
|
export interface InvocationOptions {
|
|
3
3
|
/** Command execution timeout in whole non-negative seconds. Omit, `0`, or `null` disables it. CLI default remains 30. */
|
|
4
4
|
timeout?: number | null;
|
|
5
|
-
/** Maximum time to wait for the
|
|
5
|
+
/** Maximum time to wait for the current user's invocation lock (shared across project roots), in whole non-negative seconds. Omit, `0`, or `null` waits indefinitely. CLI default remains 30. */
|
|
6
6
|
lockTimeout?: number | null;
|
|
7
7
|
/** Fail immediately instead of waiting when another invocation holds the lock. */
|
|
8
8
|
failOnLock?: boolean;
|
|
9
9
|
/**
|
|
10
|
-
* Rayon worker count.
|
|
11
|
-
*
|
|
10
|
+
* Rayon worker count. A positive integer takes precedence over `RAYON_NUM_THREADS`.
|
|
11
|
+
* Omit, `0`, or `null` uses `RAYON_NUM_THREADS`, falling back to CPU count when
|
|
12
|
+
* unset or invalid, matching CLI `--jobs 0`.
|
|
13
|
+
* The first analysis request with valid UTF-8 JSON and invocation controls that
|
|
14
|
+
* acquires the invocation lock initializes the process-wide pool before
|
|
15
|
+
* command-specific options are validated. A later command-validation failure
|
|
16
|
+
* can therefore still select the pool; JSON/control or lock failures cannot.
|
|
17
|
+
* Later calls cannot resize an already initialized pool.
|
|
12
18
|
*/
|
|
13
19
|
jobs?: number | null;
|
|
14
20
|
/** `ci` sets unbounded command and lock timeouts. CLI `--profile ci` does the same. */
|
package/named-query-types.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export interface EffectsOptions {
|
|
|
37
37
|
tsconfig?: string;
|
|
38
38
|
/** Path to the no-mistakes config file (e.g. .no-mistakes.yml). Auto-discovered in root if omitted. */
|
|
39
39
|
config?: string;
|
|
40
|
-
/** Effect
|
|
40
|
+
/** Effect family from config; supports spelling lists and binding-aware module/export targets. */
|
|
41
41
|
kind: string;
|
|
42
42
|
/** Entry file whose transitive imports are scanned. */
|
|
43
43
|
entry: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "no-mistakes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.0",
|
|
4
4
|
"description": "Deterministic impact maps, test plans, Playwright coverage, and repository checks for coding agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"planning-impact-artifacts-privacy.js",
|
|
25
25
|
"planning-impact-cli.js",
|
|
26
26
|
"planning.js",
|
|
27
|
+
"planning-artifact-inputs.js",
|
|
27
28
|
"workflow-topology-index.js",
|
|
28
29
|
"workflow-topology-index-helpers.js",
|
|
29
30
|
"scripts/native-package.js",
|
|
@@ -45,9 +46,9 @@
|
|
|
45
46
|
"access": "public"
|
|
46
47
|
},
|
|
47
48
|
"optionalDependencies": {
|
|
48
|
-
"no-mistakes-darwin-arm64": "0.
|
|
49
|
-
"no-mistakes-linux-arm64-gnu": "0.
|
|
50
|
-
"no-mistakes-linux-x64-gnu": "0.
|
|
51
|
-
"no-mistakes-win32-x64-msvc": "0.
|
|
49
|
+
"no-mistakes-darwin-arm64": "0.86.0",
|
|
50
|
+
"no-mistakes-linux-arm64-gnu": "0.86.0",
|
|
51
|
+
"no-mistakes-linux-x64-gnu": "0.86.0",
|
|
52
|
+
"no-mistakes-win32-x64-msvc": "0.86.0"
|
|
52
53
|
}
|
|
53
54
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("node:fs/promises");
|
|
4
|
+
|
|
5
|
+
function camelizeKey(key) {
|
|
6
|
+
return key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function decamelizeKey(key) {
|
|
10
|
+
return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function mapKeys(value, mapKey) {
|
|
14
|
+
if (Array.isArray(value)) return value.map((item) => mapKeys(item, mapKey));
|
|
15
|
+
if (value && typeof value === "object") {
|
|
16
|
+
return Object.fromEntries(
|
|
17
|
+
Object.entries(value).map(([key, nested]) => [mapKey(key), mapKeys(nested, mapKey)]),
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function camelizeValue(value) {
|
|
24
|
+
return mapKeys(value, camelizeKey);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function decamelizeValue(value) {
|
|
28
|
+
return mapKeys(value, decamelizeKey);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function loadPlanJson(planJson) {
|
|
32
|
+
let parsed = planJson;
|
|
33
|
+
if (typeof parsed === "string") {
|
|
34
|
+
try {
|
|
35
|
+
parsed = JSON.parse(parsed);
|
|
36
|
+
} catch {
|
|
37
|
+
return planJson;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (parsed && typeof parsed === "object") {
|
|
41
|
+
return decamelizeValue(parsed);
|
|
42
|
+
}
|
|
43
|
+
return planJson;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function readPlanFile(planPath) {
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(await fs.readFile(planPath, "utf8"));
|
|
49
|
+
} catch {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function decamelizePlanOptions(options = {}) {
|
|
55
|
+
const next = { ...options };
|
|
56
|
+
if (next.planJson != null) {
|
|
57
|
+
next.planJson = loadPlanJson(next.planJson);
|
|
58
|
+
} else if (typeof next.plan === "string") {
|
|
59
|
+
const document = await readPlanFile(next.plan);
|
|
60
|
+
if (document !== undefined) {
|
|
61
|
+
next.planJson = loadPlanJson(document);
|
|
62
|
+
delete next.plan;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return next;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = { camelizeValue, decamelizePlanOptions, loadPlanJson, readPlanFile };
|
package/planning.js
CHANGED
|
@@ -7,6 +7,12 @@ const { resolveNativePackage } = require("./scripts/native-package");
|
|
|
7
7
|
const native = require(
|
|
8
8
|
process.env.NO_MISTAKES_TEST_NAPI_ADDON_PATH || resolveNativePackage().addonPath,
|
|
9
9
|
);
|
|
10
|
+
const {
|
|
11
|
+
camelizeValue,
|
|
12
|
+
decamelizePlanOptions,
|
|
13
|
+
loadPlanJson,
|
|
14
|
+
readPlanFile,
|
|
15
|
+
} = require("./planning-artifact-inputs");
|
|
10
16
|
const PLAN_INPUT_REPORTS = new Set(["testsComment", "testsGraph", "testsGraphMermaid"]);
|
|
11
17
|
|
|
12
18
|
async function callJson(fn, options) {
|
|
@@ -23,69 +29,6 @@ function createJsonApis(descriptors) {
|
|
|
23
29
|
);
|
|
24
30
|
}
|
|
25
31
|
|
|
26
|
-
function camelizeKey(key) {
|
|
27
|
-
return key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function decamelizeKey(key) {
|
|
31
|
-
return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function mapKeys(value, mapKey) {
|
|
35
|
-
if (Array.isArray(value)) return value.map((item) => mapKeys(item, mapKey));
|
|
36
|
-
if (value && typeof value === "object") {
|
|
37
|
-
return Object.fromEntries(
|
|
38
|
-
Object.entries(value).map(([key, nested]) => [mapKey(key), mapKeys(nested, mapKey)]),
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
return value;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function camelizeValue(value) {
|
|
45
|
-
return mapKeys(value, camelizeKey);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function decamelizeValue(value) {
|
|
49
|
-
return mapKeys(value, decamelizeKey);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function loadPlanJson(planJson) {
|
|
53
|
-
let parsed = planJson;
|
|
54
|
-
if (typeof parsed === "string") {
|
|
55
|
-
try {
|
|
56
|
-
parsed = JSON.parse(parsed);
|
|
57
|
-
} catch {
|
|
58
|
-
return planJson;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
if (parsed && typeof parsed === "object") {
|
|
62
|
-
return decamelizeValue(parsed);
|
|
63
|
-
}
|
|
64
|
-
return planJson;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async function readPlanFile(planPath) {
|
|
68
|
-
try {
|
|
69
|
-
return JSON.parse(await fs.readFile(planPath, "utf8"));
|
|
70
|
-
} catch {
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function decamelizePlanOptions(options = {}) {
|
|
76
|
-
const next = { ...options };
|
|
77
|
-
if (next.planJson != null) {
|
|
78
|
-
next.planJson = loadPlanJson(next.planJson);
|
|
79
|
-
} else if (typeof next.plan === "string") {
|
|
80
|
-
const document = await readPlanFile(next.plan);
|
|
81
|
-
if (document !== undefined) {
|
|
82
|
-
next.planJson = loadPlanJson(document);
|
|
83
|
-
delete next.plan;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return next;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
32
|
async function prepareWhyPlan(options = {}) {
|
|
90
33
|
const next = { ...options };
|
|
91
34
|
let document = next.planJson;
|
|
@@ -163,6 +106,7 @@ const jsonApis = createJsonApis({
|
|
|
163
106
|
serverRouteList: "serverRouteListJson",
|
|
164
107
|
serverRouteRelated: "serverRouteRelatedJson",
|
|
165
108
|
serverRoutes: "serverRoutesJson",
|
|
109
|
+
testsAudit: "testsAuditJson",
|
|
166
110
|
testsGraph: "testsGraphJson",
|
|
167
111
|
testsImpact: "testsImpactJson",
|
|
168
112
|
testsPlan: "testsPlanJson",
|
|
@@ -170,6 +114,10 @@ const jsonApis = createJsonApis({
|
|
|
170
114
|
testsWhy: "testsWhyJson",
|
|
171
115
|
});
|
|
172
116
|
|
|
117
|
+
async function testsAudit(options) {
|
|
118
|
+
return camelizeValue(await jsonApis.testsAudit(options));
|
|
119
|
+
}
|
|
120
|
+
|
|
173
121
|
async function testsPlan(options) {
|
|
174
122
|
return camelizeValue(await jsonApis.testsPlan(options));
|
|
175
123
|
}
|
|
@@ -206,6 +154,7 @@ module.exports = {
|
|
|
206
154
|
testsComment,
|
|
207
155
|
testsGraphMermaid,
|
|
208
156
|
...jsonApis,
|
|
157
|
+
testsAudit,
|
|
209
158
|
testsGraph,
|
|
210
159
|
testsImpact,
|
|
211
160
|
testsPlan,
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
PostgresSqlSpan,
|
|
7
7
|
} from "./postgres-source-types";
|
|
8
8
|
import type { PostgresSqlQuery } from "./postgres-query-types";
|
|
9
|
+
import type { PostgresSqlReturningItem } from "./postgres-query-statement-types";
|
|
9
10
|
/** Syntactic facts only: complete does not establish replay safety. */
|
|
10
11
|
export interface PostgresSqlInsert {
|
|
11
12
|
table: PostgresSqlName | null;
|
|
@@ -15,6 +16,8 @@ export interface PostgresSqlInsert {
|
|
|
15
16
|
columnSources: PostgresSqlInsertColumnSources;
|
|
16
17
|
source: PostgresSqlInsertSource;
|
|
17
18
|
onConflict: PostgresSqlConflict | null;
|
|
19
|
+
/** Empty when the statement has no RETURNING clause. */
|
|
20
|
+
returning: PostgresSqlReturningItem[];
|
|
18
21
|
span: PostgresSqlSpan | null;
|
|
19
22
|
/** Syntax completeness is independent of provenance and does not imply replay safety. */
|
|
20
23
|
complete: boolean;
|
|
@@ -14,10 +14,35 @@ export interface PostgresSqlProceduralBlock {
|
|
|
14
14
|
bodyEncoding: PostgresSqlBodyEncoding;
|
|
15
15
|
bodySpan: PostgresSqlSpan;
|
|
16
16
|
statements: PostgresSqlStatement[];
|
|
17
|
+
/** Classified source occurrences in source order. Visibility is not execution. */
|
|
18
|
+
occurrences: PostgresSqlProceduralOccurrence[];
|
|
17
19
|
diagnostics: PostgresSqlDiagnostic[];
|
|
18
20
|
complete: boolean;
|
|
19
21
|
}
|
|
20
22
|
|
|
23
|
+
/** Closed classification for one procedural source occurrence. */
|
|
24
|
+
export type PostgresSqlProceduralOccurrenceKind =
|
|
25
|
+
| "utility"
|
|
26
|
+
| "controlFlow"
|
|
27
|
+
| "dml"
|
|
28
|
+
| "dynamicExecute"
|
|
29
|
+
| "unknown";
|
|
30
|
+
|
|
31
|
+
/** One statically visible occurrence and the occurrences it contains.
|
|
32
|
+
* `utility` is a non-DML command such as CREATE TYPE.
|
|
33
|
+
* `controlFlow` is IF, LOOP, RAISE, or another recognized procedural form.
|
|
34
|
+
* `dml` means INSERT, UPDATE, DELETE, or MERGE text is present; it does not run.
|
|
35
|
+
* `dynamicExecute` is EXECUTE of a non-literal command, including format and
|
|
36
|
+
* concatenation that is not wholly literal. `unknown` fails closed.
|
|
37
|
+
* Nested occurrences stay in source order. Spans use original source coordinates.
|
|
38
|
+
* Quoted strings and comments are not keywords.
|
|
39
|
+
*/
|
|
40
|
+
export interface PostgresSqlProceduralOccurrence {
|
|
41
|
+
kind: PostgresSqlProceduralOccurrenceKind;
|
|
42
|
+
span: PostgresSqlSpan;
|
|
43
|
+
occurrences: PostgresSqlProceduralOccurrence[];
|
|
44
|
+
}
|
|
45
|
+
|
|
21
46
|
/** Branch DDL describes source occurrences, never guaranteed execution. */
|
|
22
47
|
export interface PostgresSqlConditionalBranch {
|
|
23
48
|
condition: PostgresSqlExpression | null;
|
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
PostgresSqlName,
|
|
6
6
|
PostgresSqlSpan,
|
|
7
7
|
} from "./postgres-source-types";
|
|
8
|
-
import type { PostgresSqlConflict } from "./postgres-insert-types";
|
|
8
|
+
import type { PostgresSqlConflict, PostgresSqlInsertColumnSources } from "./postgres-insert-types";
|
|
9
9
|
import type { PostgresSqlQueryUnsupported } from "./postgres-query-types";
|
|
10
10
|
|
|
11
11
|
/** Syntactic modifying bodies in source order, not PostgreSQL execution order.
|
|
@@ -37,6 +37,8 @@ export interface PostgresSqlCteInsert {
|
|
|
37
37
|
alias: PostgresSqlIdentifier | null;
|
|
38
38
|
columns: PostgresSqlName[];
|
|
39
39
|
columnsOmitted: boolean;
|
|
40
|
+
/** Omitted for non-RETURNING CTE inserts. RETURNING keeps direct column lineage. */
|
|
41
|
+
columnSources?: PostgresSqlInsertColumnSources;
|
|
40
42
|
source: PostgresSqlCteInsertSource;
|
|
41
43
|
onConflict: PostgresSqlConflict | null;
|
|
42
44
|
diagnostics: PostgresSqlDiagnostic[];
|
|
@@ -87,6 +87,8 @@ export interface PostgresSqlQueryColumn {
|
|
|
87
87
|
}
|
|
88
88
|
export interface PostgresSqlPredicateContext {
|
|
89
89
|
mandatory: boolean;
|
|
90
|
+
/** Required conjunct after wrapping NOT inverts AND/OR; null through opaque wrappers. */
|
|
91
|
+
effectiveMandatory: boolean | null;
|
|
90
92
|
underOr: boolean;
|
|
91
93
|
underNot: boolean;
|
|
92
94
|
underCase: boolean;
|
|
@@ -105,7 +107,21 @@ export interface PostgresSqlQueryEquality {
|
|
|
105
107
|
export interface PostgresSqlQueryExists {
|
|
106
108
|
scopeId: number;
|
|
107
109
|
subqueryScopeId: number;
|
|
110
|
+
/** The EXISTS node's own flag. Wrapping `NOT` is not folded into this value. */
|
|
108
111
|
negated: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* NOT operators that apply to this EXISTS: each wrapping `NOT` (parentheses
|
|
114
|
+
* are transparent) plus one when `negated` is true.
|
|
115
|
+
*/
|
|
116
|
+
notDepth: number;
|
|
117
|
+
/**
|
|
118
|
+
* `notDepth % 2 === 1` when this EXISTS is not under a boolean test, CASE,
|
|
119
|
+
* or other wrapper. `null` when `context.underBooleanTest`,
|
|
120
|
+
* `context.underCase`, or `context.underOther` is set: those wrappers can
|
|
121
|
+
* invert or hide polarity, and this field does not guess. Always present.
|
|
122
|
+
* Distinct from `negated` and from `context.underNot`.
|
|
123
|
+
*/
|
|
124
|
+
effectiveNegated: boolean | null;
|
|
109
125
|
context: PostgresSqlPredicateContext;
|
|
110
126
|
correlated: boolean;
|
|
111
127
|
correlations: PostgresSqlQueryColumn[];
|
package/query-types.d.ts
CHANGED
|
@@ -19,7 +19,27 @@ export interface ImportersTestImpact {
|
|
|
19
19
|
count: number;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
/** A recorded gap in the prepared reverse-query source inventory. */
|
|
23
|
+
export type QueryIncompleteReason =
|
|
24
|
+
| "operational-error"
|
|
25
|
+
| "parse-error"
|
|
26
|
+
| "missing-facts"
|
|
27
|
+
| "missing-symbols";
|
|
28
|
+
|
|
29
|
+
export interface QueryIncompleteFile {
|
|
30
|
+
/** Root-relative candidate path; relevance can be unknown when imports are missing. */
|
|
31
|
+
file: string;
|
|
32
|
+
reason: QueryIncompleteReason;
|
|
33
|
+
message: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface QueryDiagnostics {
|
|
37
|
+
/** Recorded collection gaps exist. False does not guarantee exhaustive references. */
|
|
38
|
+
partial: boolean;
|
|
39
|
+
incompleteFiles: QueryIncompleteFile[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ImportersResult extends QueryDiagnostics {
|
|
23
43
|
file: string;
|
|
24
44
|
directImporters: string[];
|
|
25
45
|
dependentsCount: number;
|
|
@@ -43,6 +63,10 @@ export interface ExportRowResult {
|
|
|
43
63
|
export interface ExportsOfResult {
|
|
44
64
|
file: string;
|
|
45
65
|
exports: ExportRowResult[];
|
|
66
|
+
/** Omitted with noImporters because the reverse scan was not requested. */
|
|
67
|
+
partial?: boolean;
|
|
68
|
+
/** Omitted with noImporters. */
|
|
69
|
+
incompleteFiles?: QueryIncompleteFile[];
|
|
46
70
|
}
|
|
47
71
|
|
|
48
72
|
export interface DeadExportsOptions extends QueryFileOptions {
|
|
@@ -56,14 +80,14 @@ export interface DeadExportResult {
|
|
|
56
80
|
importerCount: number;
|
|
57
81
|
}
|
|
58
82
|
|
|
59
|
-
export interface DeadExportsResult {
|
|
83
|
+
export interface DeadExportsResult extends QueryDiagnostics {
|
|
60
84
|
file: string;
|
|
61
85
|
results: DeadExportResult[];
|
|
62
86
|
anyDead: boolean;
|
|
63
87
|
}
|
|
64
88
|
|
|
65
89
|
export interface CallSitesOptions extends QueryFileOptions {
|
|
66
|
-
/**
|
|
90
|
+
/** Exported callable to resolve through namespaces, static lexical aliases, and barrels. */
|
|
67
91
|
exportName: string;
|
|
68
92
|
}
|
|
69
93
|
|
|
@@ -90,7 +114,7 @@ export interface CallSite {
|
|
|
90
114
|
args: ArgShape[];
|
|
91
115
|
}
|
|
92
116
|
|
|
93
|
-
export interface CallSitesResult {
|
|
117
|
+
export interface CallSitesResult extends QueryDiagnostics {
|
|
94
118
|
file: string;
|
|
95
119
|
export: string;
|
|
96
120
|
callSites: CallSite[];
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { ImpactReason, TestPlan } from "./test-types";
|
|
2
|
+
|
|
3
|
+
/** Caller-recorded immutable identities; audit compares but does not verify the digests. */
|
|
4
|
+
export interface TestAuditProvenance {
|
|
5
|
+
/** Lowercase 40- or 64-digit Git revision. */
|
|
6
|
+
checkoutRevision: string;
|
|
7
|
+
/** SHA-256 of the complete source/config snapshot, including dirty changes. */
|
|
8
|
+
sourceDigest: string;
|
|
9
|
+
/** SHA-256 of the runner/project/config/instrumentation scope. */
|
|
10
|
+
scopeDigest: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface TestAuditSymbol {
|
|
14
|
+
file: string;
|
|
15
|
+
/** Exact exported/callable identity agreed upon by the producer and adapter. */
|
|
16
|
+
symbol: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface TestAuditPlanArtifact {
|
|
20
|
+
schemaVersion: 1;
|
|
21
|
+
provenance: TestAuditProvenance;
|
|
22
|
+
plan: TestPlan;
|
|
23
|
+
/** Explicit root-relative scope; must match plan.changedFiles when nonempty. */
|
|
24
|
+
changedFiles: string[];
|
|
25
|
+
/** Refines matching for these files to exact symbols rather than any file execution. */
|
|
26
|
+
changedSymbols: TestAuditSymbol[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface TestAuditObservation {
|
|
30
|
+
/** Inventory identity; does not alone prove execution. */
|
|
31
|
+
testFile: string;
|
|
32
|
+
/** Explicit execution evidence, including the test file itself when its source was evaluated. */
|
|
33
|
+
executedFiles: string[];
|
|
34
|
+
executedSymbols: TestAuditSymbol[];
|
|
35
|
+
/** Complete file AND symbol tracing for the declared scope; false makes negative evidence unknown. */
|
|
36
|
+
traceComplete: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface TestAuditObservationsArtifact {
|
|
40
|
+
schemaVersion: 1;
|
|
41
|
+
provenance: TestAuditProvenance;
|
|
42
|
+
granularity: "per-test-file";
|
|
43
|
+
suite: "full";
|
|
44
|
+
/** Declares the full suite finished; does not assert instrumentation completeness. */
|
|
45
|
+
complete: true;
|
|
46
|
+
/** One merged observation per test file; aggregate suite coverage is unsupported. */
|
|
47
|
+
tests: TestAuditObservation[];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface TestsAuditPlanFileInput {
|
|
51
|
+
plan: string;
|
|
52
|
+
planJson?: never;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface TestsAuditPlanInlineInput {
|
|
56
|
+
plan?: never;
|
|
57
|
+
planJson: TestAuditPlanArtifact | string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface TestsAuditObservationsFileInput {
|
|
61
|
+
observations: string;
|
|
62
|
+
observationsJson?: never;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface TestsAuditObservationsInlineInput {
|
|
66
|
+
observations?: never;
|
|
67
|
+
observationsJson: TestAuditObservationsArtifact | string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type TestsAuditPlanInput = TestsAuditPlanFileInput | TestsAuditPlanInlineInput;
|
|
71
|
+
export type TestsAuditObservationsInput =
|
|
72
|
+
| TestsAuditObservationsFileInput
|
|
73
|
+
| TestsAuditObservationsInlineInput;
|
|
74
|
+
/** Requires exactly one path or inline artifact for each input. */
|
|
75
|
+
export type TestsAuditOptions = TestsAuditPlanInput & TestsAuditObservationsInput;
|
|
76
|
+
|
|
77
|
+
export interface TestAuditExecutionEvidence {
|
|
78
|
+
testFile: string;
|
|
79
|
+
matchedFiles: string[];
|
|
80
|
+
matchedSymbols: TestAuditSymbol[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface TestAuditSelectionEvidence {
|
|
84
|
+
testFile: string;
|
|
85
|
+
/** Original static selection reasons for investigating excess selection. */
|
|
86
|
+
reasons: ImpactReason[];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface TestAuditReport {
|
|
90
|
+
provenance: TestAuditProvenance;
|
|
91
|
+
observedTestFiles: number;
|
|
92
|
+
selectedTestFiles: number;
|
|
93
|
+
selectedObservedTests: TestAuditExecutionEvidence[];
|
|
94
|
+
missedObservedTests: TestAuditExecutionEvidence[];
|
|
95
|
+
selectedWithoutObservedExecution: TestAuditSelectionEvidence[];
|
|
96
|
+
selectedWithoutObservations: string[];
|
|
97
|
+
selectedWithIncompleteTraces: string[];
|
|
98
|
+
/** Always explains the limits of observed execution and caller-recorded provenance. */
|
|
99
|
+
limitations: string[];
|
|
100
|
+
}
|
package/test-types.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { SymbolEntrypoint } from "./traversal-types";
|
|
2
2
|
|
|
3
|
+
/** A named project under `.no-mistakes.yml` `tests.vitest.projects`. */
|
|
4
|
+
export interface VitestProjectPolicy {
|
|
5
|
+
include?: string[];
|
|
6
|
+
exclude?: string[];
|
|
7
|
+
/** Repository-root-relative setup modules for this project's matched tests. */
|
|
8
|
+
setup_files?: string[];
|
|
9
|
+
integration_suites?: Record<string, string[]>;
|
|
10
|
+
}
|
|
11
|
+
|
|
3
12
|
/** Runner accepted by `testsPlan`, `testsTargets`, and `TestExecutionTarget`. */
|
|
4
13
|
export type TestPlanFramework =
|
|
5
14
|
| "vitest"
|
package/traversal-types.d.ts
CHANGED
|
@@ -205,4 +205,6 @@ export interface ProjectOptions {
|
|
|
205
205
|
export interface CheckOptions extends ProjectOptions {
|
|
206
206
|
/** Add deterministic accounting for findings hidden by no-mistakes directives. */
|
|
207
207
|
includeSuppressed?: boolean;
|
|
208
|
+
/** Add declared config evidence; absent slots never imply SDK defaults. */
|
|
209
|
+
includeRunnerConfigDeadlines?: boolean;
|
|
208
210
|
}
|
package/types.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./analyze-project-types";
|
|
|
4
4
|
export * from "./flow-types";
|
|
5
5
|
export * from "./import-usage-types";
|
|
6
6
|
export * from "./test-types";
|
|
7
|
+
export * from "./test-audit-types";
|
|
7
8
|
export * from "./report-types";
|
|
8
9
|
export * from "./server-contract-types";
|
|
9
10
|
export * from "./ci-types";
|
|
@@ -14,3 +15,4 @@ export * from "./mermaid-types";
|
|
|
14
15
|
export * from "./resolve-config-types";
|
|
15
16
|
export * from "./postgres-query-annotation-types";
|
|
16
17
|
export * from "./planning-impact-artifacts-types";
|
|
18
|
+
export * from "./declared-payload-types";
|