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,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.consistentImportSource = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const meta_js_1 = require("../meta.cjs");
6
+ const ZOD_IMPORT_SOURCES = [
7
+ 'zod',
8
+ 'zod/mini',
9
+ 'zod/v4',
10
+ 'zod/v4-mini',
11
+ 'zod/v3',
12
+ ];
13
+ exports.consistentImportSource = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
14
+ name: 'consistent-import-source',
15
+ meta: {
16
+ hasSuggestions: true,
17
+ type: 'suggestion',
18
+ docs: {
19
+ description: 'Enforce consistent source from Zod imports',
20
+ },
21
+ messages: {
22
+ sourceNotAllowed: '"{{source}}" is not allowed. Available values are: {{sources}}',
23
+ replaceSource: 'Replace "{{invalid}}" with "{{valid}}"',
24
+ },
25
+ schema: [
26
+ {
27
+ type: 'object',
28
+ properties: {
29
+ sources: {
30
+ type: 'array',
31
+ description: 'An array of allowed Zod import sources.',
32
+ items: {
33
+ type: 'string',
34
+ enum: [...ZOD_IMPORT_SOURCES],
35
+ },
36
+ minItems: 1,
37
+ uniqueItems: true,
38
+ },
39
+ },
40
+ additionalProperties: false,
41
+ },
42
+ ],
43
+ },
44
+ defaultOptions: [{ sources: ['zod'] }],
45
+ create(context, [{ sources }]) {
46
+ return {
47
+ ImportDeclaration(node) {
48
+ const sourceValue = node.source.value;
49
+ if (!sourceValue.startsWith('zod')) {
50
+ return;
51
+ }
52
+ if (sources.includes(sourceValue)) {
53
+ return;
54
+ }
55
+ context.report({
56
+ node,
57
+ messageId: 'sourceNotAllowed',
58
+ data: {
59
+ source: sourceValue,
60
+ sources: sources.map((s) => `"${s}"`).join(', '),
61
+ },
62
+ suggest: sources.map((it) => ({
63
+ messageId: 'replaceSource',
64
+ data: { valid: it, invalid: sourceValue },
65
+ fix(fixer) {
66
+ return fixer.replaceText(node.source, node.source.raw.replace(sourceValue, it));
67
+ },
68
+ })),
69
+ });
70
+ },
71
+ };
72
+ },
73
+ });
@@ -0,0 +1,10 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ declare const ZOD_IMPORT_SOURCES: readonly ["zod", "zod/mini", "zod/v4", "zod/v4-mini", "zod/v3"];
3
+ type ZodImportSource = (typeof ZOD_IMPORT_SOURCES)[number];
4
+ type MessageIds = 'sourceNotAllowed' | 'replaceSource';
5
+ export declare const consistentImportSource: TSESLint.RuleModule<MessageIds, [{
6
+ sources: Array<ZodImportSource>;
7
+ }], unknown, TSESLint.RuleListener> & {
8
+ name: string;
9
+ };
10
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ declare const ZOD_IMPORT_SOURCES: readonly ["zod", "zod/mini", "zod/v4", "zod/v4-mini", "zod/v3"];
3
+ type ZodImportSource = (typeof ZOD_IMPORT_SOURCES)[number];
4
+ type MessageIds = 'sourceNotAllowed' | 'replaceSource';
5
+ export declare const consistentImportSource: TSESLint.RuleModule<MessageIds, [{
6
+ sources: Array<ZodImportSource>;
7
+ }], unknown, TSESLint.RuleListener> & {
8
+ name: string;
9
+ };
10
+ export {};
@@ -0,0 +1,70 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ import { getRuleURL } from "../meta.js";
3
+ const ZOD_IMPORT_SOURCES = [
4
+ 'zod',
5
+ 'zod/mini',
6
+ 'zod/v4',
7
+ 'zod/v4-mini',
8
+ 'zod/v3',
9
+ ];
10
+ export const consistentImportSource = ESLintUtils.RuleCreator(getRuleURL)({
11
+ name: 'consistent-import-source',
12
+ meta: {
13
+ hasSuggestions: true,
14
+ type: 'suggestion',
15
+ docs: {
16
+ description: 'Enforce consistent source from Zod imports',
17
+ },
18
+ messages: {
19
+ sourceNotAllowed: '"{{source}}" is not allowed. Available values are: {{sources}}',
20
+ replaceSource: 'Replace "{{invalid}}" with "{{valid}}"',
21
+ },
22
+ schema: [
23
+ {
24
+ type: 'object',
25
+ properties: {
26
+ sources: {
27
+ type: 'array',
28
+ description: 'An array of allowed Zod import sources.',
29
+ items: {
30
+ type: 'string',
31
+ enum: [...ZOD_IMPORT_SOURCES],
32
+ },
33
+ minItems: 1,
34
+ uniqueItems: true,
35
+ },
36
+ },
37
+ additionalProperties: false,
38
+ },
39
+ ],
40
+ },
41
+ defaultOptions: [{ sources: ['zod'] }],
42
+ create(context, [{ sources }]) {
43
+ return {
44
+ ImportDeclaration(node) {
45
+ const sourceValue = node.source.value;
46
+ if (!sourceValue.startsWith('zod')) {
47
+ return;
48
+ }
49
+ if (sources.includes(sourceValue)) {
50
+ return;
51
+ }
52
+ context.report({
53
+ node,
54
+ messageId: 'sourceNotAllowed',
55
+ data: {
56
+ source: sourceValue,
57
+ sources: sources.map((s) => `"${s}"`).join(', '),
58
+ },
59
+ suggest: sources.map((it) => ({
60
+ messageId: 'replaceSource',
61
+ data: { valid: it, invalid: sourceValue },
62
+ fix(fixer) {
63
+ return fixer.replaceText(node.source, node.source.raw.replace(sourceValue, it));
64
+ },
65
+ })),
66
+ });
67
+ },
68
+ };
69
+ },
70
+ });
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.consistentObjectSchemaType = 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 ZOD_OBJECT_METHODS = ['object', 'looseObject', 'strictObject'];
8
+ const defaultOptions = { allow: ['object'] };
9
+ exports.consistentObjectSchemaType = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
10
+ name: 'consistent-object-schema-type',
11
+ meta: {
12
+ hasSuggestions: true,
13
+ type: 'suggestion',
14
+ docs: {
15
+ description: 'Enforce consistent usage of Zod schema methods',
16
+ },
17
+ messages: {
18
+ consistentMethod: "Inconsistent Zod object schema method '{{actual}}'. Allowed: {{allowedList}}.",
19
+ useMethod: "Replace with '{{expected}}'.",
20
+ },
21
+ schema: [
22
+ {
23
+ type: 'object',
24
+ properties: {
25
+ allow: {
26
+ type: 'array',
27
+ description: 'Decides which object methods are allowed',
28
+ items: {
29
+ type: 'string',
30
+ enum: [...ZOD_OBJECT_METHODS],
31
+ },
32
+ minItems: 1,
33
+ uniqueItems: true,
34
+ },
35
+ },
36
+ additionalProperties: false,
37
+ },
38
+ ],
39
+ },
40
+ defaultOptions: [defaultOptions],
41
+ create(context, [{ allow: allowedList }]) {
42
+ const { importDeclarationListener, detectZodSchemaRootNode, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
43
+ return {
44
+ ImportDeclaration: importDeclarationListener,
45
+ CallExpression(node) {
46
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
47
+ const schemaType = zodSchemaMeta === null || zodSchemaMeta === void 0 ? void 0 : zodSchemaMeta.schemaType;
48
+ if (!schemaType || !ZOD_OBJECT_METHODS.includes(schemaType)) {
49
+ return;
50
+ }
51
+ if (allowedList.includes(schemaType)) {
52
+ return;
53
+ }
54
+ const { callee } = node;
55
+ if (callee.type === utils_1.AST_NODE_TYPES.Identifier) {
56
+ context.report({
57
+ node,
58
+ messageId: 'consistentMethod',
59
+ data: { actual: schemaType, allowedList: allowedList.join(',') },
60
+ });
61
+ return;
62
+ }
63
+ if (callee.type === utils_1.AST_NODE_TYPES.MemberExpression) {
64
+ context.report({
65
+ node,
66
+ messageId: 'consistentMethod',
67
+ data: {
68
+ actual: schemaType,
69
+ allowedList: allowedList.join(','),
70
+ },
71
+ suggest: allowedList.map((it) => ({
72
+ messageId: 'useMethod',
73
+ data: { expected: it },
74
+ fix(fixer) {
75
+ return fixer.replaceText(callee.property, it);
76
+ },
77
+ })),
78
+ });
79
+ }
80
+ },
81
+ };
82
+ },
83
+ });
@@ -0,0 +1,11 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ declare const ZOD_OBJECT_METHODS: readonly ["object", "looseObject", "strictObject"];
3
+ type ZodObjectMethod = (typeof ZOD_OBJECT_METHODS)[number];
4
+ interface Options {
5
+ allow: Array<ZodObjectMethod>;
6
+ }
7
+ type MessageIds = 'consistentMethod' | 'useMethod';
8
+ export declare const consistentObjectSchemaType: TSESLint.RuleModule<MessageIds, [Options], unknown, TSESLint.RuleListener> & {
9
+ name: string;
10
+ };
11
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ declare const ZOD_OBJECT_METHODS: readonly ["object", "looseObject", "strictObject"];
3
+ type ZodObjectMethod = (typeof ZOD_OBJECT_METHODS)[number];
4
+ interface Options {
5
+ allow: Array<ZodObjectMethod>;
6
+ }
7
+ type MessageIds = 'consistentMethod' | 'useMethod';
8
+ export declare const consistentObjectSchemaType: TSESLint.RuleModule<MessageIds, [Options], unknown, TSESLint.RuleListener> & {
9
+ name: string;
10
+ };
11
+ export {};
@@ -0,0 +1,80 @@
1
+ import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';
2
+ import { getRuleURL } from "../meta.js";
3
+ import { trackZodSchemaImports } from "../utils/track-zod-schema-imports.js";
4
+ const ZOD_OBJECT_METHODS = ['object', 'looseObject', 'strictObject'];
5
+ const defaultOptions = { allow: ['object'] };
6
+ export const consistentObjectSchemaType = ESLintUtils.RuleCreator(getRuleURL)({
7
+ name: 'consistent-object-schema-type',
8
+ meta: {
9
+ hasSuggestions: true,
10
+ type: 'suggestion',
11
+ docs: {
12
+ description: 'Enforce consistent usage of Zod schema methods',
13
+ },
14
+ messages: {
15
+ consistentMethod: "Inconsistent Zod object schema method '{{actual}}'. Allowed: {{allowedList}}.",
16
+ useMethod: "Replace with '{{expected}}'.",
17
+ },
18
+ schema: [
19
+ {
20
+ type: 'object',
21
+ properties: {
22
+ allow: {
23
+ type: 'array',
24
+ description: 'Decides which object methods are allowed',
25
+ items: {
26
+ type: 'string',
27
+ enum: [...ZOD_OBJECT_METHODS],
28
+ },
29
+ minItems: 1,
30
+ uniqueItems: true,
31
+ },
32
+ },
33
+ additionalProperties: false,
34
+ },
35
+ ],
36
+ },
37
+ defaultOptions: [defaultOptions],
38
+ create(context, [{ allow: allowedList }]) {
39
+ const { importDeclarationListener, detectZodSchemaRootNode, } = trackZodSchemaImports();
40
+ return {
41
+ ImportDeclaration: importDeclarationListener,
42
+ CallExpression(node) {
43
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
44
+ const schemaType = zodSchemaMeta === null || zodSchemaMeta === void 0 ? void 0 : zodSchemaMeta.schemaType;
45
+ if (!schemaType || !ZOD_OBJECT_METHODS.includes(schemaType)) {
46
+ return;
47
+ }
48
+ if (allowedList.includes(schemaType)) {
49
+ return;
50
+ }
51
+ const { callee } = node;
52
+ if (callee.type === AST_NODE_TYPES.Identifier) {
53
+ context.report({
54
+ node,
55
+ messageId: 'consistentMethod',
56
+ data: { actual: schemaType, allowedList: allowedList.join(',') },
57
+ });
58
+ return;
59
+ }
60
+ if (callee.type === AST_NODE_TYPES.MemberExpression) {
61
+ context.report({
62
+ node,
63
+ messageId: 'consistentMethod',
64
+ data: {
65
+ actual: schemaType,
66
+ allowedList: allowedList.join(','),
67
+ },
68
+ suggest: allowedList.map((it) => ({
69
+ messageId: 'useMethod',
70
+ data: { expected: it },
71
+ fix(fixer) {
72
+ return fixer.replaceText(callee.property, it);
73
+ },
74
+ })),
75
+ });
76
+ }
77
+ },
78
+ };
79
+ },
80
+ });
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noAnySchema = 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.noAnySchema = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
8
+ name: 'no-any-schema',
9
+ meta: {
10
+ hasSuggestions: true,
11
+ type: 'suggestion',
12
+ docs: {
13
+ description: 'Disallow usage of `z.any()` in Zod schemas',
14
+ },
15
+ messages: {
16
+ noZAny: 'Using `z.any()` is not allowed. Please use a more specific schema.',
17
+ useUnknown: 'Replace `z.any()` with `z.unknown()`',
18
+ },
19
+ schema: [],
20
+ },
21
+ defaultOptions: [],
22
+ create(context) {
23
+ const { importDeclarationListener, detectZodSchemaRootNode, collectZodChainMethods, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
24
+ return {
25
+ ImportDeclaration: importDeclarationListener,
26
+ CallExpression(node) {
27
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
28
+ if ((zodSchemaMeta === null || zodSchemaMeta === void 0 ? void 0 : zodSchemaMeta.schemaType) !== 'any') {
29
+ return;
30
+ }
31
+ const { callee } = node;
32
+ if (callee.type === utils_1.AST_NODE_TYPES.Identifier) {
33
+ context.report({
34
+ node,
35
+ messageId: 'noZAny',
36
+ });
37
+ return;
38
+ }
39
+ if (callee.type === utils_1.AST_NODE_TYPES.MemberExpression) {
40
+ const [{ node: schemaMethod }] = collectZodChainMethods(node);
41
+ const schemaMethodCallee = schemaMethod.callee;
42
+ if (schemaMethodCallee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
43
+ schemaMethodCallee.property.type === utils_1.AST_NODE_TYPES.Identifier) {
44
+ context.report({
45
+ node,
46
+ messageId: 'noZAny',
47
+ suggest: [
48
+ {
49
+ messageId: 'useUnknown',
50
+ fix(fixer) {
51
+ return fixer.replaceText(schemaMethodCallee.property, 'unknown');
52
+ },
53
+ },
54
+ ],
55
+ });
56
+ return;
57
+ }
58
+ context.report({
59
+ node,
60
+ messageId: 'noZAny',
61
+ });
62
+ }
63
+ },
64
+ };
65
+ },
66
+ });
@@ -0,0 +1,4 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ export declare const noAnySchema: TSESLint.RuleModule<"noZAny" | "useUnknown", [], unknown, TSESLint.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,4 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ export declare const noAnySchema: TSESLint.RuleModule<"noZAny" | "useUnknown", [], unknown, TSESLint.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,63 @@
1
+ import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';
2
+ import { getRuleURL } from "../meta.js";
3
+ import { trackZodSchemaImports } from "../utils/track-zod-schema-imports.js";
4
+ export const noAnySchema = ESLintUtils.RuleCreator(getRuleURL)({
5
+ name: 'no-any-schema',
6
+ meta: {
7
+ hasSuggestions: true,
8
+ type: 'suggestion',
9
+ docs: {
10
+ description: 'Disallow usage of `z.any()` in Zod schemas',
11
+ },
12
+ messages: {
13
+ noZAny: 'Using `z.any()` is not allowed. Please use a more specific schema.',
14
+ useUnknown: 'Replace `z.any()` with `z.unknown()`',
15
+ },
16
+ schema: [],
17
+ },
18
+ defaultOptions: [],
19
+ create(context) {
20
+ const { importDeclarationListener, detectZodSchemaRootNode, collectZodChainMethods, } = trackZodSchemaImports();
21
+ return {
22
+ ImportDeclaration: importDeclarationListener,
23
+ CallExpression(node) {
24
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
25
+ if ((zodSchemaMeta === null || zodSchemaMeta === void 0 ? void 0 : zodSchemaMeta.schemaType) !== 'any') {
26
+ return;
27
+ }
28
+ const { callee } = node;
29
+ if (callee.type === AST_NODE_TYPES.Identifier) {
30
+ context.report({
31
+ node,
32
+ messageId: 'noZAny',
33
+ });
34
+ return;
35
+ }
36
+ if (callee.type === AST_NODE_TYPES.MemberExpression) {
37
+ const [{ node: schemaMethod }] = collectZodChainMethods(node);
38
+ const schemaMethodCallee = schemaMethod.callee;
39
+ if (schemaMethodCallee.type === AST_NODE_TYPES.MemberExpression &&
40
+ schemaMethodCallee.property.type === AST_NODE_TYPES.Identifier) {
41
+ context.report({
42
+ node,
43
+ messageId: 'noZAny',
44
+ suggest: [
45
+ {
46
+ messageId: 'useUnknown',
47
+ fix(fixer) {
48
+ return fixer.replaceText(schemaMethodCallee.property, 'unknown');
49
+ },
50
+ },
51
+ ],
52
+ });
53
+ return;
54
+ }
55
+ context.report({
56
+ node,
57
+ messageId: 'noZAny',
58
+ });
59
+ }
60
+ },
61
+ };
62
+ },
63
+ });
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noEmptyCustomSchema = 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.noEmptyCustomSchema = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
8
+ name: 'no-empty-custom-schema',
9
+ meta: {
10
+ hasSuggestions: false,
11
+ type: 'suggestion',
12
+ docs: {
13
+ description: 'Disallow usage of `z.custom()` without arguments',
14
+ },
15
+ messages: {
16
+ noEmptyCustomSchema: 'You should provide a validate function within `z.custom()`',
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 zodSchemaMeta = detectZodSchemaRootNode(node);
27
+ if (!zodSchemaMeta) {
28
+ return;
29
+ }
30
+ if (zodSchemaMeta.schemaType === 'custom' &&
31
+ node.arguments.length === 0) {
32
+ context.report({
33
+ node,
34
+ messageId: 'noEmptyCustomSchema',
35
+ });
36
+ }
37
+ },
38
+ };
39
+ },
40
+ });
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const noEmptyCustomSchema: ESLintUtils.RuleModule<"noEmptyCustomSchema", [], unknown, ESLintUtils.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const noEmptyCustomSchema: ESLintUtils.RuleModule<"noEmptyCustomSchema", [], unknown, ESLintUtils.RuleListener> & {
3
+ name: string;
4
+ };
@@ -0,0 +1,37 @@
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 noEmptyCustomSchema = ESLintUtils.RuleCreator(getRuleURL)({
5
+ name: 'no-empty-custom-schema',
6
+ meta: {
7
+ hasSuggestions: false,
8
+ type: 'suggestion',
9
+ docs: {
10
+ description: 'Disallow usage of `z.custom()` without arguments',
11
+ },
12
+ messages: {
13
+ noEmptyCustomSchema: 'You should provide a validate function within `z.custom()`',
14
+ },
15
+ schema: [],
16
+ },
17
+ defaultOptions: [],
18
+ create(context) {
19
+ const { importDeclarationListener, detectZodSchemaRootNode, } = trackZodSchemaImports();
20
+ return {
21
+ ImportDeclaration: importDeclarationListener,
22
+ CallExpression(node) {
23
+ const zodSchemaMeta = detectZodSchemaRootNode(node);
24
+ if (!zodSchemaMeta) {
25
+ return;
26
+ }
27
+ if (zodSchemaMeta.schemaType === 'custom' &&
28
+ node.arguments.length === 0) {
29
+ context.report({
30
+ node,
31
+ messageId: 'noEmptyCustomSchema',
32
+ });
33
+ }
34
+ },
35
+ };
36
+ },
37
+ });
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noNumberSchemaWithInt = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const meta_js_1 = require("../meta.cjs");
6
+ const get_outermost_call_js_1 = require("../utils/get-outermost-call.cjs");
7
+ const track_zod_schema_imports_js_1 = require("../utils/track-zod-schema-imports.cjs");
8
+ exports.noNumberSchemaWithInt = utils_1.ESLintUtils.RuleCreator(meta_js_1.getRuleURL)({
9
+ name: 'no-number-schema-with-int',
10
+ meta: {
11
+ fixable: 'code',
12
+ type: 'problem',
13
+ docs: {
14
+ description: 'Disallow usage of `z.number().int()` as it is considered legacy',
15
+ },
16
+ messages: {
17
+ removeNumber: '`z.number().int()` is considered legacy. Use `z.int()` instead.',
18
+ },
19
+ schema: [],
20
+ },
21
+ defaultOptions: [],
22
+ create(context) {
23
+ const { sourceCode } = context;
24
+ const { importDeclarationListener, detectZodSchemaRootNode, collectZodChainMethods, } = (0, track_zod_schema_imports_js_1.trackZodSchemaImports)();
25
+ return {
26
+ ImportDeclaration: importDeclarationListener,
27
+ 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) {
32
+ return;
33
+ }
34
+ if (zodSchemaMeta.schemaType !== 'number') {
35
+ return;
36
+ }
37
+ const methods = collectZodChainMethods(outer);
38
+ const numberIndex = methods.findIndex((m) => m.name === 'number');
39
+ const intIndex = methods.findIndex((m) => m.name === 'int');
40
+ if (numberIndex === -1 || intIndex === -1) {
41
+ return;
42
+ }
43
+ const numberMethod = methods[numberIndex];
44
+ const intMethod = methods[intIndex];
45
+ if (node !== intMethod.node) {
46
+ return;
47
+ }
48
+ if (zodSchemaMeta.schemaDecl === 'named') {
49
+ context.report({
50
+ node,
51
+ messageId: 'removeNumber',
52
+ });
53
+ return;
54
+ }
55
+ context.report({
56
+ node,
57
+ messageId: 'removeNumber',
58
+ fix(fixer) {
59
+ const numberNode = numberMethod.node;
60
+ const intNode = intMethod.node;
61
+ const numberCallee = numberNode.callee;
62
+ const prefixObj = numberCallee.object;
63
+ const prefixText = sourceCode.getText(prefixObj);
64
+ const methodsBetween = methods.slice(numberIndex + 1, intIndex);
65
+ const betweenSuffixes = methodsBetween.map((m) => {
66
+ const callee = m.node.callee;
67
+ const objText = sourceCode.getText(callee.object);
68
+ const fullText = sourceCode.getText(m.node);
69
+ return fullText.slice(objText.length);
70
+ });
71
+ const replacement = `${prefixText}.int()${betweenSuffixes.join('')}`;
72
+ return fixer.replaceTextRange([numberNode.range[0], intNode.range[1]], replacement);
73
+ },
74
+ });
75
+ },
76
+ };
77
+ },
78
+ });