befly 2.3.2 → 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.
- package/apis/health/info.ts +64 -0
- package/apis/tool/tokenCheck.ts +51 -0
- package/bin/befly.ts +202 -0
- package/checks/conflict.ts +408 -0
- package/checks/table.ts +284 -0
- package/config/env.ts +218 -0
- package/config/reserved.ts +96 -0
- package/main.ts +101 -0
- package/package.json +45 -16
- package/plugins/{db.js → db.ts} +25 -12
- package/plugins/logger.ts +28 -0
- package/plugins/redis.ts +51 -0
- package/plugins/tool.ts +34 -0
- package/scripts/syncDb/apply.ts +171 -0
- package/scripts/syncDb/constants.ts +70 -0
- package/scripts/syncDb/ddl.ts +182 -0
- package/scripts/syncDb/helpers.ts +172 -0
- package/scripts/syncDb/index.ts +215 -0
- package/scripts/syncDb/schema.ts +199 -0
- package/scripts/syncDb/sqlite.ts +50 -0
- package/scripts/syncDb/state.ts +104 -0
- package/scripts/syncDb/table.ts +204 -0
- package/scripts/syncDb/tableCreate.ts +142 -0
- package/scripts/syncDb/tests/constants.test.ts +104 -0
- package/scripts/syncDb/tests/ddl.test.ts +134 -0
- package/scripts/syncDb/tests/helpers.test.ts +70 -0
- package/scripts/syncDb/types.ts +92 -0
- package/scripts/syncDb/version.ts +73 -0
- package/scripts/syncDb.ts +9 -0
- package/scripts/syncDev.ts +112 -0
- package/system.ts +149 -0
- package/tables/_common.json +21 -0
- package/tables/admin.json +10 -0
- package/tsconfig.json +58 -0
- package/types/api.d.ts +246 -0
- package/types/befly.d.ts +234 -0
- package/types/common.d.ts +215 -0
- package/types/context.ts +167 -0
- package/types/crypto.d.ts +23 -0
- package/types/database.d.ts +278 -0
- package/types/index.d.ts +16 -0
- package/types/index.ts +459 -0
- package/types/jwt.d.ts +99 -0
- package/types/logger.d.ts +43 -0
- package/types/plugin.d.ts +109 -0
- package/types/redis.d.ts +44 -0
- package/types/tool.d.ts +67 -0
- package/types/validator.d.ts +45 -0
- package/utils/addonHelper.ts +60 -0
- package/utils/api.ts +23 -0
- package/utils/{colors.js → colors.ts} +79 -21
- package/utils/crypto.ts +308 -0
- package/utils/datetime.ts +51 -0
- package/utils/dbHelper.ts +142 -0
- package/utils/errorHandler.ts +68 -0
- package/utils/index.ts +46 -0
- package/utils/jwt.ts +493 -0
- package/utils/logger.ts +284 -0
- package/utils/objectHelper.ts +68 -0
- package/utils/pluginHelper.ts +62 -0
- package/utils/redisHelper.ts +338 -0
- package/utils/response.ts +38 -0
- package/utils/{sqlBuilder.js → sqlBuilder.ts} +233 -97
- package/utils/sqlHelper.ts +447 -0
- package/utils/tableHelper.ts +167 -0
- package/utils/tool.ts +230 -0
- package/utils/typeHelper.ts +101 -0
- package/utils/validate.ts +451 -0
- package/utils/{xml.js → xml.ts} +100 -74
- package/.npmrc +0 -3
- package/.prettierignore +0 -2
- package/.prettierrc +0 -11
- package/apis/health/info.js +0 -49
- package/apis/tool/tokenCheck.js +0 -29
- package/checks/table.js +0 -221
- package/config/env.js +0 -62
- package/main.js +0 -579
- package/plugins/logger.js +0 -14
- package/plugins/redis.js +0 -32
- package/plugins/tool.js +0 -8
- package/scripts/syncDb.js +0 -603
- package/system.js +0 -118
- package/tables/common.json +0 -16
- package/tables/tool.json +0 -6
- package/utils/api.js +0 -27
- package/utils/crypto.js +0 -260
- package/utils/index.js +0 -387
- package/utils/jwt.js +0 -387
- package/utils/logger.js +0 -143
- package/utils/redisHelper.js +0 -74
- package/utils/sqlManager.js +0 -471
- package/utils/tool.js +0 -31
- package/utils/validate.js +0 -228
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* syncDb 类型定义模块
|
|
3
|
+
*
|
|
4
|
+
* 集中管理核心类型定义
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// ==================== 数据库相关类型 ====================
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 列信息接口
|
|
11
|
+
*/
|
|
12
|
+
export interface ColumnInfo {
|
|
13
|
+
type: string;
|
|
14
|
+
columnType: string;
|
|
15
|
+
length: number | null;
|
|
16
|
+
nullable: boolean;
|
|
17
|
+
defaultValue: any;
|
|
18
|
+
comment: string | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 索引信息接口(键为索引名,值为列名数组)
|
|
23
|
+
*/
|
|
24
|
+
export interface IndexInfo {
|
|
25
|
+
[indexName: string]: string[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ==================== 变更相关类型 ====================
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 字段变更接口
|
|
32
|
+
*/
|
|
33
|
+
export interface FieldChange {
|
|
34
|
+
type: 'length' | 'datatype' | 'comment' | 'default';
|
|
35
|
+
current: any;
|
|
36
|
+
expected: any;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 索引操作接口
|
|
41
|
+
*/
|
|
42
|
+
export interface IndexAction {
|
|
43
|
+
action: 'create' | 'drop';
|
|
44
|
+
indexName: string;
|
|
45
|
+
fieldName: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 表变更计划接口
|
|
50
|
+
*/
|
|
51
|
+
export interface TablePlan {
|
|
52
|
+
changed: boolean;
|
|
53
|
+
addClauses: string[];
|
|
54
|
+
modifyClauses: string[];
|
|
55
|
+
defaultClauses: string[];
|
|
56
|
+
indexActions: IndexAction[];
|
|
57
|
+
commentActions?: string[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ==================== 统计相关类型 ====================
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 全局统计对象
|
|
64
|
+
*/
|
|
65
|
+
export interface GlobalStats {
|
|
66
|
+
processedTables: number;
|
|
67
|
+
createdTables: number;
|
|
68
|
+
modifiedTables: number;
|
|
69
|
+
addFields: number;
|
|
70
|
+
nameChanges: number;
|
|
71
|
+
typeChanges: number;
|
|
72
|
+
minChanges: number;
|
|
73
|
+
maxChanges: number;
|
|
74
|
+
defaultChanges: number;
|
|
75
|
+
indexCreate: number;
|
|
76
|
+
indexDrop: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ==================== 解析相关类型 ====================
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* 解析后的字段规则
|
|
83
|
+
*/
|
|
84
|
+
export interface ParsedFieldRule {
|
|
85
|
+
name: string;
|
|
86
|
+
type: string;
|
|
87
|
+
min: any;
|
|
88
|
+
max: any;
|
|
89
|
+
default: any;
|
|
90
|
+
index: number;
|
|
91
|
+
regex: string;
|
|
92
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* syncDb 数据库版本检查模块
|
|
3
|
+
*
|
|
4
|
+
* 包含:
|
|
5
|
+
* - 数据库版本验证(MySQL/PostgreSQL/SQLite)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Logger } from '../../utils/logger.js';
|
|
9
|
+
import { Env } from '../../config/env.js';
|
|
10
|
+
import { DB_VERSION_REQUIREMENTS, IS_MYSQL, IS_PG, IS_SQLITE } from './constants.js';
|
|
11
|
+
import type { SQL } from 'bun';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 数据库版本检查(按方言)
|
|
15
|
+
*
|
|
16
|
+
* 根据当前数据库类型检查版本是否符合最低要求:
|
|
17
|
+
* - MySQL: >= 8.0
|
|
18
|
+
* - PostgreSQL: >= 17
|
|
19
|
+
* - SQLite: >= 3.50.0
|
|
20
|
+
*
|
|
21
|
+
* @param sql - SQL 客户端实例
|
|
22
|
+
* @throws {Error} 如果数据库版本不符合要求或无法获取版本信息
|
|
23
|
+
*/
|
|
24
|
+
export async function ensureDbVersion(sql: SQL): Promise<void> {
|
|
25
|
+
if (!sql) throw new Error('SQL 客户端未初始化');
|
|
26
|
+
|
|
27
|
+
if (IS_MYSQL) {
|
|
28
|
+
const r = await sql`SELECT VERSION() AS version`;
|
|
29
|
+
if (!r || r.length === 0 || !r[0]?.version) {
|
|
30
|
+
throw new Error('无法获取 MySQL 版本信息');
|
|
31
|
+
}
|
|
32
|
+
const version = r[0].version;
|
|
33
|
+
const majorVersion = parseInt(String(version).split('.')[0], 10);
|
|
34
|
+
if (!Number.isFinite(majorVersion) || majorVersion < DB_VERSION_REQUIREMENTS.MYSQL_MIN_MAJOR) {
|
|
35
|
+
throw new Error(`此脚本仅支持 MySQL ${DB_VERSION_REQUIREMENTS.MYSQL_MIN_MAJOR}.0+,当前版本: ${version}`);
|
|
36
|
+
}
|
|
37
|
+
Logger.info(`MySQL 版本: ${version}`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (IS_PG) {
|
|
42
|
+
const r = await sql`SELECT version() AS version`;
|
|
43
|
+
if (!r || r.length === 0 || !r[0]?.version) {
|
|
44
|
+
throw new Error('无法获取 PostgreSQL 版本信息');
|
|
45
|
+
}
|
|
46
|
+
const versionText = r[0].version;
|
|
47
|
+
Logger.info(`PostgreSQL 版本: ${versionText}`);
|
|
48
|
+
const m = /PostgreSQL\s+(\d+)/i.exec(versionText);
|
|
49
|
+
const major = m ? parseInt(m[1], 10) : NaN;
|
|
50
|
+
if (!Number.isFinite(major) || major < DB_VERSION_REQUIREMENTS.POSTGRES_MIN_MAJOR) {
|
|
51
|
+
throw new Error(`此脚本要求 PostgreSQL >= ${DB_VERSION_REQUIREMENTS.POSTGRES_MIN_MAJOR},当前: ${versionText}`);
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (IS_SQLITE) {
|
|
57
|
+
const r = await sql`SELECT sqlite_version() AS version`;
|
|
58
|
+
if (!r || r.length === 0 || !r[0]?.version) {
|
|
59
|
+
throw new Error('无法获取 SQLite 版本信息');
|
|
60
|
+
}
|
|
61
|
+
const version = r[0].version;
|
|
62
|
+
Logger.info(`SQLite 版本: ${version}`);
|
|
63
|
+
// 强制最低版本:SQLite ≥ 3.50.0
|
|
64
|
+
const [maj, min, patch] = String(version)
|
|
65
|
+
.split('.')
|
|
66
|
+
.map((v) => parseInt(v, 10) || 0);
|
|
67
|
+
const vnum = maj * 10000 + min * 100 + patch; // 3.50.0 -> 35000
|
|
68
|
+
if (!Number.isFinite(vnum) || vnum < DB_VERSION_REQUIREMENTS.SQLITE_MIN_VERSION_NUM) {
|
|
69
|
+
throw new Error(`此脚本要求 SQLite >= ${DB_VERSION_REQUIREMENTS.SQLITE_MIN_VERSION},当前: ${version}`);
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 同步开发者用户到数据库
|
|
3
|
+
* - 用户名: Env.DEV_USERNAME (默认 dev)
|
|
4
|
+
* - 密码: Crypto2.hmacMd5(Crypto2.md5(Env.DEV_PASSWORD), Env.MD5_SALT)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { DB } from '../plugins/db.js';
|
|
8
|
+
import { Env } from '../config/env.js';
|
|
9
|
+
import { Logger } from '../utils/logger.js';
|
|
10
|
+
import { Crypto2 } from '../utils/crypto.js';
|
|
11
|
+
import { createSqlClient } from '../utils/dbHelper.js';
|
|
12
|
+
|
|
13
|
+
// CLI 参数类型
|
|
14
|
+
interface CliArgs {
|
|
15
|
+
DRY_RUN: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// 解析命令行参数
|
|
19
|
+
const ARGV = Array.isArray(process.argv) ? process.argv : [];
|
|
20
|
+
const CLI: CliArgs = { DRY_RUN: ARGV.includes('--plan') };
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 执行 SQL 查询
|
|
24
|
+
*/
|
|
25
|
+
const exec = async (client: any, query: string, params: any[] = []): Promise<any> => {
|
|
26
|
+
if (params && params.length > 0) {
|
|
27
|
+
return await client.unsafe(query, params);
|
|
28
|
+
}
|
|
29
|
+
return await client.unsafe(query);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 同步开发管理员账号
|
|
34
|
+
* @param client 可选,复用已有 SQL 客户端;不传则内部创建与关闭
|
|
35
|
+
* @returns 是否成功
|
|
36
|
+
*/
|
|
37
|
+
export async function SyncDev(client: any = null): Promise<boolean> {
|
|
38
|
+
let ownClient = false;
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
if (CLI.DRY_RUN) {
|
|
42
|
+
Logger.info('[计划] 同步完成后将初始化/更新 admin.dev 账号(plan 模式不执行)');
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!Env.DEV_PASSWORD || !Env.MD5_SALT) {
|
|
47
|
+
Logger.warn('跳过开发管理员初始化:缺少 DEV_PASSWORD 或 MD5_SALT 配置');
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!client) {
|
|
52
|
+
client = await createSqlClient({ max: 1 });
|
|
53
|
+
ownClient = true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 检查 sys_admin 表是否存在(核心表带 sys_ 前缀)
|
|
57
|
+
const exist = await exec(client, 'SELECT COUNT(*) AS cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? LIMIT 1', [Env.DB_NAME || '', 'sys_admin']);
|
|
58
|
+
|
|
59
|
+
if (!exist || !exist[0] || Number(exist[0].cnt) === 0) {
|
|
60
|
+
Logger.warn('跳过开发管理员初始化:未检测到 sys_admin 表');
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const nowTs = Date.now();
|
|
65
|
+
// 对密码进行双重加密
|
|
66
|
+
const hashed = Crypto2.hmacMd5(Crypto2.md5(Env.DEV_PASSWORD), Env.MD5_SALT);
|
|
67
|
+
|
|
68
|
+
// 更新存在的 dev 账号
|
|
69
|
+
const updateRes = await exec(client, 'UPDATE `sys_admin` SET `password` = ?, `updated_at` = ? WHERE `account` = ? LIMIT 1', [hashed, nowTs, 'dev']);
|
|
70
|
+
|
|
71
|
+
const affected = updateRes?.affectedRows ?? updateRes?.rowsAffected ?? 0;
|
|
72
|
+
|
|
73
|
+
if (!affected || affected === 0) {
|
|
74
|
+
// 插入新账号
|
|
75
|
+
const id = nowTs;
|
|
76
|
+
await exec(client, 'INSERT INTO `sys_admin` (`id`, `created_at`, `updated_at`, `deleted_at`, `state`, `account`, `password`) VALUES (?, ?, ?, 0, 0, ?, ?)', [id, nowTs, nowTs, 'dev', hashed]);
|
|
77
|
+
Logger.info('开发管理员已初始化:account=dev');
|
|
78
|
+
} else {
|
|
79
|
+
Logger.info('开发管理员已更新密码并刷新更新时间:account=dev');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return true;
|
|
83
|
+
} catch (error: any) {
|
|
84
|
+
Logger.warn(`开发管理员初始化步骤出错:${error.message}`);
|
|
85
|
+
return false;
|
|
86
|
+
} finally {
|
|
87
|
+
if (ownClient && client) {
|
|
88
|
+
try {
|
|
89
|
+
await client.close();
|
|
90
|
+
} catch (error: any) {
|
|
91
|
+
Logger.warn('关闭数据库连接时出错:', error.message);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 允许直接运行该脚本
|
|
99
|
+
*/
|
|
100
|
+
if (import.meta.main) {
|
|
101
|
+
SyncDev()
|
|
102
|
+
.then((ok: boolean) => {
|
|
103
|
+
if (CLI.DRY_RUN) {
|
|
104
|
+
process.exit(0);
|
|
105
|
+
}
|
|
106
|
+
process.exit(ok ? 0 : 1);
|
|
107
|
+
})
|
|
108
|
+
.catch((err: Error) => {
|
|
109
|
+
console.error('❌ 开发管理员同步失败:', err);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
});
|
|
112
|
+
}
|
package/system.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Befly 框架系统路径定义 - TypeScript 版本
|
|
3
|
+
* 提供统一的路径变量,供整个框架使用
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { dirname, join, resolve, relative } from 'node:path';
|
|
8
|
+
|
|
9
|
+
// 当前文件的路径信息
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
|
|
13
|
+
// Befly 框架根目录
|
|
14
|
+
export const __dirroot = __dirname;
|
|
15
|
+
|
|
16
|
+
// 各个重要目录的路径
|
|
17
|
+
export const __dirscript = join(__dirroot, 'scripts');
|
|
18
|
+
export const __dirbin = join(__dirroot, 'bin');
|
|
19
|
+
export const __dirutils = join(__dirroot, 'utils');
|
|
20
|
+
export const __dirconfig = join(__dirroot, 'config');
|
|
21
|
+
export const __dirtables = join(__dirroot, 'tables');
|
|
22
|
+
export const __dirchecks = join(__dirroot, 'checks');
|
|
23
|
+
export const __dirapis = join(__dirroot, 'apis');
|
|
24
|
+
export const __dirplugins = join(__dirroot, 'plugins');
|
|
25
|
+
export const __dirlibs = join(__dirroot, 'libs');
|
|
26
|
+
export const __dirtests = join(__dirroot, 'tests');
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 获取项目根目录(befly 框架的使用方项目)
|
|
30
|
+
*/
|
|
31
|
+
export const getProjectRoot = (): string => {
|
|
32
|
+
return process.cwd();
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 获取项目中的特定目录
|
|
37
|
+
* @param subdir - 子目录名称
|
|
38
|
+
*/
|
|
39
|
+
export const getProjectDir = (subdir: string = ''): string => {
|
|
40
|
+
return subdir ? join(getProjectRoot(), subdir) : getProjectRoot();
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 创建路径解析器,基于 befly 根目录
|
|
45
|
+
* @param paths - 路径片段
|
|
46
|
+
*/
|
|
47
|
+
export const resolveBeflyPath = (...paths: string[]): string => {
|
|
48
|
+
return resolve(__dirroot, ...paths);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 创建路径解析器,基于项目根目录
|
|
53
|
+
* @param paths - 路径片段
|
|
54
|
+
*/
|
|
55
|
+
export const resolveProjectPath = (...paths: string[]): string => {
|
|
56
|
+
return resolve(getProjectRoot(), ...paths);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 获取相对于 befly 根目录的相对路径
|
|
61
|
+
* @param targetPath - 目标路径
|
|
62
|
+
*/
|
|
63
|
+
export const getRelativeBeflyPath = (targetPath: string): string => {
|
|
64
|
+
return relative(__dirroot, targetPath);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 获取相对于项目根目录的相对路径
|
|
69
|
+
* @param targetPath - 目标路径
|
|
70
|
+
*/
|
|
71
|
+
export const getRelativeProjectPath = (targetPath: string): string => {
|
|
72
|
+
return relative(getProjectRoot(), targetPath);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 系统路径配置对象
|
|
77
|
+
*/
|
|
78
|
+
export interface SystemPaths {
|
|
79
|
+
script: string;
|
|
80
|
+
bin: string;
|
|
81
|
+
utils: string;
|
|
82
|
+
config: string;
|
|
83
|
+
tables: string;
|
|
84
|
+
checks: string;
|
|
85
|
+
apis: string;
|
|
86
|
+
plugins: string;
|
|
87
|
+
libs: string;
|
|
88
|
+
tests: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 系统工具函数集合
|
|
93
|
+
*/
|
|
94
|
+
export interface SystemUtils {
|
|
95
|
+
getProjectRoot: typeof getProjectRoot;
|
|
96
|
+
getProjectDir: typeof getProjectDir;
|
|
97
|
+
resolveBeflyPath: typeof resolveBeflyPath;
|
|
98
|
+
resolveProjectPath: typeof resolveProjectPath;
|
|
99
|
+
getRelativeBeflyPath: typeof getRelativeBeflyPath;
|
|
100
|
+
getRelativeProjectPath: typeof getRelativeProjectPath;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 系统配置对象
|
|
105
|
+
*/
|
|
106
|
+
export interface SystemConfig {
|
|
107
|
+
__filename: string;
|
|
108
|
+
__dirname: string;
|
|
109
|
+
__dirroot: string;
|
|
110
|
+
paths: SystemPaths;
|
|
111
|
+
utils: SystemUtils;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 默认导出包含所有路径信息的对象
|
|
116
|
+
*/
|
|
117
|
+
const system: SystemConfig = {
|
|
118
|
+
// 基础路径变量
|
|
119
|
+
__filename,
|
|
120
|
+
__dirname,
|
|
121
|
+
__dirroot,
|
|
122
|
+
|
|
123
|
+
// Befly 框架目录
|
|
124
|
+
paths: {
|
|
125
|
+
script: __dirscript,
|
|
126
|
+
bin: __dirbin,
|
|
127
|
+
utils: __dirutils,
|
|
128
|
+
config: __dirconfig,
|
|
129
|
+
tables: __dirtables,
|
|
130
|
+
checks: __dirchecks,
|
|
131
|
+
apis: __dirapis,
|
|
132
|
+
plugins: __dirplugins,
|
|
133
|
+
libs: __dirlibs,
|
|
134
|
+
tests: __dirtests
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
// 工具函数
|
|
138
|
+
utils: {
|
|
139
|
+
getProjectRoot,
|
|
140
|
+
getProjectDir,
|
|
141
|
+
resolveBeflyPath,
|
|
142
|
+
resolveProjectPath,
|
|
143
|
+
getRelativeBeflyPath,
|
|
144
|
+
getRelativeProjectPath
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// 重新导出基础路径变量和 system 对象
|
|
149
|
+
export { __filename, __dirname, system };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "ID|number|1|null|null|1|null",
|
|
3
|
+
"email": "邮箱|string|5|100|null|1|^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
|
4
|
+
"phone": "手机号|string|11|11|null|1|^1[3-9]\\d{9}$",
|
|
5
|
+
"page": "页码|number|1|9999|1|0|null",
|
|
6
|
+
"limit": "每页数量|number|1|100|10|0|null",
|
|
7
|
+
"title": "标题|string|1|200|null|0|null",
|
|
8
|
+
"description": "描述|string|0|500|null|0|null",
|
|
9
|
+
"keyword": "关键词|string|1|50|null|1|null",
|
|
10
|
+
"keywords": "关键词列表|array|0|50|null|0|null",
|
|
11
|
+
"enabled": "启用状态|number|0|1|1|0|^(0|1)$",
|
|
12
|
+
"date": "日期|string|10|10|null|0|^\\d{4}-\\d{2}-\\d{2}$",
|
|
13
|
+
"datetime": "日期时间|string|19|25|null|0|^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}",
|
|
14
|
+
"filename": "文件名|string|1|255|null|0|null",
|
|
15
|
+
"url": "网址|string|5|500|null|0|^https?://",
|
|
16
|
+
"tag": "标签|array|0|10|null|0|null",
|
|
17
|
+
"orderBy": "排序字段|array|0|20|null|0|null",
|
|
18
|
+
"where": "查询条件|object|null|null|null|0|null",
|
|
19
|
+
"startTime": "开始时间|number|0|9999999999999|null|0|null",
|
|
20
|
+
"endTime": "结束时间|number|0|9999999999999|null|0|null"
|
|
21
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"account": "账号|string|3|50|null|1|^[a-zA-Z0-9_]+$",
|
|
3
|
+
"password": "密码|string|32|255|null|0|null",
|
|
4
|
+
"nickname": "昵称|string|0|50|null|0|null",
|
|
5
|
+
"avatar": "头像|string|0|500|null|0|null",
|
|
6
|
+
"email": "邮箱|string|0|100|null|0|^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
|
7
|
+
"phone": "手机号|string|0|11|null|0|^1[3-9]\\d{9}$",
|
|
8
|
+
"role": "角色|string|1|20|admin|1|^(superadmin|admin|user)$",
|
|
9
|
+
"status": "状态|number|0|1|1|1|^(0|1)$"
|
|
10
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// 基础配置
|
|
4
|
+
"target": "ESNext",
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"lib": ["ESNext"],
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
|
|
9
|
+
// 类型检查
|
|
10
|
+
"strict": true,
|
|
11
|
+
"noImplicitAny": true,
|
|
12
|
+
"strictNullChecks": true,
|
|
13
|
+
"strictFunctionTypes": true,
|
|
14
|
+
"strictBindCallApply": true,
|
|
15
|
+
"strictPropertyInitialization": true,
|
|
16
|
+
"noImplicitThis": true,
|
|
17
|
+
"alwaysStrict": true,
|
|
18
|
+
|
|
19
|
+
// 额外检查
|
|
20
|
+
"noUnusedLocals": true,
|
|
21
|
+
"noUnusedParameters": true,
|
|
22
|
+
"noImplicitReturns": true,
|
|
23
|
+
"noFallthroughCasesInSwitch": true,
|
|
24
|
+
"noUncheckedIndexedAccess": false,
|
|
25
|
+
"noImplicitOverride": true,
|
|
26
|
+
"noPropertyAccessFromIndexSignature": false,
|
|
27
|
+
|
|
28
|
+
// 模块
|
|
29
|
+
"esModuleInterop": true,
|
|
30
|
+
"allowSyntheticDefaultImports": true,
|
|
31
|
+
"forceConsistentCasingInFileNames": true,
|
|
32
|
+
"resolveJsonModule": true,
|
|
33
|
+
"isolatedModules": true,
|
|
34
|
+
|
|
35
|
+
// 输出
|
|
36
|
+
"declaration": true,
|
|
37
|
+
"declarationMap": true,
|
|
38
|
+
"sourceMap": true,
|
|
39
|
+
"removeComments": false,
|
|
40
|
+
"importHelpers": false,
|
|
41
|
+
|
|
42
|
+
// 高级
|
|
43
|
+
"skipLibCheck": true,
|
|
44
|
+
"allowJs": true,
|
|
45
|
+
"checkJs": false,
|
|
46
|
+
|
|
47
|
+
// Bun 特定
|
|
48
|
+
"types": ["bun-types"],
|
|
49
|
+
|
|
50
|
+
// 路径
|
|
51
|
+
"baseUrl": ".",
|
|
52
|
+
"paths": {
|
|
53
|
+
"@/*": ["./*"]
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"include": ["**/*.ts", "**/*.js"],
|
|
57
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.js"]
|
|
58
|
+
}
|