@longzai-intelligence-oxlint/zod-plugin 0.1.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 +17 -0
- package/dist/configs/recommended.d.ts +8 -0
- package/dist/configs/recommended.js +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +1 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @longzai-intelligence-oxlint/zod-plugin
|
|
2
|
+
|
|
3
|
+
## 意图
|
|
4
|
+
|
|
5
|
+
在静态检查阶段拦截 Zod v4 误用与 v3 兼容模式遗留写法,降低运行时校验失败与迁移成本。
|
|
6
|
+
|
|
7
|
+
## 定位
|
|
8
|
+
|
|
9
|
+
Oxlint 生态的 Zod 专属规则插件,通过 `eslintCompatPlugin` 包装以同时兼容 Oxlint 与 ESLint 运行时。
|
|
10
|
+
|
|
11
|
+
## 职能
|
|
12
|
+
|
|
13
|
+
提供覆盖 Schema 命名一致性、禁用 native enum、禁用 deepPartial、禁用 merge 方法、禁用 errors 属性、禁用 superrefine、推荐 safeParse、推荐 error 参数、推荐 enum 替代字面量联合、推荐顶层 string formats、推荐 zod namespace、禁用 number schema 的 int/finite/safe/step/isFinite/isInt、require-error-message 等共二十七条规则。
|
|
14
|
+
|
|
15
|
+
## 实现情况
|
|
16
|
+
|
|
17
|
+
二十七条规则已全部实现并按规则目录组织,每条规则独立导出,插件对象以 `@longzai-intelligence/zod` 名称注册;当前规则集合稳定,覆盖 Zod v4 主要最佳实践与 v3 兼容陷阱。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={"@longzai-intelligence-oxlint/zod-plugin/prefer-top-level-string-formats":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-number-schema-with-int":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-number-schema-with-finite":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-number-schema-with-safe":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-number-schema-with-step":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-number-schema-with-is-finite":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-number-schema-with-is-int":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-record-single-arg":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-deprecated-error-params":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-deprecated-format-methods":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-merge-method":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-superrefine":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-errors-property":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-deprecated-object-methods":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-native-enum":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-deep-partial":`error`,"@longzai-intelligence-oxlint/zod-plugin/no-promise-schema":`error`,"@longzai-intelligence-oxlint/zod-plugin/prefer-error-param":`error`,"@longzai-intelligence-oxlint/zod-plugin/prefer-zod-namespace":`warn`,"@longzai-intelligence-oxlint/zod-plugin/consistent-schema-var-name":`warn`,"@longzai-intelligence-oxlint/zod-plugin/no-any-schema":`warn`,"@longzai-intelligence-oxlint/zod-plugin/no-throw-in-refine":`warn`,"@longzai-intelligence-oxlint/zod-plugin/prefer-safe-parse":`warn`,"@longzai-intelligence-oxlint/zod-plugin/prefer-meta":`warn`,"@longzai-intelligence-oxlint/zod-plugin/require-error-message":`warn`,"@longzai-intelligence-oxlint/zod-plugin/no-optional-and-default-together":`error`,"@longzai-intelligence-oxlint/zod-plugin/prefer-enum-over-literal-union":`error`};export{e as recommended};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Zod v4 Oxlint 插件
|
|
4
|
+
*
|
|
5
|
+
* 提供 Zod v4 最佳实践和 v3 兼容模式误用检测规则,
|
|
6
|
+
* 通过 eslintCompatPlugin 包装以同时支持 Oxlint 和 ESLint 运行时
|
|
7
|
+
*/
|
|
8
|
+
declare const zodPlugin: import("@oxlint/plugins").Plugin;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { zodPlugin as default, zodPlugin };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineRule as e,eslintCompatPlugin as t}from"@oxlint/plugins";function n(e){return e.callee?.type===`MemberExpression`&&r(e.callee)}function r(e){return e.object?.type===`Identifier`&&e.object.name===`z`&&e.property?.type===`Identifier`}function i(e){if(e.callee?.type!==`MemberExpression`)return!1;let t=e.callee.object;for(;t.type===`CallExpression`;){if(n(t))return!0;if(t.callee?.type===`MemberExpression`)t=t.callee.object;else break}return t.type===`Identifier`&&t.name===`z`}function a(e){if(n(e)||i(e))return!0;if(e.callee?.type===`MemberExpression`&&e.callee.object?.type===`Identifier`){let t=e.callee.object.name.toLowerCase();return t.endsWith(`schema`)||t===`schema`||t===`validator`||t===`zodschema`}return!1}function o(e){if(e.property?.type===`Identifier`)return e.property.name}function s(e){if(e.type===`Identifier`){let t=e.name.toLowerCase();return t===`error`||t===`err`||t===`e`||t===`zoderror`||t===`validationerror`}return e.type===`MemberExpression`&&o(e)===`error`}const c=[`parse`,`parseAsync`,`safeParse`,`safeParseAsync`,`spa`,`encode`,`encodeAsync`,`decode`,`decodeAsync`,`safeEncode`,`safeEncodeAsync`,`safeDecode`,`safeDecodeAsync`,`codec`,`treeifyError`,`prettifyError`,`formatError`,`flattenError`];function l(e){let t=e;for(;t!==null;)if(t.type===`CallExpression`){if(n(t)){let e=t.callee.type===`MemberExpression`&&t.callee.property?.type===`Identifier`?t.callee.property.name:void 0;if(e&&!c.includes(e))return!0;break}if(i(t))return!0;if(t.callee?.type===`MemberExpression`)t=t.callee;else break}else if(t.type===`MemberExpression`)if(t.object?.type===`CallExpression`)t=t.object;else if(t.object?.type===`MemberExpression`)t=t.object;else break;else break;return!1}const u=e({meta:{type:`suggestion`,docs:{description:`强制 Zod schema 变量命名约定`}},createOnce(e){return{VariableDeclarator(t){if(t.id?.type!==`Identifier`)return;let n=t.init;if(n?.type!==`CallExpression`||!l(n))return;let r=t.id.name;r.endsWith(`Schema`)||e.report({node:t.id,message:`Zod schema 变量 "${r}" 应遵循命名约定:后缀 "Schema"。`})}}}}),d=e({meta:{type:`suggestion`,docs:{description:`禁止使用 z.any()`}},createOnce(e){return{CallExpression(t){t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`any`&&e.report({node:t,message:`禁止使用 z.any()。z.any() 不提供任何类型安全,请使用 z.unknown() 或更具体的类型替代。`})}}}}),f=e({meta:{type:`problem`,docs:{description:`禁止使用 .deepPartial()(Zod v4 已移除)`}},createOnce(e){return{CallExpression(t){if(t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`deepPartial`){if(!a(t))return;e.report({node:t,message:`禁止使用 .deepPartial()。Zod v4 中已移除,应手动实现深度可选。`})}}}}}),p=[`invalid_type_error`,`required_error`],m=e({meta:{type:`problem`,docs:{description:`禁止使用 invalid_type_error/required_error 参数`}},createOnce(e){return{CallExpression(t){if(t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`){for(let n of t.arguments||[])if(n?.type===`ObjectExpression`)for(let t of n.properties||[])t?.type===`Property`&&t.key?.type===`Identifier`&&p.includes(t.key.name)&&e.report({node:t,message:`禁止使用 ${t.key.name} 参数。Zod v4 中已移除,请使用 error 参数替代。`})}}}}}),h=[`format`,`flatten`],g=e({meta:{type:`problem`,docs:{description:`禁止在 ZodError 上使用 .format()/.flatten()(Zod v4 已移除)`}},createOnce(e){return{CallExpression(t){t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`&&h.includes(t.callee.property.name)&&s(t.callee.object)&&e.report({node:t,message:`禁止在 ZodError 上使用 .${t.callee.property.name}()。Zod v4 中已移除,请使用 z.treeifyError() 替代。`})}}}}),_={strict:`z.strictObject()`,passthrough:`z.looseObject()`,strip:`z.object(schema.shape)`},v=e({meta:{type:`problem`,docs:{description:`禁止使用 .strict()/.passthrough()/.strip()(Zod v4 已废弃)`}},createOnce(e){return{CallExpression(t){if(t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`){let n=t.callee.property.name;if(!Object.hasOwn(_,n)||!a(t))return;let r=_[n];e.report({node:t,message:`禁止使用 .${n}()。Zod v4 中已废弃,请使用 ${r} 替代。`})}}}}}),y=e({meta:{type:`problem`,docs:{description:`禁止访问 .errors 属性,推荐使用 .issues`}},createOnce(e){return{MemberExpression(t){t.property?.type===`Identifier`&&t.property.name===`errors`&&s(t.object)&&e.report({node:t,message:`禁止访问 .errors 属性。Zod v4 中已移除,请使用 .issues 替代。`})}}}}),b=e({meta:{type:`problem`,docs:{description:`禁止使用 .merge(),推荐使用 .extend()`}},createOnce(e){return{CallExpression(t){if(t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`merge`){if(!a(t))return;e.report({node:t,message:`禁止使用 .merge()。Zod v4 中已废弃,请使用 .extend() 或展开语法替代。`})}}}}}),x=e({meta:{type:`problem`,docs:{description:`禁止使用 z.nativeEnum(),推荐使用 z.enum()`}},createOnce(e){return{CallExpression(t){t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`nativeEnum`&&e.report({node:t,message:`禁止使用 z.nativeEnum()。Zod v4 中已废弃,请使用 z.enum() 替代。`})}}}});function S(e){let t=e.object;for(;t?.type===`CallExpression`;){if(t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`number`)return!0;if(t.callee?.type===`MemberExpression`)t=t.callee.object;else break}return!1}const C=e({meta:{type:`problem`,docs:{description:`禁止使用 .finite()(Zod v4 默认不允许无限值)`}},createOnce(e){return{CallExpression(t){t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`finite`&&S(t.callee)&&e.report({node:t,message:`禁止使用 .finite()。Zod v4 中 z.number() 默认不允许无限值,此方法已不再需要。`})}}}}),w=e({meta:{type:`problem`,docs:{description:`禁止使用 z.number().int(),推荐使用 z.int()`}},createOnce(e){return{CallExpression(t){if(t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`int`){let n=t.callee.object;n?.type===`CallExpression`&&n.callee?.type===`MemberExpression`&&n.callee.object?.type===`Identifier`&&n.callee.object.name===`z`&&n.callee.property?.type===`Identifier`&&n.callee.property.name===`number`&&e.report({node:t,message:`禁止使用 z.number().int()。Zod v4 中已废弃,请使用 z.int() 替代。`})}}}}});function T(e){let t=e;for(;t?.type===`CallExpression`;){if(t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`number`)return!0;if(t.callee?.type===`MemberExpression`)t=t.callee.object;else break}return!1}const E=e({meta:{type:`problem`,docs:{description:`禁止访问 .isFinite 属性(Zod v4 始终为 true)`}},createOnce(e){return{MemberExpression(t){if(t.property?.type===`Identifier`&&t.property.name===`isFinite`){let n=t.object;n?.type===`CallExpression`&&T(n)&&e.report({node:t,message:`禁止访问 .isFinite 属性。Zod v4 中此属性始终为 true,已无意义。`})}}}}});function D(e){let t=e;for(;t?.type===`CallExpression`;){if(t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`number`)return!0;if(t.callee?.type===`MemberExpression`)t=t.callee.object;else break}return!1}const O=e({meta:{type:`problem`,docs:{description:`禁止访问 .isInt 属性(Zod v4 已废弃)`}},createOnce(e){return{MemberExpression(t){if(t.property?.type===`Identifier`&&t.property.name===`isInt`){let n=t.object;n?.type===`CallExpression`&&D(n)&&e.report({node:t,message:`禁止访问 .isInt 属性。Zod v4 中已废弃,应检查 format 属性替代。`})}}}}});function k(e){let t=e.object;for(;t?.type===`CallExpression`;){if(t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`number`)return!0;if(t.callee?.type===`MemberExpression`)t=t.callee.object;else break}return!1}const A=e({meta:{type:`problem`,docs:{description:`禁止使用 .safe(),推荐使用 z.int()`}},createOnce(e){return{CallExpression(t){t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`safe`&&k(t.callee)&&e.report({node:t,message:`禁止使用 .safe()。Zod v4 中已废弃,请使用 z.int() 替代。`})}}}});function j(e){let t=e.object;for(;t?.type===`CallExpression`;){if(t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`number`)return!0;if(t.callee?.type===`MemberExpression`)t=t.callee.object;else break}return!1}const M=e({meta:{type:`problem`,docs:{description:`禁止使用 .step(),推荐使用 .multipleOf()`}},createOnce(e){return{CallExpression(t){t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`step`&&j(t.callee)&&e.report({node:t,message:`禁止使用 .step()。Zod v4 中已废弃,请使用 .multipleOf() 替代。`})}}}});function N(e){let t=[],n=e;for(;n!==null&&!(n.callee?.type!==`MemberExpression`||n.callee.property?.type!==`Identifier`||(t.push(n.callee.property.name),n.callee.object?.type!==`CallExpression`));)n=n.callee.object;return t}const P=e({meta:{type:`problem`,docs:{description:`禁止同时使用 .optional() 和 .default()`}},createOnce(e){return{CallExpression(t){if(t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`){if(!a(t))return;let n=N(t),r=n.includes(`optional`),i=n.includes(`default`);r&&i&&e.report({node:t,message:`禁止同时使用 .optional() 和 .default()。.default() 已隐含可选语义,请移除 .optional()。`})}}}}}),F=e({meta:{type:`problem`,docs:{description:`禁止使用 z.promise()`}},createOnce(e){return{CallExpression(t){t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`promise`&&e.report({node:t,message:`禁止使用 z.promise()。Zod v4 中已移除,应在解析前使用 await。`})}}}}),I=e({meta:{type:`problem`,docs:{description:`要求 z.record() 必须有两个参数`}},createOnce(e){return{CallExpression(t){t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`record`&&t.arguments?.length===1&&e.report({node:t,message:`z.record() 必须提供两个参数(key schema 和 value schema)。Zod v4 不再支持单参数形式。`})}}}}),L=e({meta:{type:`problem`,docs:{description:`禁止使用 .superRefine(),推荐使用 .check()`}},createOnce(e){return{CallExpression(t){if(t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`superRefine`){if(!a(t))return;e.report({node:t,message:`禁止使用 .superRefine()。Zod v4 中已废弃,请使用 .check() 替代。`})}}}}}),R=[`refine`,`superRefine`,`transform`],z=e({meta:{type:`problem`,docs:{description:`禁止在 refine 回调中使用 throw 语句`}},createOnce(e){return{ThrowStatement(t){let n=t.parent;for(;n;){if(n.type===`TryStatement`)return;if(n.type===`FunctionExpression`||n.type===`ArrowFunctionExpression`){let r=n.parent;if(r?.type===`CallExpression`&&r.callee?.type===`MemberExpression`&&r.callee.property?.type===`Identifier`&&R.includes(r.callee.property.name)){if(!a(r))return;let n={refine:`禁止在 .refine() 回调中使用 throw 语句。应返回 falsy 值来表示验证失败。`,superRefine:`禁止在 .superRefine() 回调中使用 throw 语句。应使用 ctx.addIssue() 报告错误。`,transform:`禁止在 .transform() 回调中使用 throw 语句。应使用 ctx.issues.push() 并返回 z.NEVER。`}[r.callee.property.name];n&&e.report({node:t,message:n})}return}if(n.type===`FunctionDeclaration`||n.type===`Program`)return;n=n.parent}}}}}),B=e({meta:{type:`suggestion`,docs:{description:`优先使用 z.enum() 替代全字符串字面量的 z.union()`}},createOnce(e){return{CallExpression(t){if(t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`union`){let n=t.arguments?.[0];if(n?.type!==`ArrayExpression`)return;let r=!0;for(let e of n.elements||[]){if(!e){r=!1;break}if(e.type!==`CallExpression`){r=!1;break}if(e.callee?.type!==`MemberExpression`||e.callee.object?.type!==`Identifier`||e.callee.object.name!==`z`||e.callee.property?.type!==`Identifier`||e.callee.property.name!==`literal`){r=!1;break}let t=e.arguments?.[0];if(t?.type!==`Literal`||typeof t.value!=`string`){r=!1;break}}r&&(n.elements?.length??0)>0&&e.report({node:t,message:`优先使用 z.enum() 替代全字符串字面量的 z.union()。`})}}}}}),V=e({meta:{type:`suggestion`,docs:{description:`推荐使用 error 参数替代 message 参数`}},createOnce(e){return{CallExpression(t){if(!(t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`object`)&&t.callee?.type===`MemberExpression`&&t.callee.object?.type===`Identifier`&&t.callee.object.name===`z`){for(let n of t.arguments||[])if(n?.type===`ObjectExpression`)for(let t of n.properties||[])t?.type===`Property`&&t.key?.type===`Identifier`&&t.key.name===`message`&&e.report({node:t,message:`推荐使用 error 参数替代 message 参数。Zod v4 中 message 参数已废弃。`})}}}}}),H=e({meta:{type:`suggestion`,docs:{description:`推荐使用 .meta() 替代 .describe()`}},createOnce(e){return{CallExpression(t){if(t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`describe`){if(!a(t))return;e.report({node:t,message:`推荐使用 .meta() 替代 .describe()。Zod v4 中 .describe() 已废弃,.meta() 提供更丰富的元数据支持。`})}}}}}),U=e({meta:{type:`suggestion`,docs:{description:`推荐使用 .safeParse() 替代 .parse()`}},createOnce(e){return{CallExpression(t){if(t.callee?.type===`MemberExpression`&&t.callee.property?.type===`Identifier`&&t.callee.property.name===`parse`){if(!a(t))return;e.report({node:t,message:`推荐使用 .safeParse() 替代 .parse()。.safeParse() 不会抛出异常,是更安全的验证方式。`})}}}}}),W={email:`email`,uuid:`uuid`,url:`url`,uri:`uri`,date:`date`,time:`time`,datetime:`datetime`,duration:`duration`,ipv4:`ipv4`,ipv6:`ipv6`,cidrv4:`cidrv4`,cidrv6:`cidrv6`,base64:`base64`,base64url:`base64url`,json:`json`,regex:`regex`,hostname:`hostname`},G=e({meta:{type:`suggestion`,docs:{description:`优先使用顶层字符串格式 schema 替代 z.string().<format>()`}},createOnce(e){return{CallExpression(t){if(t.callee?.type!==`MemberExpression`||t.callee.property?.type!==`Identifier`)return;let n=t.callee.property.name;if(!Object.hasOwn(W,n))return;let r=t.callee.object;if(r?.type===`CallExpression`&&r.callee?.type===`MemberExpression`&&r.callee.object?.type===`Identifier`&&r.callee.object.name===`z`&&r.callee.property?.type===`Identifier`&&r.callee.property.name===`string`){let r=W[n];e.report({node:t,message:`禁止使用 z.string().${n}()。Zod v4 中已废弃,请使用 z.${r}() 替代。`})}}}}}),K=e({meta:{type:`suggestion`,docs:{description:`强制使用命名空间导入 zod`}},createOnce(e){return{ImportDeclaration(t){let n=t.source?.value;if(!(n!==`zod`&&!n?.startsWith(`zod/`)))for(let n of t.specifiers||[])n.type===`ImportDefaultSpecifier`&&e.report({node:n,message:`请使用命名空间导入 zod(import * as z from "zod")代替默认导入。`}),n.type===`ImportSpecifier`&&n.imported?.type===`Identifier`&&n.imported.name===`z`&&e.report({node:n,message:`请使用命名空间导入 zod(import * as z from "zod")代替命名导入。`})}}}});function q(e){let t=e.callee?.type===`MemberExpression`&&e.callee.property?.type===`Identifier`&&e.callee.property.name===`refine`;if(t&&!a(e))return!1;let n=e.callee?.type===`MemberExpression`&&e.callee.object?.type===`Identifier`&&e.callee.object.name===`z`&&e.callee.property?.type===`Identifier`&&e.callee.property.name===`custom`;return t||n}function J(e,t){if(!e.arguments||e.arguments.length<2){t.report({node:e,message:`.refine() 和 z.custom() 必须包含错误消息(error 属性)。`});return}let n=e.arguments[1];if(!(n?.type===`Literal`&&typeof n.value==`string`)&&n?.type===`ObjectExpression`){let r=(n.properties||[]).some(e=>e?.type===`Property`&&e.key?.type===`Identifier`&&e.key.name===`error`),i=(n.properties||[]).some(e=>e?.type===`Property`&&e.key?.type===`Identifier`&&e.key.name===`message`);if(i&&!r){for(let e of n.properties||[])e?.type===`Property`&&e.key?.type===`Identifier`&&e.key.name===`message`&&t.report({node:e,message:`请将 message 属性替换为 error 属性。Zod v4 中 message 已废弃。`});return}!r&&!i&&t.report({node:e,message:`.refine() 和 z.custom() 必须包含错误消息(error 属性)。`})}}const Y=t({meta:{name:`@longzai-intelligence-oxlint/zod-plugin`},rules:{"no-native-enum":x,"no-promise-schema":F,"no-deep-partial":f,"no-record-single-arg":I,"no-merge-method":b,"no-errors-property":y,"no-deprecated-object-methods":v,"no-deprecated-format-methods":g,"no-deprecated-error-params":m,"no-superrefine":L,"prefer-safe-parse":U,"prefer-error-param":V,"no-throw-in-refine":z,"no-any-schema":d,"no-optional-and-default-together":P,"prefer-enum-over-literal-union":B,"prefer-meta":H,"require-error-message":e({meta:{type:`suggestion`,docs:{description:`要求 refine 包含错误消息`}},createOnce(e){return{CallExpression(t){q(t)&&J(t,e)}}}}),"consistent-schema-var-name":u,"prefer-top-level-string-formats":G,"prefer-zod-namespace":K,"no-number-schema-with-int":w,"no-number-schema-with-finite":C,"no-number-schema-with-safe":A,"no-number-schema-with-step":M,"no-number-schema-with-is-finite":E,"no-number-schema-with-is-int":O}});export{Y as default,Y as zodPlugin};
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@longzai-intelligence-oxlint/zod-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Zod v4 Oxlint 插件,提供 Zod v4 最佳实践和 v3 兼容模式误用检测",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./configs/recommended": {
|
|
18
|
+
"types": "./dist/configs/recommended.d.ts",
|
|
19
|
+
"import": "./dist/configs/recommended.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "lzi-builder",
|
|
24
|
+
"build:prod": "NODE_ENV=production lzi-builder",
|
|
25
|
+
"prepublishOnly": "bun run build:prod",
|
|
26
|
+
"dev": "lzi-builder --watch",
|
|
27
|
+
"clean": "rimraf dist",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"test:coverage": "vitest run --coverage",
|
|
31
|
+
"lint": "oxlint && oxfmt --check",
|
|
32
|
+
"lint:fix": "oxlint --fix && oxfmt",
|
|
33
|
+
"typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
|
|
34
|
+
"typecheck:app": "tsgo --noEmit -p tsconfig/app.json",
|
|
35
|
+
"typecheck:node": "tsgo --noEmit -p tsconfig/node.json",
|
|
36
|
+
"typecheck:test": "tsgo --noEmit -p tsconfig/test.json"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@longzai-intelligence-oxlint/core": "0.1.0",
|
|
40
|
+
"@oxlint/plugins": "^1.74.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
44
|
+
"typescript": "^6.0.3"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"oxlint": ">=1.0.0"
|
|
48
|
+
}
|
|
49
|
+
}
|