befly 3.16.8 → 3.16.10

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/befly.js CHANGED
@@ -101,6 +101,22 @@ function isFiniteNumber(value) {
101
101
  function isIntegerNumber(value) {
102
102
  return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value);
103
103
  }
104
+ function canConvertToNumber(value) {
105
+ const maxSafe = BigInt(Number.MAX_SAFE_INTEGER);
106
+ const minSafe = BigInt(Number.MIN_SAFE_INTEGER);
107
+ if (value > maxSafe || value < minSafe) {
108
+ return null;
109
+ }
110
+ const asNumber = Number(value);
111
+ if (!Number.isSafeInteger(asNumber)) {
112
+ return null;
113
+ }
114
+ const text = String(asNumber);
115
+ if (text.includes("e") || text.includes("E")) {
116
+ return null;
117
+ }
118
+ return asNumber;
119
+ }
104
120
  function formatValuePreview(value) {
105
121
  if (value === null) {
106
122
  return "null";
@@ -7887,9 +7903,19 @@ async function checkApi(apis) {
7887
7903
  hasError = true;
7888
7904
  }
7889
7905
  const auth = record["auth"];
7890
- if (auth !== undefined && typeof auth !== "boolean") {
7891
- Logger.warn(Object.assign({}, omit(record, ["handler"]), { msg: "\u63A5\u53E3\u7684 auth \u5C5E\u6027\u5FC5\u987B\u662F\u5E03\u5C14\u503C (true=\u9700\u767B\u5F55, false=\u516C\u5F00)" }));
7892
- hasError = true;
7906
+ if (auth !== undefined) {
7907
+ if (typeof auth === "boolean") {} else if (Array.isArray(auth)) {
7908
+ if (auth.length === 0) {
7909
+ Logger.warn(Object.assign({}, omit(record, ["handler"]), { msg: "\u63A5\u53E3\u7684 auth \u6570\u7EC4\u4E0D\u80FD\u4E3A\u7A7A" }));
7910
+ hasError = true;
7911
+ } else if (auth.some((item) => typeof item !== "string" || item.trim() === "")) {
7912
+ Logger.warn(Object.assign({}, omit(record, ["handler"]), { msg: "\u63A5\u53E3\u7684 auth \u6570\u7EC4\u5FC5\u987B\u4E3A\u975E\u7A7A\u5B57\u7B26\u4E32\u6570\u7EC4\uFF08roleType \u5217\u8868\uFF09" }));
7913
+ hasError = true;
7914
+ }
7915
+ } else {
7916
+ Logger.warn(Object.assign({}, omit(record, ["handler"]), { msg: "\u63A5\u53E3\u7684 auth \u5C5E\u6027\u5FC5\u987B\u662F boolean \u6216 string[]" }));
7917
+ hasError = true;
7918
+ }
7893
7919
  }
7894
7920
  const fields = record["fields"];
7895
7921
  if (fields !== undefined && fields !== null && !isPlainObject(fields)) {
@@ -9713,6 +9739,25 @@ var getApiParentPath = (apiPath) => {
9713
9739
  return "";
9714
9740
  return `/${parentSegments.join("/")}`;
9715
9741
  };
9742
+ var normalizeAuthForDb = (value) => {
9743
+ if (value === false || value === 0 || value === "0" || value === "\u5426") {
9744
+ return "\u5426";
9745
+ }
9746
+ if (Array.isArray(value)) {
9747
+ const list = value.filter((item) => typeof item === "string").map((item) => item.trim()).filter((item) => item !== "");
9748
+ if (list.length > 0) {
9749
+ return list.join(",");
9750
+ }
9751
+ return "\u662F";
9752
+ }
9753
+ if (typeof value === "string") {
9754
+ const trimmed = value.trim();
9755
+ if (trimmed !== "") {
9756
+ return trimmed;
9757
+ }
9758
+ }
9759
+ return "\u662F";
9760
+ };
9716
9761
  async function syncApi(ctx, apis) {
9717
9762
  const tableName = "addon_admin_api";
9718
9763
  if (!ctx.db) {
@@ -9752,12 +9797,13 @@ async function syncApi(ctx, apis) {
9752
9797
  }
9753
9798
  const addonName = typeof addonNameRaw === "string" ? addonNameRaw : "";
9754
9799
  const authRaw = record["auth"];
9755
- const auth = authRaw === false || authRaw === 0 ? 0 : 1;
9800
+ const auth = normalizeAuthForDb(authRaw);
9756
9801
  const parentPath = getApiParentPath(path);
9757
9802
  apiRouteKeys.add(path);
9758
9803
  const item = allDbApiMap[path];
9759
9804
  if (item) {
9760
- const shouldUpdate = name !== item.name || path !== item.path || addonName !== item.addonName || parentPath !== item.parentPath || auth !== item.auth;
9805
+ const existingAuth = normalizeAuthForDb(item.auth);
9806
+ const shouldUpdate = name !== item.name || path !== item.path || addonName !== item.addonName || parentPath !== item.parentPath || auth !== existingAuth;
9761
9807
  if (shouldUpdate) {
9762
9808
  updData.push({
9763
9809
  id: item.id,
@@ -13112,6 +13158,7 @@ var permissionHook = {
13112
13158
  if (ctx.api.auth === false) {
13113
13159
  return;
13114
13160
  }
13161
+ const authRule = ctx.api.auth;
13115
13162
  if (typeof ctx.user.id !== "number") {
13116
13163
  ctx.response = ErrorResponse(ctx, "\u672A\u767B\u5F55", 1, null, null, "auth");
13117
13164
  return;
@@ -13119,6 +13166,17 @@ var permissionHook = {
13119
13166
  if (ctx.user.roleCode === "dev") {
13120
13167
  return;
13121
13168
  }
13169
+ if (Array.isArray(authRule)) {
13170
+ const roleType = ctx.user.roleType;
13171
+ if (typeof roleType !== "string" || !authRule.includes(roleType)) {
13172
+ const apiNameLabel = typeof ctx.api.name === "string" && ctx.api.name.length > 0 ? ctx.api.name : null;
13173
+ const apiPathLabel = typeof ctx.route === "string" && ctx.route.length > 0 ? ctx.route : null;
13174
+ const apiLabel = apiNameLabel ? apiNameLabel : apiPathLabel ? apiPathLabel : "\u672A\u77E5\u63A5\u53E3";
13175
+ ctx.response = ErrorResponse(ctx, `\u65E0\u6743\u8BBF\u95EE ${apiLabel} \u63A5\u53E3`, 1, null, { apiLabel }, "permission");
13176
+ return;
13177
+ }
13178
+ return;
13179
+ }
13122
13180
  const apiPath = ctx.route;
13123
13181
  const roleCode = ctx.user.roleCode;
13124
13182
  let hasPermission = false;
@@ -15426,6 +15484,21 @@ class DbSqlError extends Error {
15426
15484
  }
15427
15485
  }
15428
15486
 
15487
+ class TransAbortError extends Error {
15488
+ payload;
15489
+ constructor(payload) {
15490
+ super("TRANSACTION_ABORT");
15491
+ this.payload = payload;
15492
+ }
15493
+ }
15494
+ function isBeflyResponse(value) {
15495
+ if (!isPlainObject(value)) {
15496
+ return false;
15497
+ }
15498
+ const record = value;
15499
+ return typeof record["code"] === "number" && typeof record["msg"] === "string";
15500
+ }
15501
+
15429
15502
  class DbHelper {
15430
15503
  redis;
15431
15504
  dbName;
@@ -15480,8 +15553,9 @@ class DbHelper {
15480
15553
  }
15481
15554
  }
15482
15555
  if (bigintValue !== null) {
15483
- if (bigintValue <= MAX_SAFE_INTEGER_BIGINT && bigintValue >= MIN_SAFE_INTEGER_BIGINT) {
15484
- nextValue = Number(bigintValue);
15556
+ const convertedNumber = canConvertToNumber(bigintValue);
15557
+ if (convertedNumber !== null) {
15558
+ nextValue = convertedNumber;
15485
15559
  }
15486
15560
  }
15487
15561
  }
@@ -16052,7 +16126,11 @@ class DbHelper {
16052
16126
  }
16053
16127
  async trans(callback) {
16054
16128
  if (this.isTransaction) {
16055
- return await callback(this);
16129
+ const innerResult = await callback(this);
16130
+ if (isBeflyResponse(innerResult) && innerResult.code !== 0) {
16131
+ throw new TransAbortError(innerResult);
16132
+ }
16133
+ return innerResult;
16056
16134
  }
16057
16135
  const sql = this.sql;
16058
16136
  if (!sql) {
@@ -16061,10 +16139,21 @@ class DbHelper {
16061
16139
  if (!hasBegin(sql)) {
16062
16140
  throw new Error("\u5F53\u524D SQL \u5BA2\u6237\u7AEF\u4E0D\u652F\u6301\u4E8B\u52A1 begin() \u65B9\u6CD5");
16063
16141
  }
16064
- return await sql.begin(async (tx) => {
16065
- const trans = new DbHelper({ redis: this.redis, dbName: this.dbName, sql: tx, idMode: this.idMode });
16066
- return await callback(trans);
16067
- });
16142
+ try {
16143
+ return await sql.begin(async (tx) => {
16144
+ const trans = new DbHelper({ redis: this.redis, dbName: this.dbName, sql: tx, idMode: this.idMode });
16145
+ const result = await callback(trans);
16146
+ if (isBeflyResponse(result) && result.code !== 0) {
16147
+ throw new TransAbortError(result);
16148
+ }
16149
+ return result;
16150
+ });
16151
+ } catch (error) {
16152
+ if (error instanceof TransAbortError) {
16153
+ return error.payload;
16154
+ }
16155
+ throw error;
16156
+ }
16068
16157
  }
16069
16158
  async query(sql, params) {
16070
16159
  return await this.executeWithConn(sql, params);