@longzai-intelligence-oxlint/typeorm-plugin 0.1.17 → 0.1.19
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 +15 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @longzai-intelligence-oxlint/typeorm-plugin
|
|
2
|
+
|
|
3
|
+
Longzai Intelligence Oxlint 的 TypeORM 规则插件,拦截数据访问层的典型隐患写法。
|
|
4
|
+
|
|
5
|
+
## 简介
|
|
6
|
+
|
|
7
|
+
治理 TypeORM 使用规范失范的问题:关系装饰器的字符串实体引用与分页查询的 skip/take 失配等隐患在静态检查阶段拦截,防止仅生产环境复现的运行时错误流入数据访问层。
|
|
8
|
+
|
|
9
|
+
## 能力
|
|
10
|
+
|
|
11
|
+
- `no-string-entity-ref` — 禁止关系装饰器使用字符串类名引用,强制箭头函数引用实体
|
|
12
|
+
- `require-take-with-skip` — 禁止分页查询只传 skip 不传 take
|
|
13
|
+
- 关系装饰器集合与分页查询方法名常量导出
|
|
14
|
+
- 配套 recommended 配置入口
|
|
15
|
+
- 同时兼容 Oxlint 与 ESLint 运行时
|
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?!1:`value`in e}const r
|
|
1
|
+
import{defineRule as e,eslintCompatPlugin as t}from"@oxlint/plugins";function n(e){return typeof e!=`object`||!e?!1:`value`in e}const r=/* @__PURE__ */ new Set([`ManyToOne`,`OneToMany`,`OneToOne`,`ManyToMany`]);function i(e){if(e.type!==`CallExpression`)return!1;let t=e.callee;return t.type===`Identifier`&&r.has(t.name)}function a(e){if(e.type!==`Literal`||!n(e))return null;let t=e.value;return typeof t==`string`?t:null}const o=e({meta:{type:`problem`,docs:{description:`禁止 TypeORM 关系装饰器(@ManyToOne/@OneToMany/@OneToOne/@ManyToMany)使用字符串类名引用,生产构建 minify 会压缩类名导致运行时关系解析失败`}},createOnce(e){return{Decorator(t){if(!i(t.expression))return;let n=t.expression.arguments[0];if(n===void 0)return;let r=a(n);if(r===null)return;let o=t.expression.callee.type===`Identifier`?t.expression.callee.name:``;e.report({node:n,message:`@${o} 的第一个参数禁止使用字符串类名 "${r}"。生产构建 minify 会压缩类名(如 ${r} → y),导致 TypeORM 运行时抛出 "Entity metadata for y#<属性> was not found"。请改用箭头函数引用类:@${o}(() => ${r}, ...)。`})}}}}),s=/* @__PURE__ */ new Set([`find`,`findAndCount`]);function c(e){if(e.type!==`CallExpression`)return!1;let t=e.callee;if(t.type!==`MemberExpression`)return!1;let n=t.property;return n.type===`Identifier`&&s.has(n.name)}function l(e){let t=null,n=!1;for(let r of e.properties){if(r.type===`SpreadElement`)return null;if(r.type!==`Property`)continue;let e=u(r.key);e!==null&&(e===`skip`?t=r:e===`take`&&(n=!0))}return t!==null&&!n?t:null}function u(e){if(e.type===`Identifier`)return e.name;if(e.type===`Literal`&&n(e)){let t=e.value;if(typeof t==`string`)return t}return null}const d=e({meta:{type:`problem`,docs:{description:`禁止 TypeORM Repository.find/findAndCount 只传 skip 不传 take。MySQL 系 driver 对 OFFSET 不带 LIMIT 抛 OffsetWithoutLimitNotSupportedError,该错误仅在运行时、针对 MySQL 方言触发,类型系统与 SQLite 方言测试均无法捕获。`}},createOnce(e){return{CallExpression(t){if(!c(t))return;let n=t.arguments[0];if(n===void 0||n.type!==`ObjectExpression`)return;let r=l(n);if(r===null)return;let i=t.callee.type===`MemberExpression`&&t.callee.property.type===`Identifier`?t.callee.property.name:``;e.report({node:r,message:`${i} 的 FindManyOptions 含 skip 但缺少 take。MySQL 系 driver 对 OFFSET 不带 LIMIT 抛 OffsetWithoutLimitNotSupportedError(仅运行时、仅 MySQL 方言触发,类型系统与 SQLite 测试无法捕获)。请配对设置 take(分页场景用 @longzai-intelligence-pagination/typeorm 的 paginateWithRepository 等工具,它们强制 skip+take 成对;批量删除场景改用 QueryBuilder.delete().limit() 在 SQL 层直接删除)。`})}}}}),f=t({meta:{name:`@longzai-intelligence-oxlint/typeorm-plugin`},rules:{"no-string-entity-ref":o,"require-take-with-skip":d}});export{s as PAGINATED_QUERY_METHODS,r as RELATION_DECORATORS,f as default,f as typeormPlugin,o as noStringEntityRefRule,d as requireTakeWithSkipRule};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longzai-intelligence-oxlint/typeorm-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"typecheck:test": "lzi-tsgo typecheck tsconfig/test.json"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@longzai-intelligence-oxlint/core": "0.1.
|
|
38
|
+
"@longzai-intelligence-oxlint/core": "0.1.19",
|
|
39
39
|
"@oxlint/plugins": "^1.74.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|