eslint-plugin-zod 1.3.0 → 3.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.
Files changed (104) hide show
  1. package/LICENSE +19 -22
  2. package/README.md +84 -56
  3. package/dist/index.cjs +71 -0
  4. package/dist/index.d.cts +21 -0
  5. package/dist/index.d.ts +21 -0
  6. package/dist/index.js +68 -0
  7. package/dist/meta.cjs +13 -0
  8. package/dist/meta.d.cts +3 -0
  9. package/dist/meta.d.ts +3 -0
  10. package/dist/meta.js +8 -0
  11. package/dist/rules/array-style.cjs +99 -0
  12. package/dist/rules/array-style.d.cts +10 -0
  13. package/dist/rules/array-style.d.ts +10 -0
  14. package/dist/rules/array-style.js +96 -0
  15. package/dist/rules/consistent-import-source.cjs +73 -0
  16. package/dist/rules/consistent-import-source.d.cts +10 -0
  17. package/dist/rules/consistent-import-source.d.ts +10 -0
  18. package/dist/rules/consistent-import-source.js +70 -0
  19. package/dist/rules/consistent-object-schema-type.cjs +83 -0
  20. package/dist/rules/consistent-object-schema-type.d.cts +11 -0
  21. package/dist/rules/consistent-object-schema-type.d.ts +11 -0
  22. package/dist/rules/consistent-object-schema-type.js +80 -0
  23. package/dist/rules/no-any-schema.cjs +66 -0
  24. package/dist/rules/no-any-schema.d.cts +4 -0
  25. package/dist/rules/no-any-schema.d.ts +4 -0
  26. package/dist/rules/no-any-schema.js +63 -0
  27. package/dist/rules/no-empty-custom-schema.cjs +40 -0
  28. package/dist/rules/no-empty-custom-schema.d.cts +4 -0
  29. package/dist/rules/no-empty-custom-schema.d.ts +4 -0
  30. package/dist/rules/no-empty-custom-schema.js +37 -0
  31. package/dist/rules/no-number-schema-with-int.cjs +78 -0
  32. package/dist/rules/no-number-schema-with-int.d.cts +4 -0
  33. package/dist/rules/no-number-schema-with-int.d.ts +4 -0
  34. package/dist/rules/no-number-schema-with-int.js +75 -0
  35. package/dist/rules/no-optional-and-default-together.cjs +80 -0
  36. package/dist/rules/no-optional-and-default-together.d.cts +11 -0
  37. package/dist/rules/no-optional-and-default-together.d.ts +11 -0
  38. package/dist/rules/no-optional-and-default-together.js +77 -0
  39. package/dist/rules/no-throw-in-refine.cjs +84 -0
  40. package/dist/rules/no-throw-in-refine.d.cts +4 -0
  41. package/dist/rules/no-throw-in-refine.d.ts +4 -0
  42. package/dist/rules/no-throw-in-refine.js +81 -0
  43. package/dist/rules/no-unknown-schema.cjs +35 -0
  44. package/dist/rules/no-unknown-schema.d.cts +4 -0
  45. package/dist/rules/no-unknown-schema.d.ts +4 -0
  46. package/dist/rules/no-unknown-schema.js +32 -0
  47. package/dist/rules/prefer-enum-over-literal-union.cjs +72 -0
  48. package/dist/rules/prefer-enum-over-literal-union.d.cts +4 -0
  49. package/dist/rules/prefer-enum-over-literal-union.d.ts +4 -0
  50. package/dist/rules/prefer-enum-over-literal-union.js +69 -0
  51. package/dist/rules/prefer-meta-last.cjs +71 -0
  52. package/dist/rules/prefer-meta-last.d.cts +4 -0
  53. package/dist/rules/prefer-meta-last.d.ts +4 -0
  54. package/dist/rules/prefer-meta-last.js +68 -0
  55. package/dist/rules/prefer-meta.cjs +48 -0
  56. package/dist/rules/prefer-meta.d.cts +4 -0
  57. package/dist/rules/prefer-meta.d.ts +4 -0
  58. package/dist/rules/prefer-meta.js +45 -0
  59. package/dist/rules/prefer-namespace-import.cjs +145 -0
  60. package/dist/rules/prefer-namespace-import.d.cts +4 -0
  61. package/dist/rules/prefer-namespace-import.d.ts +4 -0
  62. package/dist/rules/prefer-namespace-import.js +142 -0
  63. package/dist/rules/require-brand-type-parameter.cjs +60 -0
  64. package/dist/rules/require-brand-type-parameter.d.cts +4 -0
  65. package/dist/rules/require-brand-type-parameter.d.ts +4 -0
  66. package/dist/rules/require-brand-type-parameter.js +57 -0
  67. package/dist/rules/require-error-message.cjs +101 -0
  68. package/dist/rules/require-error-message.d.cts +4 -0
  69. package/dist/rules/require-error-message.d.ts +4 -0
  70. package/dist/rules/require-error-message.js +98 -0
  71. package/dist/rules/require-schema-suffix.cjs +73 -0
  72. package/dist/rules/require-schema-suffix.d.cts +8 -0
  73. package/dist/rules/require-schema-suffix.d.ts +8 -0
  74. package/dist/rules/require-schema-suffix.js +70 -0
  75. package/dist/rules/schema-error-property-style.cjs +106 -0
  76. package/dist/rules/schema-error-property-style.d.cts +9 -0
  77. package/dist/rules/schema-error-property-style.d.ts +9 -0
  78. package/dist/rules/schema-error-property-style.js +100 -0
  79. package/dist/utils/detect-zod-schema-root-node.cjs +104 -0
  80. package/dist/utils/detect-zod-schema-root-node.d.cts +10 -0
  81. package/dist/utils/detect-zod-schema-root-node.d.ts +10 -0
  82. package/dist/utils/detect-zod-schema-root-node.js +101 -0
  83. package/dist/utils/get-outermost-call.cjs +14 -0
  84. package/dist/utils/get-outermost-call.d.cts +2 -0
  85. package/dist/utils/get-outermost-call.d.ts +2 -0
  86. package/dist/utils/get-outermost-call.js +11 -0
  87. package/dist/utils/is-zod-expression.cjs +14 -0
  88. package/dist/utils/is-zod-expression.d.cts +2 -0
  89. package/dist/utils/is-zod-expression.d.ts +2 -0
  90. package/dist/utils/is-zod-expression.js +11 -0
  91. package/dist/utils/is-zod-import-source.cjs +6 -0
  92. package/dist/utils/is-zod-import-source.d.cts +1 -0
  93. package/dist/utils/is-zod-import-source.d.ts +1 -0
  94. package/dist/utils/is-zod-import-source.js +3 -0
  95. package/dist/utils/track-zod-schema-imports.cjs +61 -0
  96. package/dist/utils/track-zod-schema-imports.d.cts +13 -0
  97. package/dist/utils/track-zod-schema-imports.d.ts +13 -0
  98. package/dist/utils/track-zod-schema-imports.js +58 -0
  99. package/package.json +82 -38
  100. package/dist/src/index.d.ts +0 -31
  101. package/dist/src/index.js +0 -14
  102. package/dist/src/rules/requireStrict.d.ts +0 -24
  103. package/dist/src/rules/requireStrict.js +0 -69
  104. package/tsconfig.json +0 -28
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const noNumberSchemaWithInt: ESLintUtils.RuleModule<"removeNumber", [], unknown, ESLintUtils.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const noNumberSchemaWithInt: ESLintUtils.RuleModule<"removeNumber", [], unknown, ESLintUtils.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,75 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ import { getRuleURL } from "../meta.js";
3
+ import { getOutermostCall } from "../utils/get-outermost-call.js";
4
+ import { trackZodSchemaImports } from "../utils/track-zod-schema-imports.js";
5
+ export const noNumberSchemaWithInt = ESLintUtils.RuleCreator(getRuleURL)({
6
+ name: 'no-number-schema-with-int',
7
+ meta: {
8
+ fixable: 'code',
9
+ type: 'problem',
10
+ docs: {
11
+ description: 'Disallow usage of `z.number().int()` as it is considered legacy',
12
+ },
13
+ messages: {
14
+ removeNumber: '`z.number().int()` is considered legacy. Use `z.int()` instead.',
15
+ },
16
+ schema: [],
17
+ },
18
+ defaultOptions: [],
19
+ create(context) {
20
+ const { sourceCode } = context;
21
+ const { importDeclarationListener, detectZodSchemaRootNode, collectZodChainMethods, } = trackZodSchemaImports();
22
+ return {
23
+ ImportDeclaration: importDeclarationListener,
24
+ 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) {
29
+ return;
30
+ }
31
+ if (zodSchemaMeta.schemaType !== 'number') {
32
+ return;
33
+ }
34
+ const methods = collectZodChainMethods(outer);
35
+ const numberIndex = methods.findIndex((m) => m.name === 'number');
36
+ const intIndex = methods.findIndex((m) => m.name === 'int');
37
+ if (numberIndex === -1 || intIndex === -1) {
38
+ return;
39
+ }
40
+ const numberMethod = methods[numberIndex];
41
+ const intMethod = methods[intIndex];
42
+ if (node !== intMethod.node) {
43
+ return;
44
+ }
45
+ if (zodSchemaMeta.schemaDecl === 'named') {
46
+ context.report({
47
+ node,
48
+ messageId: 'removeNumber',
49
+ });
50
+ return;
51
+ }
52
+ context.report({
53
+ node,
54
+ messageId: 'removeNumber',
55
+ fix(fixer) {
56
+ const numberNode = numberMethod.node;
57
+ const intNode = intMethod.node;
58
+ const numberCallee = numberNode.callee;
59
+ const prefixObj = numberCallee.object;
60
+ const prefixText = sourceCode.getText(prefixObj);
61
+ const methodsBetween = methods.slice(numberIndex + 1, intIndex);
62
+ const betweenSuffixes = methodsBetween.map((m) => {
63
+ const callee = m.node.callee;
64
+ const objText = sourceCode.getText(callee.object);
65
+ const fullText = sourceCode.getText(m.node);
66
+ return fullText.slice(objText.length);
67
+ });
68
+ const replacement = `${prefixText}.int()${betweenSuffixes.join('')}`;
69
+ return fixer.replaceTextRange([numberNode.range[0], intNode.range[1]], replacement);
70
+ },
71
+ });
72
+ },
73
+ };
74
+ },
75
+ });
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noOptionalAndDefaultTogether = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const meta_js_1 = require("../meta.cjs");
6
+ const track_zod_schema_imports_js_1 = require("../utils/track-zod-schema-imports.cjs");
7
+ const preferredMethods = ['none', 'default', 'optional'];
8
+ const defaultOptions = { preferredMethod: 'none' };
9
+ exports.noOptionalAndDefaultTogether = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
10
+ name: 'no-optional-and-default-together',
11
+ meta: {
12
+ type: 'problem',
13
+ fixable: 'code',
14
+ docs: {
15
+ description: 'Disallow using both `.optional()` and `.default()` on the same Zod schema',
16
+ },
17
+ messages: {
18
+ noOptionalAndDefaultTogether: 'Using both `.optional()` and `.default()` is redundant. A schema with a default value is already optional.',
19
+ noOptionalAndDefaultTogetherRemoveMethod: 'Using both `.optional()` and `.default()` is redundant. Remove the `.{{method}}()` method to avoid redundancy.',
20
+ },
21
+ schema: [
22
+ {
23
+ type: 'object',
24
+ properties: {
25
+ preferredMethod: {
26
+ description: 'Determines which method to keep when both are present',
27
+ type: 'string',
28
+ enum: [...preferredMethods],
29
+ },
30
+ },
31
+ additionalProperties: false,
32
+ },
33
+ ],
34
+ },
35
+ defaultOptions: [defaultOptions],
36
+ create(context, [{ preferredMethod }]) {
37
+ const { sourceCode } = context;
38
+ const { importDeclarationListener, detectZodSchemaRootNode: isZodSchema, collectZodChainMethods, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
39
+ return {
40
+ ImportDeclaration: importDeclarationListener,
41
+ CallExpression(node) {
42
+ if (!isZodSchema(node)) {
43
+ return;
44
+ }
45
+ const methods = collectZodChainMethods(node);
46
+ if (methods.length === 0) {
47
+ return;
48
+ }
49
+ const optionalMethod = methods.find((m) => m.name === 'optional');
50
+ const defaultMethod = methods.find((m) => m.name === 'default');
51
+ if (!optionalMethod || !defaultMethod) {
52
+ return;
53
+ }
54
+ const reportNode = methods.indexOf(optionalMethod) > methods.indexOf(defaultMethod)
55
+ ? optionalMethod.node
56
+ : defaultMethod.node;
57
+ if (preferredMethod === 'none') {
58
+ context.report({
59
+ node: reportNode,
60
+ messageId: 'noOptionalAndDefaultTogether',
61
+ });
62
+ return;
63
+ }
64
+ const methodToRemoveName = preferredMethod === 'default' ? 'optional' : 'default';
65
+ context.report({
66
+ node: reportNode,
67
+ messageId: 'noOptionalAndDefaultTogetherRemoveMethod',
68
+ data: { method: methodToRemoveName },
69
+ fix(fixer) {
70
+ const nodeToRemove = preferredMethod === 'default'
71
+ ? optionalMethod.node
72
+ : defaultMethod.node;
73
+ const calleeToRemove = nodeToRemove.callee;
74
+ return fixer.replaceText(nodeToRemove, sourceCode.getText(calleeToRemove.object));
75
+ },
76
+ });
77
+ },
78
+ };
79
+ },
80
+ });
@@ -0,0 +1,11 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ declare const preferredMethods: readonly ["none", "default", "optional"];
3
+ type PreferredMethod = (typeof preferredMethods)[number];
4
+ interface Options {
5
+ preferredMethod: PreferredMethod;
6
+ }
7
+ type MessageIds = 'noOptionalAndDefaultTogether' | 'noOptionalAndDefaultTogetherRemoveMethod';
8
+ export declare const noOptionalAndDefaultTogether: ESLintUtils.RuleModule<MessageIds, [Options], unknown, ESLintUtils.RuleListener> & {
9
+ name: string;
10
+ };
11
+ export {};
@@ -0,0 +1,11 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ declare const preferredMethods: readonly ["none", "default", "optional"];
3
+ type PreferredMethod = (typeof preferredMethods)[number];
4
+ interface Options {
5
+ preferredMethod: PreferredMethod;
6
+ }
7
+ type MessageIds = 'noOptionalAndDefaultTogether' | 'noOptionalAndDefaultTogetherRemoveMethod';
8
+ export declare const noOptionalAndDefaultTogether: ESLintUtils.RuleModule<MessageIds, [Options], unknown, ESLintUtils.RuleListener> & {
9
+ name: string;
10
+ };
11
+ export {};
@@ -0,0 +1,77 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ import { getRuleURL } from "../meta.js";
3
+ import { trackZodSchemaImports } from "../utils/track-zod-schema-imports.js";
4
+ const preferredMethods = ['none', 'default', 'optional'];
5
+ const defaultOptions = { preferredMethod: 'none' };
6
+ export const noOptionalAndDefaultTogether = ESLintUtils.RuleCreator(getRuleURL)({
7
+ name: 'no-optional-and-default-together',
8
+ meta: {
9
+ type: 'problem',
10
+ fixable: 'code',
11
+ docs: {
12
+ description: 'Disallow using both `.optional()` and `.default()` on the same Zod schema',
13
+ },
14
+ messages: {
15
+ noOptionalAndDefaultTogether: 'Using both `.optional()` and `.default()` is redundant. A schema with a default value is already optional.',
16
+ noOptionalAndDefaultTogetherRemoveMethod: 'Using both `.optional()` and `.default()` is redundant. Remove the `.{{method}}()` method to avoid redundancy.',
17
+ },
18
+ schema: [
19
+ {
20
+ type: 'object',
21
+ properties: {
22
+ preferredMethod: {
23
+ description: 'Determines which method to keep when both are present',
24
+ type: 'string',
25
+ enum: [...preferredMethods],
26
+ },
27
+ },
28
+ additionalProperties: false,
29
+ },
30
+ ],
31
+ },
32
+ defaultOptions: [defaultOptions],
33
+ create(context, [{ preferredMethod }]) {
34
+ const { sourceCode } = context;
35
+ const { importDeclarationListener, detectZodSchemaRootNode: isZodSchema, collectZodChainMethods, } = trackZodSchemaImports();
36
+ return {
37
+ ImportDeclaration: importDeclarationListener,
38
+ CallExpression(node) {
39
+ if (!isZodSchema(node)) {
40
+ return;
41
+ }
42
+ const methods = collectZodChainMethods(node);
43
+ if (methods.length === 0) {
44
+ return;
45
+ }
46
+ const optionalMethod = methods.find((m) => m.name === 'optional');
47
+ const defaultMethod = methods.find((m) => m.name === 'default');
48
+ if (!optionalMethod || !defaultMethod) {
49
+ return;
50
+ }
51
+ const reportNode = methods.indexOf(optionalMethod) > methods.indexOf(defaultMethod)
52
+ ? optionalMethod.node
53
+ : defaultMethod.node;
54
+ if (preferredMethod === 'none') {
55
+ context.report({
56
+ node: reportNode,
57
+ messageId: 'noOptionalAndDefaultTogether',
58
+ });
59
+ return;
60
+ }
61
+ const methodToRemoveName = preferredMethod === 'default' ? 'optional' : 'default';
62
+ context.report({
63
+ node: reportNode,
64
+ messageId: 'noOptionalAndDefaultTogetherRemoveMethod',
65
+ data: { method: methodToRemoveName },
66
+ fix(fixer) {
67
+ const nodeToRemove = preferredMethod === 'default'
68
+ ? optionalMethod.node
69
+ : defaultMethod.node;
70
+ const calleeToRemove = nodeToRemove.callee;
71
+ return fixer.replaceText(nodeToRemove, sourceCode.getText(calleeToRemove.object));
72
+ },
73
+ });
74
+ },
75
+ };
76
+ },
77
+ });
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noThrowInRefine = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const meta_js_1 = require("../meta.cjs");
6
+ const is_zod_expression_js_1 = require("../utils/is-zod-expression.cjs");
7
+ const track_zod_schema_imports_js_1 = require("../utils/track-zod-schema-imports.cjs");
8
+ exports.noThrowInRefine = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
9
+ name: 'no-throw-in-refine',
10
+ meta: {
11
+ type: 'problem',
12
+ docs: {
13
+ description: 'Disallow throwing errors directly inside Zod refine callbacks',
14
+ },
15
+ messages: {
16
+ noThrowInRefine: 'Do not throw errors directly inside a z.refine callback.',
17
+ },
18
+ schema: [],
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ const { importDeclarationListener, detectZodSchemaRootNode, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
23
+ function checkNode(node) {
24
+ if (!node) {
25
+ return;
26
+ }
27
+ switch (node.type) {
28
+ case utils_1.AST_NODE_TYPES.ThrowStatement:
29
+ context.report({ node, messageId: 'noThrowInRefine' });
30
+ break;
31
+ case utils_1.AST_NODE_TYPES.BlockStatement:
32
+ node.body.forEach(checkNode);
33
+ break;
34
+ case utils_1.AST_NODE_TYPES.IfStatement:
35
+ checkNode(node.consequent);
36
+ if (node.alternate) {
37
+ checkNode(node.alternate);
38
+ }
39
+ break;
40
+ case utils_1.AST_NODE_TYPES.ForStatement:
41
+ case utils_1.AST_NODE_TYPES.ForInStatement:
42
+ case utils_1.AST_NODE_TYPES.ForOfStatement:
43
+ case utils_1.AST_NODE_TYPES.WhileStatement:
44
+ case utils_1.AST_NODE_TYPES.DoWhileStatement:
45
+ checkNode(node.body);
46
+ break;
47
+ case utils_1.AST_NODE_TYPES.TryStatement:
48
+ checkNode(node.block);
49
+ if (node.handler) {
50
+ checkNode(node.handler.body);
51
+ }
52
+ if (node.finalizer) {
53
+ checkNode(node.finalizer);
54
+ }
55
+ break;
56
+ case utils_1.AST_NODE_TYPES.FunctionExpression:
57
+ case utils_1.AST_NODE_TYPES.ArrowFunctionExpression:
58
+ case utils_1.AST_NODE_TYPES.FunctionDeclaration:
59
+ return;
60
+ default:
61
+ if ('body' in node && Array.isArray(node.body)) {
62
+ node.body.forEach(checkNode);
63
+ }
64
+ break;
65
+ }
66
+ }
67
+ return {
68
+ ImportDeclaration: importDeclarationListener,
69
+ CallExpression(node) {
70
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
71
+ if (!zodSchemaMeta) {
72
+ return;
73
+ }
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
+ }
80
+ }
81
+ },
82
+ };
83
+ },
84
+ });
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const noThrowInRefine: ESLintUtils.RuleModule<"noThrowInRefine", [], unknown, ESLintUtils.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const noThrowInRefine: ESLintUtils.RuleModule<"noThrowInRefine", [], unknown, ESLintUtils.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,81 @@
1
+ import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';
2
+ import { getRuleURL } from "../meta.js";
3
+ import { isZodExpressionEndingWithMethod } from "../utils/is-zod-expression.js";
4
+ import { trackZodSchemaImports } from "../utils/track-zod-schema-imports.js";
5
+ export const noThrowInRefine = ESLintUtils.RuleCreator(getRuleURL)({
6
+ name: 'no-throw-in-refine',
7
+ meta: {
8
+ type: 'problem',
9
+ docs: {
10
+ description: 'Disallow throwing errors directly inside Zod refine callbacks',
11
+ },
12
+ messages: {
13
+ noThrowInRefine: 'Do not throw errors directly inside a z.refine callback.',
14
+ },
15
+ schema: [],
16
+ },
17
+ defaultOptions: [],
18
+ create(context) {
19
+ const { importDeclarationListener, detectZodSchemaRootNode, } = trackZodSchemaImports();
20
+ function checkNode(node) {
21
+ if (!node) {
22
+ return;
23
+ }
24
+ switch (node.type) {
25
+ case AST_NODE_TYPES.ThrowStatement:
26
+ context.report({ node, messageId: 'noThrowInRefine' });
27
+ break;
28
+ case AST_NODE_TYPES.BlockStatement:
29
+ node.body.forEach(checkNode);
30
+ break;
31
+ case AST_NODE_TYPES.IfStatement:
32
+ checkNode(node.consequent);
33
+ if (node.alternate) {
34
+ checkNode(node.alternate);
35
+ }
36
+ break;
37
+ case AST_NODE_TYPES.ForStatement:
38
+ case AST_NODE_TYPES.ForInStatement:
39
+ case AST_NODE_TYPES.ForOfStatement:
40
+ case AST_NODE_TYPES.WhileStatement:
41
+ case AST_NODE_TYPES.DoWhileStatement:
42
+ checkNode(node.body);
43
+ break;
44
+ case AST_NODE_TYPES.TryStatement:
45
+ checkNode(node.block);
46
+ if (node.handler) {
47
+ checkNode(node.handler.body);
48
+ }
49
+ if (node.finalizer) {
50
+ checkNode(node.finalizer);
51
+ }
52
+ break;
53
+ case AST_NODE_TYPES.FunctionExpression:
54
+ case AST_NODE_TYPES.ArrowFunctionExpression:
55
+ case AST_NODE_TYPES.FunctionDeclaration:
56
+ return;
57
+ default:
58
+ if ('body' in node && Array.isArray(node.body)) {
59
+ node.body.forEach(checkNode);
60
+ }
61
+ break;
62
+ }
63
+ }
64
+ return {
65
+ ImportDeclaration: importDeclarationListener,
66
+ CallExpression(node) {
67
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
68
+ if (!zodSchemaMeta) {
69
+ return;
70
+ }
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
+ }
77
+ }
78
+ },
79
+ };
80
+ },
81
+ });
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noUnknownSchema = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const meta_js_1 = require("../meta.cjs");
6
+ const track_zod_schema_imports_js_1 = require("../utils/track-zod-schema-imports.cjs");
7
+ exports.noUnknownSchema = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
8
+ name: 'no-unknown-schema',
9
+ meta: {
10
+ type: 'suggestion',
11
+ docs: {
12
+ description: 'Disallow usage of `z.unknown()` in Zod schemas',
13
+ },
14
+ messages: {
15
+ noZUnknown: 'Using `z.unknown()` is not allowed. Please use a more specific schema.',
16
+ },
17
+ schema: [],
18
+ },
19
+ defaultOptions: [],
20
+ create(context) {
21
+ const { importDeclarationListener, detectZodSchemaRootNode, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
22
+ return {
23
+ ImportDeclaration: importDeclarationListener,
24
+ CallExpression(node) {
25
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
26
+ if ((zodSchemaMeta === null || zodSchemaMeta === void 0 ? void 0 : zodSchemaMeta.schemaType) === 'unknown') {
27
+ context.report({
28
+ node,
29
+ messageId: 'noZUnknown',
30
+ });
31
+ }
32
+ },
33
+ };
34
+ },
35
+ });
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const noUnknownSchema: ESLintUtils.RuleModule<"noZUnknown", [], unknown, ESLintUtils.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const noUnknownSchema: ESLintUtils.RuleModule<"noZUnknown", [], unknown, ESLintUtils.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,32 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ import { getRuleURL } from "../meta.js";
3
+ import { trackZodSchemaImports } from "../utils/track-zod-schema-imports.js";
4
+ export const noUnknownSchema = ESLintUtils.RuleCreator(getRuleURL)({
5
+ name: 'no-unknown-schema',
6
+ meta: {
7
+ type: 'suggestion',
8
+ docs: {
9
+ description: 'Disallow usage of `z.unknown()` in Zod schemas',
10
+ },
11
+ messages: {
12
+ noZUnknown: 'Using `z.unknown()` is not allowed. Please use a more specific schema.',
13
+ },
14
+ schema: [],
15
+ },
16
+ defaultOptions: [],
17
+ create(context) {
18
+ const { importDeclarationListener, detectZodSchemaRootNode, } = trackZodSchemaImports();
19
+ return {
20
+ ImportDeclaration: importDeclarationListener,
21
+ CallExpression(node) {
22
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
23
+ if ((zodSchemaMeta === null || zodSchemaMeta === void 0 ? void 0 : zodSchemaMeta.schemaType) === 'unknown') {
24
+ context.report({
25
+ node,
26
+ messageId: 'noZUnknown',
27
+ });
28
+ }
29
+ },
30
+ };
31
+ },
32
+ });
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.preferEnumOverLiteralUnion = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const meta_js_1 = require("../meta.cjs");
6
+ const track_zod_schema_imports_js_1 = require("../utils/track-zod-schema-imports.cjs");
7
+ exports.preferEnumOverLiteralUnion = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
8
+ name: 'prefer-enum-over-literal-union',
9
+ meta: {
10
+ type: 'suggestion',
11
+ fixable: 'code',
12
+ docs: {
13
+ description: 'Prefer `z.enum()` over `z.union()` when all members are string literals.',
14
+ },
15
+ messages: {
16
+ useEnum: 'Replace this union of string literals with `z.enum()`.',
17
+ },
18
+ schema: [],
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ const { importDeclarationListener, detectZodSchemaRootNode, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
23
+ return {
24
+ ImportDeclaration: importDeclarationListener,
25
+ CallExpression(node) {
26
+ const zodSchema = detectZodSchemaRootNode(node);
27
+ if ((zodSchema === null || zodSchema === void 0 ? void 0 : zodSchema.schemaType) !== 'union') {
28
+ return;
29
+ }
30
+ const [unionArgument] = node.arguments;
31
+ if (unionArgument.type !== utils_1.AST_NODE_TYPES.ArrayExpression) {
32
+ return;
33
+ }
34
+ const zodLiteralStrings = unionArgument.elements.map((s) => {
35
+ if (!s) {
36
+ return null;
37
+ }
38
+ const maybeLiteralSchema = detectZodSchemaRootNode(s);
39
+ if ((maybeLiteralSchema === null || maybeLiteralSchema === void 0 ? void 0 : maybeLiteralSchema.schemaType) !== 'literal') {
40
+ return null;
41
+ }
42
+ const [literalArgument] = maybeLiteralSchema.node.arguments;
43
+ if (literalArgument.type === utils_1.AST_NODE_TYPES.Literal &&
44
+ typeof literalArgument.value === 'string') {
45
+ return literalArgument.raw;
46
+ }
47
+ return null;
48
+ });
49
+ if (zodLiteralStrings.some((it) => it === null)) {
50
+ return;
51
+ }
52
+ if (zodSchema.schemaDecl === 'named') {
53
+ context.report({
54
+ node,
55
+ messageId: 'useEnum',
56
+ });
57
+ return;
58
+ }
59
+ context.report({
60
+ node,
61
+ messageId: 'useEnum',
62
+ fix(fixer) {
63
+ return [
64
+ fixer.replaceText(node.callee.property, 'enum'),
65
+ fixer.replaceText(node.arguments[0], `[${zodLiteralStrings.join(', ')}]`),
66
+ ];
67
+ },
68
+ });
69
+ },
70
+ };
71
+ },
72
+ });
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const preferEnumOverLiteralUnion: ESLintUtils.RuleModule<"useEnum", [], unknown, ESLintUtils.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const preferEnumOverLiteralUnion: ESLintUtils.RuleModule<"useEnum", [], unknown, ESLintUtils.RuleListener> & {
3
+ name: string;
4
+ };