bk-schema-checker 0.0.0-stage → 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 +239 -2
- package/bin/bk-schema-checker.js +8 -0
- package/package.json +43 -3
- package/py/load_backend.py +2731 -0
- package/src/backend.js +52 -0
- package/src/check.js +422 -0
- package/src/cli.js +181 -0
- package/src/compare.js +442 -0
- package/src/config.js +291 -0
- package/src/fixes.js +310 -0
- package/src/index.js +2 -0
- package/src/mock-shim.js +40 -0
- package/src/runtime.js +244 -0
- package/src/scan.js +366 -0
- package/src/services.js +374 -0
- package/src/ts.js +2091 -0
package/README.md
CHANGED
|
@@ -1,3 +1,240 @@
|
|
|
1
|
-
#
|
|
1
|
+
# bk-schema-checker
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
这是一个通用的前后端接口协议检查器。对照前端 services 请求类型、Django REST 后台的路由和序列化器,以及(可选)前端 mock 实际响应。不启动 Django。
|
|
4
|
+
|
|
5
|
+
用在蓝鲸前后端仓库:CI 或本地跑一遍,尽早发现接口类型相对后台漂移。写了 `mockDir` 时还可以对照 [bk-local-mock](https://www.npmjs.com/package/bk-local-mock) handler。
|
|
6
|
+
|
|
7
|
+
## 对照什么
|
|
8
|
+
|
|
9
|
+
| 一侧 | 读哪里 | 用来比什么 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| mock 响应(可选) | 加载并执行 `mockDir` 里的 handler | 字段集合、类型、`null`、`choices`、容器形状 |
|
|
12
|
+
| 请求类型 | `servicesDir/source` 里的 `http.get` / `http.post` 等 | 路径参数、查询参数、请求体 |
|
|
13
|
+
| 后台协议 | `backendDir/urls.py` 起的路由和 DRF 序列化器 | 路由、HTTP 方法、query / body / response schema |
|
|
14
|
+
|
|
15
|
+
请求参数不看 mock 读了什么,而看 services 调用的参数类型:GET 的第二个参数是查询参数,POST、PUT、PATCH、DELETE 的第二个参数是请求体。路径参数来自 Django 的 `<str:system_id>` 这类转换器。
|
|
16
|
+
|
|
17
|
+
后台用 Python 标准库 `ast` 静态读取,包括字段继承、自定义字段子类、`SerializerMethodField` 的返回注解,以及能静态求值的 `choices`。前端 `tsconfig.json` 的 `paths` 用来展开 `@common/const` 这类别名;`export enum`、`export interface` 和 `` `${Enum}` `` 会展开成具体类型再比较。
|
|
18
|
+
|
|
19
|
+
## 环境要求
|
|
20
|
+
|
|
21
|
+
- Node.js >= 18
|
|
22
|
+
- Python >= 3.10(只跑标准库,不需要 Django 进程)
|
|
23
|
+
- 校验 mock 时需要 `jiti`;handler 里的 `bk-local-mock` 优先用前端工程已安装的包,找不到时用内置 shim。只对照后台与 services 时不需要
|
|
24
|
+
|
|
25
|
+
建议把本包装在会跑检查的那一层(前端工程或仓库根目录)。校验 mock 时再加 `jiti`:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install -D bk-schema-checker jiti
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
前端工程通常已经依赖 `bk-local-mock`。本包会依次尝试:自身 `node_modules`、当前工程、`frontend/node_modules`。
|
|
32
|
+
|
|
33
|
+
## 快速开始
|
|
34
|
+
|
|
35
|
+
在会放配置文件的目录执行:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx bk-schema-checker init
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
编辑生成的 `bk-schema-checker.json`,把三个文件夹指到本仓库的实际位置,然后:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx bk-schema-checker
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
有未忽略的 error 时退出码为 `1`,warning 不会单独让检查失败。可加进 `package.json`:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"scripts": {
|
|
52
|
+
"check:schema": "bk-schema-checker"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 配置
|
|
58
|
+
|
|
59
|
+
配置文件名是 `bk-schema-checker.json`。CLI 从当前目录向上查找(最多 4 层)。相对路径相对**该文件所在目录**,也可以写绝对路径。
|
|
60
|
+
|
|
61
|
+
配置可以放在前端目录,用 `../` 指向后台,例如 `frontend/bk-schema-checker.json` 里写 `"backendDir": "../backend"`。Python 的 `include("backend....")` 这类绝对导入会从后台包的上一层解析,不要求配置文件和 Python 包在同一目录。
|
|
62
|
+
|
|
63
|
+
| 配置 key | 默认值 | 说明 |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `backendDir` | `bkiam/apis/web` | 后台接口文件夹,入口是其中的 `urls.py` |
|
|
66
|
+
| `mockDir` | 见说明 | 前端 mock 文件夹。配置文件里省略或写成 `""` 则不校验 mock,只对照后台与 services |
|
|
67
|
+
| `servicesDir` | `frontend/src/services` | 前端接口文件夹 |
|
|
68
|
+
| `ignoreRoutes` | `[]` | 跳过校验的路由列表,每项是 `{ "url", "method" }`。`method` 忽略大小写 |
|
|
69
|
+
|
|
70
|
+
没有配置文件时,路径用上表默认值,其中 `mockDir` 为 `frontend/src/mock`(沿用蓝鲸 IAM 仓库布局)。有配置文件但没写 `mockDir` 时,不校验 mock。其他项目请改成自己的路径。命令行的 `--backend`、`--mock`、`--services`,以及 `check()` 的同名参数,覆盖文件里的路径。`check({ mockDir: "" })` 或 `--mock ""` 也会关掉 mock 校验。
|
|
71
|
+
|
|
72
|
+
`ignoreRoutes` 按报告里的路由 URL 和 HTTP 方法跳过整条校验,不再对请求、响应、方法覆盖报错。`url` 与报告中的 `path` 对齐,例如 `/api/v1/web/widgets/`、`/api/v1/web/widgets/<int:id>/`;末尾斜杠可有可无。`method` 写成 `GET` 或 `get` 都可以。没写 method 的问题(例如 `route.unmatched`)只要 URL 命中也会跳过。`check({ ignoreRoutes })` 会整表覆盖文件里的列表。
|
|
73
|
+
|
|
74
|
+
`rules` 里每个驼峰 key 控制是否报出某一类结果:
|
|
75
|
+
|
|
76
|
+
- `false`:忽略。不会出现在文本报告或 JSON 的 `issues` 里,也不计入退出码
|
|
77
|
+
- `true`:报出来
|
|
78
|
+
- 文件不存在、没有 `rules`、或没写某个 key 时,按 `true` 处理
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"backendDir": "../backend/apps/api",
|
|
83
|
+
"mockDir": "src/mock",
|
|
84
|
+
"servicesDir": "src/services",
|
|
85
|
+
"ignoreRoutes": [
|
|
86
|
+
{ "url": "/api/v1/web/widgets/", "method": "GET" }
|
|
87
|
+
],
|
|
88
|
+
"rules": {
|
|
89
|
+
"responseMissingField": false,
|
|
90
|
+
"requestMissingField": false
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
上面两项会被忽略,没写到 `rules` 里的 key 仍然报出来。只对照后台与 services 时不要写 `mockDir`:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"backendDir": "../backend/apps/api",
|
|
100
|
+
"servicesDir": "src/services"
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
程序调用可以用 `ignore` 覆盖文件,同名项以参数为准:
|
|
105
|
+
|
|
106
|
+
```js
|
|
107
|
+
import { check } from "bk-schema-checker";
|
|
108
|
+
|
|
109
|
+
const result = await check({
|
|
110
|
+
root: process.cwd(),
|
|
111
|
+
mockDir: "src/mock",
|
|
112
|
+
ignore: { responseMissingField: false },
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
报告里的 `code` 是带点号的内部代号,例如 `response.extra_field`。配置 key 用驼峰,例如 `responseExtraField`。
|
|
117
|
+
|
|
118
|
+
`init` 会列出全部 rule。其中 `routeUnmatched`、`backendUntyped`、`responseExtraField`、`responseEmptySample` 默认为 `false`,其余为 `true`。文件已存在时不覆盖。
|
|
119
|
+
|
|
120
|
+
## CLI
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
bk-schema-checker -h
|
|
124
|
+
bk-schema-checker -V
|
|
125
|
+
bk-schema-checker init [--root dir]
|
|
126
|
+
bk-schema-checker [--root dir] [--mock dir] [--services dir] [--backend dir] [--prefix /api] [--format text|json] [--output file] [--write-fixes]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
| 参数 | 说明 |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `-h` / `--help` / `help` | 打印说明 |
|
|
132
|
+
| `-V` / `-v` / `--version` / `version` | 打印版本号 |
|
|
133
|
+
| `init` | 在 `--root`(默认当前目录)写入配置文件 |
|
|
134
|
+
| `--root` | 项目根。未传时从 cwd 向上找配置文件;没有配置文件时,若同时存在 `frontend/src/mock` 和 `bkiam/apis/web` 也当作根 |
|
|
135
|
+
| `--mock` / `--services` / `--backend` | 覆盖配置里的三个路径。`--mock ""` 不校验 mock |
|
|
136
|
+
| `--prefix` | 覆盖后台 URL 前缀。未传时从站点 `urls.py` 对入口模块的挂载读取;读不到则为 `/` |
|
|
137
|
+
| `--format` | `text`(默认)或 `json` |
|
|
138
|
+
| `--output` | 把报告写到文件,父目录不存在时会创建 |
|
|
139
|
+
| `--write-fixes` | 有 error 或 warning 时,在项目根最多写两份修复建议:`bk-schema-checker-fixes-frontend.md`,以及有后台问题时的 `bk-schema-checker-fixes-backend.md`。某一侧没有问题时删除对应文件。不传此参数则不写、也不删 |
|
|
140
|
+
|
|
141
|
+
## 程序调用
|
|
142
|
+
|
|
143
|
+
```js
|
|
144
|
+
import { check } from "bk-schema-checker";
|
|
145
|
+
|
|
146
|
+
const result = await check({ root: process.cwd() });
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
| 参数 | 说明 |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `root` | 必填。配置文件所在目录 |
|
|
152
|
+
| `mockDir` / `servicesDir` / `backendDir` | 覆盖配置路径。`mockDir: ""` 不校验 mock |
|
|
153
|
+
| `backendEntry` | 直接指定后台 `urls.py`。写了它就不再用 `backendDir/urls.py` |
|
|
154
|
+
| `prefix` | 覆盖后台 URL 前缀 |
|
|
155
|
+
| `ignore` | 覆盖 `rules`,值为 `false` 表示忽略 |
|
|
156
|
+
| `ignoreRoutes` | 覆盖配置文件里的忽略路由列表 |
|
|
157
|
+
|
|
158
|
+
返回值包含 `ok`、`summary`、`checked`、`issues`。`issues[].code` 见下表。
|
|
159
|
+
|
|
160
|
+
## 路径与方法怎么对上
|
|
161
|
+
|
|
162
|
+
mock 文件按路径约定还原 URL,再对后台路由。
|
|
163
|
+
|
|
164
|
+
| mock 文件(相对 `mockDir/api`) | 对上的路径 |
|
|
165
|
+
| --- | --- |
|
|
166
|
+
| `v1/web/users/index.ts` | `/api/v1/web/users/` |
|
|
167
|
+
| `v1/web/users/_id.ts` | `/api/v1/web/users/<id>/` |
|
|
168
|
+
| `groups/-/search.ts` | `/api/v1/web/groups/-/search/`(`-` 是字面量) |
|
|
169
|
+
|
|
170
|
+
- `_id` 只匹配 Django 路径参数;多个 `_id` 按出现顺序对应
|
|
171
|
+
- 带 `export const match` 的文件用该正则去对后台路径
|
|
172
|
+
- `mockDir/install.ts`(或 `install.js`)里 `installMock({ prefix })` 会替换默认前缀 `/api`,例如 `prefix: "/apis"` 让 `api/tickets/index.ts` 对上 `/apis/tickets/`
|
|
173
|
+
- 每个文件需要 `export default` 函数。bk-local-mock 只把 default export 当作接口实现
|
|
174
|
+
- 同一文件用 `getMethod(config)` 区分 GET / POST 等。后台有的方法,mock 要有对应返回分支;mock 写死了后台没有的方法会报 `methodUnknown`
|
|
175
|
+
|
|
176
|
+
后台可以是 `path` + `APIView`,也可以是 `DefaultRouter` / `SimpleRouter` 注册的 ViewSet。`include(变量)`、`urlpatterns = router.urls` 和 `as_view({"get": "list"})` 会展开。`list` / `retrieve` / `create` / `update` / `destroy` 以及 `@action` 映射成 HTTP 方法。`ModelViewSet` 上没重写的标准动作按 DRF 约定补上。
|
|
177
|
+
|
|
178
|
+
## 请求怎么比
|
|
179
|
+
|
|
180
|
+
以 services 函数的参数类型为准。写了 `mockDir` 时,先把 mock 对上后台,再在 `servicesDir/source` 里找相同路径、相同方法的 `http.get` / `http.post` / `http.put` / `http.patch` / `http.delete`,找不到记为 `request.service_missing`。没写 `mockDir` 时从 services 出发对后台:对得上就比请求类型,对不上记为 `route.unmatched`;services 用了后台没有的方法记为 `method.unknown`。
|
|
181
|
+
|
|
182
|
+
- 路径参数:Django `<str:>` / `<slug:>` / `<uuid:>` / `<path:>` 和没写转换器的 `<system_id>` 对应字符串,`<int:>` 对应整数。写进路径的字段不会再被当成查询参数或请求体
|
|
183
|
+
- 查询参数:后台来自 `query_serializer`、FilterSet、`filterset_fields` / `filter_fields`、分页参数。GET 的第二个参数和 URL 上的 `?key=` 都算查询参数。FilterSet lookup 同时认 django-filter 的 `field__lookup` 和前端常见的 `field_lookup`
|
|
184
|
+
- 请求体:后台优先来自 swagger `request_body`,没有时再看方法里的 `params_validate(...)` 或 `XxxSLZ(data=request.data)`。`required=False` 或带 `default` 的字段可以不出现;`read_only=True` 和 `SerializerMethodField` 不要求前端提交。类上的 `serializer_class` 若是输出序列化器,不会当成 PATCH / PUT 的请求体
|
|
185
|
+
- 分页查询参数来自类或 `@action` 上的 `pagination_class`;没写时用 `settings.py` 或 `config/default.py` 里的 `REST_FRAMEWORK["DEFAULT_PAGINATION_CLASS"]`。`pagination_class = None` 表示不分页。`LimitOffsetPagination` 对应 `limit`、`offset`;`PageNumberPagination` 对应 `page`(写了 `page_size_query_param` 再加该名)。这些参数只进入查询参数,不当作必填
|
|
186
|
+
|
|
187
|
+
## 响应怎么比
|
|
188
|
+
|
|
189
|
+
比较的是 handler 的返回值。`bk-local-mock` 的 `wrapResponse`(例如 `{ code, data, message }`)包在 handler 外面,不参与字段比较。
|
|
190
|
+
|
|
191
|
+
- 字段名集合和类型必须与成功响应序列化器一致,嵌套对象和数组元素递归比较
|
|
192
|
+
- `write_only=True` 的字段不在响应里
|
|
193
|
+
- 后台字段没有 `allow_null=True` 时,mock 不能给 `null` / `undefined`
|
|
194
|
+
- 能解析出 `choices` 字面量时,样本值必须在可选值中
|
|
195
|
+
- 分页看方法体是否调用了 `get_page_params`、`paginate_queryset`、`get_paginated_response`,或直接 `Response({"count", "results"})`。swagger 写成 `Serializer(many=True)` 但方法走了分页时,仍按 `{ count, results }` 对象比较。`listResult` / `paginatedListResult` 多出来的 `next`、`previous`、`permission` 记为冗余字段
|
|
196
|
+
- 后台成功响应没有响应体时,不比较 mock 返回的数据
|
|
197
|
+
- 空的 `Serializer(many=True)` 只检查是不是数组,并给出警告
|
|
198
|
+
- 执行结果是空对象时,才退回静态推导
|
|
199
|
+
- 没写 swagger `responses` 时,用能静态看懂的 `serializer_class` 或 `get_serializer_class`。`ModelSerializer` 会再读 `Meta.model`(`fields`、`exclude`、`read_only_fields`、`extra_kwargs`)
|
|
200
|
+
|
|
201
|
+
## 规则一览
|
|
202
|
+
|
|
203
|
+
| 配置 key | 报告 code | 级别 | 说明 |
|
|
204
|
+
| --- | --- | --- | --- |
|
|
205
|
+
| `mockParseError` | `mock.parse_error` | error | mock 文件无法解析。该文件不再往下对路由、请求和响应 |
|
|
206
|
+
| `mockNoHandler` | `mock.no_handler` | error | 对上了后台路由,但没有 `export default` handler |
|
|
207
|
+
| `routeUnmatched` | `route.unmatched` | error | mock 还原出的 URL 在 `backendDir` 里找不到对应路由 |
|
|
208
|
+
| `methodUnknown` | `method.unknown` | error | mock 用 `getMethod` 写死了某个方法,后台这条路由没有。兜底返回不会触发 |
|
|
209
|
+
| `methodUncovered` | `method.uncovered` | error | 后台声明了某个方法,mock 没有对应返回分支。该分支的请求和响应也不再比较 |
|
|
210
|
+
| `backendSchemaMissing` | `backend.schema_missing` | warning | 后台方法没有可用的成功响应序列化器,跳过响应字段比较。请求参数仍检查 |
|
|
211
|
+
| `backendUntyped` | `backend.untyped` | warning | 后台成功响应用了空的 `Serializer()` 或没有字段的 `Serializer(many=True)`。`init` 默认忽略 |
|
|
212
|
+
| `responseUnresolved` | `response.unresolved` | error | 执行 mock 抛错,或得不到可比较的数据,静态推导也失败 |
|
|
213
|
+
| `responseContainer` | `response.container` | error | 根节点容器类型和后台不一致(对象 / 数组 / 分页对象) |
|
|
214
|
+
| `responseExtraField` | `response.extra_field` | error | mock 返回了后台响应序列化器没有的字段 |
|
|
215
|
+
| `responseMissingField` | `response.missing_field` | error | 后台会输出的字段,mock 样本里没有(含 `required=False` 和 `SerializerMethodField`) |
|
|
216
|
+
| `responseType` | `response.type` | error | 字段名在,类型对不上。`number` 可对应整数或浮点;非整数字面量对不上 `IntegerField` |
|
|
217
|
+
| `responseNull` | `response.null` | error | mock 给了 `null` / `undefined`,后台字段没有 `allow_null=True` |
|
|
218
|
+
| `responseChoice` | `response.choice` | error | 样本值不在可解析的 `choices` 中。无法静态求值时不报 |
|
|
219
|
+
| `responseEmptySample` | `response.empty_sample` | warning | 后台要求有字段的数组,mock 给了 `[]`。同一 handler 的非空样本仍会比较 |
|
|
220
|
+
| `requestUnknownQuery` | `request.unknown_query` | error | services 查询类型有这个字段,后台没有声明 |
|
|
221
|
+
| `requestMissingQuery` | `request.missing_query` | error | 后台查询参数必填,services 查询类型没有。分页参数和 FilterSet lookup 默认非必填 |
|
|
222
|
+
| `requestUnexpectedBody` | `request.unexpected_body` | error | 后台没有请求体,services 的 POST / PUT / PATCH / DELETE 却传了 body 字段 |
|
|
223
|
+
| `requestMissingBody` | `request.missing_body` | error | 后台有必填请求体,services 没有可展开的对象类型。能展开时缺单个字段走 `requestMissingField` |
|
|
224
|
+
| `requestExtraField` | `request.extra_field` | error | services 请求体有后台请求体序列化器没有的字段。`ModelSerializer` 从模型展开的字段(含 `read_only`)算已声明。方法里的 `XxxSLZ(data=request.data)` 也算已声明,不会误用输出用的 `serializer_class` |
|
|
225
|
+
| `requestMissingField` | `request.missing_field` | error | 后台请求体的必填字段没有出现在 services 的 body 类型里 |
|
|
226
|
+
| `requestOptionalRequired` | `request.optional_required` | error | 后台必填,services 却标成可选,例如 `name?: string` |
|
|
227
|
+
| `requestType` | `request.type` | error | 请求字段类型和后台不一致。后台的字符串 / 整数 / 浮点与 services 的 `string` / `number` 可以互认 |
|
|
228
|
+
| `requestNull` | `request.null` | error | services 把字段收成 `null`,后台没有 `allow_null=True`。可选字段走 `requestOptionalRequired` |
|
|
229
|
+
| `requestChoice` | `request.choice` | error | services 给了具体字面量,但不在可解析的 `choices` 中。宽泛的 `string` / `number` 不报 |
|
|
230
|
+
| `requestUntyped` | `request.untyped` | warning | services 声明了类型,但无法展开成字段列表;或 services 文件解析失败 |
|
|
231
|
+
| `requestServiceMissing` | `request.service_missing` | warning | 写了 `mockDir` 且 mock 已对上后台,但 `servicesDir/source` 里没有相同路径和方法的 `http.*` 调用 |
|
|
232
|
+
|
|
233
|
+
## 会跳过什么
|
|
234
|
+
|
|
235
|
+
- 正则路由里带分组的 `re_path`
|
|
236
|
+
- 函数视图
|
|
237
|
+
- 分支过于动态、无法静态看懂的 `get_serializer_class`
|
|
238
|
+
- 后台成功响应没有响应体时的 mock 数据比较
|
|
239
|
+
|
|
240
|
+
FilterSet 同时认 `filterset_class`、`filter_class`,以及 ViewSet 上的 `filterset_fields` / `filter_fields`(列表或 `{字段: [lookup]}`;`exact` 用字段本名,其它 lookup 同时认 django-filter 的 `field__lookup` 和前端常见的 `field_lookup`,例如 `apply_time__gte` / `apply_time_gte`)。`@action(..., filter_fields=None)` 会盖掉同名类属性。`ForeignKey` / `OneToOneField` 按整型主键,`ManyToManyField` 按整型数组。`from .alarm import *` 这种再导出也能定位到模型类。`common_swagger_auto_schema` 和 `swagger_auto_schema` 同样读取。
|
package/package.json
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bk-schema-checker",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "对照前端 services、Django REST 序列化器,以及可选的 bk-local-mock 响应,做接口协议检查。不启动 Django。",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "austinqli",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"bin": {
|
|
9
|
+
"bk-schema-checker": "./bin/bk-schema-checker.js"
|
|
10
|
+
},
|
|
11
|
+
"main": "./src/index.js",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": "./src/index.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin",
|
|
17
|
+
"py/load_backend.py",
|
|
18
|
+
"src",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"bk-schema-checker",
|
|
23
|
+
"schema-checker",
|
|
24
|
+
"django",
|
|
25
|
+
"drf",
|
|
26
|
+
"mock",
|
|
27
|
+
"schema",
|
|
28
|
+
"cli",
|
|
29
|
+
"typescript"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"jiti": ">=2"
|
|
36
|
+
},
|
|
37
|
+
"peerDependenciesMeta": {
|
|
38
|
+
"jiti": {
|
|
39
|
+
"optional": true
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"check": "node ./bin/bk-schema-checker.js",
|
|
44
|
+
"test": "node --test test/"
|
|
45
|
+
}
|
|
6
46
|
}
|