eslint-plugin-zod 3.0.0 → 3.0.2

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.
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.arrayStyle = void 0;
4
4
  const utils_1 = require("@typescript-eslint/utils");
5
5
  const meta_js_1 = require("../meta.cjs");
6
- const is_zod_expression_js_1 = require("../utils/is-zod-expression.cjs");
7
6
  const track_zod_schema_imports_js_1 = require("../utils/track-zod-schema-imports.cjs");
8
7
  const ZOD_ARRAY_STYLES = ['function', 'method'];
9
8
  const defaultOptions = { style: 'function' };
@@ -74,14 +73,17 @@ exports.arrayStyle = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
74
73
  }
75
74
  return;
76
75
  }
77
- const { callee } = node;
78
- if ((0, is_zod_expression_js_1.isZodExpressionEndingWithMethod)(callee, 'array') &&
79
- node.arguments.length === 0) {
76
+ const methods = collectZodChainMethods(node);
77
+ const arrayMethod = methods.find((it) => it.name === 'array' &&
78
+ it.node.arguments.length === 0);
79
+ if (arrayMethod) {
80
+ const arrayNode = arrayMethod.node;
80
81
  if (schemaDecl === 'namespace') {
81
82
  context.report({
82
83
  node,
83
84
  messageId: 'useFunction',
84
85
  fix(fixer) {
86
+ const callee = arrayNode.callee;
85
87
  const objText = sourceCode.getText(callee.object);
86
88
  return fixer.replaceText(node, `z.array(${objText})`);
87
89
  },
@@ -1,6 +1,5 @@
1
1
  import { ESLintUtils } from '@typescript-eslint/utils';
2
2
  import { getRuleURL } from "../meta.js";
3
- import { isZodExpressionEndingWithMethod } from "../utils/is-zod-expression.js";
4
3
  import { trackZodSchemaImports } from "../utils/track-zod-schema-imports.js";
5
4
  const ZOD_ARRAY_STYLES = ['function', 'method'];
6
5
  const defaultOptions = { style: 'function' };
@@ -71,14 +70,17 @@ export const arrayStyle = ESLintUtils.RuleCreator(getRuleURL)({
71
70
  }
72
71
  return;
73
72
  }
74
- const { callee } = node;
75
- if (isZodExpressionEndingWithMethod(callee, 'array') &&
76
- node.arguments.length === 0) {
73
+ const methods = collectZodChainMethods(node);
74
+ const arrayMethod = methods.find((it) => it.name === 'array' &&
75
+ it.node.arguments.length === 0);
76
+ if (arrayMethod) {
77
+ const arrayNode = arrayMethod.node;
77
78
  if (schemaDecl === 'namespace') {
78
79
  context.report({
79
80
  node,
80
81
  messageId: 'useFunction',
81
82
  fix(fixer) {
83
+ const callee = arrayNode.callee;
82
84
  const objText = sourceCode.getText(callee.object);
83
85
  return fixer.replaceText(node, `z.array(${objText})`);
84
86
  },
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.noNumberSchemaWithInt = void 0;
4
4
  const utils_1 = require("@typescript-eslint/utils");
5
5
  const meta_js_1 = require("../meta.cjs");
6
- const get_outermost_call_js_1 = require("../utils/get-outermost-call.cjs");
7
6
  const track_zod_schema_imports_js_1 = require("../utils/track-zod-schema-imports.cjs");
8
7
  exports.noNumberSchemaWithInt = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
9
8
  name: 'no-number-schema-with-int',
@@ -25,26 +24,18 @@ exports.noNumberSchemaWithInt = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRul
25
24
  return {
26
25
  ImportDeclaration: importDeclarationListener,
27
26
  CallExpression(node) {
28
- var _a;
29
- const outer = (_a = (0, get_outermost_call_js_1.getOutermostCall)(node)) !== null && _a !== void 0 ? _a : node;
30
- const zodSchemaMeta = detectZodSchemaRootNode(outer);
31
- if (!zodSchemaMeta) {
27
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
28
+ if ((zodSchemaMeta === null || zodSchemaMeta === void 0 ? void 0 : zodSchemaMeta.schemaType) !== 'number') {
32
29
  return;
33
30
  }
34
- if (zodSchemaMeta.schemaType !== 'number') {
35
- return;
36
- }
37
- const methods = collectZodChainMethods(outer);
31
+ const methods = collectZodChainMethods(node);
38
32
  const numberIndex = methods.findIndex((m) => m.name === 'number');
39
33
  const intIndex = methods.findIndex((m) => m.name === 'int');
40
34
  if (numberIndex === -1 || intIndex === -1) {
41
35
  return;
42
36
  }
43
- const numberMethod = methods[numberIndex];
44
- const intMethod = methods[intIndex];
45
- if (node !== intMethod.node) {
46
- return;
47
- }
37
+ const numberNode = methods[numberIndex].node;
38
+ const intNode = methods[intIndex].node;
48
39
  if (zodSchemaMeta.schemaDecl === 'named') {
49
40
  context.report({
50
41
  node,
@@ -56,8 +47,6 @@ exports.noNumberSchemaWithInt = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRul
56
47
  node,
57
48
  messageId: 'removeNumber',
58
49
  fix(fixer) {
59
- const numberNode = numberMethod.node;
60
- const intNode = intMethod.node;
61
50
  const numberCallee = numberNode.callee;
62
51
  const prefixObj = numberCallee.object;
63
52
  const prefixText = sourceCode.getText(prefixObj);
@@ -1,6 +1,5 @@
1
1
  import { ESLintUtils } from '@typescript-eslint/utils';
2
2
  import { getRuleURL } from "../meta.js";
3
- import { getOutermostCall } from "../utils/get-outermost-call.js";
4
3
  import { trackZodSchemaImports } from "../utils/track-zod-schema-imports.js";
5
4
  export const noNumberSchemaWithInt = ESLintUtils.RuleCreator(getRuleURL)({
6
5
  name: 'no-number-schema-with-int',
@@ -22,26 +21,18 @@ export const noNumberSchemaWithInt = ESLintUtils.RuleCreator(getRuleURL)({
22
21
  return {
23
22
  ImportDeclaration: importDeclarationListener,
24
23
  CallExpression(node) {
25
- var _a;
26
- const outer = (_a = getOutermostCall(node)) !== null && _a !== void 0 ? _a : node;
27
- const zodSchemaMeta = detectZodSchemaRootNode(outer);
28
- if (!zodSchemaMeta) {
24
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
25
+ if ((zodSchemaMeta === null || zodSchemaMeta === void 0 ? void 0 : zodSchemaMeta.schemaType) !== 'number') {
29
26
  return;
30
27
  }
31
- if (zodSchemaMeta.schemaType !== 'number') {
32
- return;
33
- }
34
- const methods = collectZodChainMethods(outer);
28
+ const methods = collectZodChainMethods(node);
35
29
  const numberIndex = methods.findIndex((m) => m.name === 'number');
36
30
  const intIndex = methods.findIndex((m) => m.name === 'int');
37
31
  if (numberIndex === -1 || intIndex === -1) {
38
32
  return;
39
33
  }
40
- const numberMethod = methods[numberIndex];
41
- const intMethod = methods[intIndex];
42
- if (node !== intMethod.node) {
43
- return;
44
- }
34
+ const numberNode = methods[numberIndex].node;
35
+ const intNode = methods[intIndex].node;
45
36
  if (zodSchemaMeta.schemaDecl === 'named') {
46
37
  context.report({
47
38
  node,
@@ -53,8 +44,6 @@ export const noNumberSchemaWithInt = ESLintUtils.RuleCreator(getRuleURL)({
53
44
  node,
54
45
  messageId: 'removeNumber',
55
46
  fix(fixer) {
56
- const numberNode = numberMethod.node;
57
- const intNode = intMethod.node;
58
47
  const numberCallee = numberNode.callee;
59
48
  const prefixObj = numberCallee.object;
60
49
  const prefixText = sourceCode.getText(prefixObj);
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.noThrowInRefine = void 0;
4
4
  const utils_1 = require("@typescript-eslint/utils");
5
5
  const meta_js_1 = require("../meta.cjs");
6
- const is_zod_expression_js_1 = require("../utils/is-zod-expression.cjs");
7
6
  const track_zod_schema_imports_js_1 = require("../utils/track-zod-schema-imports.cjs");
8
7
  exports.noThrowInRefine = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
9
8
  name: 'no-throw-in-refine',
@@ -19,7 +18,7 @@ exports.noThrowInRefine = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)(
19
18
  },
20
19
  defaultOptions: [],
21
20
  create(context) {
22
- const { importDeclarationListener, detectZodSchemaRootNode, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
21
+ const { importDeclarationListener, detectZodSchemaRootNode, collectZodChainMethods, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
23
22
  function checkNode(node) {
24
23
  if (!node) {
25
24
  return;
@@ -71,12 +70,15 @@ exports.noThrowInRefine = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)(
71
70
  if (!zodSchemaMeta) {
72
71
  return;
73
72
  }
74
- if ((0, is_zod_expression_js_1.isZodExpressionEndingWithMethod)(node.callee, 'refine')) {
75
- const [callback] = node.arguments;
76
- if (callback.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
77
- callback.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
78
- checkNode(callback.body);
79
- }
73
+ const methods = collectZodChainMethods(node);
74
+ const refineMethod = methods.find((it) => it.name === 'refine');
75
+ if (!refineMethod) {
76
+ return;
77
+ }
78
+ const [callback] = refineMethod.node.arguments;
79
+ if (callback.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
80
+ callback.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
81
+ checkNode(callback.body);
80
82
  }
81
83
  },
82
84
  };
@@ -1,6 +1,5 @@
1
1
  import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';
2
2
  import { getRuleURL } from "../meta.js";
3
- import { isZodExpressionEndingWithMethod } from "../utils/is-zod-expression.js";
4
3
  import { trackZodSchemaImports } from "../utils/track-zod-schema-imports.js";
5
4
  export const noThrowInRefine = ESLintUtils.RuleCreator(getRuleURL)({
6
5
  name: 'no-throw-in-refine',
@@ -16,7 +15,7 @@ export const noThrowInRefine = ESLintUtils.RuleCreator(getRuleURL)({
16
15
  },
17
16
  defaultOptions: [],
18
17
  create(context) {
19
- const { importDeclarationListener, detectZodSchemaRootNode, } = trackZodSchemaImports();
18
+ const { importDeclarationListener, detectZodSchemaRootNode, collectZodChainMethods, } = trackZodSchemaImports();
20
19
  function checkNode(node) {
21
20
  if (!node) {
22
21
  return;
@@ -68,12 +67,15 @@ export const noThrowInRefine = ESLintUtils.RuleCreator(getRuleURL)({
68
67
  if (!zodSchemaMeta) {
69
68
  return;
70
69
  }
71
- if (isZodExpressionEndingWithMethod(node.callee, 'refine')) {
72
- const [callback] = node.arguments;
73
- if (callback.type === AST_NODE_TYPES.ArrowFunctionExpression ||
74
- callback.type === AST_NODE_TYPES.FunctionExpression) {
75
- checkNode(callback.body);
76
- }
70
+ const methods = collectZodChainMethods(node);
71
+ const refineMethod = methods.find((it) => it.name === 'refine');
72
+ if (!refineMethod) {
73
+ return;
74
+ }
75
+ const [callback] = refineMethod.node.arguments;
76
+ if (callback.type === AST_NODE_TYPES.ArrowFunctionExpression ||
77
+ callback.type === AST_NODE_TYPES.FunctionExpression) {
78
+ checkNode(callback.body);
77
79
  }
78
80
  },
79
81
  };
@@ -19,7 +19,7 @@ exports.preferEnumOverLiteralUnion = utils_1.ESLintUtils.RuleCreator(meta_js_1.g
19
19
  },
20
20
  defaultOptions: [],
21
21
  create(context) {
22
- const { importDeclarationListener, detectZodSchemaRootNode, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
22
+ const { importDeclarationListener, detectZodSchemaRootNode, collectZodChainMethods, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
23
23
  return {
24
24
  ImportDeclaration: importDeclarationListener,
25
25
  CallExpression(node) {
@@ -27,8 +27,14 @@ exports.preferEnumOverLiteralUnion = utils_1.ESLintUtils.RuleCreator(meta_js_1.g
27
27
  if ((zodSchema === null || zodSchema === void 0 ? void 0 : zodSchema.schemaType) !== 'union') {
28
28
  return;
29
29
  }
30
- const [unionArgument] = node.arguments;
31
- if (unionArgument.type !== utils_1.AST_NODE_TYPES.ArrayExpression) {
30
+ const methods = collectZodChainMethods(zodSchema.node);
31
+ const union = methods.find((it) => it.name === 'union');
32
+ if (!union) {
33
+ return;
34
+ }
35
+ const unionNode = union.node;
36
+ const unionArgument = unionNode.arguments.at(0);
37
+ if ((unionArgument === null || unionArgument === void 0 ? void 0 : unionArgument.type) !== utils_1.AST_NODE_TYPES.ArrayExpression) {
32
38
  return;
33
39
  }
34
40
  const zodLiteralStrings = unionArgument.elements.map((s) => {
@@ -61,8 +67,8 @@ exports.preferEnumOverLiteralUnion = utils_1.ESLintUtils.RuleCreator(meta_js_1.g
61
67
  messageId: 'useEnum',
62
68
  fix(fixer) {
63
69
  return [
64
- fixer.replaceText(node.callee.property, 'enum'),
65
- fixer.replaceText(node.arguments[0], `[${zodLiteralStrings.join(', ')}]`),
70
+ fixer.replaceText(unionNode.callee.property, 'enum'),
71
+ fixer.replaceText(unionNode.arguments[0], `[${zodLiteralStrings.join(', ')}]`),
66
72
  ];
67
73
  },
68
74
  });
@@ -16,7 +16,7 @@ export const preferEnumOverLiteralUnion = ESLintUtils.RuleCreator(getRuleURL)({
16
16
  },
17
17
  defaultOptions: [],
18
18
  create(context) {
19
- const { importDeclarationListener, detectZodSchemaRootNode, } = trackZodSchemaImports();
19
+ const { importDeclarationListener, detectZodSchemaRootNode, collectZodChainMethods, } = trackZodSchemaImports();
20
20
  return {
21
21
  ImportDeclaration: importDeclarationListener,
22
22
  CallExpression(node) {
@@ -24,8 +24,14 @@ export const preferEnumOverLiteralUnion = ESLintUtils.RuleCreator(getRuleURL)({
24
24
  if ((zodSchema === null || zodSchema === void 0 ? void 0 : zodSchema.schemaType) !== 'union') {
25
25
  return;
26
26
  }
27
- const [unionArgument] = node.arguments;
28
- if (unionArgument.type !== AST_NODE_TYPES.ArrayExpression) {
27
+ const methods = collectZodChainMethods(zodSchema.node);
28
+ const union = methods.find((it) => it.name === 'union');
29
+ if (!union) {
30
+ return;
31
+ }
32
+ const unionNode = union.node;
33
+ const unionArgument = unionNode.arguments.at(0);
34
+ if ((unionArgument === null || unionArgument === void 0 ? void 0 : unionArgument.type) !== AST_NODE_TYPES.ArrayExpression) {
29
35
  return;
30
36
  }
31
37
  const zodLiteralStrings = unionArgument.elements.map((s) => {
@@ -58,8 +64,8 @@ export const preferEnumOverLiteralUnion = ESLintUtils.RuleCreator(getRuleURL)({
58
64
  messageId: 'useEnum',
59
65
  fix(fixer) {
60
66
  return [
61
- fixer.replaceText(node.callee.property, 'enum'),
62
- fixer.replaceText(node.arguments[0], `[${zodLiteralStrings.join(', ')}]`),
67
+ fixer.replaceText(unionNode.callee.property, 'enum'),
68
+ fixer.replaceText(unionNode.arguments[0], `[${zodLiteralStrings.join(', ')}]`),
63
69
  ];
64
70
  },
65
71
  });
@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.preferMetaLast = void 0;
4
4
  const utils_1 = require("@typescript-eslint/utils");
5
5
  const meta_js_1 = require("../meta.cjs");
6
- const get_outermost_call_js_1 = require("../utils/get-outermost-call.cjs");
7
- const is_zod_expression_js_1 = require("../utils/is-zod-expression.cjs");
8
6
  const track_zod_schema_imports_js_1 = require("../utils/track-zod-schema-imports.cjs");
9
7
  exports.preferMetaLast = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
10
8
  name: 'prefer-meta-last',
@@ -23,19 +21,11 @@ exports.preferMetaLast = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
23
21
  return {
24
22
  ImportDeclaration: importDeclarationListener,
25
23
  CallExpression(node) {
26
- if (node.callee.type !== utils_1.AST_NODE_TYPES.MemberExpression ||
27
- !(0, is_zod_expression_js_1.isZodExpressionEndingWithMethod)(node.callee, 'meta')) {
28
- return;
29
- }
30
- const outer = (0, get_outermost_call_js_1.getOutermostCall)(node);
31
- if (!outer) {
32
- return;
33
- }
34
- const zodSchemaMeta = detectZodSchemaRootNode(outer);
35
- const chain = collectZodChainMethods(outer);
24
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
36
25
  if (!zodSchemaMeta) {
37
26
  return;
38
27
  }
28
+ const chain = collectZodChainMethods(node);
39
29
  const metaIndex = chain.findIndex((c) => c.name === 'meta');
40
30
  if (metaIndex === -1) {
41
31
  return;
@@ -1,7 +1,5 @@
1
- import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
2
  import { getRuleURL } from "../meta.js";
3
- import { getOutermostCall } from "../utils/get-outermost-call.js";
4
- import { isZodExpressionEndingWithMethod } from "../utils/is-zod-expression.js";
5
3
  import { trackZodSchemaImports } from "../utils/track-zod-schema-imports.js";
6
4
  export const preferMetaLast = ESLintUtils.RuleCreator(getRuleURL)({
7
5
  name: 'prefer-meta-last',
@@ -20,19 +18,11 @@ export const preferMetaLast = ESLintUtils.RuleCreator(getRuleURL)({
20
18
  return {
21
19
  ImportDeclaration: importDeclarationListener,
22
20
  CallExpression(node) {
23
- if (node.callee.type !== AST_NODE_TYPES.MemberExpression ||
24
- !isZodExpressionEndingWithMethod(node.callee, 'meta')) {
25
- return;
26
- }
27
- const outer = getOutermostCall(node);
28
- if (!outer) {
29
- return;
30
- }
31
- const zodSchemaMeta = detectZodSchemaRootNode(outer);
32
- const chain = collectZodChainMethods(outer);
21
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
33
22
  if (!zodSchemaMeta) {
34
23
  return;
35
24
  }
25
+ const chain = collectZodChainMethods(node);
36
26
  const metaIndex = chain.findIndex((c) => c.name === 'meta');
37
27
  if (metaIndex === -1) {
38
28
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-zod",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "type": "module",
5
5
  "description": "ESLint plugin that adds custom linting rules to enforce best practices when using Zod",
6
6
  "engines": {
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getOutermostCall = getOutermostCall;
4
- const utils_1 = require("@typescript-eslint/utils");
5
- function getOutermostCall(node) {
6
- var _a;
7
- let current = node;
8
- while (((_a = current.parent) === null || _a === void 0 ? void 0 : _a.type) === utils_1.AST_NODE_TYPES.MemberExpression &&
9
- current.parent.object === current &&
10
- current.parent.parent.type === utils_1.AST_NODE_TYPES.CallExpression) {
11
- current = current.parent.parent;
12
- }
13
- return current.type === utils_1.AST_NODE_TYPES.CallExpression ? current : null;
14
- }
@@ -1,2 +0,0 @@
1
- import type { TSESTree } from '@typescript-eslint/utils';
2
- export declare function getOutermostCall(node: TSESTree.Node): TSESTree.CallExpression | null;
@@ -1,2 +0,0 @@
1
- import type { TSESTree } from '@typescript-eslint/utils';
2
- export declare function getOutermostCall(node: TSESTree.Node): TSESTree.CallExpression | null;
@@ -1,11 +0,0 @@
1
- import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
- export function getOutermostCall(node) {
3
- var _a;
4
- let current = node;
5
- while (((_a = current.parent) === null || _a === void 0 ? void 0 : _a.type) === AST_NODE_TYPES.MemberExpression &&
6
- current.parent.object === current &&
7
- current.parent.parent.type === AST_NODE_TYPES.CallExpression) {
8
- current = current.parent.parent;
9
- }
10
- return current.type === AST_NODE_TYPES.CallExpression ? current : null;
11
- }
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isZodExpressionEndingWithMethod = isZodExpressionEndingWithMethod;
4
- const utils_1 = require("@typescript-eslint/utils");
5
- function isZodExpressionEndingWithMethod(node, propName) {
6
- if (node.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
7
- return false;
8
- }
9
- if (node.property.type === utils_1.AST_NODE_TYPES.Identifier &&
10
- node.property.name === propName) {
11
- return true;
12
- }
13
- return false;
14
- }
@@ -1,2 +0,0 @@
1
- import type { TSESTree } from '@typescript-eslint/utils';
2
- export declare function isZodExpressionEndingWithMethod(node: TSESTree.Node, propName: string): node is TSESTree.MemberExpression;
@@ -1,2 +0,0 @@
1
- import type { TSESTree } from '@typescript-eslint/utils';
2
- export declare function isZodExpressionEndingWithMethod(node: TSESTree.Node, propName: string): node is TSESTree.MemberExpression;
@@ -1,11 +0,0 @@
1
- import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
- export function isZodExpressionEndingWithMethod(node, propName) {
3
- if (node.type !== AST_NODE_TYPES.MemberExpression) {
4
- return false;
5
- }
6
- if (node.property.type === AST_NODE_TYPES.Identifier &&
7
- node.property.name === propName) {
8
- return true;
9
- }
10
- return false;
11
- }