@longzai-intelligence-oxlint/nestjs-route-plugin 0.1.37 → 0.1.39

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 (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{defineRule as e,eslintCompatPlugin as t}from"@oxlint/plugins";function n(e){return typeof e==`object`&&!!e}function r(e){return n(e)&&`typeAnnotation`in e}function i(e){return n(e)&&`typeName`in e}function a(e){return n(e)&&`typeParameters`in e}function o(e){return n(e)&&`params`in e}function s(e){return n(e)&&`name`in e}function c(e){return n(e)&&`left`in e&&`right`in e}function l(e){return n(e)&&`type`in e}function u(e){return n(e)&&`exprName`in e}function d(e){return e.type!==`CallExpression`||e.callee.type!==`Identifier`?!1:e.callee.name===`defineHandler`}function f(e){if(e.type!==`ObjectPattern`)return[];let t=[];for(let n of e.properties)n.type===`Property`?n.key.type===`Identifier`&&t.push(n.key.name):n.type===`RestElement`&&n.argument.type===`Identifier`&&t.push(n.argument.name);return t}function p(e){if(e.type!==`MethodDefinition`||!(`decorators`in e)||!e.decorators)return!1;for(let t of e.decorators){let e=t.expression;if(e.type===`CallExpression`&&e.callee.type===`Identifier`&&e.callee.name===`TypedHandle`)return!0}return!1}function m(e,t){return!e||e.type!==`CallExpression`||e.callee.type!==`Identifier`?!1:t.includes(e.callee.name)}function h(e){if(e.type!==`BlockStatement`)return!1;for(let t of e.body)if(t.type===`ReturnStatement`&&t.argument!==null)return!0;return!1}const g=[`typedResponse`,`typedEmpty`];function _(e){if(!r(e))return!1;let t=e.typeAnnotation;if(!n(t))return!1;if(i(t)){let e=t.typeName;if(s(e)&&e.name===`InferRouteReturn`)return!0}if(a(t)){let e=t.typeParameters;if(o(e)){let t=e.params;for(let e of t)if(i(e)){let t=e.typeName;if(s(t)&&t.name===`InferRouteReturn`)return!0}}}return!1}function v(e){if(!r(e))return`unknown`;let t=e.typeAnnotation;if(!n(t)||!i(t))return`unknown`;let a=t.typeName;if(s(a)&&typeof a.name==`string`)return a.name;if(c(a)){let e=a.left,t=a.right;if(s(e)&&s(t)){let n=e.name,r=t.name;if(typeof n==`string`&&typeof r==`string`)return`${n}.${r}`}}return`unknown`}function y(e){if(!r(e))return!1;let t=e.typeAnnotation;if(!i(t))return!1;let n=t,c=n.typeName;if(!s(c)||c.name!==`Parameters`||!a(n))return!1;let d=n.typeParameters;if(!o(d))return!1;let f=d.params;if(f.length===0)return!1;let p=f[0];if(!l(p)||p.type!==`TSTypeQuery`||!u(p))return!1;let m=p.exprName;return s(m)&&m.name===`typedResponse`}function b(e){if(e.type!==`ObjectExpression`)return!1;for(let t of e.properties)if(t.type===`Property`&&t.key.type===`Identifier`&&t.key.name===`success`)return!0;return!1}function x(e,t,n){e.init&&d(e.init)&&e.id.type===`ObjectPattern`&&f(e.id).includes(`TypedHandle`)&&n()}function S(e,t){if(!p(e))return;let n=e.value;if(n.type!==`FunctionExpression`)return;let r=`returnType`in n?n.returnType:void 0;if(r&&!_(r)){let n=v(r);t.report({node:e,message:`handle 方法的返回类型必须使用 InferRouteReturn<typeof route>,当前使用了自定义类型 "${n}"。这会导致路由定义与实现的类型约束脱节。`})}let i=n.body;if(i)for(let e of i.body){if(e.type!==`ReturnStatement`)continue;let n=e.argument;n!=null&&(m(n,g)||b(n)&&t.report({node:e,message:`禁止在 @TypedHandle 方法中直接返回包含 success/error 字段的对象。请使用 typedResponse() 包装成功响应,通过抛出异常处理错误情况。`}))}}const C=e({meta:{type:`suggestion`,docs:{description:`强制 TypedHandler 的 handle 方法使用 InferRouteReturn 作为返回类型`}},createOnce(e){let t=!1;return{VariableDeclarator(n){x(n,e,()=>{t=!0})},TSTypeAliasDeclaration(n){t&&y(n)&&e.report({node:n,message:`禁止使用 Parameters<typeof typedResponse> 推断响应类型。请直接使用 InferRouteReturn<typeof route> 作为 handle 方法的返回类型。`})},MethodDefinition(n){t&&S(n,e)}}}}),w=/* @__PURE__ */ new Set([`Get`,`Post`,`Put`,`Delete`,`Patch`,`All`,`Options`,`Head`]);function T(e){return!e.includes(`:`)}function E(e){let t=e.arguments;if(!t.length)return`/`;let n=t[0];if(!n)return null;if(n.type===`Literal`){let e=`value`in n?n.value:void 0;if(typeof e==`string`)return e}return null}function D(e){return e.callee.type===`Identifier`?e.callee.name:null}function O(e){return e.type===`CallExpression`&&e.callee.type===`Identifier`&&w.has(e.callee.name)}function k(e){let t=[];for(let n of e)if(n.type===`MethodDefinition`&&`decorators`in n&&n.decorators)for(let e of n.decorators){let n=e.expression;if(!O(n)||n.type!==`CallExpression`)continue;let r=E(n),i=D(n);r!==null&&i&&t.push({path:r,method:i,isStatic:T(r)})}return t}function A(e){let t=/* @__PURE__ */ new Map;for(let n of e){let e=`${n.method}|${n.path}`,r=t.get(e);r?r.push(n):t.set(e,[n])}let n=/* @__PURE__ */ new Map;for(let[e,r]of t)r.length>1&&n.set(e,r);return n}function j(e){return e.type===`CallExpression`?e.callee.type===`Identifier`&&e.callee.name===`Controller`:e.type===`Identifier`&&e.name===`Controller`}function M(e){return e.type===`CallExpression`?e.callee.type===`Identifier`&&e.callee.name===`ApiTags`:e.type===`Identifier`&&e.name===`ApiTags`}function N(e){switch(e.type){case`Literal`:return typeof(`value`in e?e.value:void 0)==`string`;case`TemplateLiteral`:return!0;case`BinaryExpression`:return`operator`in e&&e.operator===`+`;default:return!1}}function P(e,t){if(!e)return t;switch(e.type){case`Identifier`:case`MemberExpression`:case`CallExpression`:return!0;default:return!1}}const F=e({meta:{type:`problem`,docs:{description:`防止 NestJS 控制器中出现重复的路由定义`}},createOnce(e){return{ClassBody(t){let n=A(k(t.body));for(let[,r]of n){let n=r[0];if(!n)continue;let i=`${n.method}('${n.path}')`;for(let n=1;n<r.length;n++)e.report({node:t,message:`发现重复路由 ${i}。控制器内的每个路由应该是唯一的,请检查并移除重复定义。`})}}}}}),I=e({meta:{type:`problem`,docs:{description:`确保 NestJS 控制器中静态路由位于参数化路由之前`}},createOnce(e){return{ClassBody(t){let n=k(t.body);if(n.length<2)return;let r=/* @__PURE__ */ new Map;for(let e of n){let t=r.get(e.method);t?t.push(e):r.set(e.method,[e])}for(let[,n]of r){let r=!1;for(let i of n)if(!i.isStatic)r=!0;else if(r){let r=n.find(e=>!e.isStatic);r&&e.report({node:t,message:`静态路由('${i.path}')应该位于参数化路由('${r.path}')之前。参数化路由会拦截静态路由的请求。`});return}}}}}});function L(e){return!(typeof e!=`object`||!e)}const R=e({meta:{type:`suggestion`,docs:{description:`推荐使用 TypedController 装饰器替代 Controller + ApiTags 组合`},schema:[{type:`object`,properties:{checkApiTags:{type:`boolean`,description:`是否检查同时存在 ApiTags 装饰器`}},additionalProperties:!1}]},createOnce(e){let t=e.options?.[0]??{},n=L(t)?t:{},r=n.checkApiTags===void 0||n.checkApiTags;return{ClassDeclaration(t){`decorators`in t&&t.decorators&&t.decorators.length!==0&&t.decorators.some(e=>j(e.expression))&&(!r||t.decorators.some(e=>M(e.expression)))&&e.report({node:t,message:`推荐使用 @TypedController() 装饰器替代 @Controller() + @ApiTags() 组合。TypedController 可以从路由定义中自动提取 API 标签。`})}}}});function z(e){return!(typeof e!=`object`||!e)}const B=e({meta:{type:`problem`,docs:{description:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量`},schema:[{type:`object`,properties:{allowedIdentifiers:{type:`array`,items:{type:`string`},description:`允许的路由常量标识符前缀列表`},allowEmpty:{type:`boolean`,description:`是否允许 Controller 装饰器无参数`}},additionalProperties:!1}]},createOnce(e){let t=e.options?.[0]??{},n=z(t)?t:{},r=n.allowEmpty===void 0||n.allowEmpty;return{Decorator(t){let n=t.expression;if(!j(n)||n.type!==`CallExpression`)return;let i=n.arguments[0];if(!i){r||e.report({node:t,message:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量。请使用 clientRoutes.xxx.prefix 或 manageRoutes.xxx.prefix 替代。`});return}if(N(i)){e.report({node:i,message:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量。请使用 clientRoutes.xxx.prefix 或 manageRoutes.xxx.prefix 替代。`});return}P(i,r)||e.report({node:i,message:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量。请使用 clientRoutes.xxx.prefix 或 manageRoutes.xxx.prefix 替代。`})}}}}),V=[`typedResponse`,`typedEmpty`,`typedStream`,`rawResponse`];function H(e){return!(typeof e!=`object`||!e)}function U(e,t,n,r){let i=e.init;if(!i||!d(i))return;let a=e.id;if(a.type!==`ObjectPattern`)return;let o=f(a),s=o.includes(`TypedHandle`),c=o.some(e=>t.includes(e));s&&r(),s&&!c&&n.report({node:e,message:`使用 defineHandler 且解构 TypedHandle 时,必须同时解构 typedResponse 或 typedEmpty`})}function W(e,t,n,r){if(!p(e)||n)return;let i=e.value;if(i.type!==`FunctionExpression`)return;let a=i.body;if(a&&h(a))for(let e of a.body){if(e.type!==`ReturnStatement`)continue;let n=e.argument;n!=null&&(m(n,t)||r.report({node:e,message:`@TypedHandle 方法的 return 语句必须使用 typedResponse() 或 typedEmpty() 包装返回值`}))}}const G=e({meta:{type:`problem`,docs:{description:`使用 defineHandler 且解构 TypedHandle 时,必须同时解构 typedResponse、typedEmpty 或 typedStream,且 TypedHandle 方法的 return 语句必须使用包装函数`},schema:[{type:`object`,properties:{responseFunctions:{type:`array`,items:{type:`string`},description:`覆盖默认的响应包装函数名列表`},allowDirectReturn:{type:`boolean`,description:`是否允许 TypedHandle 方法直接返回值(不经过包装函数)`}},additionalProperties:!1}]},createOnce(e){let t=e.options?.[0]??{},n=H(t)?t:{},r=n.responseFunctions??V,i=n.allowDirectReturn??!1,a=!1;return{VariableDeclarator(t){U(t,r,e,()=>{a=!0})},MethodDefinition(t){a&&W(t,r,i,e)}}}}),K=t({meta:{name:`@longzai-intelligence-oxlint/nestjs-route-plugin`},rules:{order:I,"no-duplicates":F,"require-route-constant":B,"prefer-typed-controller":R,"require-typed-response":G,"enforce-typed-handler-return":C}});export{K as default,K as nestjsRoutePlugin,C as enforceTypedHandlerReturnRule,f as extractDestructuredNames,k as extractRouteInfos,A as findDuplicateRoutes,h as hasReturnStatement,p as hasTypedHandleDecorator,M as isApiTagsDecorator,j as isControllerDecorator,d as isDefineHandlerCall,m as isResponseFunctionCall,O as isRouteDecorator,T as isStaticRoute,F as noDuplicatesRule,I as orderRule,R as preferTypedControllerRule,B as requireRouteConstantRule,G as requireTypedResponseRule};
1
+ import{defineRule as e,eslintCompatPlugin as t}from"@oxlint/plugins";function n(e){return typeof e==`object`&&!!e}function r(e){return n(e)&&`typeAnnotation`in e}function i(e){return n(e)&&`typeName`in e}function a(e){return n(e)&&`typeParameters`in e}function o(e){return n(e)&&`params`in e}function s(e){return n(e)&&`name`in e}function c(e){return n(e)&&`left`in e&&`right`in e}function l(e){return n(e)&&`type`in e}function u(e){return n(e)&&`exprName`in e}function d(e){return e.type!==`CallExpression`||e.callee.type!==`Identifier`?!1:e.callee.name===`defineHandler`}function f(e){if(e.type!==`ObjectPattern`)return[];let t=[];for(let n of e.properties)n.type===`Property`?n.key.type===`Identifier`&&t.push(n.key.name):n.type===`RestElement`&&n.argument.type===`Identifier`&&t.push(n.argument.name);return t}function p(e){if(e.type!==`MethodDefinition`||!(`decorators`in e)||!e.decorators)return!1;for(let t of e.decorators){let e=t.expression;if(e.type===`CallExpression`&&e.callee.type===`Identifier`&&e.callee.name===`TypedHandle`)return!0}return!1}function m(e,t){return!e||e.type!==`CallExpression`||e.callee.type!==`Identifier`?!1:t.includes(e.callee.name)}function h(e){if(e.type!==`BlockStatement`)return!1;for(let t of e.body)if(t.type===`ReturnStatement`&&t.argument!==null)return!0;return!1}const g=[`typedResponse`,`typedEmpty`];function _(e){if(!r(e))return!1;let t=e.typeAnnotation;if(!n(t))return!1;if(i(t)){let e=t.typeName;if(s(e)&&e.name===`InferRouteReturn`)return!0}if(a(t)){let e=t.typeParameters;if(o(e)){let t=e.params;for(let e of t)if(i(e)){let t=e.typeName;if(s(t)&&t.name===`InferRouteReturn`)return!0}}}return!1}function v(e){if(!r(e))return`unknown`;let t=e.typeAnnotation;if(!n(t)||!i(t))return`unknown`;let a=t.typeName;if(s(a)&&typeof a.name==`string`)return a.name;if(c(a)){let e=a.left,t=a.right;if(s(e)&&s(t)){let n=e.name,r=t.name;if(typeof n==`string`&&typeof r==`string`)return`${n}.${r}`}}return`unknown`}function y(e){if(!r(e))return!1;let t=e.typeAnnotation;if(!i(t))return!1;let n=t,c=n.typeName;if(!s(c)||c.name!==`Parameters`||!a(n))return!1;let d=n.typeParameters;if(!o(d))return!1;let f=d.params;if(f.length===0)return!1;let p=f[0];if(!l(p)||p.type!==`TSTypeQuery`||!u(p))return!1;let m=p.exprName;return s(m)&&m.name===`typedResponse`}function b(e){if(e.type!==`ObjectExpression`)return!1;for(let t of e.properties)if(t.type===`Property`&&t.key.type===`Identifier`&&t.key.name===`success`)return!0;return!1}function x(e,t,n){e.init&&d(e.init)&&e.id.type===`ObjectPattern`&&f(e.id).includes(`TypedHandle`)&&n()}function S(e,t){if(!p(e))return;let n=e.value;if(n.type!==`FunctionExpression`)return;let r=`returnType`in n?n.returnType:void 0;if(r&&!_(r)){let n=v(r);t.report({node:e,message:`handle 方法的返回类型必须使用 InferRouteReturn<typeof route>,当前使用了自定义类型 "${n}"。这会导致路由定义与实现的类型约束脱节。`})}let i=n.body;if(i)for(let e of i.body){if(e.type!==`ReturnStatement`)continue;let n=e.argument;n!=null&&(m(n,g)||b(n)&&t.report({node:e,message:`禁止在 @TypedHandle 方法中直接返回包含 success/error 字段的对象。请使用 typedResponse() 包装成功响应,通过抛出异常处理错误情况。`}))}}const C=e({meta:{type:`suggestion`,docs:{description:`强制 TypedHandler 的 handle 方法使用 InferRouteReturn 作为返回类型`}},createOnce(e){let t=!1;return{VariableDeclarator(n){x(n,e,()=>{t=!0})},TSTypeAliasDeclaration(n){t&&y(n)&&e.report({node:n,message:`禁止使用 Parameters<typeof typedResponse> 推断响应类型。请直接使用 InferRouteReturn<typeof route> 作为 handle 方法的返回类型。`})},MethodDefinition(n){t&&S(n,e)}}}}),w=/* @__PURE__ */ new Set([`Get`,`Post`,`Put`,`Delete`,`Patch`,`All`,`Options`,`Head`]);function T(e){return!e.includes(`:`)}function E(e){let t=e.arguments;if(!t.length)return`/`;let n=t[0];if(!n)return null;if(n.type===`Literal`){let e=`value`in n?n.value:void 0;if(typeof e==`string`)return e}return null}function D(e){return e.callee.type===`Identifier`?e.callee.name:null}function O(e){return e.type===`CallExpression`&&e.callee.type===`Identifier`&&w.has(e.callee.name)}function k(e){let t=[];for(let n of e)if(n.type===`MethodDefinition`&&`decorators`in n&&n.decorators)for(let e of n.decorators){let n=e.expression;if(!O(n)||n.type!==`CallExpression`)continue;let r=E(n),i=D(n);r!==null&&i&&t.push({path:r,method:i,isStatic:T(r)})}return t}function A(e){let t=/* @__PURE__ */ new Map;for(let n of e){let e=`${n.method}|${n.path}`,r=t.get(e);r?r.push(n):t.set(e,[n])}let n=/* @__PURE__ */ new Map;for(let[e,r]of t)r.length>1&&n.set(e,r);return n}function j(e){return e.type===`CallExpression`?e.callee.type===`Identifier`&&e.callee.name===`Controller`:e.type===`Identifier`&&e.name===`Controller`}function M(e){return e.type===`CallExpression`?e.callee.type===`Identifier`&&e.callee.name===`ApiTags`:e.type===`Identifier`&&e.name===`ApiTags`}function N(e){switch(e.type){case`Literal`:return typeof(`value`in e?e.value:void 0)==`string`;case`TemplateLiteral`:return!0;case`BinaryExpression`:return`operator`in e&&e.operator===`+`;default:return!1}}function P(e,t){if(!e)return t;switch(e.type){case`Identifier`:case`MemberExpression`:case`CallExpression`:return!0;default:return!1}}const F=e({meta:{type:`problem`,docs:{description:`防止 NestJS 控制器中出现重复的路由定义`}},createOnce(e){return{ClassBody(t){let n=A(k(t.body));for(let[,r]of n){let n=r[0];if(!n)continue;let i=`${n.method}('${n.path}')`;for(let n=1;n<r.length;n++)e.report({node:t,message:`发现重复路由 ${i}。控制器内的每个路由应该是唯一的,请检查并移除重复定义。`})}}}}}),I=e({meta:{type:`problem`,docs:{description:`确保 NestJS 控制器中静态路由位于参数化路由之前`}},createOnce(e){return{ClassBody(t){let n=k(t.body);if(n.length<2)return;let r=/* @__PURE__ */ new Map;for(let e of n){let t=r.get(e.method);t?t.push(e):r.set(e.method,[e])}for(let[,n]of r){let r=!1;for(let i of n)if(!i.isStatic)r=!0;else if(r){let r=n.find(e=>!e.isStatic);r&&e.report({node:t,message:`静态路由('${i.path}')应该位于参数化路由('${r.path}')之前。参数化路由会拦截静态路由的请求。`});return}}}}}});function L(e){return!(typeof e!=`object`||!e)}const R=e({meta:{type:`suggestion`,docs:{description:`推荐使用 TypedController 装饰器替代 Controller + ApiTags 组合`},schema:[{type:`object`,properties:{checkApiTags:{type:`boolean`,description:`是否检查同时存在 ApiTags 装饰器`}},additionalProperties:!1}]},createOnce(e){let t=e.options?.[0]??{},n=L(t)?t:{},r=n.checkApiTags===void 0||n.checkApiTags;return{ClassDeclaration(t){`decorators`in t&&t.decorators&&t.decorators.length!==0&&t.decorators.some(e=>j(e.expression))&&(!r||t.decorators.some(e=>M(e.expression)))&&e.report({node:t,message:`推荐使用 @TypedController() 装饰器替代 @Controller() + @ApiTags() 组合。TypedController 可以从路由定义中自动提取 API 标签。`})}}}});function z(e){return!(typeof e!=`object`||!e)}const B=e({meta:{type:`problem`,docs:{description:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量`},schema:[{type:`object`,properties:{allowedIdentifiers:{type:`array`,items:{type:`string`},description:`允许的路由常量标识符前缀列表`},allowEmpty:{type:`boolean`,description:`是否允许 Controller 装饰器无参数`}},additionalProperties:!1}]},createOnce(e){let t=e.options?.[0]??{},n=z(t)?t:{},r=n.allowEmpty===void 0||n.allowEmpty;return{Decorator(t){let n=t.expression;if(!j(n)||n.type!==`CallExpression`)return;let i=n.arguments[0];i?N(i)?e.report({node:i,message:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量。请使用 clientRoutes.xxx.prefix 或 manageRoutes.xxx.prefix 替代。`}):P(i,r)||e.report({node:i,message:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量。请使用 clientRoutes.xxx.prefix 或 manageRoutes.xxx.prefix 替代。`}):r||e.report({node:t,message:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量。请使用 clientRoutes.xxx.prefix 或 manageRoutes.xxx.prefix 替代。`})}}}}),V=[`typedResponse`,`typedEmpty`,`typedStream`,`rawResponse`];function H(e){return!(typeof e!=`object`||!e)}function U(e,t,n,r){let i=e.init;if(!i||!d(i))return;let a=e.id;if(a.type!==`ObjectPattern`)return;let o=f(a),s=o.includes(`TypedHandle`),c=o.some(e=>t.includes(e));s&&r(),s&&!c&&n.report({node:e,message:`使用 defineHandler 且解构 TypedHandle 时,必须同时解构 typedResponse 或 typedEmpty`})}function W(e,t,n,r){if(!p(e)||n)return;let i=e.value;if(i.type!==`FunctionExpression`)return;let a=i.body;if(a&&h(a))for(let e of a.body){if(e.type!==`ReturnStatement`)continue;let n=e.argument;n!=null&&(m(n,t)||r.report({node:e,message:`@TypedHandle 方法的 return 语句必须使用 typedResponse() 或 typedEmpty() 包装返回值`}))}}const G=e({meta:{type:`problem`,docs:{description:`使用 defineHandler 且解构 TypedHandle 时,必须同时解构 typedResponse、typedEmpty 或 typedStream,且 TypedHandle 方法的 return 语句必须使用包装函数`},schema:[{type:`object`,properties:{responseFunctions:{type:`array`,items:{type:`string`},description:`覆盖默认的响应包装函数名列表`},allowDirectReturn:{type:`boolean`,description:`是否允许 TypedHandle 方法直接返回值(不经过包装函数)`}},additionalProperties:!1}]},createOnce(e){let t=e.options?.[0]??{},n=H(t)?t:{},r=n.responseFunctions??V,i=n.allowDirectReturn??!1,a=!1;return{VariableDeclarator(t){U(t,r,e,()=>{a=!0})},MethodDefinition(t){a&&W(t,r,i,e)}}}}),K=t({meta:{name:`@longzai-intelligence-oxlint/nestjs-route-plugin`},rules:{order:I,"no-duplicates":F,"require-route-constant":B,"prefer-typed-controller":R,"require-typed-response":G,"enforce-typed-handler-return":C}});export{K as default,K as nestjsRoutePlugin,C as enforceTypedHandlerReturnRule,f as extractDestructuredNames,k as extractRouteInfos,A as findDuplicateRoutes,h as hasReturnStatement,p as hasTypedHandleDecorator,M as isApiTagsDecorator,j as isControllerDecorator,d as isDefineHandlerCall,m as isResponseFunctionCall,O as isRouteDecorator,T as isStaticRoute,F as noDuplicatesRule,I as orderRule,R as preferTypedControllerRule,B as requireRouteConstantRule,G as requireTypedResponseRule};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longzai-intelligence-oxlint/nestjs-route-plugin",
3
- "version": "0.1.37",
3
+ "version": "0.1.39",
4
4
  "description": "Longzai Intelligence oxlint NestJS 路由规则插件",
5
5
  "keywords": [
6
6
  "longzai-intelligence",