bk-schema-checker 0.1.1 → 0.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bk-schema-checker",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "对照前端 services、Django REST 序列化器,以及可选的 bk-local-mock 响应,做接口协议检查。不启动 Django。",
5
5
  "type": "module",
6
6
  "author": "austinqli",
@@ -938,7 +938,9 @@ class BackendLoader:
938
938
  if func is not None and is_paginated(func):
939
939
  return True
940
940
  if spec["action"] == "list" and not self.pagination_disabled(ref):
941
- return self.class_assign_mro(ref, "pagination_class") is not None
941
+ # DRF ListModelMixin.list 在 pagination_class 非空时包成 {count, results}。
942
+ # 类上没写则用 REST_FRAMEWORK["DEFAULT_PAGINATION_CLASS"],和查询参数同源。
943
+ return self.pagination_source(ref, spec) is not None
942
944
  return False
943
945
 
944
946
  def pagination_disabled_here(self, ref):
package/src/mock-shim.js CHANGED
@@ -23,7 +23,7 @@ export const listResult = (results) => ({
23
23
  });
24
24
 
25
25
  export const getRequestParam = (config, key) => {
26
- const value = config?.params?.[key];
26
+ const value = config?.params?.[key] ?? new URL(config?.url || "", "https://mock.local").searchParams.get(key);
27
27
  return value === undefined || value === null ? "" : String(value);
28
28
  };
29
29
 
@@ -38,3 +38,5 @@ export const paginatedListResult = (results, config) => {
38
38
  };
39
39
 
40
40
  export const getMethod = (config) => (config?.method || "get").toLowerCase();
41
+
42
+ export const getPathname = (url) => new URL(url || "", "https://mock.local").pathname;
package/src/runtime.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import fs from "node:fs";
2
+ import { createRequire } from "node:module";
2
3
  import path from "node:path";
3
4
  import { fileURLToPath, pathToFileURL } from "node:url";
4
5
 
@@ -9,12 +10,12 @@ const METHOD_ORDER = ["get", "post", "put", "patch", "delete"];
9
10
  * 同一个运行时里模块缓存是共享的,后执行的接口能看到前面写入的内存数据。
10
11
  */
11
12
  export async function createMockRuntime({ root, mockDir, servicesDir }) {
12
- const createJiti = await loadCreateJiti(root);
13
+ const createJiti = await loadCreateJiti(root, mockDir);
13
14
  const jiti = createJiti(import.meta.url, {
14
15
  alias: {
15
16
  "@mock": mockDir,
16
17
  "@services": servicesDir,
17
- "bk-local-mock": findMockPackage(root),
18
+ "bk-local-mock": findMockPackage(root, mockDir),
18
19
  },
19
20
  interopDefault: true,
20
21
  fsCache: false,
@@ -200,7 +201,7 @@ function snapshot(value) {
200
201
  }
201
202
  }
202
203
 
203
- async function loadCreateJiti(root) {
204
+ async function loadCreateJiti(root, mockDir) {
204
205
  try {
205
206
  const mod = await import("jiti");
206
207
  if (typeof mod.createJiti === "function") {
@@ -209,6 +210,17 @@ async function loadCreateJiti(root) {
209
210
  } catch {
210
211
  // 检查器自己没装 jiti 时,用前端工程里的那一份。
211
212
  }
213
+ for (const start of moduleResolveStarts(root, mockDir)) {
214
+ try {
215
+ const resolved = createRequire(start).resolve("jiti");
216
+ const mod = await import(pathToFileURL(resolved).href);
217
+ if (typeof mod.createJiti === "function") {
218
+ return mod.createJiti;
219
+ }
220
+ } catch {
221
+ // 这一层没有安装,继续往上看。
222
+ }
223
+ }
212
224
  for (const candidate of jitiCandidates(root)) {
213
225
  if (fs.existsSync(candidate)) {
214
226
  const mod = await import(pathToFileURL(candidate).href);
@@ -220,13 +232,25 @@ async function loadCreateJiti(root) {
220
232
  throw new Error("执行 mock 需要 jiti。请在 frontend 安装依赖,或在 bk-schema-checker 中安装 jiti。");
221
233
  }
222
234
 
223
- function findMockPackage(root) {
224
- for (const candidate of [
225
- path.join(root, "frontend/node_modules/bk-local-mock/index.js"),
226
- path.resolve(fileDir(), "../../frontend/node_modules/bk-local-mock/index.js"),
227
- ]) {
228
- if (fs.existsSync(candidate)) {
229
- return candidate;
235
+ function moduleResolveStarts(root, mockDir) {
236
+ return [
237
+ mockDir && path.join(mockDir, "handler.js"),
238
+ root && path.join(root, "package.json"),
239
+ root && path.join(root, "frontend/package.json"),
240
+ path.join(fileDir(), "runtime.js"),
241
+ ].filter(Boolean);
242
+ }
243
+
244
+ /**
245
+ * 按 Node 解析规则找已安装的 bk-local-mock。
246
+ * 配置文件常放在 frontend/,旧逻辑只认 root/frontend/node_modules,会漏掉当前工程自己的依赖。
247
+ */
248
+ export function findMockPackage(root, mockDir) {
249
+ for (const start of moduleResolveStarts(root, mockDir)) {
250
+ try {
251
+ return createRequire(start).resolve("bk-local-mock");
252
+ } catch {
253
+ // 这一层没有安装,继续往上看。
230
254
  }
231
255
  }
232
256
  return path.join(fileDir(), "mock-shim.js");
package/src/ts.js CHANGED
@@ -6,6 +6,7 @@ import { maskComments, readIdentifier, skipSpace, sliceBalanced, splitTop } from
6
6
  const HELPERS = new Set([
7
7
  "clone",
8
8
  "getMethod",
9
+ "getPathname",
9
10
  "getRequestParam",
10
11
  "listResult",
11
12
  "paginatedListResult",
@@ -1532,7 +1533,7 @@ function evalCall(node, env) {
1532
1533
  }
1533
1534
  return new Partial("string");
1534
1535
  }
1535
- if (callee?.helper === "getMethod") {
1536
+ if (callee?.helper === "getMethod" || callee?.helper === "getPathname") {
1536
1537
  return new Partial("string");
1537
1538
  }
1538
1539
  if (callee && callee.kind === "function") {