befly 3.17.13 → 3.17.14

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.
@@ -2,7 +2,6 @@ import { UAParser } from "ua-parser-js";
2
2
 
3
3
  import adminTable from "../../tables/admin.json";
4
4
  import { toSessionTtlSeconds } from "../../utils/toSessionTtlSeconds.js";
5
- import { isString } from "../../utils/is.js";
6
5
 
7
6
  export default {
8
7
  name: "管理员登录",
package/checks/table.js CHANGED
@@ -8,10 +8,8 @@ z.config(z.locales.zhCN());
8
8
 
9
9
  const lowerCamelRegex = /^_?[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$/;
10
10
  const noTrimString = z.string().refine(isNoTrimStringAllowEmpty, "不允许首尾空格");
11
- const FIELD_NAME_REGEX_SOURCE = "^[\\u4e00-\\u9fa5a-zA-Z0-9_]+$";
12
11
  const INPUT_TYPES = ["number", "integer", "string", "char", "array", "array_number", "array_integer", "json", "json_number", "json_integer"];
13
12
 
14
- const fieldNameRegex = new RegExp(FIELD_NAME_REGEX_SOURCE);
15
13
  const inputRegexLiteral = /^\/.*?\/[gimsuy]*$/;
16
14
  const inputEnumRegex = /^[^/].*\|.*$/;
17
15
  const inputAliasRegex = /^@.+$/;
package/hooks/auth.js CHANGED
@@ -3,7 +3,7 @@ import { toSessionTtlSeconds } from "../utils/toSessionTtlSeconds.js";
3
3
  export default {
4
4
  deps: [],
5
5
  handler: async (befly, ctx) => {
6
- const authHeader = ctx.req.headers.get("authorization");
6
+ const authHeader = ctx.headers.get("authorization");
7
7
  const ttlSeconds = toSessionTtlSeconds(befly.config?.session?.expireDays);
8
8
 
9
9
  if (authHeader && authHeader.startsWith("Bearer ")) {
package/hooks/parser.js CHANGED
@@ -15,36 +15,25 @@ const xmlParser = new XMLParser();
15
15
  export default {
16
16
  deps: ["auth"],
17
17
  handler: async (befly, ctx) => {
18
- if (!ctx.apiPath) {
19
- return;
20
- }
21
-
22
- // body=raw 模式:跳过解析,保留原始请求供 handler 自行处理
18
+ // apiBody=raw 模式:跳过解析,保留原始请求供 handler 自行处理
23
19
  // 适用于:微信回调、支付回调、webhook 等需要手动解密/验签的场景
24
- if (ctx.body === "raw") {
20
+ if (ctx.apiBody === "raw") {
25
21
  ctx.body = {};
26
22
  return;
27
23
  }
28
-
24
+ const queryParams = Object.fromEntries(new URL(ctx.url).searchParams);
25
+ const contentType = ctx.headers.get("content-type") || "";
29
26
  // GET 请求:解析查询参数
30
- if (ctx.req.method === "GET") {
31
- const url = new URL(ctx.req.url);
32
- const params = Object.fromEntries(url.searchParams);
33
- ctx.body = params;
34
- } else if (ctx.req.method === "POST") {
27
+ if (ctx.method === "GET") {
28
+ ctx.body = queryParams;
29
+ } else if (ctx.method === "POST") {
35
30
  // POST 请求:解析请求体
36
- const contentType = ctx.req.headers.get("content-type") || "";
37
- // 获取 URL 查询参数(POST 请求也可能带参数)
38
- const url = new URL(ctx.req.url);
39
- const queryParams = Object.fromEntries(url.searchParams);
40
-
41
31
  try {
42
32
  // JSON 格式
43
33
  if (contentType.includes("application/json")) {
44
34
  const body = await ctx.req.json();
45
35
  // 合并 URL 参数和请求体(请求体优先)
46
- const merged = Object.assign({}, queryParams, body);
47
- ctx.body = merged;
36
+ ctx.body = Object.assign({}, queryParams, body);
48
37
  } else if (contentType.includes("application/xml") || contentType.includes("text/xml")) {
49
38
  // XML 格式
50
39
  const text = await ctx.req.text();
@@ -53,8 +42,7 @@ export default {
53
42
  const rootKey = Object.keys(parsed)[0];
54
43
  const body = rootKey && typeof parsed[rootKey] === "object" ? parsed[rootKey] : parsed;
55
44
  // 合并 URL 参数和请求体(请求体优先)
56
- const merged = Object.assign({}, queryParams, body);
57
- ctx.body = merged;
45
+ ctx.body = Object.assign({}, queryParams, body);
58
46
  } else {
59
47
  // 不支持的 Content-Type
60
48
  ctx.response = ErrorResponse(
@@ -1,8 +1,7 @@
1
1
  import { CacheKeys } from "../lib/cacheKeys.js";
2
- import { Logger } from "../lib/logger.js";
3
2
  // 相对导入
4
3
  import { ErrorResponse } from "../utils/response.js";
5
- import { isNonEmptyString, isString, isValidPositiveInt } from "../utils/is.js";
4
+ import { isValidPositiveInt } from "../utils/is.js";
6
5
 
7
6
  /**
8
7
  * 权限检查钩子
@@ -16,7 +15,7 @@ export default {
16
15
  deps: ["validator"],
17
16
  handler: async (befly, ctx) => {
18
17
  // 1. 接口无需权限
19
- if (ctx.auth === false) {
18
+ if (ctx.apiAuth === false) {
20
19
  return;
21
20
  }
22
21
 
@@ -31,8 +30,8 @@ export default {
31
30
  return;
32
31
  }
33
32
 
34
- // 3.5 auth 为角色类型白名单时,仅做 ctx.roleType 校验
35
- if (Array.isArray(ctx.auth) && ctx.auth.includes(ctx.roleType) === false) {
33
+ // 3.5 apiAuth 为角色类型白名单时,仅做 ctx.roleType 校验
34
+ if (Array.isArray(ctx.apiAuth) && ctx.apiAuth.includes(ctx.roleType) === false) {
36
35
  ctx.response = ErrorResponse(
37
36
  ctx,
38
37
  `无权访问 ${ctx.apiName} 接口`,
@@ -15,7 +15,7 @@ export default {
15
15
  const rawBody = isPlainObject(ctx.body) ? ctx.body : {};
16
16
  const nextBody = {};
17
17
 
18
- for (const [field] of Object.entries(ctx.fields)) {
18
+ for (const [field] of Object.entries(ctx.apiFields)) {
19
19
  let value = rawBody[field];
20
20
 
21
21
  if (value === undefined) {
@@ -33,7 +33,7 @@ export default {
33
33
  ctx.body = nextBody;
34
34
 
35
35
  // 验证参数
36
- const result = Validator.validate(ctx.body, ctx.fields, ctx.required || []);
36
+ const result = Validator.validate(ctx.body, ctx.apiFields, ctx.apiRequired);
37
37
 
38
38
  if (result.code !== 0) {
39
39
  ctx.response = ErrorResponse(ctx, result.firstError || "参数验证失败", 1, null, result.fieldErrors, "validator");
package/index.js CHANGED
@@ -32,7 +32,6 @@ import { calcPerfTime } from "./utils/calcPerfTime.js";
32
32
  import { scanSources } from "./utils/scanSources.js";
33
33
  import { isPrimaryProcess } from "./utils/is.js";
34
34
  import { deepMerge } from "./utils/deepMerge.js";
35
- import { omit } from "./utils/util.js";
36
35
  import { sortModules } from "./utils/sortModules.js";
37
36
 
38
37
  function prefixMenuPaths(menus, prefix) {
package/lib/connect.js CHANGED
@@ -87,7 +87,7 @@ export class Connect {
87
87
  };
88
88
 
89
89
  // Called when disconnected from Redis server
90
- this.redisClient.onclose = (error) => {
90
+ this.redisClient.onclose = () => {
91
91
  Logger.warn("Redis 断开连接");
92
92
  };
93
93
  } catch (error) {
@@ -1,4 +1,4 @@
1
- import { isNullable, isNumber } from "../../utils/is.js";
1
+ import { isNumber } from "../../utils/is.js";
2
2
  import { snakeCase } from "../../utils/util.js";
3
3
  import { Logger } from "../logger.js";
4
4
  import { SqlBuilder } from "../sqlBuilder/index.js";
package/lib/logger.js CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { createWriteStream, existsSync, mkdirSync } from "node:fs";
6
6
  import { stat } from "node:fs/promises";
7
- import { isAbsolute as nodePathIsAbsolute, join as nodePathJoin, resolve as nodePathResolve } from "node:path";
7
+ import { join as nodePathJoin, resolve as nodePathResolve } from "node:path";
8
8
 
9
9
  import { formatYmdHms } from "../utils/formatYmdHms.js";
10
10
  import { buildSensitiveKeyMatcher, sanitizeLogObject } from "../utils/loggerUtils.js";
@@ -5,7 +5,6 @@
5
5
 
6
6
  import { Connect } from "./connect.js";
7
7
  import { Logger } from "./logger.js";
8
- import { isFiniteNumber, isNonEmptyString, isString } from "../utils/is.js";
9
8
 
10
9
  /**
11
10
  * Redis 助手类
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.17.13",
4
- "gitHead": "1259303ee55a5aa686be914e961dc42767c0136b",
3
+ "version": "3.17.14",
4
+ "gitHead": "c71ecec269032dcc0aa8ca995da4918f99f5ee0e",
5
5
  "private": false,
6
6
  "description": "Befly - 为 Bun 专属打造的 JavaScript API 接口框架核心引擎",
7
7
  "keywords": [
package/router/api.js CHANGED
@@ -56,6 +56,7 @@ export function apiHandler(apis, hooks, context) {
56
56
  const ctx = {
57
57
  // 请求的参数
58
58
  method: req.method,
59
+ url: req.url,
59
60
  body: {},
60
61
  req: req,
61
62
  now: now,
@@ -66,13 +67,13 @@ export function apiHandler(apis, hooks, context) {
66
67
  // 接口的参数
67
68
  apiPath: apiData.apiPath,
68
69
  apiName: apiData.name,
69
- filePath: apiData.filePath,
70
- handler: apiData.handler,
71
- method: apiData.method,
72
- body: apiData.body,
73
- auth: apiData.auth,
74
- fields: apiData.fields,
75
- required: apiData.required
70
+ apiMethod: apiData.method,
71
+ apiBody: apiData.body,
72
+ apiHandler: apiData.handler,
73
+ apiAuth: apiData.auth,
74
+ apiFields: apiData.fields,
75
+ apiRequired: apiData.required,
76
+ apiFile: apiData.filePath
76
77
  };
77
78
 
78
79
  try {
@@ -108,7 +109,7 @@ export function apiHandler(apis, hooks, context) {
108
109
  Logger.info("请求", logData);
109
110
 
110
111
  // 5. 执行 API handler
111
- const result = await ctx.handler(context, ctx);
112
+ const result = await ctx.apiHandler(context, ctx);
112
113
 
113
114
  if (result instanceof Response) {
114
115
  ctx.response = result;
@@ -120,9 +121,8 @@ export function apiHandler(apis, hooks, context) {
120
121
  return FinalResponse(ctx);
121
122
  } catch (err) {
122
123
  // 全局错误处理
123
- const errorPath = ctx.apiPath ? ctx.apiPath : req.url;
124
124
  Logger.error("请求错误", err, {
125
- path: errorPath,
125
+ path: ctx.apiPath,
126
126
  requestId: requestId,
127
127
  method: req.method,
128
128
  apiPath: ctx.apiPath,
@@ -57,7 +57,7 @@ export function buildSyncDbDiff(groupedDbColumns, existingTableMap) {
57
57
  const missingFields = [];
58
58
  for (const columnMeta of columns) {
59
59
  const fieldInfo = toSyncDbFieldDef(columnMeta);
60
- if (Object.prototype.hasOwnProperty.call(existingFields, fieldInfo.fieldName)) {
60
+ if (Object.hasOwn(existingFields, fieldInfo.fieldName)) {
61
61
  continue;
62
62
  }
63
63
 
@@ -1,14 +1,3 @@
1
- function getValueByPath(source, path) {
2
- if (!Array.isArray(path)) return undefined;
3
-
4
- let current = source;
5
- for (const segment of path) {
6
- if (current === null || current === undefined) return undefined;
7
- current = current[segment];
8
- }
9
- return current;
10
- }
11
-
12
1
  function formatValue(value) {
13
2
  if (value === undefined) return "undefined";
14
3
  if (value === null) return "null";
@@ -1,5 +1,3 @@
1
- import { join } from "pathe";
2
-
3
1
  import {
4
2
  //
5
3
  coreTableDir,