@clipboard-health/eslint-plugin 2.7.3 → 2.9.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/README.md +12 -0
- package/package.json +1 -1
- package/src/index.d.ts +6 -0
- package/src/index.js +4 -0
- package/src/index.js.map +1 -1
- package/src/lib/rules/require-contract-fixture-construction/index.d.ts +5 -0
- package/src/lib/rules/require-contract-fixture-construction/index.js +616 -0
- package/src/lib/rules/require-contract-fixture-construction/index.js.map +1 -0
- package/src/lib/rules/require-contract-response-parse/index.d.ts +23 -0
- package/src/lib/rules/require-contract-response-parse/index.js +377 -0
- package/src/lib/rules/require-contract-response-parse/index.js.map +1 -0
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@ Clipboard's [ESLint](https://eslint.org/) plugin.
|
|
|
5
5
|
## Table of contents <!-- omit from toc -->
|
|
6
6
|
|
|
7
7
|
- [Install](#install)
|
|
8
|
+
- [Contract fixture construction](#contract-fixture-construction)
|
|
8
9
|
- [Local development commands](#local-development-commands)
|
|
9
10
|
|
|
10
11
|
## Install
|
|
@@ -34,6 +35,17 @@ module.exports = {
|
|
|
34
35
|
};
|
|
35
36
|
```
|
|
36
37
|
|
|
38
|
+
## Contract fixture construction
|
|
39
|
+
|
|
40
|
+
`require-contract-fixture-construction` requires MSW and Playwright response fixtures to be
|
|
41
|
+
constructed through response schemas imported from `@clipboard-health/contract-*` packages. It
|
|
42
|
+
also checks exported fixtures in `testUtils/mocks` modules and rejects fixtures mutated after they
|
|
43
|
+
were parsed.
|
|
44
|
+
|
|
45
|
+
Prefer the `contractFixtures` preset from `@clipboard-health/oxlint-config`. Repositories migrating
|
|
46
|
+
an existing fixture backlog should enable the preset's warning baseline, then add local error-level
|
|
47
|
+
overrides for each migrated directory.
|
|
48
|
+
|
|
37
49
|
## Local development commands
|
|
38
50
|
|
|
39
51
|
See [`package.json`](./package.json) `scripts` for a list of commands.
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -5,6 +5,12 @@ export declare const rules: {
|
|
|
5
5
|
"no-cross-contract-imports": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noCrossContractImport", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
6
6
|
name: string;
|
|
7
7
|
};
|
|
8
|
+
"require-contract-fixture-construction": import("@typescript-eslint/utils/ts-eslint").RuleModule<"parseMock" | "parsePayload", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
11
|
+
"require-contract-response-parse": import("@typescript-eslint/utils/ts-eslint").RuleModule<"inlineAnySchema" | "missingContractParse" | "nonContractSchema", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
8
14
|
"require-http-module-factory": import("@typescript-eslint/utils/ts-eslint").RuleModule<"noImport" | "requireFactory" | "wrongPackage", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
9
15
|
name: string;
|
|
10
16
|
};
|
package/src/index.js
CHANGED
|
@@ -4,12 +4,16 @@ exports.rules = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const enforce_ts_rest_in_controllers_1 = tslib_1.__importDefault(require("./lib/rules/enforce-ts-rest-in-controllers"));
|
|
6
6
|
const no_cross_contract_imports_1 = tslib_1.__importDefault(require("./lib/rules/no-cross-contract-imports"));
|
|
7
|
+
const require_contract_fixture_construction_1 = tslib_1.__importDefault(require("./lib/rules/require-contract-fixture-construction"));
|
|
8
|
+
const require_contract_response_parse_1 = tslib_1.__importDefault(require("./lib/rules/require-contract-response-parse"));
|
|
7
9
|
const require_http_module_factory_1 = tslib_1.__importDefault(require("./lib/rules/require-http-module-factory"));
|
|
8
10
|
const require_run_validators_with_upsert_1 = tslib_1.__importDefault(require("./lib/rules/require-run-validators-with-upsert"));
|
|
9
11
|
const require_zod_import_in_contracts_1 = tslib_1.__importDefault(require("./lib/rules/require-zod-import-in-contracts"));
|
|
10
12
|
exports.rules = {
|
|
11
13
|
"enforce-ts-rest-in-controllers": enforce_ts_rest_in_controllers_1.default,
|
|
12
14
|
"no-cross-contract-imports": no_cross_contract_imports_1.default,
|
|
15
|
+
"require-contract-fixture-construction": require_contract_fixture_construction_1.default,
|
|
16
|
+
"require-contract-response-parse": require_contract_response_parse_1.default,
|
|
13
17
|
"require-http-module-factory": require_http_module_factory_1.default,
|
|
14
18
|
"require-run-validators-with-upsert": require_run_validators_with_upsert_1.default,
|
|
15
19
|
"require-zod-import-in-contracts": require_zod_import_in_contracts_1.default,
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/eslint-plugin/src/index.ts"],"names":[],"mappings":";;;;AAAA,wHAAoF;AACpF,8GAA2E;AAC3E,kHAA+E;AAC/E,gIAA4F;AAC5F,0HAAsF;AAEzE,QAAA,KAAK,GAAG;IACnB,gCAAgC,EAAE,wCAA0B;IAC5D,2BAA2B,EAAE,mCAAsB;IACnD,6BAA6B,EAAE,qCAAwB;IACvD,oCAAoC,EAAE,4CAA8B;IACpE,iCAAiC,EAAE,yCAA2B;CAC/D,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/eslint-plugin/src/index.ts"],"names":[],"mappings":";;;;AAAA,wHAAoF;AACpF,8GAA2E;AAC3E,sIAAmG;AACnG,0HAAuF;AACvF,kHAA+E;AAC/E,gIAA4F;AAC5F,0HAAsF;AAEzE,QAAA,KAAK,GAAG;IACnB,gCAAgC,EAAE,wCAA0B;IAC5D,2BAA2B,EAAE,mCAAsB;IACnD,uCAAuC,EAAE,+CAAkC;IAC3E,iCAAiC,EAAE,yCAA4B;IAC/D,6BAA6B,EAAE,qCAAwB;IACvD,oCAAoC,EAAE,4CAA8B;IACpE,iCAAiC,EAAE,yCAA2B;CAC/D,CAAC"}
|
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("@typescript-eslint/utils");
|
|
4
|
+
const createRule_1 = require("../../createRule");
|
|
5
|
+
const CONTRACT_PACKAGE_PREFIX = "@clipboard-health/contract-";
|
|
6
|
+
const MOCKS_FILE_PATTERN = /\/(?:testUtils|test-utils)\/mocks\.[cm]?[jt]sx?$/u;
|
|
7
|
+
const MOCK_NAME_PATTERN = /mock/iu;
|
|
8
|
+
const MUTATING_METHOD_NAMES = new Set([
|
|
9
|
+
"add",
|
|
10
|
+
"clear",
|
|
11
|
+
"copyWithin",
|
|
12
|
+
"delete",
|
|
13
|
+
"fill",
|
|
14
|
+
"pop",
|
|
15
|
+
"push",
|
|
16
|
+
"reverse",
|
|
17
|
+
"set",
|
|
18
|
+
"shift",
|
|
19
|
+
"sort",
|
|
20
|
+
"splice",
|
|
21
|
+
"unshift",
|
|
22
|
+
]);
|
|
23
|
+
const OBJECT_MUTATOR_NAMES = new Set([
|
|
24
|
+
"assign",
|
|
25
|
+
"defineProperties",
|
|
26
|
+
"defineProperty",
|
|
27
|
+
"setPrototypeOf",
|
|
28
|
+
]);
|
|
29
|
+
function unwrap(node) {
|
|
30
|
+
let current = node;
|
|
31
|
+
while (current?.type === utils_1.AST_NODE_TYPES.ChainExpression ||
|
|
32
|
+
current?.type === utils_1.AST_NODE_TYPES.TSAsExpression ||
|
|
33
|
+
current?.type === utils_1.AST_NODE_TYPES.TSInstantiationExpression ||
|
|
34
|
+
current?.type === utils_1.AST_NODE_TYPES.TSNonNullExpression ||
|
|
35
|
+
current?.type === utils_1.AST_NODE_TYPES.TSSatisfiesExpression ||
|
|
36
|
+
current?.type === utils_1.AST_NODE_TYPES.TSTypeAssertion) {
|
|
37
|
+
current = current.expression;
|
|
38
|
+
}
|
|
39
|
+
return current;
|
|
40
|
+
}
|
|
41
|
+
function propertyName(node) {
|
|
42
|
+
const property = node.type === utils_1.AST_NODE_TYPES.MemberExpression ? node.property : node.key;
|
|
43
|
+
const computed = node.computed;
|
|
44
|
+
if (!computed && property.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
45
|
+
return property.name;
|
|
46
|
+
}
|
|
47
|
+
if (computed && property.type === utils_1.AST_NODE_TYPES.Literal && typeof property.value === "string") {
|
|
48
|
+
return property.value;
|
|
49
|
+
}
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
function isExpression(node) {
|
|
53
|
+
return (node !== null &&
|
|
54
|
+
node !== undefined &&
|
|
55
|
+
node.type !== utils_1.AST_NODE_TYPES.SpreadElement &&
|
|
56
|
+
node.type !== utils_1.AST_NODE_TYPES.JSXElement &&
|
|
57
|
+
node.type !== utils_1.AST_NODE_TYPES.JSXFragment);
|
|
58
|
+
}
|
|
59
|
+
function rootIdentifier(node) {
|
|
60
|
+
let current = unwrap(node);
|
|
61
|
+
while (current?.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
62
|
+
current = unwrap(current.object);
|
|
63
|
+
}
|
|
64
|
+
return current?.type === utils_1.AST_NODE_TYPES.Identifier ? current : undefined;
|
|
65
|
+
}
|
|
66
|
+
function objectProperty(object, name) {
|
|
67
|
+
return object.properties.find((entry) => entry.type === utils_1.AST_NODE_TYPES.Property && propertyName(entry) === name);
|
|
68
|
+
}
|
|
69
|
+
function isRouteFulfillCall(node, allowAnyReceiver) {
|
|
70
|
+
return (node.callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
71
|
+
propertyName(node.callee) === "fulfill" &&
|
|
72
|
+
node.callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
73
|
+
(allowAnyReceiver || /route$/iu.test(node.callee.object.name)));
|
|
74
|
+
}
|
|
75
|
+
function isFixtureValue(name, node) {
|
|
76
|
+
const current = unwrap(node);
|
|
77
|
+
return (MOCK_NAME_PATTERN.test(name) ||
|
|
78
|
+
current?.type === utils_1.AST_NODE_TYPES.ArrayExpression ||
|
|
79
|
+
current?.type === utils_1.AST_NODE_TYPES.ObjectExpression);
|
|
80
|
+
}
|
|
81
|
+
function importName(specifier) {
|
|
82
|
+
if (specifier.type === utils_1.AST_NODE_TYPES.ImportSpecifier) {
|
|
83
|
+
return specifier.imported.type === utils_1.AST_NODE_TYPES.Identifier
|
|
84
|
+
? specifier.imported.name
|
|
85
|
+
: specifier.imported.value;
|
|
86
|
+
}
|
|
87
|
+
return specifier.type === utils_1.AST_NODE_TYPES.ImportNamespaceSpecifier ? "*" : "default";
|
|
88
|
+
}
|
|
89
|
+
const rule = (0, createRule_1.createRule)({
|
|
90
|
+
name: "require-contract-fixture-construction",
|
|
91
|
+
defaultOptions: [],
|
|
92
|
+
meta: {
|
|
93
|
+
type: "problem",
|
|
94
|
+
docs: {
|
|
95
|
+
description: "Require response fixtures to be constructed by producer-owned contracts",
|
|
96
|
+
},
|
|
97
|
+
schema: [],
|
|
98
|
+
messages: {
|
|
99
|
+
parseMock: "Construct exported response fixtures with a producer-owned contract response schema.",
|
|
100
|
+
parsePayload: "Construct JSON response fixtures with a producer-owned contract response schema before passing them to the test transport.",
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
create(context) {
|
|
104
|
+
const filename = context.filename.replaceAll("\\", "/");
|
|
105
|
+
const isMocksFile = MOCKS_FILE_PATTERN.test(filename);
|
|
106
|
+
const isPlaywrightFile = filename.includes("/playwright/");
|
|
107
|
+
const isTestUtilsFile = /\/(?:testUtils|test-utils)\//u.test(filename);
|
|
108
|
+
const contractImports = new Map();
|
|
109
|
+
const fixtureBuilderFactoryImports = new Set();
|
|
110
|
+
const oneShotBuilderImports = new Set();
|
|
111
|
+
const httpResponseImports = new Set();
|
|
112
|
+
const trustedFixtureImports = new Set();
|
|
113
|
+
const variableInitializers = new Map();
|
|
114
|
+
const fixtureBuilders = new Set();
|
|
115
|
+
const mutations = new Map();
|
|
116
|
+
const aliasTargets = new Map();
|
|
117
|
+
const candidates = [];
|
|
118
|
+
const directFixtureCandidates = [];
|
|
119
|
+
const functionReturns = new Map();
|
|
120
|
+
const functionStack = [];
|
|
121
|
+
const exportedFunctions = new Set();
|
|
122
|
+
const indirectExports = [];
|
|
123
|
+
function variableFor(identifier) {
|
|
124
|
+
return (utils_1.ASTUtils.findVariable(context.sourceCode.getScope(identifier), identifier) ?? undefined);
|
|
125
|
+
}
|
|
126
|
+
function declaredVariable(node) {
|
|
127
|
+
return context.sourceCode.getDeclaredVariables(node)[0];
|
|
128
|
+
}
|
|
129
|
+
function recordMutation(node, position) {
|
|
130
|
+
const identifier = rootIdentifier(node);
|
|
131
|
+
if (!identifier) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const variable = variableFor(identifier);
|
|
135
|
+
if (!variable) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const positions = mutations.get(variable) ?? [];
|
|
139
|
+
positions.push(position);
|
|
140
|
+
mutations.set(variable, positions);
|
|
141
|
+
}
|
|
142
|
+
function wasMutated(variable, observationPosition) {
|
|
143
|
+
return mutations.get(variable)?.some((position) => position < observationPosition) === true;
|
|
144
|
+
}
|
|
145
|
+
function isContractRoot(identifier) {
|
|
146
|
+
const variable = variableFor(identifier);
|
|
147
|
+
return variable !== undefined && contractImports.has(variable);
|
|
148
|
+
}
|
|
149
|
+
function isContractResponseSchema(node, seen = new Set()) {
|
|
150
|
+
const current = unwrap(node);
|
|
151
|
+
if (!current) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
if (current.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
155
|
+
const variable = variableFor(current);
|
|
156
|
+
if (!variable) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
const importedName = contractImports.get(variable);
|
|
160
|
+
if (importedName !== undefined) {
|
|
161
|
+
return importedName.endsWith("ResponseSchema");
|
|
162
|
+
}
|
|
163
|
+
if (seen.has(variable)) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
seen.add(variable);
|
|
167
|
+
return isContractResponseSchema(variableInitializers.get(variable), seen);
|
|
168
|
+
}
|
|
169
|
+
if (current.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
const selectedFromResponses = current.computed &&
|
|
173
|
+
current.object.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
174
|
+
propertyName(current.object) === "responses";
|
|
175
|
+
if (selectedFromResponses) {
|
|
176
|
+
const root = rootIdentifier(current);
|
|
177
|
+
return root !== undefined && isContractRoot(root);
|
|
178
|
+
}
|
|
179
|
+
const selectedNamedSchema = propertyName(current)?.endsWith("ResponseSchema") === true;
|
|
180
|
+
if (selectedNamedSchema) {
|
|
181
|
+
const root = rootIdentifier(current);
|
|
182
|
+
return root !== undefined && isContractRoot(root);
|
|
183
|
+
}
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
function hasContractSchemaOption(call) {
|
|
187
|
+
const [options] = call.arguments;
|
|
188
|
+
const current = unwrap(options);
|
|
189
|
+
if (current?.type !== utils_1.AST_NODE_TYPES.ObjectExpression) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
const schema = objectProperty(current, "schema");
|
|
193
|
+
return (schema !== undefined && isExpression(schema.value) && isContractResponseSchema(schema.value));
|
|
194
|
+
}
|
|
195
|
+
function isOneShotBuilderCall(node) {
|
|
196
|
+
const current = unwrap(node);
|
|
197
|
+
if (current?.type !== utils_1.AST_NODE_TYPES.CallExpression ||
|
|
198
|
+
current.callee.type !== utils_1.AST_NODE_TYPES.Identifier) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
const variable = variableFor(current.callee);
|
|
202
|
+
return (variable !== undefined &&
|
|
203
|
+
oneShotBuilderImports.has(variable) &&
|
|
204
|
+
hasContractSchemaOption(current));
|
|
205
|
+
}
|
|
206
|
+
function isFixtureBuilderFactoryCall(node) {
|
|
207
|
+
const current = unwrap(node);
|
|
208
|
+
if (current?.type !== utils_1.AST_NODE_TYPES.CallExpression ||
|
|
209
|
+
current.callee.type !== utils_1.AST_NODE_TYPES.Identifier) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
const variable = variableFor(current.callee);
|
|
213
|
+
return (variable !== undefined &&
|
|
214
|
+
fixtureBuilderFactoryImports.has(variable) &&
|
|
215
|
+
hasContractSchemaOption(current));
|
|
216
|
+
}
|
|
217
|
+
function isContractParseCall(node) {
|
|
218
|
+
const current = unwrap(node);
|
|
219
|
+
return (current?.type === utils_1.AST_NODE_TYPES.CallExpression &&
|
|
220
|
+
current.callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
221
|
+
propertyName(current.callee) === "parse" &&
|
|
222
|
+
isContractResponseSchema(current.callee.object));
|
|
223
|
+
}
|
|
224
|
+
function isContractConstructed(node, observationPosition, seen = new Set()) {
|
|
225
|
+
const current = unwrap(node);
|
|
226
|
+
if (!current) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
if (isContractParseCall(current) || isOneShotBuilderCall(current)) {
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
if (current.type === utils_1.AST_NODE_TYPES.CallExpression &&
|
|
233
|
+
current.callee.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
234
|
+
const variable = variableFor(current.callee);
|
|
235
|
+
if (variable !== undefined && fixtureBuilders.has(variable)) {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (current.type !== utils_1.AST_NODE_TYPES.Identifier) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
const variable = variableFor(current);
|
|
243
|
+
if (!variable || seen.has(variable) || wasMutated(variable, observationPosition)) {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
if (trustedFixtureImports.has(variable)) {
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
const initializer = variableInitializers.get(variable);
|
|
250
|
+
if (!initializer) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
seen.add(variable);
|
|
254
|
+
return isContractConstructed(initializer, observationPosition, seen);
|
|
255
|
+
}
|
|
256
|
+
function resolveObject(node, observationPosition, seen = new Set()) {
|
|
257
|
+
const current = unwrap(node);
|
|
258
|
+
if (current?.type === utils_1.AST_NODE_TYPES.ObjectExpression) {
|
|
259
|
+
return current;
|
|
260
|
+
}
|
|
261
|
+
if (current?.type !== utils_1.AST_NODE_TYPES.Identifier) {
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
const variable = variableFor(current);
|
|
265
|
+
if (!variable || seen.has(variable) || wasMutated(variable, observationPosition)) {
|
|
266
|
+
return undefined;
|
|
267
|
+
}
|
|
268
|
+
const initializer = variableInitializers.get(variable);
|
|
269
|
+
if (!initializer) {
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
seen.add(variable);
|
|
273
|
+
return resolveObject(initializer, observationPosition, seen);
|
|
274
|
+
}
|
|
275
|
+
function jsonStringifyPayload(node, seen = new Set()) {
|
|
276
|
+
const current = unwrap(node);
|
|
277
|
+
if (current?.type === utils_1.AST_NODE_TYPES.CallExpression &&
|
|
278
|
+
current.callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
279
|
+
current.callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
280
|
+
current.callee.object.name === "JSON" &&
|
|
281
|
+
propertyName(current.callee) === "stringify") {
|
|
282
|
+
const [payload] = current.arguments;
|
|
283
|
+
return isExpression(payload) ? payload : undefined;
|
|
284
|
+
}
|
|
285
|
+
if (current?.type !== utils_1.AST_NODE_TYPES.Identifier) {
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
const variable = variableFor(current);
|
|
289
|
+
if (!variable || seen.has(variable)) {
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
seen.add(variable);
|
|
293
|
+
return jsonStringifyPayload(variableInitializers.get(variable), seen);
|
|
294
|
+
}
|
|
295
|
+
function playwrightPayloads(node, observationPosition, seen = new Set()) {
|
|
296
|
+
const options = resolveObject(node, observationPosition, seen);
|
|
297
|
+
if (!options) {
|
|
298
|
+
return isExpression(unwrap(node)) ? { unknown: unwrap(node) } : {};
|
|
299
|
+
}
|
|
300
|
+
const payloads = {};
|
|
301
|
+
for (const entry of options.properties) {
|
|
302
|
+
if (entry.type === utils_1.AST_NODE_TYPES.SpreadElement) {
|
|
303
|
+
const spread = playwrightPayloads(entry.argument, observationPosition, new Set(seen));
|
|
304
|
+
if (spread.unknown) {
|
|
305
|
+
return { unknown: spread.unknown };
|
|
306
|
+
}
|
|
307
|
+
if (spread.body !== undefined) {
|
|
308
|
+
payloads.body = spread.body;
|
|
309
|
+
}
|
|
310
|
+
if (spread.json !== undefined) {
|
|
311
|
+
payloads.json = spread.json;
|
|
312
|
+
}
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
const name = propertyName(entry);
|
|
316
|
+
if (name === undefined && entry.computed && isExpression(entry.value)) {
|
|
317
|
+
return { unknown: entry.value };
|
|
318
|
+
}
|
|
319
|
+
if (!isExpression(entry.value)) {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (name === "json") {
|
|
323
|
+
payloads.json = entry.value;
|
|
324
|
+
}
|
|
325
|
+
else if (name === "body") {
|
|
326
|
+
const serialized = jsonStringifyPayload(entry.value);
|
|
327
|
+
if (serialized) {
|
|
328
|
+
payloads.body = serialized;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return payloads;
|
|
333
|
+
}
|
|
334
|
+
function isMswJsonCall(node) {
|
|
335
|
+
if (node.callee.type !== utils_1.AST_NODE_TYPES.MemberExpression ||
|
|
336
|
+
propertyName(node.callee) !== "json" ||
|
|
337
|
+
node.callee.object.type !== utils_1.AST_NODE_TYPES.Identifier) {
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
if (node.callee.object.name === "ctx" || node.callee.object.name === "context") {
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
const variable = variableFor(node.callee.object);
|
|
344
|
+
return variable !== undefined && httpResponseImports.has(variable);
|
|
345
|
+
}
|
|
346
|
+
function addCandidate(node, observationPosition) {
|
|
347
|
+
if (isExpression(node)) {
|
|
348
|
+
candidates.push({ node, observationPosition });
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
function addDirectFixture(node) {
|
|
352
|
+
if (isExpression(node)) {
|
|
353
|
+
directFixtureCandidates.push({
|
|
354
|
+
node,
|
|
355
|
+
observationPosition: Number.MAX_SAFE_INTEGER,
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
function registerBuilderVariables() {
|
|
360
|
+
let changed = true;
|
|
361
|
+
while (changed) {
|
|
362
|
+
changed = false;
|
|
363
|
+
for (const [variable, initializer] of variableInitializers) {
|
|
364
|
+
if (!fixtureBuilders.has(variable) && isFixtureBuilderFactoryCall(initializer)) {
|
|
365
|
+
fixtureBuilders.add(variable);
|
|
366
|
+
changed = true;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function propagateAliasMutations() {
|
|
372
|
+
let changed = true;
|
|
373
|
+
while (changed) {
|
|
374
|
+
changed = false;
|
|
375
|
+
for (const [alias, target] of aliasTargets) {
|
|
376
|
+
const aliasMutations = mutations.get(alias) ?? [];
|
|
377
|
+
const targetMutations = mutations.get(target) ?? [];
|
|
378
|
+
for (const position of aliasMutations) {
|
|
379
|
+
if (!targetMutations.includes(position)) {
|
|
380
|
+
targetMutations.push(position);
|
|
381
|
+
changed = true;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (targetMutations.length > 0) {
|
|
385
|
+
mutations.set(target, targetMutations);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function reportDirectFixtures() {
|
|
391
|
+
for (const candidate of directFixtureCandidates) {
|
|
392
|
+
if (!isContractConstructed(candidate.node, candidate.observationPosition)) {
|
|
393
|
+
context.report({ node: candidate.node, messageId: "parseMock" });
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
function reportExportedFunctions() {
|
|
398
|
+
for (const functionNode of exportedFunctions) {
|
|
399
|
+
for (const returnValue of functionReturns.get(functionNode) ?? []) {
|
|
400
|
+
if (!isContractConstructed(returnValue, returnValue.range[0])) {
|
|
401
|
+
context.report({ node: returnValue, messageId: "parseMock" });
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
function reportIndirectExports() {
|
|
407
|
+
for (const { exportedName, local } of indirectExports) {
|
|
408
|
+
const variable = variableFor(local);
|
|
409
|
+
if (!variable) {
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
const initializer = variableInitializers.get(variable);
|
|
413
|
+
const current = unwrap(initializer);
|
|
414
|
+
if (current?.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
|
415
|
+
current?.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
|
|
416
|
+
for (const returnValue of functionReturns.get(current) ?? []) {
|
|
417
|
+
if (!isContractConstructed(returnValue, returnValue.range[0])) {
|
|
418
|
+
context.report({ node: returnValue, messageId: "parseMock" });
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
else if (isFixtureValue(exportedName, initializer) &&
|
|
423
|
+
!isContractConstructed(local, Number.MAX_SAFE_INTEGER)) {
|
|
424
|
+
context.report({ node: initializer ?? local, messageId: "parseMock" });
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
function reportTransportCandidates() {
|
|
429
|
+
for (const candidate of candidates) {
|
|
430
|
+
if (!isContractConstructed(candidate.node, candidate.observationPosition)) {
|
|
431
|
+
context.report({ node: candidate.node, messageId: "parsePayload" });
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return {
|
|
436
|
+
ImportDeclaration(node) {
|
|
437
|
+
const source = node.source.value;
|
|
438
|
+
for (const specifier of node.specifiers) {
|
|
439
|
+
const variable = declaredVariable(specifier);
|
|
440
|
+
if (!variable) {
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
const importedName = importName(specifier);
|
|
444
|
+
if (source.startsWith(CONTRACT_PACKAGE_PREFIX)) {
|
|
445
|
+
contractImports.set(variable, importedName);
|
|
446
|
+
}
|
|
447
|
+
if ((source === "@clipboard-health/testing-core" ||
|
|
448
|
+
/(?:^|\/)test(?:Utils|-utils)\/createContractFixtureBuilder$/u.test(source)) &&
|
|
449
|
+
importedName === "createContractFixtureBuilder") {
|
|
450
|
+
fixtureBuilderFactoryImports.add(variable);
|
|
451
|
+
}
|
|
452
|
+
if ((source === "@clipboard-health/testing-core" ||
|
|
453
|
+
/(?:^|\/)test(?:Utils|-utils)\/buildContractFixture$/u.test(source)) &&
|
|
454
|
+
importedName === "buildContractFixture") {
|
|
455
|
+
oneShotBuilderImports.add(variable);
|
|
456
|
+
}
|
|
457
|
+
if (source === "msw" && importedName === "HttpResponse") {
|
|
458
|
+
httpResponseImports.add(variable);
|
|
459
|
+
}
|
|
460
|
+
if (/(?:^|\/)test(?:Utils|-utils)\/mocks$/u.test(source) ||
|
|
461
|
+
(isTestUtilsFile && /^\.\/mocks$/u.test(source))) {
|
|
462
|
+
trustedFixtureImports.add(variable);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
VariableDeclarator(node) {
|
|
467
|
+
if (!isExpression(node.init)) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
if (node.id.type !== utils_1.AST_NODE_TYPES.Identifier) {
|
|
471
|
+
const aliasIdentifier = rootIdentifier(node.init);
|
|
472
|
+
const target = aliasIdentifier ? variableFor(aliasIdentifier) : undefined;
|
|
473
|
+
if (target) {
|
|
474
|
+
for (const variable of context.sourceCode.getDeclaredVariables(node)) {
|
|
475
|
+
aliasTargets.set(variable, target);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
const variable = declaredVariable(node);
|
|
481
|
+
if (!variable) {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
variableInitializers.set(variable, node.init);
|
|
485
|
+
const aliasIdentifier = rootIdentifier(node.init);
|
|
486
|
+
const target = aliasIdentifier ? variableFor(aliasIdentifier) : undefined;
|
|
487
|
+
if (target && target !== variable) {
|
|
488
|
+
aliasTargets.set(variable, target);
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
FunctionDeclaration(node) {
|
|
492
|
+
functionReturns.set(node, []);
|
|
493
|
+
functionStack.push(node);
|
|
494
|
+
if (node.parent.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration && isMocksFile) {
|
|
495
|
+
exportedFunctions.add(node);
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
"FunctionDeclaration:exit"() {
|
|
499
|
+
functionStack.pop();
|
|
500
|
+
},
|
|
501
|
+
FunctionExpression(node) {
|
|
502
|
+
functionReturns.set(node, []);
|
|
503
|
+
functionStack.push(node);
|
|
504
|
+
},
|
|
505
|
+
"FunctionExpression:exit"() {
|
|
506
|
+
functionStack.pop();
|
|
507
|
+
},
|
|
508
|
+
ArrowFunctionExpression(node) {
|
|
509
|
+
functionReturns.set(node, node.body.type === utils_1.AST_NODE_TYPES.BlockStatement ? [] : [node.body]);
|
|
510
|
+
functionStack.push(node);
|
|
511
|
+
},
|
|
512
|
+
"ArrowFunctionExpression:exit"() {
|
|
513
|
+
functionStack.pop();
|
|
514
|
+
},
|
|
515
|
+
ReturnStatement(node) {
|
|
516
|
+
const current = functionStack.at(-1);
|
|
517
|
+
if (current && isExpression(node.argument)) {
|
|
518
|
+
functionReturns.get(current)?.push(node.argument);
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
ExportNamedDeclaration(node) {
|
|
522
|
+
if (!isMocksFile) {
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
for (const specifier of node.specifiers) {
|
|
526
|
+
if (specifier.type === utils_1.AST_NODE_TYPES.ExportSpecifier &&
|
|
527
|
+
specifier.local.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
528
|
+
indirectExports.push({
|
|
529
|
+
exportedName: specifier.exported.type === utils_1.AST_NODE_TYPES.Identifier
|
|
530
|
+
? specifier.exported.name
|
|
531
|
+
: specifier.exported.value,
|
|
532
|
+
local: specifier.local,
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
if (node.declaration?.type !== utils_1.AST_NODE_TYPES.VariableDeclaration) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
for (const declaration of node.declaration.declarations) {
|
|
540
|
+
if (declaration.id.type !== utils_1.AST_NODE_TYPES.Identifier ||
|
|
541
|
+
!isExpression(declaration.init)) {
|
|
542
|
+
addDirectFixture(declaration.init);
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
const initializer = unwrap(declaration.init);
|
|
546
|
+
if (initializer?.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
|
547
|
+
initializer?.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
|
|
548
|
+
exportedFunctions.add(initializer);
|
|
549
|
+
}
|
|
550
|
+
else if (isFixtureValue(declaration.id.name, declaration.init)) {
|
|
551
|
+
addDirectFixture(declaration.id);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
ExportDefaultDeclaration(node) {
|
|
556
|
+
if (!isMocksFile) {
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
if (node.declaration.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
560
|
+
indirectExports.push({ exportedName: node.declaration.name, local: node.declaration });
|
|
561
|
+
}
|
|
562
|
+
else if (isExpression(node.declaration)) {
|
|
563
|
+
const current = unwrap(node.declaration);
|
|
564
|
+
if (current?.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
|
565
|
+
current?.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
|
|
566
|
+
exportedFunctions.add(current);
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
addDirectFixture(node.declaration);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
AssignmentExpression(node) {
|
|
574
|
+
recordMutation(node.left, node.range[0]);
|
|
575
|
+
},
|
|
576
|
+
UpdateExpression(node) {
|
|
577
|
+
recordMutation(node.argument, node.range[0]);
|
|
578
|
+
},
|
|
579
|
+
UnaryExpression(node) {
|
|
580
|
+
if (node.operator === "delete") {
|
|
581
|
+
recordMutation(node.argument, node.range[0]);
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
CallExpression(node) {
|
|
585
|
+
if (isMswJsonCall(node)) {
|
|
586
|
+
addCandidate(node.arguments[0], node.range[0]);
|
|
587
|
+
}
|
|
588
|
+
if (isRouteFulfillCall(node, isPlaywrightFile)) {
|
|
589
|
+
const payloads = playwrightPayloads(node.arguments[0], node.range[0]);
|
|
590
|
+
addCandidate(payloads.unknown ?? payloads.json ?? payloads.body, node.range[0]);
|
|
591
|
+
}
|
|
592
|
+
if (node.callee.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
593
|
+
const method = propertyName(node.callee);
|
|
594
|
+
if (node.callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
595
|
+
node.callee.object.name === "Object" &&
|
|
596
|
+
OBJECT_MUTATOR_NAMES.has(method ?? "")) {
|
|
597
|
+
recordMutation(node.arguments[0], node.range[0]);
|
|
598
|
+
}
|
|
599
|
+
else if (MUTATING_METHOD_NAMES.has(method ?? "")) {
|
|
600
|
+
recordMutation(node.callee.object, node.range[0]);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
},
|
|
604
|
+
"Program:exit"() {
|
|
605
|
+
registerBuilderVariables();
|
|
606
|
+
propagateAliasMutations();
|
|
607
|
+
reportDirectFixtures();
|
|
608
|
+
reportExportedFunctions();
|
|
609
|
+
reportIndirectExports();
|
|
610
|
+
reportTransportCandidates();
|
|
611
|
+
},
|
|
612
|
+
};
|
|
613
|
+
},
|
|
614
|
+
});
|
|
615
|
+
exports.default = rule;
|
|
616
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/eslint-plugin/src/lib/rules/require-contract-fixture-construction/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Require contract-package response schemas before response-shape assertions.
|
|
3
|
+
*
|
|
4
|
+
* Migration playbook:
|
|
5
|
+
* 1. Find the endpoint in its `@clipboard-health/contract-*` package and use the schema for the
|
|
6
|
+
* asserted status code, commonly `contract.endpoint.responses[status]` or an exported
|
|
7
|
+
* `XResponseSchema`.
|
|
8
|
+
* 2. Parse before shape assertions with `parseBody(response, schema)` or
|
|
9
|
+
* `schema.parse(response.parsedBody)`, then assert on the parsed value.
|
|
10
|
+
* 3. If the contract package has no response schema, file a contract-gap ticket and add the schema
|
|
11
|
+
* there. An inline permissive schema or ESLint exemption is not a contract oracle.
|
|
12
|
+
*
|
|
13
|
+
* Warn-to-error ratchet:
|
|
14
|
+
* Enable the rule as a warning across the migration scope. Migrate one directory at a time and add
|
|
15
|
+
* an error-level override for each completed directory. CI may suppress the warning backlog with
|
|
16
|
+
* `--quiet`, making every error-level directory a blocking ratchet. Once the full scope is migrated,
|
|
17
|
+
* replace the overrides with one error-level setting and restore the zero-warning budget.
|
|
18
|
+
*/
|
|
19
|
+
import { type TSESLint } from "@typescript-eslint/utils";
|
|
20
|
+
declare const rule: TSESLint.RuleModule<"inlineAnySchema" | "missingContractParse" | "nonContractSchema", [], unknown, TSESLint.RuleListener> & {
|
|
21
|
+
name: string;
|
|
22
|
+
};
|
|
23
|
+
export default rule;
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Require contract-package response schemas before response-shape assertions.
|
|
5
|
+
*
|
|
6
|
+
* Migration playbook:
|
|
7
|
+
* 1. Find the endpoint in its `@clipboard-health/contract-*` package and use the schema for the
|
|
8
|
+
* asserted status code, commonly `contract.endpoint.responses[status]` or an exported
|
|
9
|
+
* `XResponseSchema`.
|
|
10
|
+
* 2. Parse before shape assertions with `parseBody(response, schema)` or
|
|
11
|
+
* `schema.parse(response.parsedBody)`, then assert on the parsed value.
|
|
12
|
+
* 3. If the contract package has no response schema, file a contract-gap ticket and add the schema
|
|
13
|
+
* there. An inline permissive schema or ESLint exemption is not a contract oracle.
|
|
14
|
+
*
|
|
15
|
+
* Warn-to-error ratchet:
|
|
16
|
+
* Enable the rule as a warning across the migration scope. Migrate one directory at a time and add
|
|
17
|
+
* an error-level override for each completed directory. CI may suppress the warning backlog with
|
|
18
|
+
* `--quiet`, making every error-level directory a blocking ratchet. Once the full scope is migrated,
|
|
19
|
+
* replace the overrides with one error-level setting and restore the zero-warning budget.
|
|
20
|
+
*/
|
|
21
|
+
const utils_1 = require("@typescript-eslint/utils");
|
|
22
|
+
const createRule_1 = require("../../createRule");
|
|
23
|
+
const CONTRACT_PACKAGE_PREFIX = "@clipboard-health/contract-";
|
|
24
|
+
const ANY_SCHEMA_METHODS = new Set(["any", "unknown"]);
|
|
25
|
+
const SCHEMA_PARSE_METHODS = new Set(["parse", "parseAsync"]);
|
|
26
|
+
const MATCHER_MODIFIERS = new Set(["not", "rejects", "resolves"]);
|
|
27
|
+
const CONTROL_FLOW_TYPES = new Set([
|
|
28
|
+
utils_1.AST_NODE_TYPES.CatchClause,
|
|
29
|
+
utils_1.AST_NODE_TYPES.ConditionalExpression,
|
|
30
|
+
utils_1.AST_NODE_TYPES.DoWhileStatement,
|
|
31
|
+
utils_1.AST_NODE_TYPES.ForInStatement,
|
|
32
|
+
utils_1.AST_NODE_TYPES.ForOfStatement,
|
|
33
|
+
utils_1.AST_NODE_TYPES.ForStatement,
|
|
34
|
+
utils_1.AST_NODE_TYPES.IfStatement,
|
|
35
|
+
utils_1.AST_NODE_TYPES.LogicalExpression,
|
|
36
|
+
utils_1.AST_NODE_TYPES.SwitchCase,
|
|
37
|
+
utils_1.AST_NODE_TYPES.SwitchStatement,
|
|
38
|
+
utils_1.AST_NODE_TYPES.TryStatement,
|
|
39
|
+
utils_1.AST_NODE_TYPES.WhileStatement,
|
|
40
|
+
]);
|
|
41
|
+
function unwrap(node) {
|
|
42
|
+
let current = node;
|
|
43
|
+
while (current?.type === utils_1.AST_NODE_TYPES.ChainExpression ||
|
|
44
|
+
current?.type === utils_1.AST_NODE_TYPES.TSAsExpression ||
|
|
45
|
+
current?.type === utils_1.AST_NODE_TYPES.TSInstantiationExpression ||
|
|
46
|
+
current?.type === utils_1.AST_NODE_TYPES.TSNonNullExpression ||
|
|
47
|
+
current?.type === utils_1.AST_NODE_TYPES.TSSatisfiesExpression ||
|
|
48
|
+
current?.type === utils_1.AST_NODE_TYPES.TSTypeAssertion) {
|
|
49
|
+
current = current.expression;
|
|
50
|
+
}
|
|
51
|
+
return current;
|
|
52
|
+
}
|
|
53
|
+
function memberPropertyName(node) {
|
|
54
|
+
if (!node.computed && node.property.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
55
|
+
return node.property.name;
|
|
56
|
+
}
|
|
57
|
+
if (node.computed && node.property.type === utils_1.AST_NODE_TYPES.Literal) {
|
|
58
|
+
return typeof node.property.value === "string" ? node.property.value : undefined;
|
|
59
|
+
}
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
function containingFunction(node) {
|
|
63
|
+
let current = node.parent;
|
|
64
|
+
while (current) {
|
|
65
|
+
if (current.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
|
66
|
+
current.type === utils_1.AST_NODE_TYPES.FunctionDeclaration ||
|
|
67
|
+
current.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
|
|
68
|
+
return current;
|
|
69
|
+
}
|
|
70
|
+
current = current.parent;
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
function addEvidence(collection, key, node) {
|
|
75
|
+
const nodes = collection.get(key) ?? [];
|
|
76
|
+
nodes.push(node);
|
|
77
|
+
collection.set(key, nodes);
|
|
78
|
+
}
|
|
79
|
+
function isAncestor(ancestor, node) {
|
|
80
|
+
let current = node;
|
|
81
|
+
while (current) {
|
|
82
|
+
if (current === ancestor) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
current = current.parent;
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
function directChild(ancestor, node) {
|
|
90
|
+
let current = node;
|
|
91
|
+
while (current?.parent && current.parent !== ancestor) {
|
|
92
|
+
current = current.parent;
|
|
93
|
+
}
|
|
94
|
+
return current?.parent === ancestor ? current : undefined;
|
|
95
|
+
}
|
|
96
|
+
function objectContainsParsedBodyProperty(node) {
|
|
97
|
+
if (node?.type !== utils_1.AST_NODE_TYPES.ObjectExpression) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return node.properties.some((property) => {
|
|
101
|
+
if (property.type !== utils_1.AST_NODE_TYPES.Property) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const propertyName = property.key.type === utils_1.AST_NODE_TYPES.Identifier
|
|
105
|
+
? property.key.name
|
|
106
|
+
: property.key.type === utils_1.AST_NODE_TYPES.Literal
|
|
107
|
+
? property.key.value
|
|
108
|
+
: undefined;
|
|
109
|
+
return propertyName === "parsedBody" || objectContainsParsedBodyProperty(property.value);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function isParsedBodyPropertyPath(node) {
|
|
113
|
+
if (node?.type === utils_1.AST_NODE_TYPES.Literal && typeof node.value === "string") {
|
|
114
|
+
return /^parsedBody(?:\.|\[|$)/u.test(node.value);
|
|
115
|
+
}
|
|
116
|
+
return (node?.type === utils_1.AST_NODE_TYPES.ArrayExpression &&
|
|
117
|
+
node.elements[0]?.type === utils_1.AST_NODE_TYPES.Literal &&
|
|
118
|
+
node.elements[0].value === "parsedBody");
|
|
119
|
+
}
|
|
120
|
+
const rule = (0, createRule_1.createRule)({
|
|
121
|
+
name: "require-contract-response-parse",
|
|
122
|
+
defaultOptions: [],
|
|
123
|
+
meta: {
|
|
124
|
+
type: "problem",
|
|
125
|
+
docs: {
|
|
126
|
+
description: "Require response assertions to use contract-package schemas",
|
|
127
|
+
},
|
|
128
|
+
schema: [],
|
|
129
|
+
messages: {
|
|
130
|
+
inlineAnySchema: "Inline z.{{method}}() schemas are not contract oracles. Use the endpoint response schema from a @clipboard-health/contract-* package.",
|
|
131
|
+
missingContractParse: "Parse this response body with its @clipboard-health/contract-* response schema before asserting its shape.",
|
|
132
|
+
nonContractSchema: "This schema is not a contract oracle. Use the endpoint response schema from a @clipboard-health/contract-* package.",
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
create(context) {
|
|
136
|
+
const contractBindings = new Set();
|
|
137
|
+
const zodBindings = new Set();
|
|
138
|
+
const functionStates = new Map();
|
|
139
|
+
const topLevelState = { parses: new Map(), writes: new Map() };
|
|
140
|
+
const validatedParsedBodyAccesses = new WeakSet();
|
|
141
|
+
function rootIdentifier(node) {
|
|
142
|
+
let current = unwrap(node);
|
|
143
|
+
while (current?.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
144
|
+
current = unwrap(current.object);
|
|
145
|
+
}
|
|
146
|
+
return current?.type === utils_1.AST_NODE_TYPES.Identifier ? current : undefined;
|
|
147
|
+
}
|
|
148
|
+
function parsedBodyAccess(node) {
|
|
149
|
+
let current = unwrap(node);
|
|
150
|
+
while (current?.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
151
|
+
if (memberPropertyName(current) === "parsedBody") {
|
|
152
|
+
return current;
|
|
153
|
+
}
|
|
154
|
+
current = unwrap(current.object);
|
|
155
|
+
}
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
function findVariable(node) {
|
|
159
|
+
return utils_1.ASTUtils.findVariable(context.sourceCode.getScope(node), node) ?? undefined;
|
|
160
|
+
}
|
|
161
|
+
function responseKey(node) {
|
|
162
|
+
const current = unwrap(node);
|
|
163
|
+
if (current?.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
164
|
+
return findVariable(current) ?? current.name;
|
|
165
|
+
}
|
|
166
|
+
if (current?.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
167
|
+
return context.sourceCode.getText(current);
|
|
168
|
+
}
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
function isContractSchema(node) {
|
|
172
|
+
const identifier = rootIdentifier(node);
|
|
173
|
+
if (!identifier) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
const variable = findVariable(identifier);
|
|
177
|
+
return variable !== undefined && contractBindings.has(variable);
|
|
178
|
+
}
|
|
179
|
+
function stateFor(node) {
|
|
180
|
+
const functionNode = containingFunction(node);
|
|
181
|
+
if (!functionNode) {
|
|
182
|
+
return topLevelState;
|
|
183
|
+
}
|
|
184
|
+
const existingState = functionStates.get(functionNode);
|
|
185
|
+
if (existingState) {
|
|
186
|
+
return existingState;
|
|
187
|
+
}
|
|
188
|
+
const state = { parses: new Map(), writes: new Map() };
|
|
189
|
+
functionStates.set(functionNode, state);
|
|
190
|
+
return state;
|
|
191
|
+
}
|
|
192
|
+
function parseDominatesAssertion(parseNode, assertionNode) {
|
|
193
|
+
if (containingFunction(parseNode) !== containingFunction(assertionNode) ||
|
|
194
|
+
parseNode.range[0] >= assertionNode.range[0]) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
let current = parseNode.parent;
|
|
198
|
+
const functionNode = containingFunction(parseNode);
|
|
199
|
+
while (current && current !== functionNode) {
|
|
200
|
+
if (CONTROL_FLOW_TYPES.has(current.type) &&
|
|
201
|
+
(!isAncestor(current, assertionNode) ||
|
|
202
|
+
directChild(current, parseNode) !== directChild(current, assertionNode))) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
current = current.parent;
|
|
206
|
+
}
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
function hasContractParse(node, key) {
|
|
210
|
+
const state = stateFor(node);
|
|
211
|
+
const parses = state.parses.get(key) ?? [];
|
|
212
|
+
const writes = state.writes.get(key) ?? [];
|
|
213
|
+
return parses.some((parseNode) => parseDominatesAssertion(parseNode, node) &&
|
|
214
|
+
!writes.some((writeNode) => writeNode.range[0] > parseNode.range[1] && writeNode.range[0] < node.range[0]));
|
|
215
|
+
}
|
|
216
|
+
function recordResponseWrite(node, expression) {
|
|
217
|
+
const key = responseKey(expression);
|
|
218
|
+
if (key !== undefined) {
|
|
219
|
+
addEvidence(stateFor(node).writes, key, node);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function checkParseBody(node) {
|
|
223
|
+
if (node.callee.type !== utils_1.AST_NODE_TYPES.Identifier || node.callee.name !== "parseBody") {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const [response, schema] = node.arguments;
|
|
227
|
+
if (!response || !schema) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (!isContractSchema(schema)) {
|
|
231
|
+
context.report({ node: schema, messageId: "nonContractSchema" });
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const key = responseKey(response);
|
|
235
|
+
if (key !== undefined) {
|
|
236
|
+
addEvidence(stateFor(node).parses, key, node);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function checkSchemaParse(node) {
|
|
240
|
+
if (node.callee.type !== utils_1.AST_NODE_TYPES.MemberExpression ||
|
|
241
|
+
!SCHEMA_PARSE_METHODS.has(memberPropertyName(node.callee) ?? "") ||
|
|
242
|
+
!isContractSchema(node.callee.object)) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const argument = unwrap(node.arguments[0]);
|
|
246
|
+
const access = parsedBodyAccess(argument);
|
|
247
|
+
if (!access || argument !== access) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
validatedParsedBodyAccesses.add(access);
|
|
251
|
+
const key = responseKey(access.object);
|
|
252
|
+
if (key !== undefined) {
|
|
253
|
+
addEvidence(stateFor(node).parses, key, node);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function checkParsedBodyAccess(node) {
|
|
257
|
+
if (memberPropertyName(node) !== "parsedBody" || validatedParsedBodyAccesses.has(node)) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const key = responseKey(node.object);
|
|
261
|
+
if (key === undefined || !hasContractParse(node, key)) {
|
|
262
|
+
context.report({ node, messageId: "missingContractParse" });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function expectCall(node) {
|
|
266
|
+
if (node.callee.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
267
|
+
return undefined;
|
|
268
|
+
}
|
|
269
|
+
let matcherTarget = node.callee.object;
|
|
270
|
+
while (matcherTarget.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
271
|
+
MATCHER_MODIFIERS.has(memberPropertyName(matcherTarget) ?? "")) {
|
|
272
|
+
matcherTarget = matcherTarget.object;
|
|
273
|
+
}
|
|
274
|
+
if (matcherTarget.type !== utils_1.AST_NODE_TYPES.CallExpression ||
|
|
275
|
+
matcherTarget.callee.type !== utils_1.AST_NODE_TYPES.Identifier ||
|
|
276
|
+
matcherTarget.callee.name !== "expect") {
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
279
|
+
return matcherTarget;
|
|
280
|
+
}
|
|
281
|
+
function checkWholeResponseAssertion(node) {
|
|
282
|
+
const expectation = expectCall(node);
|
|
283
|
+
if (!expectation) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const assertsParsedBodyProperty = node.arguments.some((argument) => objectContainsParsedBodyProperty(argument));
|
|
287
|
+
const matcherName = node.callee.type === utils_1.AST_NODE_TYPES.MemberExpression
|
|
288
|
+
? memberPropertyName(node.callee)
|
|
289
|
+
: undefined;
|
|
290
|
+
const assertsParsedBodyPath = matcherName === "toHaveProperty" && isParsedBodyPropertyPath(node.arguments[0]);
|
|
291
|
+
if (!assertsParsedBodyProperty && !assertsParsedBodyPath) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const key = responseKey(expectation.arguments[0]);
|
|
295
|
+
if (key !== undefined && !hasContractParse(node, key)) {
|
|
296
|
+
context.report({ node: expectation, messageId: "missingContractParse" });
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function checkParsedBodyDestructuring(node) {
|
|
300
|
+
if (node.id.type !== utils_1.AST_NODE_TYPES.ObjectPattern) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const parsedBodyProperty = node.id.properties.find((property) => {
|
|
304
|
+
if (property.type !== utils_1.AST_NODE_TYPES.Property) {
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
return ((property.key.type === utils_1.AST_NODE_TYPES.Identifier && property.key.name === "parsedBody") ||
|
|
308
|
+
(property.key.type === utils_1.AST_NODE_TYPES.Literal && property.key.value === "parsedBody"));
|
|
309
|
+
});
|
|
310
|
+
if (!parsedBodyProperty) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const key = responseKey(node.init ?? undefined);
|
|
314
|
+
if (key === undefined || !hasContractParse(node, key)) {
|
|
315
|
+
context.report({ node: parsedBodyProperty, messageId: "missingContractParse" });
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function checkInlineAnySchema(node) {
|
|
319
|
+
if (node.callee.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const method = memberPropertyName(node.callee);
|
|
323
|
+
const identifier = rootIdentifier(node.callee.object);
|
|
324
|
+
if (!method || !ANY_SCHEMA_METHODS.has(method) || !identifier) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const variable = findVariable(identifier);
|
|
328
|
+
if (variable !== undefined && zodBindings.has(variable)) {
|
|
329
|
+
context.report({ node, messageId: "inlineAnySchema", data: { method } });
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return {
|
|
333
|
+
ImportDeclaration(node) {
|
|
334
|
+
if (node.source.value.startsWith(CONTRACT_PACKAGE_PREFIX)) {
|
|
335
|
+
for (const specifier of node.specifiers) {
|
|
336
|
+
const [variable] = context.sourceCode.getDeclaredVariables(specifier);
|
|
337
|
+
if (variable) {
|
|
338
|
+
contractBindings.add(variable);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (node.source.value === "zod") {
|
|
343
|
+
for (const specifier of node.specifiers) {
|
|
344
|
+
const importsZodNamespace = specifier.type === utils_1.AST_NODE_TYPES.ImportNamespaceSpecifier;
|
|
345
|
+
const importsZodDefault = specifier.type === utils_1.AST_NODE_TYPES.ImportDefaultSpecifier;
|
|
346
|
+
const importsZodBinding = specifier.type === utils_1.AST_NODE_TYPES.ImportSpecifier &&
|
|
347
|
+
specifier.imported.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
348
|
+
specifier.imported.name === "z";
|
|
349
|
+
if (!importsZodNamespace && !importsZodDefault && !importsZodBinding) {
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
const [variable] = context.sourceCode.getDeclaredVariables(specifier);
|
|
353
|
+
if (variable) {
|
|
354
|
+
zodBindings.add(variable);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
CallExpression(node) {
|
|
360
|
+
checkInlineAnySchema(node);
|
|
361
|
+
checkParseBody(node);
|
|
362
|
+
checkSchemaParse(node);
|
|
363
|
+
checkWholeResponseAssertion(node);
|
|
364
|
+
},
|
|
365
|
+
MemberExpression: checkParsedBodyAccess,
|
|
366
|
+
VariableDeclarator: checkParsedBodyDestructuring,
|
|
367
|
+
AssignmentExpression(node) {
|
|
368
|
+
recordResponseWrite(node, node.left);
|
|
369
|
+
},
|
|
370
|
+
UpdateExpression(node) {
|
|
371
|
+
recordResponseWrite(node, node.argument);
|
|
372
|
+
},
|
|
373
|
+
};
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
exports.default = rule;
|
|
377
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/eslint-plugin/src/lib/rules/require-contract-response-parse/index.ts"],"names":[],"mappings":"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"}
|