befly 3.13.6 → 3.13.8

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.
@@ -72,17 +72,18 @@ const defaultOptions = {
72
72
  addons: {}
73
73
  };
74
74
  export async function loadBeflyConfig(nodeEnv) {
75
- const normalizedNodeEnv = normalizeNodeEnv(nodeEnv);
76
- const envSuffix = normalizedNodeEnv === "production" ? "production" : "development";
75
+ if (nodeEnv !== "development" && nodeEnv !== "production") {
76
+ throw new Error(`配置错误:NODE_ENV 只能是 'development' 'production',当前值=${String(nodeEnv)}`);
77
+ }
77
78
  // 使用 importDefault 加载 configs 目录下的配置文件。
78
79
  // 合并顺序:defaultOptions ← befly.common.json ← befly.development/production.json
79
80
  const configsDir = join(process.cwd(), "configs");
80
81
  const commonConfig = await importDefault(join(configsDir, "befly.common.json"), {});
81
- const envConfig = await importDefault(join(configsDir, `befly.${envSuffix}.json`), {});
82
+ const envConfig = await importDefault(join(configsDir, `befly.${nodeEnv}.json`), {});
82
83
  const config = mergeAndConcat(defaultOptions, commonConfig, envConfig);
83
84
  // 重要:nodeEnv 的来源只从 Befly.start(env) 的入参 env.NODE_ENV 传入,避免 process.env 在 bundle 阶段被常量折叠。
84
85
  // 同时确保运行时行为(例如 Bun.serve development 标记)与实际选择的配置文件一致。
85
- config.nodeEnv = normalizedNodeEnv;
86
+ config.nodeEnv = nodeEnv;
86
87
  // 配置校验:redis.prefix 作为 key 前缀,由 RedisHelper 统一拼接 ":"。
87
88
  // 因此 prefix 本身不允许包含 ":",否则会导致 key 结构出现空段或多段分隔(例如 "prefix::key"),
88
89
  // 在 RedisInsight 等工具里可能显示 [NO NAME] 空分组,且容易造成 key 管理混乱。
@@ -95,9 +96,3 @@ export async function loadBeflyConfig(nodeEnv) {
95
96
  }
96
97
  return config;
97
98
  }
98
- function normalizeNodeEnv(nodeEnv) {
99
- if (typeof nodeEnv === "string" && nodeEnv.trim()) {
100
- return nodeEnv.trim();
101
- }
102
- return "development";
103
- }
package/dist/befly.js CHANGED
@@ -83,30 +83,6 @@ function normalizePositiveInt(value, fallback, min, max) {
83
83
  return max;
84
84
  return v;
85
85
  }
86
- function isEmpty(value) {
87
- if (value === null || value === undefined) {
88
- return true;
89
- }
90
- if (typeof value === "string") {
91
- return value.trim().length === 0;
92
- }
93
- if (typeof value === "number") {
94
- return value === 0 || Number.isNaN(value);
95
- }
96
- if (typeof value === "boolean") {
97
- return value === false;
98
- }
99
- if (Array.isArray(value)) {
100
- return value.length === 0;
101
- }
102
- if (value instanceof Map || value instanceof Set) {
103
- return value.size === 0;
104
- }
105
- if (isPlainObject(value)) {
106
- return Object.keys(value).length === 0;
107
- }
108
- return false;
109
- }
110
86
  function forOwn(obj, iteratee) {
111
87
  if (typeof iteratee !== "function") {
112
88
  return;
@@ -203,17 +179,6 @@ var keysToCamel = (obj) => {
203
179
  if (!arr || !Array.isArray(arr))
204
180
  return arr;
205
181
  return arr.map((item) => keysToCamel(item));
206
- }, pickFields = (obj, keys) => {
207
- if (!obj || !isPlainObject(obj) && !Array.isArray(obj)) {
208
- return {};
209
- }
210
- const result = {};
211
- for (const key of keys) {
212
- if (key in obj) {
213
- result[key] = obj[key];
214
- }
215
- }
216
- return result;
217
182
  };
218
183
  var init_util = () => {};
219
184
 
@@ -7609,13 +7574,14 @@ var defaultOptions = {
7609
7574
  addons: {}
7610
7575
  };
7611
7576
  async function loadBeflyConfig(nodeEnv) {
7612
- const normalizedNodeEnv = normalizeNodeEnv(nodeEnv);
7613
- const envSuffix = normalizedNodeEnv === "production" ? "production" : "development";
7577
+ if (nodeEnv !== "development" && nodeEnv !== "production") {
7578
+ throw new Error(`\u914D\u7F6E\u9519\u8BEF\uFF1ANODE_ENV \u53EA\u80FD\u662F 'development' \u6216 'production'\uFF0C\u5F53\u524D\u503C=${String(nodeEnv)}`);
7579
+ }
7614
7580
  const configsDir = join(process.cwd(), "configs");
7615
7581
  const commonConfig = await importDefault(join(configsDir, "befly.common.json"), {});
7616
- const envConfig = await importDefault(join(configsDir, `befly.${envSuffix}.json`), {});
7582
+ const envConfig = await importDefault(join(configsDir, `befly.${nodeEnv}.json`), {});
7617
7583
  const config2 = mergeAndConcat(defaultOptions, commonConfig, envConfig);
7618
- config2.nodeEnv = normalizedNodeEnv;
7584
+ config2.nodeEnv = nodeEnv;
7619
7585
  const redisPrefix = config2?.redis?.prefix;
7620
7586
  if (typeof redisPrefix === "string") {
7621
7587
  const trimmedPrefix = redisPrefix.trim();
@@ -7625,12 +7591,6 @@ async function loadBeflyConfig(nodeEnv) {
7625
7591
  }
7626
7592
  return config2;
7627
7593
  }
7628
- function normalizeNodeEnv(nodeEnv) {
7629
- if (typeof nodeEnv === "string" && nodeEnv.trim()) {
7630
- return nodeEnv.trim();
7631
- }
7632
- return "development";
7633
- }
7634
7594
 
7635
7595
  // checks/checkApi.ts
7636
7596
  init_logger();
@@ -12132,7 +12092,6 @@ class XMLParser {
12132
12092
  }
12133
12093
 
12134
12094
  // hooks/parser.ts
12135
- init_util();
12136
12095
  var xmlParser = new XMLParser;
12137
12096
  var parserHook = {
12138
12097
  name: "parser",
@@ -12148,11 +12107,7 @@ var parserHook = {
12148
12107
  if (ctx.req.method === "GET") {
12149
12108
  const url = new URL(ctx.req.url);
12150
12109
  const params = Object.fromEntries(url.searchParams);
12151
- if (isPlainObject(ctx.api.fields) && !isEmpty(ctx.api.fields)) {
12152
- ctx.body = pickFields(params, Object.keys(ctx.api.fields));
12153
- } else {
12154
- ctx.body = params;
12155
- }
12110
+ ctx.body = params;
12156
12111
  } else if (ctx.req.method === "POST") {
12157
12112
  const contentType = ctx.req.headers.get("content-type") || "";
12158
12113
  const url = new URL(ctx.req.url);
@@ -12161,22 +12116,14 @@ var parserHook = {
12161
12116
  if (contentType.includes("application/json")) {
12162
12117
  const body = await ctx.req.json();
12163
12118
  const merged = { ...queryParams, ...body };
12164
- if (isPlainObject(ctx.api.fields) && !isEmpty(ctx.api.fields)) {
12165
- ctx.body = pickFields(merged, Object.keys(ctx.api.fields));
12166
- } else {
12167
- ctx.body = merged;
12168
- }
12119
+ ctx.body = merged;
12169
12120
  } else if (contentType.includes("application/xml") || contentType.includes("text/xml")) {
12170
12121
  const text = await ctx.req.text();
12171
12122
  const parsed = xmlParser.parse(text);
12172
12123
  const rootKey = Object.keys(parsed)[0];
12173
12124
  const body = rootKey && typeof parsed[rootKey] === "object" ? parsed[rootKey] : parsed;
12174
12125
  const merged = { ...queryParams, ...body };
12175
- if (isPlainObject(ctx.api.fields) && !isEmpty(ctx.api.fields)) {
12176
- ctx.body = pickFields(merged, Object.keys(ctx.api.fields));
12177
- } else {
12178
- ctx.body = merged;
12179
- }
12126
+ ctx.body = merged;
12180
12127
  } else {
12181
12128
  ctx.response = ErrorResponse(ctx, "\u65E0\u6548\u7684\u8BF7\u6C42\u53C2\u6570\u683C\u5F0F", 1, null, {
12182
12129
  location: "content-type",
@@ -12331,7 +12278,7 @@ class Validator {
12331
12278
  }
12332
12279
  for (const field of required) {
12333
12280
  const value = data[field];
12334
- if (value === undefined || value === null || value === "") {
12281
+ if (value === undefined || value === null) {
12335
12282
  const label = rules[field]?.name || field;
12336
12283
  fieldErrors[field] = `${label}\u4E3A\u5FC5\u586B\u9879`;
12337
12284
  }
@@ -12504,6 +12451,7 @@ class Validator {
12504
12451
  }
12505
12452
 
12506
12453
  // hooks/validator.ts
12454
+ init_util();
12507
12455
  var validatorHook = {
12508
12456
  name: "validator",
12509
12457
  enable: true,
@@ -12514,10 +12462,25 @@ var validatorHook = {
12514
12462
  if (!ctx.api.fields) {
12515
12463
  return;
12516
12464
  }
12517
- for (const [field, fieldDef] of Object.entries(ctx.api.fields)) {
12518
- if (ctx.body[field] === undefined && fieldDef?.default !== undefined && fieldDef?.default !== null) {
12519
- ctx.body[field] = fieldDef.default;
12465
+ if (isPlainObject(ctx.api.fields)) {
12466
+ const rawBody = isPlainObject(ctx.body) ? ctx.body : {};
12467
+ const nextBody = {};
12468
+ for (const [field, fieldDef] of Object.entries(ctx.api.fields)) {
12469
+ let value = rawBody[field];
12470
+ if (value === undefined) {
12471
+ const snakeField = snakeCase(field);
12472
+ if (rawBody[snakeField] !== undefined) {
12473
+ value = rawBody[snakeField];
12474
+ }
12475
+ }
12476
+ if (value === undefined && fieldDef?.default !== undefined && fieldDef?.default !== null) {
12477
+ value = fieldDef.default;
12478
+ }
12479
+ if (value !== undefined) {
12480
+ nextBody[field] = value;
12481
+ }
12520
12482
  }
12483
+ ctx.body = nextBody;
12521
12484
  }
12522
12485
  const result = Validator.validate(ctx.body, ctx.api.fields, ctx.api.required || []);
12523
12486
  if (result.code !== 0) {