@clipboard-health/oxlint-plugin 1.0.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 +27 -0
- package/package.json +30 -0
- package/src/index.d.ts +9 -0
- package/src/index.js +21 -0
- package/src/index.js.map +1 -0
- package/src/lib/internal/findVariable.d.ts +4 -0
- package/src/lib/internal/findVariable.js +15 -0
- package/src/lib/internal/findVariable.js.map +1 -0
- package/src/lib/rules/enforce-ts-rest-in-controllers/index.d.ts +2 -0
- package/src/lib/rules/enforce-ts-rest-in-controllers/index.js +111 -0
- package/src/lib/rules/enforce-ts-rest-in-controllers/index.js.map +1 -0
- package/src/lib/rules/no-cross-contract-imports/index.d.ts +2 -0
- package/src/lib/rules/no-cross-contract-imports/index.js +116 -0
- package/src/lib/rules/no-cross-contract-imports/index.js.map +1 -0
- package/src/lib/rules/require-contract-fixture-construction/index.d.ts +3 -0
- package/src/lib/rules/require-contract-fixture-construction/index.js +615 -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 +21 -0
- package/src/lib/rules/require-contract-response-parse/index.js +368 -0
- package/src/lib/rules/require-contract-response-parse/index.js.map +1 -0
- package/src/lib/rules/require-http-module-factory/index.d.ts +2 -0
- package/src/lib/rules/require-http-module-factory/index.js +74 -0
- package/src/lib/rules/require-http-module-factory/index.js.map +1 -0
- package/src/lib/rules/require-run-validators-with-upsert/index.d.ts +2 -0
- package/src/lib/rules/require-run-validators-with-upsert/index.js +110 -0
- package/src/lib/rules/require-run-validators-with-upsert/index.js.map +1 -0
- package/src/lib/rules/require-zod-import-in-contracts/index.d.ts +2 -0
- package/src/lib/rules/require-zod-import-in-contracts/index.js +46 -0
- package/src/lib/rules/require-zod-import-in-contracts/index.js.map +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
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 { Rule } from "@oxlint/plugins";
|
|
20
|
+
declare const rule: Rule;
|
|
21
|
+
export default rule;
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const findVariable_1 = require("../../internal/findVariable");
|
|
4
|
+
const CONTRACT_PACKAGE_PREFIX = "@clipboard-health/contract-";
|
|
5
|
+
const ANY_SCHEMA_METHODS = new Set(["any", "unknown"]);
|
|
6
|
+
const SCHEMA_PARSE_METHODS = new Set(["parse", "parseAsync"]);
|
|
7
|
+
const MATCHER_MODIFIERS = new Set(["not", "rejects", "resolves"]);
|
|
8
|
+
const CONTROL_FLOW_TYPES = new Set([
|
|
9
|
+
"CatchClause",
|
|
10
|
+
"ConditionalExpression",
|
|
11
|
+
"DoWhileStatement",
|
|
12
|
+
"ForInStatement",
|
|
13
|
+
"ForOfStatement",
|
|
14
|
+
"ForStatement",
|
|
15
|
+
"IfStatement",
|
|
16
|
+
"LogicalExpression",
|
|
17
|
+
"SwitchCase",
|
|
18
|
+
"SwitchStatement",
|
|
19
|
+
"TryStatement",
|
|
20
|
+
"WhileStatement",
|
|
21
|
+
]);
|
|
22
|
+
function unwrap(node) {
|
|
23
|
+
let current = node;
|
|
24
|
+
while (current?.type === "ChainExpression" ||
|
|
25
|
+
current?.type === "TSAsExpression" ||
|
|
26
|
+
current?.type === "TSInstantiationExpression" ||
|
|
27
|
+
current?.type === "TSNonNullExpression" ||
|
|
28
|
+
current?.type === "TSSatisfiesExpression" ||
|
|
29
|
+
current?.type === "TSTypeAssertion") {
|
|
30
|
+
current = current.expression;
|
|
31
|
+
}
|
|
32
|
+
return current;
|
|
33
|
+
}
|
|
34
|
+
function memberPropertyName(node) {
|
|
35
|
+
if (!node.computed && node.property.type === "Identifier") {
|
|
36
|
+
return node.property.name;
|
|
37
|
+
}
|
|
38
|
+
if (node.computed && node.property.type === "Literal") {
|
|
39
|
+
return typeof node.property.value === "string" ? node.property.value : undefined;
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
function containingFunction(node) {
|
|
44
|
+
let current = node.parent;
|
|
45
|
+
while (current) {
|
|
46
|
+
if (current.type === "ArrowFunctionExpression" ||
|
|
47
|
+
current.type === "FunctionDeclaration" ||
|
|
48
|
+
current.type === "FunctionExpression") {
|
|
49
|
+
return current;
|
|
50
|
+
}
|
|
51
|
+
current = current.parent;
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
function addEvidence(collection, key, node) {
|
|
56
|
+
const nodes = collection.get(key) ?? [];
|
|
57
|
+
nodes.push(node);
|
|
58
|
+
collection.set(key, nodes);
|
|
59
|
+
}
|
|
60
|
+
function isAncestor(ancestor, node) {
|
|
61
|
+
let current = node;
|
|
62
|
+
while (current) {
|
|
63
|
+
if (current === ancestor) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
current = current.parent;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
function directChild(ancestor, node) {
|
|
71
|
+
let current = node;
|
|
72
|
+
while (current?.parent && current.parent !== ancestor) {
|
|
73
|
+
current = current.parent;
|
|
74
|
+
}
|
|
75
|
+
return current?.parent === ancestor ? current : undefined;
|
|
76
|
+
}
|
|
77
|
+
function objectContainsParsedBodyProperty(node) {
|
|
78
|
+
if (node?.type !== "ObjectExpression") {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return node.properties.some((property) => {
|
|
82
|
+
if (property.type !== "Property") {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
const propertyName = property.key.type === "Identifier"
|
|
86
|
+
? property.key.name
|
|
87
|
+
: property.key.type === "Literal"
|
|
88
|
+
? property.key.value
|
|
89
|
+
: undefined;
|
|
90
|
+
return propertyName === "parsedBody" || objectContainsParsedBodyProperty(property.value);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function isParsedBodyPropertyPath(node) {
|
|
94
|
+
if (node?.type === "Literal" && typeof node.value === "string") {
|
|
95
|
+
return /^parsedBody(?:\.|\[|$)/u.test(node.value);
|
|
96
|
+
}
|
|
97
|
+
return (node?.type === "ArrayExpression" &&
|
|
98
|
+
node.elements[0]?.type === "Literal" &&
|
|
99
|
+
node.elements[0].value === "parsedBody");
|
|
100
|
+
}
|
|
101
|
+
const rule = {
|
|
102
|
+
meta: {
|
|
103
|
+
type: "problem",
|
|
104
|
+
docs: {
|
|
105
|
+
description: "Require response assertions to use contract-package schemas",
|
|
106
|
+
url: "https://github.com/ClipboardHealth/core-utils/tree/main/packages/eslint-plugin/src/lib/rules/require-contract-response-parse",
|
|
107
|
+
},
|
|
108
|
+
schema: [],
|
|
109
|
+
messages: {
|
|
110
|
+
inlineAnySchema: "Inline z.{{method}}() schemas are not contract oracles. Use the endpoint response schema from a @clipboard-health/contract-* package.",
|
|
111
|
+
missingContractParse: "Parse this response body with its @clipboard-health/contract-* response schema before asserting its shape.",
|
|
112
|
+
nonContractSchema: "This schema is not a contract oracle. Use the endpoint response schema from a @clipboard-health/contract-* package.",
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
create(context) {
|
|
116
|
+
const contractBindings = new Set();
|
|
117
|
+
const zodBindings = new Set();
|
|
118
|
+
const functionStates = new Map();
|
|
119
|
+
const topLevelState = {
|
|
120
|
+
parses: new Map(),
|
|
121
|
+
writes: new Map(),
|
|
122
|
+
};
|
|
123
|
+
const validatedParsedBodyAccesses = new WeakSet();
|
|
124
|
+
function rootIdentifier(node) {
|
|
125
|
+
let current = unwrap(node);
|
|
126
|
+
while (current?.type === "MemberExpression") {
|
|
127
|
+
current = unwrap(current.object);
|
|
128
|
+
}
|
|
129
|
+
return current?.type === "Identifier" ? current : undefined;
|
|
130
|
+
}
|
|
131
|
+
function parsedBodyAccess(node) {
|
|
132
|
+
let current = unwrap(node);
|
|
133
|
+
while (current?.type === "MemberExpression") {
|
|
134
|
+
if (memberPropertyName(current) === "parsedBody") {
|
|
135
|
+
return current;
|
|
136
|
+
}
|
|
137
|
+
current = unwrap(current.object);
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
function findVariable(node) {
|
|
142
|
+
return (0, findVariable_1.findVariable)(context.sourceCode, node);
|
|
143
|
+
}
|
|
144
|
+
function responseKey(node) {
|
|
145
|
+
const current = unwrap(node);
|
|
146
|
+
if (current?.type === "Identifier") {
|
|
147
|
+
return findVariable(current) ?? current.name;
|
|
148
|
+
}
|
|
149
|
+
if (current?.type === "MemberExpression") {
|
|
150
|
+
return context.sourceCode.getText(current);
|
|
151
|
+
}
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
function isContractSchema(node) {
|
|
155
|
+
const identifier = rootIdentifier(node);
|
|
156
|
+
if (!identifier) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
const variable = findVariable(identifier);
|
|
160
|
+
return variable !== undefined && contractBindings.has(variable);
|
|
161
|
+
}
|
|
162
|
+
function stateFor(node) {
|
|
163
|
+
const functionNode = containingFunction(node);
|
|
164
|
+
if (!functionNode) {
|
|
165
|
+
return topLevelState;
|
|
166
|
+
}
|
|
167
|
+
const existingState = functionStates.get(functionNode);
|
|
168
|
+
if (existingState) {
|
|
169
|
+
return existingState;
|
|
170
|
+
}
|
|
171
|
+
const state = { parses: new Map(), writes: new Map() };
|
|
172
|
+
functionStates.set(functionNode, state);
|
|
173
|
+
return state;
|
|
174
|
+
}
|
|
175
|
+
function parseDominatesAssertion(parseNode, assertionNode) {
|
|
176
|
+
if (containingFunction(parseNode) !== containingFunction(assertionNode) ||
|
|
177
|
+
parseNode.range[0] >= assertionNode.range[0]) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
let current = parseNode.parent;
|
|
181
|
+
const functionNode = containingFunction(parseNode);
|
|
182
|
+
while (current && current !== functionNode) {
|
|
183
|
+
if (CONTROL_FLOW_TYPES.has(current.type) &&
|
|
184
|
+
(!isAncestor(current, assertionNode) ||
|
|
185
|
+
directChild(current, parseNode) !== directChild(current, assertionNode))) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
current = current.parent;
|
|
189
|
+
}
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
function hasContractParse(node, key) {
|
|
193
|
+
const state = stateFor(node);
|
|
194
|
+
const parses = state.parses.get(key) ?? [];
|
|
195
|
+
const writes = state.writes.get(key) ?? [];
|
|
196
|
+
return parses.some((parseNode) => parseDominatesAssertion(parseNode, node) &&
|
|
197
|
+
!writes.some((writeNode) => writeNode.range[0] > parseNode.range[1] && writeNode.range[0] < node.range[0]));
|
|
198
|
+
}
|
|
199
|
+
function recordResponseWrite(node, expression) {
|
|
200
|
+
const key = responseKey(expression);
|
|
201
|
+
if (key !== undefined) {
|
|
202
|
+
addEvidence(stateFor(node).writes, key, node);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function checkParseBody(node) {
|
|
206
|
+
if (node.callee.type !== "Identifier" || node.callee.name !== "parseBody") {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const [response, schema] = node.arguments;
|
|
210
|
+
if (!response || !schema) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (!isContractSchema(schema)) {
|
|
214
|
+
context.report({ node: schema, messageId: "nonContractSchema" });
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const key = responseKey(response);
|
|
218
|
+
if (key !== undefined) {
|
|
219
|
+
addEvidence(stateFor(node).parses, key, node);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function checkSchemaParse(node) {
|
|
223
|
+
if (node.callee.type !== "MemberExpression" ||
|
|
224
|
+
!SCHEMA_PARSE_METHODS.has(memberPropertyName(node.callee) ?? "") ||
|
|
225
|
+
!isContractSchema(node.callee.object)) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const argument = unwrap(node.arguments[0]);
|
|
229
|
+
const access = parsedBodyAccess(argument);
|
|
230
|
+
if (!access || argument !== access) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
validatedParsedBodyAccesses.add(access);
|
|
234
|
+
const key = responseKey(access.object);
|
|
235
|
+
if (key !== undefined) {
|
|
236
|
+
addEvidence(stateFor(node).parses, key, node);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function checkParsedBodyAccess(node) {
|
|
240
|
+
if (memberPropertyName(node) !== "parsedBody" || validatedParsedBodyAccesses.has(node)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const key = responseKey(node.object);
|
|
244
|
+
if (key === undefined || !hasContractParse(node, key)) {
|
|
245
|
+
context.report({ node, messageId: "missingContractParse" });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function expectCall(node) {
|
|
249
|
+
if (node.callee.type !== "MemberExpression") {
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
let matcherTarget = node.callee.object;
|
|
253
|
+
while (matcherTarget.type === "MemberExpression" &&
|
|
254
|
+
MATCHER_MODIFIERS.has(memberPropertyName(matcherTarget) ?? "")) {
|
|
255
|
+
matcherTarget = matcherTarget.object;
|
|
256
|
+
}
|
|
257
|
+
if (matcherTarget.type !== "CallExpression" ||
|
|
258
|
+
matcherTarget.callee.type !== "Identifier" ||
|
|
259
|
+
matcherTarget.callee.name !== "expect") {
|
|
260
|
+
return undefined;
|
|
261
|
+
}
|
|
262
|
+
return matcherTarget;
|
|
263
|
+
}
|
|
264
|
+
function checkWholeResponseAssertion(node) {
|
|
265
|
+
const expectation = expectCall(node);
|
|
266
|
+
if (!expectation) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const assertsParsedBodyProperty = node.arguments.some((argument) => objectContainsParsedBodyProperty(argument));
|
|
270
|
+
const matcherName = node.callee.type === "MemberExpression" ? memberPropertyName(node.callee) : undefined;
|
|
271
|
+
const assertsParsedBodyPath = matcherName === "toHaveProperty" && isParsedBodyPropertyPath(node.arguments[0]);
|
|
272
|
+
if (!assertsParsedBodyProperty && !assertsParsedBodyPath) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const key = responseKey(expectation.arguments[0]);
|
|
276
|
+
if (key !== undefined && !hasContractParse(node, key)) {
|
|
277
|
+
context.report({
|
|
278
|
+
node: expectation,
|
|
279
|
+
messageId: "missingContractParse",
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function checkParsedBodyDestructuring(node) {
|
|
284
|
+
if (node.id.type !== "ObjectPattern") {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const parsedBodyProperty = node.id.properties.find((property) => {
|
|
288
|
+
if (property.type !== "Property") {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
return ((property.key.type === "Identifier" && property.key.name === "parsedBody") ||
|
|
292
|
+
(property.key.type === "Literal" && property.key.value === "parsedBody"));
|
|
293
|
+
});
|
|
294
|
+
if (!parsedBodyProperty) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const key = responseKey(node.init ?? undefined);
|
|
298
|
+
if (key === undefined || !hasContractParse(node, key)) {
|
|
299
|
+
context.report({
|
|
300
|
+
node: parsedBodyProperty,
|
|
301
|
+
messageId: "missingContractParse",
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function checkInlineAnySchema(node) {
|
|
306
|
+
if (node.callee.type !== "MemberExpression") {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const method = memberPropertyName(node.callee);
|
|
310
|
+
const identifier = rootIdentifier(node.callee.object);
|
|
311
|
+
if (!method || !ANY_SCHEMA_METHODS.has(method) || !identifier) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
const variable = findVariable(identifier);
|
|
315
|
+
if (variable !== undefined && zodBindings.has(variable)) {
|
|
316
|
+
context.report({
|
|
317
|
+
node,
|
|
318
|
+
messageId: "inlineAnySchema",
|
|
319
|
+
data: { method },
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
ImportDeclaration(node) {
|
|
325
|
+
if (node.source.value.startsWith(CONTRACT_PACKAGE_PREFIX)) {
|
|
326
|
+
for (const specifier of node.specifiers) {
|
|
327
|
+
const [variable] = context.sourceCode.getDeclaredVariables(specifier);
|
|
328
|
+
if (variable) {
|
|
329
|
+
contractBindings.add(variable);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (node.source.value === "zod") {
|
|
334
|
+
for (const specifier of node.specifiers) {
|
|
335
|
+
const importsZodNamespace = specifier.type === "ImportNamespaceSpecifier";
|
|
336
|
+
const importsZodDefault = specifier.type === "ImportDefaultSpecifier";
|
|
337
|
+
const importsZodBinding = specifier.type === "ImportSpecifier" &&
|
|
338
|
+
specifier.imported.type === "Identifier" &&
|
|
339
|
+
specifier.imported.name === "z";
|
|
340
|
+
if (!importsZodNamespace && !importsZodDefault && !importsZodBinding) {
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
const [variable] = context.sourceCode.getDeclaredVariables(specifier);
|
|
344
|
+
if (variable) {
|
|
345
|
+
zodBindings.add(variable);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
CallExpression(node) {
|
|
351
|
+
checkInlineAnySchema(node);
|
|
352
|
+
checkParseBody(node);
|
|
353
|
+
checkSchemaParse(node);
|
|
354
|
+
checkWholeResponseAssertion(node);
|
|
355
|
+
},
|
|
356
|
+
MemberExpression: checkParsedBodyAccess,
|
|
357
|
+
VariableDeclarator: checkParsedBodyDestructuring,
|
|
358
|
+
AssignmentExpression(node) {
|
|
359
|
+
recordResponseWrite(node, node.left);
|
|
360
|
+
},
|
|
361
|
+
UpdateExpression(node) {
|
|
362
|
+
recordResponseWrite(node, node.argument);
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
},
|
|
366
|
+
};
|
|
367
|
+
exports.default = rule;
|
|
368
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/oxlint-plugin/src/lib/rules/require-contract-response-parse/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Rule to require HttpModule to use registerAsync factory to avoid shared axios client issues
|
|
5
|
+
*/
|
|
6
|
+
const plugins_1 = require("@oxlint/plugins");
|
|
7
|
+
function isHttpModuleImport(specifier) {
|
|
8
|
+
return (specifier.type === "ImportSpecifier" &&
|
|
9
|
+
specifier.imported.type === "Identifier" &&
|
|
10
|
+
specifier.imported.name === "HttpModule");
|
|
11
|
+
}
|
|
12
|
+
function isImportsArray(node) {
|
|
13
|
+
const { parent } = node;
|
|
14
|
+
return (parent?.type === "Property" &&
|
|
15
|
+
parent.key.type === "Identifier" &&
|
|
16
|
+
parent.key.name === "imports" &&
|
|
17
|
+
parent.value === node);
|
|
18
|
+
}
|
|
19
|
+
const rule = (0, plugins_1.defineRule)({
|
|
20
|
+
meta: {
|
|
21
|
+
type: "problem",
|
|
22
|
+
docs: {
|
|
23
|
+
description: "Require HttpModule to use registerAsync factory to avoid shared axios client issues",
|
|
24
|
+
url: "https://github.com/ClipboardHealth/core-utils/tree/main/packages/eslint-plugin/src/lib/rules/require-http-module-factory",
|
|
25
|
+
},
|
|
26
|
+
schema: [],
|
|
27
|
+
messages: {
|
|
28
|
+
requireFactory: "HttpModule must use .registerAsync() with a custom factory to create a new axios client instance. Direct HttpModule imports share the global axios client and can cause interceptor conflicts.",
|
|
29
|
+
wrongPackage: "HttpModule must be imported from '@nestjs/axios' package. Using HttpModule from other packages may not provide the expected factory methods.",
|
|
30
|
+
noImport: "HttpModule is used but not imported from '@nestjs/axios'. Import HttpModule and use .registerAsync() with a custom factory.",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
create(context) {
|
|
34
|
+
let httpModuleImportedCorrectly = false;
|
|
35
|
+
let httpModuleImportName;
|
|
36
|
+
function checkHttpModuleUsage(element) {
|
|
37
|
+
if (element?.type !== "Identifier") {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const isDirectHttpModule = element.name === "HttpModule";
|
|
41
|
+
const isAliasedHttpModule = httpModuleImportedCorrectly && element.name === httpModuleImportName;
|
|
42
|
+
if (isDirectHttpModule) {
|
|
43
|
+
const messageId = httpModuleImportedCorrectly ? "requireFactory" : "noImport";
|
|
44
|
+
context.report({ node: element, messageId });
|
|
45
|
+
}
|
|
46
|
+
else if (isAliasedHttpModule) {
|
|
47
|
+
context.report({ node: element, messageId: "requireFactory" });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
ImportDeclaration(node) {
|
|
52
|
+
if (node.source.value !== "@nestjs/axios") {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
for (const specifier of node.specifiers) {
|
|
56
|
+
if (isHttpModuleImport(specifier)) {
|
|
57
|
+
httpModuleImportedCorrectly = true;
|
|
58
|
+
httpModuleImportName = specifier.local.name;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
ArrayExpression(node) {
|
|
63
|
+
if (!isImportsArray(node)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
for (const element of node.elements) {
|
|
67
|
+
checkHttpModuleUsage(element);
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
exports.default = rule;
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/oxlint-plugin/src/lib/rules/require-http-module-factory/index.ts"],"names":[],"mappings":";;AAAA;;GAEG;AACH,6CAA0D;AAE1D,SAAS,kBAAkB,CAAC,SAA4C;IACtE,OAAO,CACL,SAAS,CAAC,IAAI,KAAK,iBAAiB;QACpC,SAAS,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;QACxC,SAAS,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CACzC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,IAA4B;IAClD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,OAAO,CACL,MAAM,EAAE,IAAI,KAAK,UAAU;QAC3B,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,YAAY;QAChC,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS;QAC7B,MAAM,CAAC,KAAK,KAAK,IAAI,CACtB,CAAC;AACJ,CAAC;AAED,MAAM,IAAI,GAAG,IAAA,oBAAU,EAAC;IACtB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,qFAAqF;YACvF,GAAG,EAAE,0HAA0H;SAChI;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,cAAc,EACZ,gMAAgM;YAClM,YAAY,EACV,8IAA8I;YAChJ,QAAQ,EACN,6HAA6H;SAChI;KACF;IACD,MAAM,CAAC,OAAO;QACZ,IAAI,2BAA2B,GAAG,KAAK,CAAC;QACxC,IAAI,oBAAwC,CAAC;QAE7C,SAAS,oBAAoB,CAAC,OAAsC;YAClE,IAAI,OAAO,EAAE,IAAI,KAAK,YAAY,EAAE,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC;YACzD,MAAM,mBAAmB,GACvB,2BAA2B,IAAI,OAAO,CAAC,IAAI,KAAK,oBAAoB,CAAC;YAEvE,IAAI,kBAAkB,EAAE,CAAC;gBACvB,MAAM,SAAS,GAAG,2BAA2B,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC;gBAC9E,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;YAC/C,CAAC;iBAAM,IAAI,mBAAmB,EAAE,CAAC;gBAC/B,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QAED,OAAO;YACL,iBAAiB,CAAC,IAAI;gBACpB,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;oBAC1C,OAAO;gBACT,CAAC;gBAED,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;oBACxC,IAAI,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;wBAClC,2BAA2B,GAAG,IAAI,CAAC;wBACnC,oBAAoB,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;oBAC9C,CAAC;gBACH,CAAC;YACH,CAAC;YAED,eAAe,CAAC,IAAI;gBAClB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1B,OAAO;gBACT,CAAC;gBAED,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACpC,oBAAoB,CAAC,OAAO,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC;kBAEY,IAAI"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Rule to require runValidators: true when upsert: true is used in Mongoose operations
|
|
5
|
+
*/
|
|
6
|
+
const plugins_1 = require("@oxlint/plugins");
|
|
7
|
+
const UPSERT_METHODS = new Set([
|
|
8
|
+
"updateOne",
|
|
9
|
+
"updateMany",
|
|
10
|
+
"findOneAndUpdate",
|
|
11
|
+
"findByIdAndUpdate",
|
|
12
|
+
"findOneAndReplace",
|
|
13
|
+
"replaceOne",
|
|
14
|
+
]);
|
|
15
|
+
function hasPropertyWithValue(property, name, value) {
|
|
16
|
+
return (property.type === "Property" &&
|
|
17
|
+
property.key.type === "Identifier" &&
|
|
18
|
+
property.key.name === name &&
|
|
19
|
+
property.value.type === "Literal" &&
|
|
20
|
+
property.value.value === value);
|
|
21
|
+
}
|
|
22
|
+
function findProperty(objectExpression, name) {
|
|
23
|
+
for (const property of objectExpression.properties) {
|
|
24
|
+
if (property.type === "Property" &&
|
|
25
|
+
property.key.type === "Identifier" &&
|
|
26
|
+
property.key.name === name) {
|
|
27
|
+
return property;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
function hasUpsertTrue(objectExpression) {
|
|
33
|
+
return objectExpression.properties.some((property) => hasPropertyWithValue(property, "upsert", true));
|
|
34
|
+
}
|
|
35
|
+
function hasRunValidatorsTrue(objectExpression) {
|
|
36
|
+
return objectExpression.properties.some((property) => hasPropertyWithValue(property, "runValidators", true));
|
|
37
|
+
}
|
|
38
|
+
function hasRunValidatorsFalse(objectExpression) {
|
|
39
|
+
return objectExpression.properties.some((property) => hasPropertyWithValue(property, "runValidators", false));
|
|
40
|
+
}
|
|
41
|
+
function hasRunValidatorsProperty(objectExpression) {
|
|
42
|
+
return objectExpression.properties.some((property) => property.type === "Property" &&
|
|
43
|
+
property.key.type === "Identifier" &&
|
|
44
|
+
property.key.name === "runValidators");
|
|
45
|
+
}
|
|
46
|
+
const rule = (0, plugins_1.defineRule)({
|
|
47
|
+
meta: {
|
|
48
|
+
type: "problem",
|
|
49
|
+
docs: {
|
|
50
|
+
description: "Require runValidators: true when upsert: true is used in Mongoose update operations",
|
|
51
|
+
url: "https://github.com/ClipboardHealth/core-utils/tree/main/packages/eslint-plugin/src/lib/rules/require-run-validators-with-upsert",
|
|
52
|
+
},
|
|
53
|
+
schema: [],
|
|
54
|
+
messages: {
|
|
55
|
+
missingRunValidators: "Mongoose upsert operations must include 'runValidators: true' to ensure schema validation on inserted documents. Add 'runValidators: true' to the options object.",
|
|
56
|
+
runValidatorsFalse: "Mongoose upsert operations should not have 'runValidators: false'. Schema validation should be enabled for upserts to ensure data integrity.",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
create(context) {
|
|
60
|
+
return {
|
|
61
|
+
CallExpression(node) {
|
|
62
|
+
if (node.callee.type !== "MemberExpression") {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const { property } = node.callee;
|
|
66
|
+
if (property.type !== "Identifier") {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (!UPSERT_METHODS.has(property.name)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
for (const argument of node.arguments) {
|
|
73
|
+
if (argument.type !== "ObjectExpression") {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (!hasUpsertTrue(argument)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (hasRunValidatorsTrue(argument)) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (hasRunValidatorsFalse(argument)) {
|
|
83
|
+
const runValidatorsProperty = findProperty(argument, "runValidators");
|
|
84
|
+
if (runValidatorsProperty) {
|
|
85
|
+
context.report({
|
|
86
|
+
node: runValidatorsProperty,
|
|
87
|
+
messageId: "runValidatorsFalse",
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
// If runValidators is present with a non-literal value (e.g., a variable),
|
|
93
|
+
// we consider it valid since the developer is explicitly setting it.
|
|
94
|
+
if (hasRunValidatorsProperty(argument)) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const upsertProperty = findProperty(argument, "upsert");
|
|
98
|
+
if (upsertProperty) {
|
|
99
|
+
context.report({
|
|
100
|
+
node: upsertProperty,
|
|
101
|
+
messageId: "missingRunValidators",
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
exports.default = rule;
|
|
110
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/oxlint-plugin/src/lib/rules/require-run-validators-with-upsert/index.ts"],"names":[],"mappings":"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"}
|