@longzai-intelligence/oxlint-plugin-nestjs-route 0.0.1

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/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require(`@oxlint/plugins`);const t=new Set([`Get`,`Post`,`Put`,`Delete`,`Patch`,`All`,`Options`,`Head`]);function n(e){return!e.includes(`:`)}function r(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 i(e){return e.callee.type===`Identifier`?e.callee.name:null}function a(e){return e.type===`CallExpression`&&e.callee.type===`Identifier`?t.has(e.callee.name):!1}function o(e){let t=[];for(let o of e)if(o.type===`MethodDefinition`&&!(!(`decorators`in o)||!o.decorators))for(let e of o.decorators){let o=e.expression;if(!a(o)||o.type!==`CallExpression`)continue;let s=r(o),c=i(o);s!==null&&c&&t.push({path:s,method:c,isStatic:n(s)})}return t}function s(e){let t=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=new Map;for(let[e,r]of t)r.length>1&&n.set(e,r);return n}function c(e){return e.type===`CallExpression`?e.callee.type===`Identifier`&&e.callee.name===`Controller`:e.type===`Identifier`?e.name===`Controller`:!1}function l(e){return e.type===`CallExpression`?e.callee.type===`Identifier`&&e.callee.name===`ApiTags`:e.type===`Identifier`?e.name===`ApiTags`:!1}function u(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 d(e,t){if(!e)return t;switch(e.type){case`Identifier`:case`MemberExpression`:case`CallExpression`:return!0;default:return!1}}const f=(0,e.defineRule)({meta:{type:`problem`,docs:{description:`防止 NestJS 控制器中出现重复的路由定义`}},createOnce(e){return{ClassBody(t){let n=s(o(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}。控制器内的每个路由应该是唯一的,请检查并移除重复定义。`})}}}}}),p=(0,e.defineRule)({meta:{type:`problem`,docs:{description:`确保 NestJS 控制器中静态路由位于参数化路由之前`}},createOnce(e){return{ClassBody(t){let n=o(t.body);if(n.length<2)return;let r=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 m(e){return!(typeof e!=`object`||!e)}const h=(0,e.defineRule)({meta:{type:`suggestion`,docs:{description:`推荐使用 TypedController 装饰器替代 Controller + ApiTags 组合`}},createOnce(e){let t=e.options?.[0]??{},n=m(t)?t:{},r=n.checkApiTags===void 0?!0:n.checkApiTags;return{ClassDeclaration(t){!(`decorators`in t)||!t.decorators||t.decorators.length===0||t.decorators.some(e=>c(e.expression))&&(r&&!t.decorators.some(e=>l(e.expression))||e.report({node:t,message:`推荐使用 @TypedController() 装饰器替代 @Controller() + @ApiTags() 组合。TypedController 可以从路由定义中自动提取 API 标签。`}))}}}});function g(e){return!(typeof e!=`object`||!e)}const _=(0,e.defineRule)({meta:{type:`problem`,docs:{description:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量`}},createOnce(e){let t=e.options?.[0]??{},n=g(t)?t:{},r=n.allowEmpty===void 0?!0:n.allowEmpty;return{Decorator(t){let n=t.expression;if(!c(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(u(i)){e.report({node:i,message:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量。请使用 clientRoutes.xxx.prefix 或 manageRoutes.xxx.prefix 替代。`});return}d(i,r)||e.report({node:i,message:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量。请使用 clientRoutes.xxx.prefix 或 manageRoutes.xxx.prefix 替代。`})}}}});function v(e){return e.type!==`CallExpression`||e.callee.type!==`Identifier`?!1:e.callee.name===`defineHandler`}function y(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 b(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 x(e,t){return!e||e.type!==`CallExpression`||e.callee.type!==`Identifier`?!1:t.includes(e.callee.name)}function S(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 C=[`typedResponse`,`typedEmpty`];function w(e){return!(typeof e!=`object`||!e)}function T(e,t,n,r){let i=e.init;if(!i||!v(i))return;let a=e.id;if(a.type!==`ObjectPattern`)return;let o=y(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 E(e,t,n,r){if(!b(e)||n)return;let i=e.value;if(i.type!==`FunctionExpression`)return;let a=i.body;if(a&&S(a))for(let e of a.body){if(e.type!==`ReturnStatement`)continue;let n=e.argument;n!=null&&(x(n,t)||r.report({node:e,message:`@TypedHandle 方法的 return 语句必须使用 typedResponse() 或 typedEmpty() 包装返回值`}))}}const D=(0,e.defineRule)({meta:{type:`problem`,docs:{description:`使用 defineHandler 且解构 TypedHandle 时,必须同时解构 typedResponse 或 typedEmpty,且 TypedHandle 方法的 return 语句必须使用包装函数`}},createOnce(e){let t=e.options?.[0]??{},n=w(t)?t:{},r=n.responseFunctions??C,i=n.allowDirectReturn??!1,a=!1;return{VariableDeclarator(t){T(t,r,e,()=>{a=!0})},MethodDefinition(t){a&&E(t,r,i,e)}}}}),O=(0,e.eslintCompatPlugin)({meta:{name:`@longzai-intelligence/nestjs-route`},rules:{order:p,"no-duplicates":f,"require-route-constant":_,"prefer-typed-controller":h,"require-typed-response":D}});exports.default=O,exports.nestjsRoutePlugin=O,exports.extractDestructuredNames=y,exports.extractRouteInfos=o,exports.findDuplicateRoutes=s,exports.hasReturnStatement=S,exports.hasTypedHandleDecorator=b,exports.isApiTagsDecorator=l,exports.isControllerDecorator=c,exports.isDefineHandlerCall=v,exports.isResponseFunctionCall=x,exports.isRouteDecorator=a,exports.isStaticRoute=n,exports.noDuplicatesRule=f,exports.orderRule=p,exports.preferTypedControllerRule=h,exports.requireRouteConstantRule=_,exports.requireTypedResponseRule=D;
@@ -0,0 +1,55 @@
1
+ import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
+ import { ESTree } from "@oxlint/plugins";
3
+
4
+ //#region src/rules/no-duplicates/index.d.ts
5
+ declare const noDuplicatesRule: _$_oxlint_plugins0.Rule;
6
+ //#endregion
7
+ //#region src/rules/order/index.d.ts
8
+ declare const orderRule: _$_oxlint_plugins0.Rule;
9
+ //#endregion
10
+ //#region src/rules/prefer-typed-controller/index.d.ts
11
+ declare const preferTypedControllerRule: _$_oxlint_plugins0.Rule;
12
+ //#endregion
13
+ //#region src/rules/require-route-constant/index.d.ts
14
+ declare const requireRouteConstantRule: _$_oxlint_plugins0.Rule;
15
+ //#endregion
16
+ //#region src/rules/require-typed-response/index.d.ts
17
+ declare const requireTypedResponseRule: _$_oxlint_plugins0.Rule;
18
+ //#endregion
19
+ //#region src/types.d.ts
20
+ type RouteInfo = {
21
+ path: string;
22
+ method: string;
23
+ isStatic: boolean;
24
+ };
25
+ type RequireRouteConstantOptions = {
26
+ allowedIdentifiers?: string[];
27
+ allowEmpty?: boolean;
28
+ };
29
+ type PreferTypedControllerOptions = {
30
+ checkApiTags?: boolean;
31
+ };
32
+ type RequireTypedResponseOptions = {
33
+ responseFunctions?: string[];
34
+ allowDirectReturn?: boolean;
35
+ };
36
+ //#endregion
37
+ //#region src/utils/route.utils.d.ts
38
+ declare function isStaticRoute(path: string): boolean;
39
+ declare function isRouteDecorator(expression: ESTree.Node): boolean;
40
+ declare function extractRouteInfos(body: ESTree.ClassBody['body']): RouteInfo[];
41
+ declare function findDuplicateRoutes(routeInfos: RouteInfo[]): Map<string, RouteInfo[]>;
42
+ declare function isControllerDecorator(expression: ESTree.Node): boolean;
43
+ declare function isApiTagsDecorator(expression: ESTree.Node): boolean;
44
+ //#endregion
45
+ //#region src/utils/handler.utils.d.ts
46
+ declare function isDefineHandlerCall(node: ESTree.Node): boolean;
47
+ declare function extractDestructuredNames(node: ESTree.Node): string[];
48
+ declare function hasTypedHandleDecorator(node: ESTree.Node): boolean;
49
+ declare function isResponseFunctionCall(node: ESTree.Node | null | undefined, responseFunctions: string[]): boolean;
50
+ declare function hasReturnStatement(node: ESTree.Node): boolean;
51
+ //#endregion
52
+ //#region src/index.d.ts
53
+ declare const nestjsRoutePlugin: _$_oxlint_plugins0.Plugin;
54
+ //#endregion
55
+ export { type PreferTypedControllerOptions, type RequireRouteConstantOptions, type RequireTypedResponseOptions, type RouteInfo, nestjsRoutePlugin as default, nestjsRoutePlugin, extractDestructuredNames, extractRouteInfos, findDuplicateRoutes, hasReturnStatement, hasTypedHandleDecorator, isApiTagsDecorator, isControllerDecorator, isDefineHandlerCall, isResponseFunctionCall, isRouteDecorator, isStaticRoute, noDuplicatesRule, orderRule, preferTypedControllerRule, requireRouteConstantRule, requireTypedResponseRule };
@@ -0,0 +1,55 @@
1
+ import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
+ import { ESTree } from "@oxlint/plugins";
3
+
4
+ //#region src/rules/no-duplicates/index.d.ts
5
+ declare const noDuplicatesRule: _$_oxlint_plugins0.Rule;
6
+ //#endregion
7
+ //#region src/rules/order/index.d.ts
8
+ declare const orderRule: _$_oxlint_plugins0.Rule;
9
+ //#endregion
10
+ //#region src/rules/prefer-typed-controller/index.d.ts
11
+ declare const preferTypedControllerRule: _$_oxlint_plugins0.Rule;
12
+ //#endregion
13
+ //#region src/rules/require-route-constant/index.d.ts
14
+ declare const requireRouteConstantRule: _$_oxlint_plugins0.Rule;
15
+ //#endregion
16
+ //#region src/rules/require-typed-response/index.d.ts
17
+ declare const requireTypedResponseRule: _$_oxlint_plugins0.Rule;
18
+ //#endregion
19
+ //#region src/types.d.ts
20
+ type RouteInfo = {
21
+ path: string;
22
+ method: string;
23
+ isStatic: boolean;
24
+ };
25
+ type RequireRouteConstantOptions = {
26
+ allowedIdentifiers?: string[];
27
+ allowEmpty?: boolean;
28
+ };
29
+ type PreferTypedControllerOptions = {
30
+ checkApiTags?: boolean;
31
+ };
32
+ type RequireTypedResponseOptions = {
33
+ responseFunctions?: string[];
34
+ allowDirectReturn?: boolean;
35
+ };
36
+ //#endregion
37
+ //#region src/utils/route.utils.d.ts
38
+ declare function isStaticRoute(path: string): boolean;
39
+ declare function isRouteDecorator(expression: ESTree.Node): boolean;
40
+ declare function extractRouteInfos(body: ESTree.ClassBody['body']): RouteInfo[];
41
+ declare function findDuplicateRoutes(routeInfos: RouteInfo[]): Map<string, RouteInfo[]>;
42
+ declare function isControllerDecorator(expression: ESTree.Node): boolean;
43
+ declare function isApiTagsDecorator(expression: ESTree.Node): boolean;
44
+ //#endregion
45
+ //#region src/utils/handler.utils.d.ts
46
+ declare function isDefineHandlerCall(node: ESTree.Node): boolean;
47
+ declare function extractDestructuredNames(node: ESTree.Node): string[];
48
+ declare function hasTypedHandleDecorator(node: ESTree.Node): boolean;
49
+ declare function isResponseFunctionCall(node: ESTree.Node | null | undefined, responseFunctions: string[]): boolean;
50
+ declare function hasReturnStatement(node: ESTree.Node): boolean;
51
+ //#endregion
52
+ //#region src/index.d.ts
53
+ declare const nestjsRoutePlugin: _$_oxlint_plugins0.Plugin;
54
+ //#endregion
55
+ export { type PreferTypedControllerOptions, type RequireRouteConstantOptions, type RequireTypedResponseOptions, type RouteInfo, nestjsRoutePlugin as default, nestjsRoutePlugin, extractDestructuredNames, extractRouteInfos, findDuplicateRoutes, hasReturnStatement, hasTypedHandleDecorator, isApiTagsDecorator, isControllerDecorator, isDefineHandlerCall, isResponseFunctionCall, isRouteDecorator, isStaticRoute, noDuplicatesRule, orderRule, preferTypedControllerRule, requireRouteConstantRule, requireTypedResponseRule };
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import{defineRule as e,eslintCompatPlugin as t}from"@oxlint/plugins";const n=new Set([`Get`,`Post`,`Put`,`Delete`,`Patch`,`All`,`Options`,`Head`]);function r(e){return!e.includes(`:`)}function i(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 a(e){return e.callee.type===`Identifier`?e.callee.name:null}function o(e){return e.type===`CallExpression`&&e.callee.type===`Identifier`?n.has(e.callee.name):!1}function s(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 s=i(n),c=a(n);s!==null&&c&&t.push({path:s,method:c,isStatic:r(s)})}return t}function c(e){let t=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=new Map;for(let[e,r]of t)r.length>1&&n.set(e,r);return n}function l(e){return e.type===`CallExpression`?e.callee.type===`Identifier`&&e.callee.name===`Controller`:e.type===`Identifier`?e.name===`Controller`:!1}function u(e){return e.type===`CallExpression`?e.callee.type===`Identifier`&&e.callee.name===`ApiTags`:e.type===`Identifier`?e.name===`ApiTags`:!1}function d(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 f(e,t){if(!e)return t;switch(e.type){case`Identifier`:case`MemberExpression`:case`CallExpression`:return!0;default:return!1}}const p=e({meta:{type:`problem`,docs:{description:`防止 NestJS 控制器中出现重复的路由定义`}},createOnce(e){return{ClassBody(t){let n=c(s(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}。控制器内的每个路由应该是唯一的,请检查并移除重复定义。`})}}}}}),m=e({meta:{type:`problem`,docs:{description:`确保 NestJS 控制器中静态路由位于参数化路由之前`}},createOnce(e){return{ClassBody(t){let n=s(t.body);if(n.length<2)return;let r=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 h(e){return!(typeof e!=`object`||!e)}const g=e({meta:{type:`suggestion`,docs:{description:`推荐使用 TypedController 装饰器替代 Controller + ApiTags 组合`}},createOnce(e){let t=e.options?.[0]??{},n=h(t)?t:{},r=n.checkApiTags===void 0?!0:n.checkApiTags;return{ClassDeclaration(t){!(`decorators`in t)||!t.decorators||t.decorators.length===0||t.decorators.some(e=>l(e.expression))&&(r&&!t.decorators.some(e=>u(e.expression))||e.report({node:t,message:`推荐使用 @TypedController() 装饰器替代 @Controller() + @ApiTags() 组合。TypedController 可以从路由定义中自动提取 API 标签。`}))}}}});function _(e){return!(typeof e!=`object`||!e)}const v=e({meta:{type:`problem`,docs:{description:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量`}},createOnce(e){let t=e.options?.[0]??{},n=_(t)?t:{},r=n.allowEmpty===void 0?!0:n.allowEmpty;return{Decorator(t){let n=t.expression;if(!l(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(d(i)){e.report({node:i,message:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量。请使用 clientRoutes.xxx.prefix 或 manageRoutes.xxx.prefix 替代。`});return}f(i,r)||e.report({node:i,message:`Controller 装饰器必须使用路由常量,禁止使用字符串字面量。请使用 clientRoutes.xxx.prefix 或 manageRoutes.xxx.prefix 替代。`})}}}});function y(e){return e.type!==`CallExpression`||e.callee.type!==`Identifier`?!1:e.callee.name===`defineHandler`}function b(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 x(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 S(e,t){return!e||e.type!==`CallExpression`||e.callee.type!==`Identifier`?!1:t.includes(e.callee.name)}function C(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 w=[`typedResponse`,`typedEmpty`];function T(e){return!(typeof e!=`object`||!e)}function E(e,t,n,r){let i=e.init;if(!i||!y(i))return;let a=e.id;if(a.type!==`ObjectPattern`)return;let o=b(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 D(e,t,n,r){if(!x(e)||n)return;let i=e.value;if(i.type!==`FunctionExpression`)return;let a=i.body;if(a&&C(a))for(let e of a.body){if(e.type!==`ReturnStatement`)continue;let n=e.argument;n!=null&&(S(n,t)||r.report({node:e,message:`@TypedHandle 方法的 return 语句必须使用 typedResponse() 或 typedEmpty() 包装返回值`}))}}const O=e({meta:{type:`problem`,docs:{description:`使用 defineHandler 且解构 TypedHandle 时,必须同时解构 typedResponse 或 typedEmpty,且 TypedHandle 方法的 return 语句必须使用包装函数`}},createOnce(e){let t=e.options?.[0]??{},n=T(t)?t:{},r=n.responseFunctions??w,i=n.allowDirectReturn??!1,a=!1;return{VariableDeclarator(t){E(t,r,e,()=>{a=!0})},MethodDefinition(t){a&&D(t,r,i,e)}}}}),k=t({meta:{name:`@longzai-intelligence/nestjs-route`},rules:{order:m,"no-duplicates":p,"require-route-constant":v,"prefer-typed-controller":g,"require-typed-response":O}});export{k as default,k as nestjsRoutePlugin,b as extractDestructuredNames,s as extractRouteInfos,c as findDuplicateRoutes,C as hasReturnStatement,x as hasTypedHandleDecorator,u as isApiTagsDecorator,l as isControllerDecorator,y as isDefineHandlerCall,S as isResponseFunctionCall,o as isRouteDecorator,r as isStaticRoute,p as noDuplicatesRule,m as orderRule,g as preferTypedControllerRule,v as requireRouteConstantRule,O as requireTypedResponseRule};
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@longzai-intelligence/oxlint-plugin-nestjs-route",
3
+ "version": "0.0.1",
4
+ "license": "UNLICENSED",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "type": "module",
9
+ "main": "./dist/index.cjs",
10
+ "module": "./dist/index.mjs",
11
+ "types": "./dist/index.d.mts",
12
+ "exports": {
13
+ ".": {
14
+ "types": {
15
+ "import": "./dist/index.d.mts",
16
+ "require": "./dist/index.d.cts"
17
+ },
18
+ "import": "./dist/index.mjs",
19
+ "require": "./dist/index.cjs"
20
+ }
21
+ },
22
+ "scripts": {
23
+ "build": "tsdown",
24
+ "build:prod": "NODE_ENV=production tsdown",
25
+ "prepublishOnly": "bun run build:prod",
26
+ "dev": "tsdown --watch",
27
+ "clean": "rimraf dist",
28
+ "test": "vitest run",
29
+ "test:watch": "vitest",
30
+ "test:coverage": "vitest run --coverage",
31
+ "lint": "bun run lint:oxlint",
32
+ "lint:oxlint": "oxlint",
33
+ "lint:eslint": "eslint .",
34
+ "lint:fix": "bun run oxc:fix",
35
+ "lint:fix:oxlint": "oxlint --fix",
36
+ "lint:fix:eslint": "eslint . --fix",
37
+ "typecheck": "bun run typecheck:app && bun run typecheck:node",
38
+ "typecheck:app": "tsc --noEmit -p tsconfig/app.json",
39
+ "typecheck:node": "tsc --noEmit -p tsconfig/node.json",
40
+ "lint:file": "bun run lint:file:oxlint",
41
+ "lint:file:oxlint": "oxlint",
42
+ "lint:file:eslint": "eslint",
43
+ "fmt": "oxfmt",
44
+ "fmt:check": "oxfmt --check",
45
+ "oxc": "bun run lint:oxlint && bun run fmt:check",
46
+ "oxc:fix": "bun run lint:fix:oxlint && bun run fmt"
47
+ },
48
+ "dependencies": {
49
+ "@oxlint/plugins": "^1.64.0"
50
+ },
51
+ "devDependencies": {
52
+ "@longzai-intelligence/eslint-preset-library": "0.2.13",
53
+ "@longzai-intelligence/oxlint-config": "0.0.1",
54
+ "@longzai-intelligence/oxlint-plugin-architecture": "0.0.1",
55
+ "@longzai-intelligence/oxlint-plugin-code-style": "0.0.1",
56
+ "@longzai-intelligence/oxlint-plugin-package-json": "0.0.1",
57
+ "@longzai-intelligence/oxlint-plugin-perfectionist": "0.0.1",
58
+ "@longzai-intelligence/oxlint-plugin-schema-type-separation": "0.0.1",
59
+ "@longzai-intelligence/oxlint-plugin-stylistic": "0.0.1",
60
+ "@longzai-intelligence/oxlint-plugin-tsdoc": "0.0.1",
61
+ "@longzai-intelligence/oxlint-plugin-typescript-eslint": "0.0.1",
62
+ "@longzai-intelligence/oxlint-plugin-zod": "0.0.1",
63
+ "@longzai-intelligence/oxlint-testing": "0.0.1",
64
+ "@longzai-intelligence/oxlint-utils": "0.0.1",
65
+ "@longzai-intelligence/tsdown-config": "0.0.1",
66
+ "@longzai-intelligence/typescript-config": "0.0.3",
67
+ "@longzai-intelligence/vitest-config": "0.0.10",
68
+ "@types/node": "^25.7.0",
69
+ "oxlint": "^1.64.0",
70
+ "rimraf": "^6.1.3",
71
+ "tsdown": "^0.21.10",
72
+ "typescript": "^6.0.3",
73
+ "vitest": "^4.1.6"
74
+ },
75
+ "peerDependencies": {
76
+ "oxlint": ">=1.0.0"
77
+ }
78
+ }