befly 2.0.12 → 2.0.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.
package/.gitignore ADDED
@@ -0,0 +1,93 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ esdata
6
+ data
7
+ .cache
8
+ lab
9
+ labs
10
+ cache
11
+ .VSCodeCounter
12
+ oclif.manifest.json
13
+ dist
14
+ report.html
15
+ dist-ssr
16
+ *.local
17
+ .vscode-test/
18
+ *.vsix
19
+ out
20
+ CHANGELOG.md
21
+ note.md
22
+ .changeset
23
+ addons2
24
+ pnpm-lock.yaml
25
+ bun.lock
26
+ other
27
+
28
+ # Editor directories and files
29
+ .vscode/*
30
+ .cache
31
+ .yicode/auto-imports.d.ts
32
+ !.vscode/extensions.json
33
+ .idea
34
+ .DS_Store
35
+ *.suo
36
+ *.ntvs*
37
+ *.njsproj
38
+ *.sln
39
+ *.sw?
40
+
41
+ # Runtime data
42
+ pids
43
+ *.pid
44
+ *.seed
45
+
46
+ # Directory for instrumented libs generated by jscoverage/JSCover
47
+ lib-cov
48
+
49
+ # Coverage directory used by tools like istanbul
50
+ coverage
51
+
52
+ # nyc test coverage
53
+ .nyc_output
54
+
55
+ # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
56
+ .grunt
57
+
58
+ # node-waf configuration
59
+ .lock-wscript
60
+
61
+ # Compiled binary addons (http://nodejs.org/api/addons.html)
62
+ build/Release
63
+
64
+ # Dependency directories
65
+ node_modules
66
+ jspm_packages
67
+
68
+ # Optional npm cache directory
69
+ .npm
70
+
71
+ # Optional REPL history
72
+ .node_repl_history
73
+
74
+ # 0x
75
+ profile-*
76
+
77
+ # mac files
78
+ .DS_Store
79
+
80
+ # vim swap files
81
+ *.swp
82
+
83
+ # webstorm
84
+ .idea
85
+
86
+ # vscode
87
+ .vscode
88
+ *code-workspace
89
+
90
+ # clinic
91
+ profile*
92
+ *clinic*
93
+ *flamegraph*
package/.npmrc ADDED
@@ -0,0 +1,3 @@
1
+ # registry=https://registry.npmmirror.com
2
+ registry=https://registry.npmjs.org
3
+ link-workspace-packages=true
@@ -0,0 +1,2 @@
1
+ LICENSE
2
+ LICENSE.md
package/.prettierrc ADDED
@@ -0,0 +1,11 @@
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
+ }
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # Befly
1
+ # Befly - 蜜蜂飞舞
2
2
 
3
- 自用框架,请勿使用。
3
+ 道生一,一生二,二生三,三生万物,v3版本发布后可才是公测版本。
package/USEAGE.md ADDED
@@ -0,0 +1,5 @@
1
+ ## 接口参数定义
2
+
3
+ > 名称#类型#最小值#最大值#表达式
4
+
5
+ 如果`类型`为`number`,`表达式`可以为`x*3=2`的形式。
package/bin/befly.js ADDED
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Befly CLI 工具
5
+ * 提供命令行接口来执行 befly 框架的各种脚本
6
+ */
7
+
8
+ import { spawn } from 'node:child_process';
9
+ import { resolve, join, dirname } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { existsSync, readFileSync } from 'node:fs';
12
+ import { readdir } from 'node:fs/promises';
13
+ import { __dirroot, __dirscript } from '../system.js';
14
+
15
+ // 使用 system.js 中定义的路径变量
16
+ const BEFLY_ROOT = __dirroot;
17
+ const SCRIPTS_DIR = __dirscript;
18
+
19
+ // 显示帮助信息
20
+ const showHelp = async () => {
21
+ console.log(`
22
+ Befly CLI 工具 v2.0.12
23
+
24
+ 用法:
25
+ befly <script-name> [args...]
26
+
27
+ 可用的脚本:
28
+ `);
29
+
30
+ // 列出所有可用的脚本
31
+ if (existsSync(SCRIPTS_DIR)) {
32
+ try {
33
+ const fileList = await readdir(SCRIPTS_DIR);
34
+ const scripts = fileList
35
+ .filter((file) => file.endsWith('.js'))
36
+ .map((file) => file.replace('.js', ''))
37
+ .sort();
38
+
39
+ if (scripts.length > 0) {
40
+ scripts.forEach((script) => {
41
+ console.log(` befly ${script}`);
42
+ });
43
+ } else {
44
+ console.log(' (没有找到可用的脚本)');
45
+ }
46
+ } catch (error) {
47
+ console.log(` (无法读取脚本目录: ${error.message})`);
48
+ }
49
+ } else {
50
+ console.log(' (脚本目录不存在)');
51
+ }
52
+
53
+ console.log(`
54
+ 选项:
55
+ -h, --help 显示此帮助信息
56
+ -v, --version 显示版本信息
57
+
58
+ 更多信息请访问: https://chensuiyi.me
59
+ `);
60
+ };
61
+
62
+ // 显示版本信息
63
+ const showVersion = () => {
64
+ try {
65
+ const packageJsonPath = join(BEFLY_ROOT, 'package.json');
66
+ if (existsSync(packageJsonPath)) {
67
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
68
+ console.log(`befly v${packageJson.version}`);
69
+ } else {
70
+ console.log('befly v2.0.12');
71
+ }
72
+ } catch (error) {
73
+ console.log('befly v2.0.12');
74
+ }
75
+ };
76
+
77
+ // 执行脚本
78
+ const runScript = (scriptName, args = []) => {
79
+ // 检查脚本文件是否存在
80
+ const scriptPath = join(SCRIPTS_DIR, `${scriptName}.js`);
81
+
82
+ if (!existsSync(scriptPath)) {
83
+ console.error(`❌ 错误: 脚本 '${scriptName}' 不存在`);
84
+ console.error(`脚本路径: ${scriptPath}`);
85
+ console.error('');
86
+ console.error('运行 "befly --help" 查看可用的脚本列表');
87
+ process.exit(1);
88
+ }
89
+
90
+ console.log(`🚀 执行脚本: ${scriptName}`);
91
+ console.log(`📁 脚本路径: ${scriptPath}`);
92
+
93
+ // 检测运行环境,优先使用 bun,回退到 node
94
+ const isWindows = process.platform === 'win32';
95
+ let runtime = 'bun';
96
+ let runtimeArgs = ['run'];
97
+
98
+ // 如果 bun 不可用,回退到 node
99
+ const testBun = spawn(isWindows ? 'bun.exe' : 'bun', ['--version'], {
100
+ stdio: 'ignore',
101
+ shell: isWindows
102
+ });
103
+
104
+ testBun.on('error', () => {
105
+ runtime = 'node';
106
+ runtimeArgs = [];
107
+ });
108
+
109
+ testBun.on('close', (code) => {
110
+ if (code !== 0) {
111
+ runtime = 'node';
112
+ runtimeArgs = [];
113
+ }
114
+
115
+ console.log(`⚡ 使用运行时: ${runtime}`);
116
+ console.log('');
117
+
118
+ // 执行脚本
119
+ const child = spawn(isWindows ? `${runtime}.exe` : runtime, [...runtimeArgs, scriptPath, ...args], {
120
+ stdio: 'inherit',
121
+ shell: isWindows,
122
+ cwd: process.cwd() // 使用调用者的工作目录
123
+ });
124
+
125
+ child.on('error', (error) => {
126
+ console.error(`❌ 执行失败: ${error.message}`);
127
+ process.exit(1);
128
+ });
129
+
130
+ child.on('close', (code) => {
131
+ if (code !== 0) {
132
+ console.error(`❌ 脚本执行失败,退出码: ${code}`);
133
+ process.exit(code);
134
+ } else {
135
+ console.log(`✅ 脚本执行完成`);
136
+ }
137
+ });
138
+ });
139
+ };
140
+
141
+ // 主函数
142
+ const main = async () => {
143
+ const args = process.argv.slice(2);
144
+
145
+ // 没有参数或请求帮助
146
+ if (args.length === 0 || args.includes('-h') || args.includes('--help')) {
147
+ await showHelp();
148
+ return;
149
+ }
150
+
151
+ // 显示版本
152
+ if (args.includes('-v') || args.includes('--version')) {
153
+ showVersion();
154
+ return;
155
+ }
156
+
157
+ // 执行脚本
158
+ const scriptName = args[0];
159
+ const scriptArgs = args.slice(1);
160
+
161
+ runScript(scriptName, scriptArgs);
162
+ };
163
+
164
+ // 错误处理
165
+ process.on('uncaughtException', (error) => {
166
+ console.error('❌ 未捕获的异常:', error.message);
167
+ process.exit(1);
168
+ });
169
+
170
+ process.on('unhandledRejection', (reason, promise) => {
171
+ console.error('❌ 未处理的 Promise 拒绝:', reason);
172
+ process.exit(1);
173
+ });
174
+
175
+ // 启动 CLI
176
+ main();
@@ -1,12 +1,13 @@
1
1
  import path from 'node:path';
2
- import { ruleSplit } from '../utils/util.js';
3
2
  import { Logger } from '../utils/Logger.js';
3
+ import { parseFieldRule } from '../utils/util.js';
4
+ import { __dirtables, getProjectDir } from '../system.js';
4
5
 
5
6
  export default async () => {
6
7
  try {
7
- const schemaGlob = new Bun.Glob('*.json');
8
- const coreSchemaDir = path.join(__dirname, '..', 'schema');
9
- const userSchemaDir = path.join(process.cwd(), 'schema');
8
+ const tablesGlob = new Bun.Glob('*.json');
9
+ const coreTablesDir = __dirtables;
10
+ const userTablesDir = getProjectDir('tables');
10
11
 
11
12
  // 统计信息
12
13
  let totalFiles = 0;
@@ -19,53 +20,70 @@ export default async () => {
19
20
  const fileName = path.basename(file);
20
21
  try {
21
22
  // 读取并解析 JSON 文件
22
- const schema = await Bun.file(file).json();
23
+ const table = await Bun.file(file).json();
23
24
  let fileValid = true;
24
25
  let fileRules = 0;
25
26
 
26
- // 检查 schema 中的每个验证规则
27
- for (const [fieldName, rule] of Object.entries(schema)) {
27
+ // 保留字段列表
28
+ const reservedFields = ['id', 'created_at', 'updated_at', 'deleted_at', 'state'];
29
+
30
+ // 检查 table 中的每个验证规则
31
+ for (const [fieldName, rule] of Object.entries(table)) {
28
32
  fileRules++;
29
33
  totalRules++;
30
34
 
35
+ // 检查是否使用了保留字段
36
+ if (reservedFields.includes(fieldName)) {
37
+ Logger.error(`${fileName} 文件包含保留字段 ${fieldName},不能在表定义中使用以下字段: ${reservedFields.join(', ')}`);
38
+ fileValid = false;
39
+ continue;
40
+ }
41
+
31
42
  // 验证规则格式
32
- const ruleParts = ruleSplit(rule);
43
+ const ruleParts = parseFieldRule(rule);
33
44
 
34
- if (ruleParts.length !== 5) {
35
- Logger.warn(`${fileName} 文件 ${fieldName} 验证规则错误,应包含 5 个部分,但包含 ${ruleParts.length} 个部分`);
45
+ if (ruleParts.length !== 7) {
46
+ Logger.warn(`${fileName} 文件 ${fieldName} 验证规则错误,应包含 7 个部分,但包含 ${ruleParts.length} 个部分`);
36
47
  fileValid = false;
37
48
  continue;
38
49
  }
39
50
 
40
- const [name, type, minStr, maxStr, spec] = ruleParts;
51
+ const [name, type, minStr, maxStr, defaultValue, isIndexStr, regexConstraint] = ruleParts;
41
52
 
42
53
  // 验证类型(必须严格使用小写类型名称)
43
- const validTypes = ['number', 'string', 'array'];
54
+ const validTypes = ['number', 'string', 'text', 'array'];
44
55
  if (!validTypes.includes(type)) {
45
- Logger.warn(`${fileName} 文件 ${fieldName} 类型 ${type} 不支持,应为小写的 number、string 或 array`);
56
+ Logger.warn(`${fileName} 文件 ${fieldName} 类型 ${type} 不支持,应为小写的 number、string、text 或 array`);
46
57
  fileValid = false;
47
58
  continue;
48
59
  }
49
60
 
50
61
  // 验证最小值/最大值
51
62
  if (minStr !== 'null' && isNaN(parseInt(minStr))) {
52
- Logger.warn(`${fileName} 文件 ${fieldName} 最小值 ${minStr} 应为数字或 "null"`);
63
+ Logger.warn(`${fileName} 文件 ${fieldName} 最小值 ${minStr} 应为数字或 null`);
53
64
  fileValid = false;
54
65
  continue;
55
66
  }
56
67
 
57
68
  if (maxStr !== 'null' && isNaN(parseInt(maxStr))) {
58
- Logger.warn(`${fileName} 文件 ${fieldName} 最大值 ${maxStr} 应为数字或 "null"`);
69
+ Logger.warn(`${fileName} 文件 ${fieldName} 最大值 ${maxStr} 应为数字或 null`);
70
+ fileValid = false;
71
+ continue;
72
+ }
73
+
74
+ // 验证索引字段
75
+ if (isIndexStr !== 'null' && !['0', '1'].includes(isIndexStr)) {
76
+ Logger.warn(`${fileName} 文件 ${fieldName} 索引标识 ${isIndexStr} 应为 0、1 或 null`);
59
77
  fileValid = false;
60
78
  continue;
61
79
  }
62
80
 
63
- // 验证特殊规则
64
- if (spec !== 'null') {
65
- if (type === 'number' && spec.includes('=')) {
81
+ // 验证正则约束
82
+ if (regexConstraint !== 'null') {
83
+ if (type === 'number' && regexConstraint.includes('=')) {
66
84
  // 数字计算表达式应包含安全字符
67
85
  const safePattern = /^[x\d\+\-\*\/\(\)\.\s\%]+$/;
68
- const expressionPart = spec.split('=')[0].trim();
86
+ const expressionPart = regexConstraint.split('=')[0].trim();
69
87
 
70
88
  if (!safePattern.test(expressionPart)) {
71
89
  Logger.warn(`${fileName} 文件 ${fieldName} 表达式 ${expressionPart} 包含不安全的字符`);
@@ -74,18 +92,18 @@ export default async () => {
74
92
  }
75
93
 
76
94
  // 验证等号右侧是否为数字
77
- const rightPart = spec.split('=')[1].trim();
95
+ const rightPart = regexConstraint.split('=')[1].trim();
78
96
  if (isNaN(parseFloat(rightPart))) {
79
97
  Logger.error(`${fileName} 文件 ${fieldName} 计算规则右边必须是数字,而不是 ${rightPart}`);
80
98
  fileValid = false;
81
99
  continue;
82
100
  }
83
- } else if (type === 'string' || type === 'array') {
101
+ } else if (type === 'string' || type === 'array' || type === 'text') {
84
102
  // 尝试编译正则表达式以检查是否有效
85
103
  try {
86
- new RegExp(spec);
104
+ new RegExp(regexConstraint);
87
105
  } catch (e) {
88
- Logger.error(`${fileName} 文件 ${fieldName} 正则表达式 ${spec} 无效: ${e.message}`);
106
+ Logger.error(`${fileName} 文件 ${fieldName} 正则表达式 ${regexConstraint} 无效: ${e.message}`);
89
107
  fileValid = false;
90
108
  continue;
91
109
  }
@@ -99,21 +117,21 @@ export default async () => {
99
117
  invalidFiles++;
100
118
  }
101
119
  } catch (error) {
102
- Logger.error(`Schema ${fileName} 解析失败: ${error.message}`);
120
+ Logger.error(`Table ${fileName} 解析失败: ${error.message}`);
103
121
  invalidFiles++;
104
122
  }
105
123
  };
106
124
 
107
- for await (const file of schemaGlob.scan({
108
- cwd: coreSchemaDir,
125
+ for await (const file of tablesGlob.scan({
126
+ cwd: coreTablesDir,
109
127
  absolute: true,
110
128
  onlyFiles: true
111
129
  })) {
112
130
  await validateFile(file);
113
131
  }
114
132
 
115
- for await (const file of schemaGlob.scan({
116
- cwd: userSchemaDir,
133
+ for await (const file of tablesGlob.scan({
134
+ cwd: userTablesDir,
117
135
  absolute: true,
118
136
  onlyFiles: true
119
137
  })) {
@@ -126,7 +144,7 @@ export default async () => {
126
144
  return true;
127
145
  }
128
146
  } catch (error) {
129
- Logger.error(`Schema 检查过程中出错:`, error);
147
+ Logger.error(`Tables 检查过程中出错:`, error);
130
148
  return false;
131
149
  }
132
150
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "2.0.12",
3
+ "version": "2.0.14",
4
4
  "description": "Buma - 为 Bun 专属打造的 API 接口框架核心引擎",
5
5
  "type": "module",
6
6
  "private": false,
@@ -9,11 +9,17 @@
9
9
  "registry": "https://registry.npmjs.org"
10
10
  },
11
11
  "main": "main.js",
12
+ "bin": {
13
+ "befly": "./bin/befly.js"
14
+ },
12
15
  "exports": {
13
16
  ".": "./main.js"
14
17
  },
15
18
  "scripts": {
16
19
  "r": "bun publish --registry=https://registry.npmjs.org --access=public",
20
+ "ra": "bun run scripts/release.js -a",
21
+ "rb": "bun run scripts/release.js -b",
22
+ "rc": "bun run scripts/release.js -c",
17
23
  "test": "bun test",
18
24
  "test:jwt": "bun test tests/jwt.test.js"
19
25
  },
@@ -32,11 +38,13 @@
32
38
  "license": "Apache-2.0",
33
39
  "files": [
34
40
  "apis/",
41
+ "bin/",
35
42
  "checks/",
36
43
  "config/",
37
44
  "libs/",
38
45
  "plugins/",
39
- "schema/",
46
+ "scripts/",
47
+ "tables/",
40
48
  "utils/",
41
49
  ".gitignore",
42
50
  ".npmignore",
@@ -47,9 +55,25 @@
47
55
  ".prettierrc",
48
56
  "LICENSE",
49
57
  "main.js",
58
+ "system.js",
50
59
  "package.json",
51
60
  "README.md",
61
+ "USEAGE.md",
52
62
  "vitest.config.js"
53
63
  ],
54
- "gitHead": "0c177fe05242f6c798e9f85262ee92343dbc6c46"
64
+ "gitHead": "1dc5f118a723969456559e758e2ba889f4601224",
65
+ "dependencies": {
66
+ "mariadb": "^3.4.5"
67
+ },
68
+ "simple-git-hooks": {
69
+ "pre-commit": "bunx --bun lint-staged"
70
+ },
71
+ "lint-staged": {
72
+ "*.{js,css,scss,less,ts,jsx,vue,html,json,md,yaml}": "bunx --bun prettier --write --cache --ignore-unknown"
73
+ },
74
+ "devDependencies": {
75
+ "lint-staged": "^16.1.5",
76
+ "prettier": "^3.6.2",
77
+ "simple-git-hooks": "^2.13.1"
78
+ }
55
79
  }