@lark-apaas/fullstack-cli 1.1.6-alpha.7 → 1.1.6

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/README.md CHANGED
@@ -1,14 +1,12 @@
1
1
  # @lark-apaas/fullstack-cli
2
2
 
3
- > Fullstack 开发工具集 - 文件派生、数据库 Schema 生成、OpenAPI 生成、能力管理
3
+ > Fullstack 开发工具集 - 文件派生、数据库 Schema 生成、OpenAPI 生成
4
4
 
5
5
  ## 功能
6
6
 
7
7
  1. **自动派生** - 自动管理项目脚本和配置文件
8
8
  2. **数据库 Schema 生成** - 从现有数据库生成 Drizzle ORM schema
9
9
  3. **OpenAPI 生成** - 自动生成 API 文档和客户端 SDK
10
- 4. **Action 插件管理** - 安装、更新、删除 action 插件
11
- 5. **能力配置管理** - 查看、充血、迁移能力配置
12
10
 
13
11
  ## 安装
14
12
 
@@ -74,137 +72,7 @@ CLIENT_BASE_PATH=/ # 客户端基础路径
74
72
  2. 挂载 DevToolsModule
75
73
  3. 生成 OpenAPI 文档和客户端 SDK
76
74
 
77
- ### 4. Action 插件管理
78
-
79
- 管理 Action 插件的安装、更新、删除和查看:
80
-
81
- ```bash
82
- # 安装插件(默认最新版)
83
- fullstack-cli action-plugin install @office/feishu-create-group
84
-
85
- # 安装指定版本
86
- fullstack-cli action-plugin install @office/feishu-create-group@1.0.0
87
-
88
- # 更新插件到最新版
89
- fullstack-cli action-plugin update @office/feishu-create-group
90
-
91
- # 删除插件
92
- fullstack-cli action-plugin remove @office/feishu-create-group
93
-
94
- # 查看已安装的插件列表
95
- fullstack-cli action-plugin list
96
- ```
97
-
98
- **命令别名:**
99
- | 完整命令 | 别名 |
100
- |----------|------|
101
- | `action-plugin install` | `action-plugin i` |
102
- | `action-plugin update` | `action-plugin up` |
103
- | `action-plugin remove` | `action-plugin rm` |
104
- | `action-plugin list` | `action-plugin ls` |
105
-
106
- **插件存储:**
107
- - 插件文件:`node_modules/<plugin-name>/`(标准 npm 包位置)
108
- - 配置文件:`.capabilityrc.json`(记录已安装的 action 插件元信息)
109
-
110
- ### 5. 能力配置管理
111
-
112
- 查看和管理项目中的能力配置:
113
-
114
- ```bash
115
- # 列出所有能力(充血后,带 actions 信息)
116
- fullstack-cli capability list
117
-
118
- # 列出所有能力(原始配置,不充血)
119
- fullstack-cli capability list --summary
120
-
121
- # 获取指定能力配置
122
- fullstack-cli capability list --id create_feishu_group_for_task
123
-
124
- # 获取指定能力原始配置
125
- fullstack-cli capability list --id create_feishu_group_for_task --summary
126
- ```
127
-
128
- **能力充血:**
129
- - 默认返回充血后的能力配置,包含从插件 manifest 读取的 actions 信息
130
- - 支持动态 Schema:manifest 中标记 `{ dynamic: true }` 的 schema 会运行时生成
131
- - Schema 优先级:`capability.paramsSchema > 动态 schema > 静态 schema`
132
- - 充血失败时返回原始配置 + `_hydrateError` 字段(不抛异常)
133
- - `--summary` 返回原始配置(存储在 `server/capabilities/*.json` 中的内容)
134
-
135
- ### 6. 能力迁移
136
-
137
- 将老版本 capability 配置(`capabilities.json`)迁移到新版本(独立 JSON 文件):
138
-
139
- ```bash
140
- # 执行迁移
141
- fullstack-cli capability migration
142
-
143
- # 预览模式(不修改文件)
144
- fullstack-cli capability migration --dry-run
145
-
146
- # 跳过插件安装
147
- fullstack-cli capability migration --skip-install
148
-
149
- # 跳过代码迁移
150
- fullstack-cli capability migration --skip-code
151
-
152
- # 使用自定义映射文件
153
- fullstack-cli capability migration --mapping ./my-mapping.json
154
- ```
155
-
156
- **迁移步骤:**
157
-
158
- 1. **JSON 文件迁移**
159
- - 读取 `server/capabilities.json`(老格式:数组)
160
- - 转换为独立文件 `server/capabilities/<id>.json`(新格式)
161
- - 自动备份原文件为 `capabilities.json.backup`
162
-
163
- 2. **插件安装**
164
- - 根据 `sourceActionID → pluginID` 映射表查找对应插件
165
- - 自动调用 `fullstack-cli action-plugin install` 安装缺失的插件
166
-
167
- 3. **代码迁移**
168
- - 扫描 `server/` 目录下的 TypeScript 文件
169
- - 移除 capability 直接导入 `import xxx from '@/capabilities/xxx'`
170
- - 添加 `CapabilityService` 依赖注入
171
- - 替换调用点为 `capabilityService.load('xxx').call('run', params)`
172
-
173
- **老格式 vs 新格式:**
174
-
175
- ```typescript
176
- // 老格式 (capabilities.json)
177
- {
178
- "id": "create_group",
179
- "sourceActionID": "feishu_group_create", // 老字段
180
- "name": "创建群组",
181
- "desc": "创建飞书群组", // 老字段
182
- "actionInput": { ... }, // 老字段
183
- "inputSchema": { ... }
184
- }
185
-
186
- // 新格式 (server/capabilities/create_group.json)
187
- {
188
- "id": "create_group",
189
- "pluginID": "@official/feishu-group", // 新字段
190
- "pluginVersion": "1.0.0", // 新字段
191
- "name": "创建群组",
192
- "description": "创建飞书群组", // 重命名
193
- "formValue": { ... }, // 重命名
194
- "paramsSchema": { ... }
195
- }
196
- ```
197
-
198
- **映射文件格式:**
199
-
200
- ```json
201
- {
202
- "feishu_group_create": "@official/feishu-group",
203
- "feishu_send_message": "@official/feishu-message"
204
- }
205
- ```
206
-
207
- ### 7. CLI 命令
75
+ ### 4. CLI 命令
208
76
 
209
77
  ```bash
210
78
  # 查看帮助
@@ -216,16 +84,6 @@ fullstack-cli gen-db-schema
216
84
  # 生成 OpenAPI
217
85
  fullstack-cli gen-openapi
218
86
 
219
- # Action 插件管理
220
- fullstack-cli action-plugin --help
221
- fullstack-cli action-plugin install <plugin>
222
- fullstack-cli action-plugin list
223
-
224
- # 能力配置管理
225
- fullstack-cli capability --help
226
- fullstack-cli capability list
227
- fullstack-cli capability migration --dry-run
228
-
229
87
  # 查看版本
230
88
  fullstack-cli --version
231
89
  ```
@@ -321,23 +179,6 @@ fullstack-cli
321
179
  }
322
180
  ```
323
181
 
324
- ### Capability 迁移
325
-
326
- 如果项目使用老版本的 capability 系统(`capabilities.json` 文件),可以使用迁移命令自动升级:
327
-
328
- ```bash
329
- # 1. 先预览迁移效果
330
- fullstack-cli capability migration --dry-run
331
-
332
- # 2. 确认无误后执行迁移
333
- fullstack-cli capability migration
334
- ```
335
-
336
- 迁移会自动完成:
337
- - JSON 配置文件格式转换
338
- - 插件安装
339
- - 代码调用方式更新(从直接导入改为 CapabilityService 注入)
340
-
341
182
  ## License
342
183
 
343
184
  MIT
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 生成数据库 schema
3
+ *
4
+ * 命令行选项:
5
+ * - --output <path>: schema 输出路径,默认 'server/database/schema.ts'
6
+ * - --schema-filter <schemas>: schema 过滤器,逗号分隔
7
+ * - --tables-filter <tables>: 表过滤器,逗号分隔,默认 '*'
8
+ *
9
+ * 环境变量配置:
10
+ * - SUDA_DATABASE_URL: 数据库连接 URL(必需)
11
+ * - DB_SCHEMA_OUTPUT: schema 输出路径(命令行选项优先)
12
+ * - DRIZZLE_SCHEMA_FILTER: schema 过滤器(命令行选项优先)
13
+ * - DRIZZLE_TABLES_FILTER: 表过滤器(命令行选项优先)
14
+ */
15
+ export declare function run(options?: {
16
+ enableNestModuleGenerate?: boolean;
17
+ output?: string;
18
+ schemaFilter?: string;
19
+ tablesFilter?: string;
20
+ }): Promise<void>;
@@ -0,0 +1,115 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { spawnSync } from 'node:child_process';
5
+ import { createRequire } from 'node:module';
6
+ // 加载 .env 配置
7
+ import { config as loadEnv } from 'dotenv';
8
+ // 创建 require 函数来加载 CommonJS 模块
9
+ const require = createRequire(import.meta.url);
10
+ /**
11
+ * 生成数据库 schema
12
+ *
13
+ * 命令行选项:
14
+ * - --output <path>: schema 输出路径,默认 'server/database/schema.ts'
15
+ * - --schema-filter <schemas>: schema 过滤器,逗号分隔
16
+ * - --tables-filter <tables>: 表过滤器,逗号分隔,默认 '*'
17
+ *
18
+ * 环境变量配置:
19
+ * - SUDA_DATABASE_URL: 数据库连接 URL(必需)
20
+ * - DB_SCHEMA_OUTPUT: schema 输出路径(命令行选项优先)
21
+ * - DRIZZLE_SCHEMA_FILTER: schema 过滤器(命令行选项优先)
22
+ * - DRIZZLE_TABLES_FILTER: 表过滤器(命令行选项优先)
23
+ */
24
+ export async function run(options = {}) {
25
+ // 加载用户项目的 .env 文件
26
+ let exitCode = 0;
27
+ const envPath = path.resolve(process.cwd(), '.env');
28
+ if (fs.existsSync(envPath)) {
29
+ loadEnv({ path: envPath });
30
+ console.log('[gen-db-schema] ✓ Loaded .env file');
31
+ }
32
+ const databaseUrl = process.env.SUDA_DATABASE_URL;
33
+ if (!databaseUrl) {
34
+ console.error('[gen-db-schema] Error: SUDA_DATABASE_URL environment variable is required');
35
+ process.exit(1);
36
+ }
37
+ // 命令行选项优先于环境变量
38
+ const outputPath = options.output || process.env.DB_SCHEMA_OUTPUT || 'server/database/schema.ts';
39
+ const OUT_DIR = path.resolve(process.cwd(), 'server/database/.introspect');
40
+ const SCHEMA_FILE = path.resolve(process.cwd(), outputPath);
41
+ console.log('[gen-db-schema] Starting...');
42
+ // 获取当前文件所在目录(ESM 方式)
43
+ const __filename = fileURLToPath(import.meta.url);
44
+ const __dirname = path.dirname(__filename);
45
+ // 使用 CLI 内部的 drizzle 配置
46
+ const cliRoot = path.resolve(__dirname, '../');
47
+ const configPath = path.join(cliRoot, 'config', 'drizzle.config.js');
48
+ if (!fs.existsSync(configPath)) {
49
+ console.error('[gen-db-schema] Error: drizzle config not found in CLI package');
50
+ process.exit(1);
51
+ }
52
+ try {
53
+ // 通过环境变量传递绝对路径给配置文件
54
+ const env = {
55
+ ...process.env,
56
+ __DRIZZLE_OUT_DIR__: OUT_DIR,
57
+ __DRIZZLE_SCHEMA_PATH__: SCHEMA_FILE,
58
+ };
59
+ // 执行 drizzle-kit introspect
60
+ const args = process.argv.slice(3).filter((arg) => !arg.startsWith('--enable-nest-module-generate'));
61
+ const spawnArgs = ['--yes', 'drizzle-kit', 'introspect', '--config', configPath, ...args];
62
+ const result = spawnSync('npx', spawnArgs, { stdio: 'inherit', env });
63
+ if (result.error) {
64
+ console.error('[gen-db-schema] Execution failed:', result.error);
65
+ throw result.error;
66
+ }
67
+ if ((result.status ?? 0) !== 0) {
68
+ throw new Error(`drizzle-kit introspect failed with status ${result.status}`);
69
+ }
70
+ // 复制生成的 schema
71
+ const generatedSchema = path.join(OUT_DIR, 'schema.ts');
72
+ if (!fs.existsSync(generatedSchema)) {
73
+ console.error('[gen-db-schema] schema.ts not generated');
74
+ throw new Error('drizzle-kit introspect failed to generate schema.ts');
75
+ }
76
+ fs.mkdirSync(path.dirname(SCHEMA_FILE), { recursive: true });
77
+ fs.copyFileSync(generatedSchema, SCHEMA_FILE);
78
+ console.log(`[gen-db-schema] ✓ Copied to ${outputPath}`);
79
+ // 后处理 schema(使用 CommonJS require 方式加载)
80
+ const { postprocessDrizzleSchema } = require('@lark-apaas/devtool-kits');
81
+ const stats = postprocessDrizzleSchema(SCHEMA_FILE);
82
+ if (stats?.unmatchedUnknown?.length) {
83
+ console.warn('[gen-db-schema] Unmatched custom types detected:', stats.unmatchedUnknown);
84
+ }
85
+ console.log('[gen-db-schema] ✓ Postprocessed schema');
86
+ try {
87
+ if (options.enableNestModuleGenerate) {
88
+ const { parseAndGenerateNestResourceTemplate } = require('@lark-apaas/devtool-kits');
89
+ const tsConfigFilePath = path.resolve(process.cwd(), 'tsconfig.json');
90
+ const schemaFilePath = SCHEMA_FILE;
91
+ await parseAndGenerateNestResourceTemplate({
92
+ tsConfigFilePath,
93
+ schemaFilePath,
94
+ moduleOutputDir: path.resolve(process.cwd(), 'server/modules'),
95
+ });
96
+ console.log('[gen-db-schema] ✓ Generate NestJS Module Boilerplate Successfully');
97
+ }
98
+ }
99
+ catch (error) {
100
+ console.warn('[gen-db-schema] Generate NestJS Module Boilerplate failed:', error instanceof Error ? error.message : String(error));
101
+ }
102
+ console.log('[gen-db-schema] ✓ Complete');
103
+ }
104
+ catch (err) {
105
+ console.error('[gen-db-schema] Failed:', err instanceof Error ? err.message : String(err));
106
+ exitCode = 1;
107
+ }
108
+ finally {
109
+ // 清理临时文件
110
+ if (fs.existsSync(OUT_DIR)) {
111
+ fs.rmSync(OUT_DIR, { recursive: true, force: true });
112
+ }
113
+ process.exit(exitCode);
114
+ }
115
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 同步模板文件到用户项目
3
+ */
4
+ export declare function run(options: {
5
+ disableGenOpenapi?: boolean;
6
+ }): Promise<void>;
@@ -0,0 +1,204 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { genSyncConfig } from '../config/sync.js';
5
+ /**
6
+ * 同步模板文件到用户项目
7
+ */
8
+ export async function run(options) {
9
+ // 检测是否在用户项目中(通过 INIT_CWD 判断)
10
+ const userProjectRoot = process.env.INIT_CWD || process.cwd();
11
+ // 获取插件根目录
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = path.dirname(__filename);
14
+ const pluginRoot = path.resolve(__dirname, '../..');
15
+ // 只有在插件自己的开发目录中才跳过(避免在开发插件时触发 sync)
16
+ if (userProjectRoot === pluginRoot) {
17
+ console.log('[fullstack-cli] Skip syncing (installing plugin itself)');
18
+ process.exit(0);
19
+ }
20
+ // 检查是否存在 package.json,确保是有效的项目
21
+ const userPackageJson = path.join(userProjectRoot, 'package.json');
22
+ if (!fs.existsSync(userPackageJson)) {
23
+ console.log('[fullstack-cli] Skip syncing (not a valid npm project)');
24
+ process.exit(0);
25
+ }
26
+ try {
27
+ console.log('[fullstack-cli] Starting sync...');
28
+ // 使用配置
29
+ const config = genSyncConfig({
30
+ disableGenOpenapi: options.disableGenOpenapi ?? false,
31
+ });
32
+ if (!config || !config.sync) {
33
+ console.warn('[fullstack-cli] No sync configuration found');
34
+ process.exit(0);
35
+ }
36
+ // 执行同步规则
37
+ for (const rule of config.sync) {
38
+ await syncRule(rule, pluginRoot, userProjectRoot);
39
+ }
40
+ // 设置权限
41
+ if (config.permissions) {
42
+ setPermissions(config.permissions, userProjectRoot);
43
+ }
44
+ console.log('[fullstack-cli] Sync completed successfully ✅');
45
+ }
46
+ catch (error) {
47
+ const message = error instanceof Error ? error.message : String(error);
48
+ console.error('[fullstack-cli] Failed to sync:', message);
49
+ process.exit(1);
50
+ }
51
+ }
52
+ /**
53
+ * 执行单个同步规则
54
+ */
55
+ async function syncRule(rule, pluginRoot, userProjectRoot) {
56
+ // 处理删除操作(只需要 to 路径)
57
+ if (rule.type === 'delete-file' || rule.type === 'delete-directory') {
58
+ const destPath = path.join(userProjectRoot, rule.to);
59
+ if (rule.type === 'delete-file') {
60
+ deleteFile(destPath);
61
+ }
62
+ else {
63
+ deleteDirectory(destPath);
64
+ }
65
+ return;
66
+ }
67
+ // TypeScript 类型窄化:使用 'from' in rule 确保类型安全
68
+ if (!('from' in rule)) {
69
+ return;
70
+ }
71
+ // 处理需要源文件的操作(CopyRule 和 AppendRule)
72
+ const srcPath = path.join(pluginRoot, rule.from);
73
+ const destPath = path.join(userProjectRoot, rule.to);
74
+ if (!fs.existsSync(srcPath)) {
75
+ console.warn(`[fullstack-cli] Source not found: ${rule.from}`);
76
+ return;
77
+ }
78
+ switch (rule.type) {
79
+ case 'directory':
80
+ syncDirectory(srcPath, destPath, rule.overwrite ?? true);
81
+ break;
82
+ case 'file':
83
+ syncFile(srcPath, destPath, rule.overwrite ?? true);
84
+ break;
85
+ case 'append':
86
+ appendToFile(srcPath, destPath);
87
+ break;
88
+ }
89
+ }
90
+ /**
91
+ * 同步单个文件
92
+ */
93
+ function syncFile(src, dest, overwrite = true) {
94
+ // 确保目标目录存在
95
+ const destDir = path.dirname(dest);
96
+ if (!fs.existsSync(destDir)) {
97
+ fs.mkdirSync(destDir, { recursive: true });
98
+ }
99
+ // 检查目标文件是否存在
100
+ if (fs.existsSync(dest) && !overwrite) {
101
+ console.log(`[fullstack-cli] ○ ${path.basename(dest)} (skipped, already exists)`);
102
+ return;
103
+ }
104
+ // 复制文件
105
+ fs.copyFileSync(src, dest);
106
+ console.log(`[fullstack-cli] ✓ ${path.basename(dest)}`);
107
+ }
108
+ /**
109
+ * 同步整个目录
110
+ */
111
+ function syncDirectory(src, dest, overwrite = true) {
112
+ // 确保目标目录存在
113
+ if (!fs.existsSync(dest)) {
114
+ fs.mkdirSync(dest, { recursive: true });
115
+ }
116
+ // 读取源目录所有文件
117
+ const files = fs.readdirSync(src);
118
+ let count = 0;
119
+ files.forEach(file => {
120
+ const srcFile = path.join(src, file);
121
+ const destFile = path.join(dest, file);
122
+ const stats = fs.statSync(srcFile);
123
+ if (stats.isDirectory()) {
124
+ // 递归处理子目录
125
+ syncDirectory(srcFile, destFile, overwrite);
126
+ }
127
+ else {
128
+ // 复制文件
129
+ if (overwrite || !fs.existsSync(destFile)) {
130
+ fs.copyFileSync(srcFile, destFile);
131
+ console.log(`[fullstack-cli] ✓ ${path.relative(dest, destFile)}`);
132
+ count++;
133
+ }
134
+ }
135
+ });
136
+ if (count > 0) {
137
+ console.log(`[fullstack-cli] Synced ${count} files to ${path.basename(dest)}/`);
138
+ }
139
+ }
140
+ /**
141
+ * 追加内容到文件
142
+ */
143
+ function appendToFile(src, dest) {
144
+ const content = fs.readFileSync(src, 'utf-8');
145
+ // 读取目标文件内容(如果存在)
146
+ let existingContent = '';
147
+ if (fs.existsSync(dest)) {
148
+ existingContent = fs.readFileSync(dest, 'utf-8');
149
+ }
150
+ // 检查是否已包含相同内容(避免重复追加)
151
+ if (existingContent.includes(content.trim())) {
152
+ console.log(`[fullstack-cli] ○ ${path.basename(dest)} (already contains content)`);
153
+ return;
154
+ }
155
+ // 追加内容
156
+ fs.appendFileSync(dest, content);
157
+ console.log(`[fullstack-cli] ✓ ${path.basename(dest)} (appended)`);
158
+ }
159
+ /**
160
+ * 设置文件权限
161
+ */
162
+ function setPermissions(permissions, projectRoot) {
163
+ for (const [pattern, mode] of Object.entries(permissions)) {
164
+ // 简单实现:只支持 **/*.sh 这种模式
165
+ if (pattern === '**/*.sh') {
166
+ const scriptsDir = path.join(projectRoot, 'scripts');
167
+ if (fs.existsSync(scriptsDir)) {
168
+ const files = fs.readdirSync(scriptsDir);
169
+ files.forEach(file => {
170
+ if (file.endsWith('.sh')) {
171
+ const filePath = path.join(scriptsDir, file);
172
+ fs.chmodSync(filePath, mode);
173
+ }
174
+ });
175
+ }
176
+ }
177
+ }
178
+ }
179
+ /**
180
+ * 删除单个文件
181
+ * @param filePath 要删除的文件路径
182
+ */
183
+ function deleteFile(filePath) {
184
+ if (fs.existsSync(filePath)) {
185
+ fs.unlinkSync(filePath);
186
+ console.log(`[fullstack-cli] ✓ ${path.basename(filePath)} (deleted)`);
187
+ }
188
+ else {
189
+ console.log(`[fullstack-cli] ○ ${path.basename(filePath)} (not found)`);
190
+ }
191
+ }
192
+ /**
193
+ * 删除整个目录
194
+ * @param dirPath 要删除的目录路径
195
+ */
196
+ function deleteDirectory(dirPath) {
197
+ if (fs.existsSync(dirPath)) {
198
+ fs.rmSync(dirPath, { recursive: true });
199
+ console.log(`[fullstack-cli] ✓ ${path.basename(dirPath)} (deleted)`);
200
+ }
201
+ else {
202
+ console.log(`[fullstack-cli] ○ ${path.basename(dirPath)} (not found)`);
203
+ }
204
+ }
@@ -1,5 +1,3 @@
1
1
  import { Config } from 'drizzle-kit';
2
-
3
2
  declare const _default: Config;
4
-
5
- export { _default as default };
3
+ export default _default;
@@ -1,21 +1,17 @@
1
- // src/config/drizzle.config.ts
2
- import { defineConfig } from "drizzle-kit";
3
- var outputDir = process.env.__DRIZZLE_OUT_DIR__ || "./server/database/.introspect";
4
- var schemaPath = process.env.__DRIZZLE_SCHEMA_PATH__ || "./server/database/schema.ts";
5
- var parsedUrl = new URL(process.env.SUDA_DATABASE_URL || "");
6
- var schemaFilter = parsedUrl.searchParams.get("schema")?.split(",") ?? [];
7
- parsedUrl.searchParams.delete("schema");
8
- var config = {
9
- schema: schemaPath,
10
- out: outputDir,
11
- tablesFilter: ["*"],
12
- schemaFilter,
13
- dialect: "postgresql",
14
- dbCredentials: {
15
- url: parsedUrl.toString()
16
- }
17
- };
18
- var drizzle_config_default = defineConfig(config);
19
- export {
20
- drizzle_config_default as default
1
+ import { defineConfig } from 'drizzle-kit';
2
+ const outputDir = process.env.__DRIZZLE_OUT_DIR__ || './server/database/.introspect';
3
+ const schemaPath = process.env.__DRIZZLE_SCHEMA_PATH__ || './server/database/schema.ts';
4
+ const parsedUrl = new URL(process.env.SUDA_DATABASE_URL || '');
5
+ const schemaFilter = parsedUrl.searchParams.get('schema')?.split(',') ?? [];
6
+ parsedUrl.searchParams.delete('schema'); // 移除schema参数,避免 drizzle-kit 解析错误
7
+ const config = {
8
+ schema: schemaPath,
9
+ out: outputDir,
10
+ tablesFilter: ['*'],
11
+ schemaFilter,
12
+ dialect: 'postgresql',
13
+ dbCredentials: {
14
+ url: parsedUrl.toString(),
15
+ },
21
16
  };
17
+ export default defineConfig(config);
@@ -0,0 +1,43 @@
1
+ /**
2
+ * fullstack-cli 派生配置
3
+ * 定义哪些文件/目录需要同步到用户项目
4
+ */
5
+ /** 复制目录或文件规则 */
6
+ type CopyRule = {
7
+ /** 源文件/目录路径(相对于插件根目录) */
8
+ from: string;
9
+ /** 目标文件/目录路径(相对于用户项目根目录) */
10
+ to: string;
11
+ /** 同步类型 */
12
+ type: 'directory' | 'file';
13
+ /** 是否覆盖已存在的文件 */
14
+ overwrite?: boolean;
15
+ };
16
+ /** 追加内容规则 */
17
+ type AppendRule = {
18
+ /** 源文件路径(相对于插件根目录) */
19
+ from: string;
20
+ /** 目标文件路径(相对于用户项目根目录) */
21
+ to: string;
22
+ /** 同步类型 */
23
+ type: 'append';
24
+ };
25
+ /** 删除文件或目录规则 */
26
+ type DeleteRule = {
27
+ /** 目标文件/目录路径(相对于用户项目根目录) */
28
+ to: string;
29
+ /** 同步类型 */
30
+ type: 'delete-file' | 'delete-directory';
31
+ };
32
+ /** 同步规则联合类型 */
33
+ export type SyncRule = CopyRule | AppendRule | DeleteRule;
34
+ export interface SyncConfig {
35
+ /** 派生规则 */
36
+ sync: SyncRule[];
37
+ /** 文件权限设置 */
38
+ permissions?: Record<string, number>;
39
+ }
40
+ export declare function genSyncConfig(perms?: {
41
+ disableGenOpenapi?: boolean;
42
+ }): SyncConfig;
43
+ export {};
@@ -0,0 +1,48 @@
1
+ /**
2
+ * fullstack-cli 派生配置
3
+ * 定义哪些文件/目录需要同步到用户项目
4
+ */
5
+ const syncConfig = {
6
+ // 派生规则
7
+ sync: [
8
+ // 1. 派生 scripts 目录(总是覆盖)
9
+ {
10
+ from: 'templates/scripts',
11
+ to: 'scripts',
12
+ type: 'directory',
13
+ overwrite: true,
14
+ },
15
+ // // 2. 追加内容到 .gitignore
16
+ // {
17
+ // from: 'templates/.gitignore.append',
18
+ // to: '.gitignore',
19
+ // type: 'append',
20
+ // },
21
+ // 3. 派生 server/type.ts 文件(总是覆盖)
22
+ // {
23
+ // from: 'templates/server/global.d.ts',
24
+ // to: 'server/types/global.d.ts',
25
+ // type: 'file',
26
+ // },
27
+ {
28
+ type: 'delete-directory',
29
+ to: '.swc', // 删除 .swc 目录(如果存在)
30
+ },
31
+ ],
32
+ // 文件权限设置
33
+ permissions: {
34
+ // 所有 .sh 文件设置为可执行
35
+ // '**/*.sh': 0o755,
36
+ },
37
+ };
38
+ export function genSyncConfig(perms = {}) {
39
+ if (!perms.disableGenOpenapi) {
40
+ syncConfig.sync.push({
41
+ from: 'templates/helper/gen-openapi.ts',
42
+ to: 'scripts/gen-openapi.ts',
43
+ type: 'file',
44
+ overwrite: true,
45
+ });
46
+ }
47
+ return syncConfig;
48
+ }
package/dist/index.d.ts CHANGED
@@ -1,2 +1 @@
1
-
2
- export { }
1
+ export {};