befly 2.3.3 → 3.0.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.
Files changed (93) hide show
  1. package/apis/health/info.ts +64 -0
  2. package/apis/tool/tokenCheck.ts +51 -0
  3. package/bin/befly.ts +202 -0
  4. package/checks/conflict.ts +408 -0
  5. package/checks/{table.js → table.ts} +139 -61
  6. package/config/env.ts +218 -0
  7. package/config/reserved.ts +96 -0
  8. package/main.ts +101 -0
  9. package/package.json +44 -8
  10. package/plugins/{db.js → db.ts} +24 -11
  11. package/plugins/logger.ts +28 -0
  12. package/plugins/redis.ts +51 -0
  13. package/plugins/tool.ts +34 -0
  14. package/scripts/syncDb/apply.ts +171 -0
  15. package/scripts/syncDb/constants.ts +70 -0
  16. package/scripts/syncDb/ddl.ts +182 -0
  17. package/scripts/syncDb/helpers.ts +172 -0
  18. package/scripts/syncDb/index.ts +215 -0
  19. package/scripts/syncDb/schema.ts +199 -0
  20. package/scripts/syncDb/sqlite.ts +50 -0
  21. package/scripts/syncDb/state.ts +104 -0
  22. package/scripts/syncDb/table.ts +204 -0
  23. package/scripts/syncDb/tableCreate.ts +142 -0
  24. package/scripts/syncDb/tests/constants.test.ts +104 -0
  25. package/scripts/syncDb/tests/ddl.test.ts +134 -0
  26. package/scripts/syncDb/tests/helpers.test.ts +70 -0
  27. package/scripts/syncDb/types.ts +92 -0
  28. package/scripts/syncDb/version.ts +73 -0
  29. package/scripts/syncDb.ts +9 -0
  30. package/scripts/{syncDev.js → syncDev.ts} +41 -25
  31. package/system.ts +149 -0
  32. package/tables/_common.json +21 -0
  33. package/tables/admin.json +10 -0
  34. package/tsconfig.json +58 -0
  35. package/types/api.d.ts +246 -0
  36. package/types/befly.d.ts +234 -0
  37. package/types/common.d.ts +215 -0
  38. package/types/context.ts +167 -0
  39. package/types/crypto.d.ts +23 -0
  40. package/types/database.d.ts +278 -0
  41. package/types/index.d.ts +16 -0
  42. package/types/index.ts +459 -0
  43. package/types/jwt.d.ts +99 -0
  44. package/types/logger.d.ts +43 -0
  45. package/types/plugin.d.ts +109 -0
  46. package/types/redis.d.ts +44 -0
  47. package/types/tool.d.ts +67 -0
  48. package/types/validator.d.ts +45 -0
  49. package/utils/addonHelper.ts +60 -0
  50. package/utils/api.ts +23 -0
  51. package/utils/{colors.js → colors.ts} +79 -21
  52. package/utils/crypto.ts +308 -0
  53. package/utils/datetime.ts +51 -0
  54. package/utils/dbHelper.ts +142 -0
  55. package/utils/errorHandler.ts +68 -0
  56. package/utils/index.ts +46 -0
  57. package/utils/jwt.ts +493 -0
  58. package/utils/logger.ts +284 -0
  59. package/utils/objectHelper.ts +68 -0
  60. package/utils/pluginHelper.ts +62 -0
  61. package/utils/redisHelper.ts +338 -0
  62. package/utils/response.ts +38 -0
  63. package/utils/{sqlBuilder.js → sqlBuilder.ts} +233 -97
  64. package/utils/sqlHelper.ts +447 -0
  65. package/utils/tableHelper.ts +167 -0
  66. package/utils/tool.ts +230 -0
  67. package/utils/typeHelper.ts +101 -0
  68. package/utils/validate.ts +451 -0
  69. package/utils/{xml.js → xml.ts} +100 -74
  70. package/.npmrc +0 -3
  71. package/.prettierignore +0 -2
  72. package/.prettierrc +0 -11
  73. package/apis/health/info.js +0 -49
  74. package/apis/tool/tokenCheck.js +0 -29
  75. package/bin/befly.js +0 -109
  76. package/config/env.js +0 -64
  77. package/main.js +0 -579
  78. package/plugins/logger.js +0 -14
  79. package/plugins/redis.js +0 -32
  80. package/plugins/tool.js +0 -8
  81. package/scripts/syncDb.js +0 -752
  82. package/system.js +0 -118
  83. package/tables/common.json +0 -16
  84. package/tables/tool.json +0 -6
  85. package/utils/api.js +0 -27
  86. package/utils/crypto.js +0 -260
  87. package/utils/index.js +0 -334
  88. package/utils/jwt.js +0 -387
  89. package/utils/logger.js +0 -143
  90. package/utils/redisHelper.js +0 -74
  91. package/utils/sqlManager.js +0 -471
  92. package/utils/tool.js +0 -31
  93. package/utils/validate.js +0 -226
@@ -1,39 +1,66 @@
1
1
  /**
2
- * XML 解析器
2
+ * XML 解析器 - TypeScript 版本
3
3
  * 将 XML 字符串解析为 JSON 对象
4
4
  */
5
- class Xml {
5
+
6
+ /**
7
+ * XML 解析选项
8
+ */
9
+ interface XmlParseOptions {
10
+ /** 是否忽略属性 */
11
+ ignoreAttributes?: boolean;
12
+ /** 属性前缀 */
13
+ attributePrefix?: string;
14
+ /** 文本内容的键名 */
15
+ textKey?: string;
16
+ /** 是否去除首尾空格 */
17
+ trimValues?: boolean;
18
+ /** 是否解析布尔值 */
19
+ parseBooleans?: boolean;
20
+ /** 是否解析数字 */
21
+ parseNumbers?: boolean;
22
+ /** 是否使用自定义解析器 */
23
+ customParser?: boolean;
24
+ }
25
+
26
+ /**
27
+ * 解析结果接口(内部使用)
28
+ */
29
+ interface ParseResult {
30
+ value: Record<string, any>;
31
+ end: number;
32
+ }
33
+
34
+ /**
35
+ * XML 解析器类
36
+ */
37
+ export class Xml {
38
+ private options: Required<XmlParseOptions>;
39
+
6
40
  /**
7
41
  * 构造函数
8
- * @param {Object} options - 解析选项
42
+ * @param options - 解析选项
9
43
  */
10
- constructor(options = {}) {
44
+ constructor(options: XmlParseOptions = {}) {
11
45
  // 默认配置
12
46
  this.options = {
13
- // 基本配置
14
- ignoreAttributes: false, // 是否忽略属性
15
- attributePrefix: '@', // 属性前缀
16
- textKey: '#text', // 文本内容的键名
17
-
18
- // 格式化配置
19
- trimValues: true, // 是否去除首尾空格
20
- parseBooleans: true, // 是否解析布尔值
21
- parseNumbers: true, // 是否解析数字
22
-
23
- // 高级配置
24
- customParser: true, // 是否使用自定义解析器
25
-
26
- // 合并用户选项
47
+ ignoreAttributes: false,
48
+ attributePrefix: '@',
49
+ textKey: '#text',
50
+ trimValues: true,
51
+ parseBooleans: true,
52
+ parseNumbers: true,
53
+ customParser: true,
27
54
  ...options
28
55
  };
29
56
  }
30
57
 
31
58
  /**
32
59
  * 解析 XML 字符串为 JSON 对象
33
- * @param {string} xmlData - XML 字符串
34
- * @returns {Object} 解析后的 JSON 对象
60
+ * @param xmlData - XML 字符串
61
+ * @returns 解析后的 JSON 对象
35
62
  */
36
- parse(xmlData) {
63
+ parse(xmlData: string): Record<string, any> {
37
64
  if (typeof xmlData !== 'string') {
38
65
  throw new Error('无效的 XML 数据');
39
66
  }
@@ -54,20 +81,22 @@ class Xml {
54
81
 
55
82
  // 自定义解析
56
83
  if (this.options.customParser) {
57
- return this.#customParse(xmlData);
84
+ return this.customParse(xmlData);
58
85
  }
86
+
87
+ return {};
59
88
  }
60
89
 
61
90
  /**
62
91
  * 解析属性字符串
63
- * @param {string} attributesStr - 属性字符串
64
- * @param {Object} element - 元素对象
92
+ * @param attributesStr - 属性字符串
93
+ * @param element - 元素对象
65
94
  */
66
- #parseAttributes(attributesStr, element) {
95
+ private parseAttributes(attributesStr: string, element: Record<string, any>): void {
67
96
  // 移除标签名,只保留属性部分
68
97
  const attrPart = attributesStr.replace(/^\w+\s*/, '');
69
98
  const attrRegex = /(\w+)=["']([^"']*)["']/g;
70
- let match;
99
+ let match: RegExpExecArray | null;
71
100
 
72
101
  while ((match = attrRegex.exec(attrPart)) !== null) {
73
102
  const attrName = this.options.attributePrefix + match[1];
@@ -78,18 +107,18 @@ class Xml {
78
107
  element[attrName] = attrValue;
79
108
  } else {
80
109
  // 其他属性进行类型解析
81
- element[attrName] = this.#parseValue(attrValue);
110
+ element[attrName] = this.parseValue(attrValue);
82
111
  }
83
112
  }
84
113
  }
85
114
 
86
115
  /**
87
116
  * 自定义解析方法
88
- * @param {string} xmlData - XML 数据
89
- * @returns {Object} 解析结果
117
+ * @param xmlData - XML 数据
118
+ * @returns 解析结果
90
119
  */
91
- #customParse(xmlData) {
92
- const result = this.#parseXmlElement(xmlData, 0).value;
120
+ private customParse(xmlData: string): Record<string, any> {
121
+ const result = this.parseXmlElement(xmlData, 0).value;
93
122
 
94
123
  // 如果结果只有一个根元素,返回该元素的内容
95
124
  const keys = Object.keys(result);
@@ -101,11 +130,11 @@ class Xml {
101
130
 
102
131
  /**
103
132
  * 解析 XML 元素
104
- * @param {string} xml - XML 字符串
105
- * @param {number} start - 开始位置
106
- * @returns {Object} 包含解析结果和结束位置的对象
133
+ * @param xml - XML 字符串
134
+ * @param start - 开始位置
135
+ * @returns 包含解析结果和结束位置的对象
107
136
  */
108
- #parseXmlElement(xml, start) {
137
+ private parseXmlElement(xml: string, start: number): ParseResult {
109
138
  const tagStart = xml.indexOf('<', start);
110
139
  if (tagStart === -1) {
111
140
  return { value: {}, end: xml.length };
@@ -117,13 +146,13 @@ class Xml {
117
146
  }
118
147
 
119
148
  const fullTag = xml.slice(tagStart + 1, tagEnd);
120
- const element = {};
149
+ const element: Record<string, any> = {};
121
150
 
122
151
  // 自闭合标签
123
152
  if (fullTag.endsWith('/')) {
124
153
  const tagName = fullTag.slice(0, -1).split(/\s+/)[0];
125
154
  if (!this.options.ignoreAttributes && fullTag.includes(' ')) {
126
- this.#parseAttributes(fullTag.slice(0, -1), element);
155
+ this.parseAttributes(fullTag.slice(0, -1), element);
127
156
  }
128
157
  return { value: { [tagName]: Object.keys(element).length > 0 ? element : '' }, end: tagEnd + 1 };
129
158
  }
@@ -134,7 +163,7 @@ class Xml {
134
163
  if (commentEnd === -1) {
135
164
  throw new Error('格式错误:未找到注释结束符');
136
165
  }
137
- return this.#parseXmlElement(xml, commentEnd + 3);
166
+ return this.parseXmlElement(xml, commentEnd + 3);
138
167
  }
139
168
 
140
169
  // CDATA
@@ -143,15 +172,14 @@ class Xml {
143
172
  if (cdataEnd === -1) {
144
173
  throw new Error('格式错误:未找到 CDATA 结束符');
145
174
  }
146
- const cdataContent = xml.slice(tagEnd + 1, cdataEnd);
147
- return this.#parseXmlElement(xml, cdataEnd + 3);
175
+ return this.parseXmlElement(xml, cdataEnd + 3);
148
176
  }
149
177
 
150
178
  const tagName = fullTag.split(/\s+/)[0];
151
179
 
152
180
  // 解析属性
153
181
  if (!this.options.ignoreAttributes && fullTag.includes(' ')) {
154
- this.#parseAttributes(fullTag, element);
182
+ this.parseAttributes(fullTag, element);
155
183
  }
156
184
 
157
185
  // 查找结束标签
@@ -171,7 +199,7 @@ class Xml {
171
199
 
172
200
  // 如果没有子标签,直接解析文本
173
201
  if (!content.includes('<')) {
174
- const textValue = this.#parseValue(content);
202
+ const textValue = this.parseValue(content);
175
203
  if (Object.keys(element).length === 0) {
176
204
  return { value: { [tagName]: textValue }, end: endTagStart + endTag.length };
177
205
  } else {
@@ -181,7 +209,7 @@ class Xml {
181
209
  } else {
182
210
  // 解析子元素和混合内容
183
211
  let pos = 0;
184
- const texts = [];
212
+ const texts: string[] = [];
185
213
 
186
214
  while (pos < content.length) {
187
215
  const nextTag = content.indexOf('<', pos);
@@ -200,12 +228,12 @@ class Xml {
200
228
  }
201
229
 
202
230
  // 解析子元素
203
- const childResult = this.#parseXmlElement(content, nextTag);
231
+ const childResult = this.parseXmlElement(content, nextTag);
204
232
  const childObj = childResult.value;
205
233
 
206
234
  // 合并子元素到当前元素
207
235
  for (const [key, value] of Object.entries(childObj)) {
208
- this.#addElement(element, key, value);
236
+ this.addElement(element, key, value);
209
237
  }
210
238
 
211
239
  pos = childResult.end;
@@ -215,9 +243,9 @@ class Xml {
215
243
  if (texts.length > 0) {
216
244
  const combinedText = texts.join(' ');
217
245
  if (Object.keys(element).length === 0) {
218
- return { value: { [tagName]: this.#parseValue(combinedText) }, end: endTagStart + endTag.length };
246
+ return { value: { [tagName]: this.parseValue(combinedText) }, end: endTagStart + endTag.length };
219
247
  } else {
220
- element[this.options.textKey] = this.#parseValue(combinedText);
248
+ element[this.options.textKey] = this.parseValue(combinedText);
221
249
  }
222
250
  }
223
251
 
@@ -227,11 +255,11 @@ class Xml {
227
255
 
228
256
  /**
229
257
  * 添加元素到对象
230
- * @param {Object} parent - 父对象
231
- * @param {string} name - 元素名
232
- * @param {any} value - 元素值
258
+ * @param parent - 父对象
259
+ * @param name - 元素名
260
+ * @param value - 元素值
233
261
  */
234
- #addElement(parent, name, value) {
262
+ private addElement(parent: Record<string, any>, name: string, value: any): void {
235
263
  if (parent[name] === undefined) {
236
264
  parent[name] = value;
237
265
  } else if (Array.isArray(parent[name])) {
@@ -243,10 +271,10 @@ class Xml {
243
271
 
244
272
  /**
245
273
  * 解析值的类型
246
- * @param {string} value - 原始值
247
- * @returns {any} 解析后的值
274
+ * @param value - 原始值
275
+ * @returns 解析后的值
248
276
  */
249
- #parseValue(value) {
277
+ private parseValue(value: string): string | number | boolean {
250
278
  if (!value || typeof value !== 'string') {
251
279
  return value;
252
280
  }
@@ -288,16 +316,16 @@ class Xml {
288
316
  }
289
317
 
290
318
  // 处理 XML 实体
291
- return this.#decodeEntities(value);
319
+ return this.decodeEntities(value);
292
320
  }
293
321
 
294
322
  /**
295
323
  * 解码 XML 实体
296
- * @param {string} value - 包含实体的字符串
297
- * @returns {string} 解码后的字符串
324
+ * @param value - 包含实体的字符串
325
+ * @returns 解码后的字符串
298
326
  */
299
- #decodeEntities(value) {
300
- const entities = {
327
+ private decodeEntities(value: string): string {
328
+ const entities: Record<string, string> = {
301
329
  '&amp;': '&',
302
330
  '&lt;': '<',
303
331
  '&gt;': '>',
@@ -312,39 +340,39 @@ class Xml {
312
340
 
313
341
  /**
314
342
  * 静态方法:快速解析 XML
315
- * @param {string} xmlData - XML 数据
316
- * @param {Object} options - 解析选项
317
- * @returns {Object} 解析后的 JSON 对象
343
+ * @param xmlData - XML 数据
344
+ * @param options - 解析选项
345
+ * @returns 解析后的 JSON 对象
318
346
  */
319
- static parse(xmlData, options = {}) {
347
+ static parse(xmlData: string, options: XmlParseOptions = {}): Record<string, any> {
320
348
  const parser = new Xml(options);
321
349
  return parser.parse(xmlData);
322
350
  }
323
351
 
324
352
  /**
325
353
  * 静态方法:解析 XML 并保留属性
326
- * @param {string} xmlData - XML 数据
327
- * @returns {Object} 解析后的 JSON 对象
354
+ * @param xmlData - XML 数据
355
+ * @returns 解析后的 JSON 对象
328
356
  */
329
- static parseWithAttributes(xmlData) {
357
+ static parseWithAttributes(xmlData: string): Record<string, any> {
330
358
  return Xml.parse(xmlData, { ignoreAttributes: false });
331
359
  }
332
360
 
333
361
  /**
334
362
  * 静态方法:解析 XML 并忽略属性
335
- * @param {string} xmlData - XML 数据
336
- * @returns {Object} 解析后的 JSON 对象
363
+ * @param xmlData - XML 数据
364
+ * @returns 解析后的 JSON 对象
337
365
  */
338
- static parseIgnoreAttributes(xmlData) {
366
+ static parseIgnoreAttributes(xmlData: string): Record<string, any> {
339
367
  return Xml.parse(xmlData, { ignoreAttributes: true });
340
368
  }
341
369
 
342
370
  /**
343
371
  * 静态方法:验证 XML 格式
344
- * @param {string} xmlData - XML 数据
345
- * @returns {boolean} 是否有效
372
+ * @param xmlData - XML 数据
373
+ * @returns 是否有效
346
374
  */
347
- static validate(xmlData) {
375
+ static validate(xmlData: string): boolean {
348
376
  try {
349
377
  Xml.parse(xmlData);
350
378
  return true;
@@ -353,5 +381,3 @@ class Xml {
353
381
  }
354
382
  }
355
383
  }
356
-
357
- export { Xml };
package/.npmrc DELETED
@@ -1,3 +0,0 @@
1
- # registry=https://registry.npmmirror.com
2
- registry=https://registry.npmjs.org
3
- link-workspace-packages=true
package/.prettierignore DELETED
@@ -1,2 +0,0 @@
1
- LICENSE
2
- LICENSE.md
package/.prettierrc DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "trailingComma": "none",
3
- "tabWidth": 4,
4
- "semi": true,
5
- "singleQuote": true,
6
- "printWidth": 1024,
7
- "bracketSpacing": true,
8
- "useTabs": false,
9
- "arrowParens": "always",
10
- "endOfLine": "lf"
11
- }
@@ -1,49 +0,0 @@
1
- import { Env } from '../../config/env.js';
2
- import { Api } from '../../utils/api.js';
3
- import { RYes, RNo } from '../../utils/index.js';
4
-
5
- export default Api.POST(
6
- //
7
- '健康检查',
8
- false,
9
- {},
10
- [],
11
- async (befly, ctx) => {
12
- try {
13
- const info = {
14
- status: 'ok',
15
- timestamp: new Date().toISOString(),
16
- uptime: process.uptime(),
17
- memory: process.memoryUsage(),
18
- runtime: 'Bun',
19
- version: Bun.version,
20
- platform: process.platform,
21
- arch: process.arch
22
- };
23
- // 检查 Redis 连接状态
24
- if (Env.REDIS_ENABLE === 1) {
25
- if (befly.redis) {
26
- try {
27
- await befly.redis.ping();
28
- info.redis = '已连接';
29
- } catch (error) {
30
- info.redis = '未连接';
31
- info.redisError = error.message;
32
- }
33
- } else {
34
- info.redis = '未开启';
35
- }
36
- } else {
37
- info.redis = '禁用';
38
- }
39
- return RYes('健康检查成功', info);
40
- } catch (error) {
41
- befly.logger.error({
42
- msg: '健康检查失败',
43
- error: error.message,
44
- stack: error.stack
45
- });
46
- return RNo('健康检查失败');
47
- }
48
- }
49
- );
@@ -1,29 +0,0 @@
1
- import { Env } from '../../config/env.js';
2
- import { Api } from '../../utils/api.js';
3
- import { RYes, RNo } from '../../utils/index.js';
4
- import { Jwt } from '../../utils/jwt.js';
5
-
6
- export default Api.POST(
7
- //
8
- '令牌检测',
9
- false,
10
- {},
11
- [],
12
- async (befly, ctx) => {
13
- try {
14
- const token = ctx.headers?.authorization?.split(' ')[1] || '';
15
- if (!token) {
16
- return RNo('令牌不能为空');
17
- }
18
- const jwtData = await Jwt.verify(token);
19
- return RYes('令牌有效');
20
- } catch (error) {
21
- befly.logger.error({
22
- msg: '令牌检测失败',
23
- error: error.message,
24
- stack: error.stack
25
- });
26
- return RNo('令牌检测失败');
27
- }
28
- }
29
- );
package/bin/befly.js DELETED
@@ -1,109 +0,0 @@
1
- #!/usr/bin/env -S bun run
2
- // Befly CLI (Bun): 列出并执行 core/scripts 与 tpl/scripts 下的脚本
3
-
4
- import path from 'node:path';
5
- import { Glob } from 'bun';
6
- import { __dirscript as coreScriptsDir, getProjectDir } from '../system.js';
7
-
8
- // 解析目录(来自 system.js)
9
- // 核心脚本目录:core/scripts
10
- // 用户项目(如 tpl)的脚本目录:始终基于当前工作目录
11
- const tplScriptsDir = getProjectDir('scripts');
12
-
13
- function safeList(dir) {
14
- try {
15
- // 使用 Bun.Glob 查找当前目录下的所有 .js 文件(不递归)
16
- const glob = new Glob('*.js');
17
- const files = Array.from(glob.scanSync({ cwd: dir, absolute: false, onlyFiles: true, dot: false }));
18
- return files.map((f) => path.basename(f, '.js')).sort();
19
- } catch {
20
- return [];
21
- }
22
- }
23
-
24
- function buildScriptItems() {
25
- const coreList = safeList(coreScriptsDir);
26
- const tplList = safeList(tplScriptsDir);
27
- const coreSet = new Set(coreList);
28
-
29
- const items = [];
30
- for (const name of coreList) {
31
- items.push({
32
- name: name,
33
- source: 'core',
34
- duplicate: tplList.includes(name),
35
- path: path.resolve(coreScriptsDir, `${name}.js`)
36
- });
37
- }
38
- for (const name of tplList) {
39
- items.push({
40
- name: name,
41
- source: 'tpl',
42
- duplicate: coreSet.has(name),
43
- path: path.resolve(tplScriptsDir, `${name}.js`)
44
- });
45
- }
46
- // 排序:名称字典序,core 在前
47
- items.sort((a, b) => (a.name === b.name ? (a.source === b.source ? 0 : a.source === 'core' ? -1 : 1) : a.name.localeCompare(b.name)));
48
- return items;
49
- }
50
-
51
- function printAllScripts() {
52
- const items = buildScriptItems();
53
- if (items.length === 0) {
54
- console.log(' • <无>');
55
- return;
56
- }
57
- for (const it of items) {
58
- if (it.source === 'tpl' && it.duplicate) console.log(` • ${it.name}(重复)`);
59
- else console.log(` • ${it.name}`);
60
- }
61
- }
62
-
63
- async function resolveScriptPath(name) {
64
- const base = name.endsWith('.js') ? name.slice(0, -3) : name;
65
- const filename = `${base}.js`;
66
- const corePath = path.resolve(coreScriptsDir, filename);
67
- const tplPath = path.resolve(tplScriptsDir, filename);
68
- if (await Bun.file(corePath).exists()) return corePath;
69
- if (await Bun.file(tplPath).exists()) return tplPath;
70
- // 回退到列表匹配(防止极端路径或大小写差异)
71
- const items = buildScriptItems();
72
- const hit = items.find((it) => it.name.toLowerCase() === base.toLowerCase() && it.source === 'core') || items.find((it) => it.name.toLowerCase() === base.toLowerCase());
73
- return hit ? hit.path : null;
74
- }
75
-
76
- async function runScriptAtPath(targetPath, label, args = []) {
77
- const bunExe = process.execPath || 'bun';
78
- const child = Bun.spawn({
79
- cmd: [bunExe, targetPath, ...args],
80
- stdio: ['inherit', 'inherit', 'inherit'],
81
- cwd: process.cwd(),
82
- env: { ...process.env, LOG_TO_CONSOLE: '1' }
83
- });
84
- const code = await child.exited;
85
- return code ?? 0;
86
- }
87
-
88
- async function main() {
89
- const [, , cmd, ...args] = process.argv;
90
- // 无参数:打印所有脚本
91
- if (!cmd) {
92
- printAllScripts();
93
- process.exit(0);
94
- }
95
- // 按名称执行(将剩余参数透传给脚本)
96
- const target = await resolveScriptPath(cmd);
97
- if (!target) {
98
- console.error(`未找到脚本: ${cmd}`);
99
- printAllScripts();
100
- process.exit(1);
101
- }
102
- const code = await runScriptAtPath(target, cmd, args);
103
- process.exit(code ?? 0);
104
- }
105
-
106
- main().catch((e) => {
107
- console.error('Befly CLI 执行失败:', e);
108
- process.exit(1);
109
- });
package/config/env.js DELETED
@@ -1,64 +0,0 @@
1
- export const Env = {
2
- // 项目模式
3
- NODE_ENV: process.env.NODE_ENV,
4
- // 应用名称
5
- APP_NAME: process.env.APP_NAME,
6
- // 加密盐
7
- MD5_SALT: process.env.MD5_SALT,
8
- // 监听端口
9
- APP_PORT: Number(process.env.APP_PORT),
10
- // 监听主机
11
- APP_HOST: process.env.APP_HOST,
12
- // 超级管理员密码
13
- DEV_PASSWORD: process.env.DEV_PASSWORD,
14
- // 请求体大小 10M
15
- BODY_LIMIT: Number(process.env.BODY_LIMIT),
16
- // 是否进行参数验证
17
- PARAMS_CHECK: process.env.PARAMS_CHECK,
18
- // 日志等级
19
- LOG_LEVEL: process.env.LOG_LEVEL,
20
- LOG_EXCLUDE_FIELDS: process.env.LOG_EXCLUDE_FIELDS,
21
- LOG_DIR: process.env.LOG_DIR,
22
- LOG_TO_CONSOLE: Number(process.env.LOG_TO_CONSOLE),
23
- LOG_MAX_SIZE: Number(process.env.LOG_MAX_SIZE),
24
- // 时区
25
- TZ: process.env.TZ,
26
- // 数据库配置
27
- DB_ENABLE: Number(process.env.DB_ENABLE),
28
- // 通用数据库连接参数
29
- DB_TYPE: process.env.DB_TYPE, // sqlite | mysql | postgresql
30
- DB_HOST: process.env.DB_HOST,
31
- DB_PORT: Number(process.env.DB_PORT),
32
- DB_USER: process.env.DB_USER,
33
- DB_PASS: process.env.DB_PASS,
34
- DB_NAME: process.env.DB_NAME,
35
- DB_DEBUG: Number(process.env.DB_DEBUG),
36
- DB_POOL_MAX: Number(process.env.DB_POOL_MAX),
37
- // Redis配置
38
- REDIS_URL: process.env.REDIS_URL,
39
- REDIS_ENABLE: Number(process.env.REDIS_ENABLE),
40
- REDIS_HOST: process.env.REDIS_HOST,
41
- REDIS_PORT: Number(process.env.REDIS_PORT),
42
- REDIS_USERNAME: process.env.REDIS_USERNAME,
43
- REDIS_PASSWORD: process.env.REDIS_PASSWORD,
44
- REDIS_DB: Number(process.env.REDIS_DB),
45
- REDIS_KEY_PREFIX: process.env.REDIS_KEY_PREFIX,
46
- // JWT配置
47
- JWT_SECRET: process.env.JWT_SECRET,
48
- JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN,
49
- JWT_ALGORITHM: process.env.JWT_ALGORITHM,
50
- // 邮件配置
51
- MAIL_HOST: process.env.MAIL_HOST,
52
- MAIL_PORT: Number(process.env.MAIL_PORT),
53
- MAIL_POOL: process.env.MAIL_POOL,
54
- MAIL_SECURE: process.env.MAIL_SECURE,
55
- MAIL_USER: process.env.MAIL_USER,
56
- MAIL_PASS: process.env.MAIL_PASS,
57
- MAIL_SENDER: process.env.MAIL_SENDER,
58
- MAIL_ADDRESS: process.env.MAIL_ADDRESS,
59
- // 同步脚本开关(用于 core/scripts/syncDb.js)
60
- SYNC_MERGE_ALTER: process.env.SYNC_MERGE_ALTER,
61
- SYNC_ONLINE_INDEX: process.env.SYNC_ONLINE_INDEX,
62
- SYNC_DISALLOW_SHRINK: process.env.SYNC_DISALLOW_SHRINK,
63
- SYNC_ALLOW_TYPE_CHANGE: process.env.SYNC_ALLOW_TYPE_CHANGE
64
- };