@lark-apaas/miaoda-cli 0.1.4 → 0.1.5-alpha.2f1e0ff
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 +6 -5
- package/dist/api/deploy/index.js +13 -1
- package/dist/api/deploy/modern-types.js +23 -0
- package/dist/api/deploy/modern.js +78 -0
- package/dist/api/deploy/plugin-instances-types.js +6 -0
- package/dist/api/deploy/plugin-instances.js +22 -0
- package/dist/api/observability/api.js +10 -0
- package/dist/api/observability/index.js +2 -1
- package/dist/cli/commands/app/index.js +144 -2
- package/dist/cli/commands/deploy/modern.js +50 -0
- package/dist/cli/commands/index.js +68 -5
- package/dist/cli/commands/observability/index.js +62 -6
- package/dist/cli/commands/shared.js +5 -0
- package/dist/cli/commands/skills/index.js +79 -0
- package/dist/cli/handlers/app/index.js +9 -1
- package/dist/cli/handlers/app/init.js +132 -0
- package/dist/cli/handlers/app/sync.js +215 -0
- package/dist/cli/handlers/deploy/modern.js +33 -0
- package/dist/cli/handlers/observability/helpers.js +4 -0
- package/dist/cli/handlers/observability/index.js +3 -1
- package/dist/cli/handlers/observability/log.js +8 -2
- package/dist/cli/handlers/observability/source-stack.js +389 -0
- package/dist/cli/handlers/observability/trace.js +7 -1
- package/dist/cli/handlers/skills/index.js +7 -0
- package/dist/cli/handlers/skills/status.js +31 -0
- package/dist/cli/handlers/skills/sync.js +49 -0
- package/dist/config/fullstack-cli-pin.js +17 -0
- package/dist/config/sync-configs/design-stack.js +98 -0
- package/dist/config/sync-configs/index.js +62 -0
- package/dist/config/sync-configs/nestjs-react-fullstack.js +177 -0
- package/dist/config/sync.js +14 -0
- package/dist/services/app/init/index.js +12 -0
- package/dist/services/app/init/install.js +123 -0
- package/dist/services/app/init/template.js +108 -0
- package/dist/services/deploy/modern/atoms/build.js +59 -0
- package/dist/services/deploy/modern/atoms/context.js +27 -0
- package/dist/services/deploy/modern/atoms/index.js +17 -0
- package/dist/services/deploy/modern/atoms/local-release.js +27 -0
- package/dist/services/deploy/modern/atoms/pre-release.js +13 -0
- package/dist/services/deploy/modern/atoms/save-plugin-instances.js +72 -0
- package/dist/services/deploy/modern/atoms/upload.js +246 -0
- package/dist/services/deploy/modern/check.js +53 -0
- package/dist/services/deploy/modern/constants.js +13 -0
- package/dist/services/deploy/modern/index.js +16 -0
- package/dist/services/deploy/modern/pipelines/index.js +5 -0
- package/dist/services/deploy/modern/pipelines/local.js +75 -0
- package/dist/services/deploy/modern/protocol.js +122 -0
- package/dist/services/deploy/modern/run-types.js +4 -0
- package/dist/services/deploy/modern/run.js +13 -0
- package/dist/services/deploy/modern/template-key-map.js +22 -0
- package/dist/services/skills/index.js +5 -0
- package/dist/services/skills/status.js +37 -0
- package/dist/utils/coding-steering.js +169 -0
- package/dist/utils/file-ops.js +45 -0
- package/dist/utils/git.js +22 -0
- package/dist/utils/githooks.js +55 -0
- package/dist/utils/http.js +21 -11
- package/dist/utils/merge-json.js +63 -0
- package/dist/utils/npm-pack.js +55 -0
- package/dist/utils/platform-sync.js +160 -0
- package/dist/utils/spark-meta.js +42 -0
- package/dist/utils/sync-rule.js +295 -0
- package/package.json +5 -3
- package/upgrade/templates/README.md +34 -0
- package/upgrade/templates/design-stack/templates/.githooks/pre-commit +4 -0
- package/upgrade/templates/design-stack/templates/scripts/dev-local.sh +53 -0
- package/upgrade/templates/design-stack/templates/scripts/dev.sh +25 -0
- package/upgrade/templates/design-stack/templates/scripts/hooks/run-precommit.js +37 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/.githooks/pre-commit +4 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/.gitignore.append +8 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/.spark_project +16 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/drizzle.config.ts +55 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/helper/gen-openapi.ts +34 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/nest-cli.json +25 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/build.sh +207 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev-local.sh +61 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev.js +295 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev.sh +25 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/hooks/run-precommit.js +37 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/lint.js +150 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/prune-smart.js +330 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/run.sh +8 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/server/global.d.ts +19 -0
- package/upgrade/templates/nestjs-react-fullstack/templates/tsconfig.node.json +5 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// FULLSTACK_PRECOMMIT_V1
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const { spawnSync } = require('node:child_process');
|
|
6
|
+
|
|
7
|
+
const SEP = ' ' + '─'.repeat(36);
|
|
8
|
+
|
|
9
|
+
function failAndExit(step, body) {
|
|
10
|
+
process.stderr.write('\n✗ pre-commit failed: ' + step + '\n');
|
|
11
|
+
process.stderr.write(SEP + '\n');
|
|
12
|
+
if (body && body.length > 0) {
|
|
13
|
+
process.stderr.write(body.replace(/\s+$/, '') + '\n');
|
|
14
|
+
}
|
|
15
|
+
process.stderr.write(SEP + '\n');
|
|
16
|
+
process.stderr.write(' bypass: git commit --no-verify\n');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function runLint() {
|
|
21
|
+
const cwd = process.cwd();
|
|
22
|
+
const res = spawnSync('npm', ['run', 'lint'], {
|
|
23
|
+
cwd,
|
|
24
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
25
|
+
env: process.env,
|
|
26
|
+
});
|
|
27
|
+
if (res.error) {
|
|
28
|
+
failAndExit('lint', String(res.error.message || res.error));
|
|
29
|
+
}
|
|
30
|
+
if (res.status !== 0) {
|
|
31
|
+
const stdout = res.stdout ? res.stdout.toString() : '';
|
|
32
|
+
const stderr = res.stderr ? res.stderr.toString() : '';
|
|
33
|
+
failAndExit('lint', stdout + '\n' + stderr);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
runLint();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
run = ["npm", "run", "dev"] # 默认 spark-cli dev
|
|
2
|
+
hidden = [".config", ".git", "scripts", "node_modules", "dist", ".spark", ".agent", ".agents", "tmp", ".spark_project", ".playwright-cli"]
|
|
3
|
+
lint = ["npm", "run", "lint"]
|
|
4
|
+
test = ["npm", "run", "test"]
|
|
5
|
+
genDbSchema = ["npm", "run", "gen:db-schema"]
|
|
6
|
+
genOpenApiClient = ["npm", "run", "gen:openapi"]
|
|
7
|
+
|
|
8
|
+
[deployment]
|
|
9
|
+
build = ["npm", "run", "build"]
|
|
10
|
+
run = ["npm", "run", "start"]
|
|
11
|
+
|
|
12
|
+
[files]
|
|
13
|
+
[files.restrict]
|
|
14
|
+
pathPatterns = ["client/src/api/gen", "package.json", ".spark_project", ".gitignore"]
|
|
15
|
+
[files.hidden]
|
|
16
|
+
pathPatterns = [".config", ".git", "scripts", "node_modules", "dist", ".spark", ".agent", ".agents", "tmp", ".spark_project", ".playwright-cli"]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { defineConfig, Config } from 'drizzle-kit';
|
|
2
|
+
require('dotenv').config();
|
|
3
|
+
|
|
4
|
+
const outputDir = process.env.__DRIZZLE_OUT_DIR__ || './tmp/.introspect';
|
|
5
|
+
const schemaPath = process.env.__DRIZZLE_SCHEMA_PATH__ || './server/database/schema.ts';
|
|
6
|
+
|
|
7
|
+
const parsedUrl = new URL(process.env.SUDA_DATABASE_URL || '');
|
|
8
|
+
|
|
9
|
+
const envSchemaFilter = process.env.DRIZZLE_SCHEMA_FILTER;
|
|
10
|
+
const urlSchemaFilter = parsedUrl.searchParams.get('schema');
|
|
11
|
+
|
|
12
|
+
const schemaFilter = (envSchemaFilter ?? urlSchemaFilter ?? '')
|
|
13
|
+
.split(',')
|
|
14
|
+
.map((s) => s.trim())
|
|
15
|
+
.filter(Boolean);
|
|
16
|
+
|
|
17
|
+
parsedUrl.searchParams.delete('schema'); // 移除schema参数,避免 drizzle-kit 解析错误
|
|
18
|
+
|
|
19
|
+
// 默认排除的系统对象(PostgreSQL 扩展和系统视图)
|
|
20
|
+
// 这些对象在 drizzle-kit introspect 时可能导致无效的 JS 代码生成
|
|
21
|
+
const SYSTEM_OBJECTS_EXCLUSIONS = [
|
|
22
|
+
'!spatial_ref_sys', // PostGIS 空间参考系统表
|
|
23
|
+
'!geography_columns', // PostGIS 地理列视图
|
|
24
|
+
'!geometry_columns', // PostGIS 几何列视图
|
|
25
|
+
'!raster_columns', // PostGIS 栅格列视图
|
|
26
|
+
'!raster_overviews', // PostGIS 栅格概览视图
|
|
27
|
+
'!pg_stat_statements', // pg_stat_statements 扩展
|
|
28
|
+
'!pg_stat_statements_info', // pg_stat_statements 扩展
|
|
29
|
+
'!part_config', // pg_partman 分区配置表
|
|
30
|
+
'!part_config_sub', // pg_partman 子分区配置表
|
|
31
|
+
'!table_privs', // 系统权限视图
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const envTablesFilter = process.env.DRIZZLE_TABLES_FILTER;
|
|
35
|
+
const userTablesFilter = (envTablesFilter ?? '*')
|
|
36
|
+
.split(',')
|
|
37
|
+
.map((s) => s.trim())
|
|
38
|
+
.filter(Boolean);
|
|
39
|
+
|
|
40
|
+
// 合并用户过滤器和系统对象排除
|
|
41
|
+
// 用户可以通过设置 DRIZZLE_TABLES_FILTER 来覆盖(如果需要包含某些系统对象)
|
|
42
|
+
const tablesFilter = [...userTablesFilter, ...SYSTEM_OBJECTS_EXCLUSIONS];
|
|
43
|
+
|
|
44
|
+
const config:Config = {
|
|
45
|
+
schema: schemaPath,
|
|
46
|
+
out: outputDir,
|
|
47
|
+
tablesFilter,
|
|
48
|
+
schemaFilter,
|
|
49
|
+
dialect: 'postgresql',
|
|
50
|
+
dbCredentials: {
|
|
51
|
+
url: parsedUrl.toString(),
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default defineConfig(config);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// This file is auto-generated by @lark-apaas/fullstack-cli
|
|
2
|
+
import { NestFactory } from '@nestjs/core';
|
|
3
|
+
import { DevToolsV2Module } from '@lark-apaas/fullstack-nestjs-core';
|
|
4
|
+
|
|
5
|
+
import { AppModule } from '../server/app.module';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 生成 OpenAPI 文档和客户端 SDK
|
|
9
|
+
*
|
|
10
|
+
* 此文件由 @lark-apaas/fullstack-cli 自动派生,请勿手动修改
|
|
11
|
+
* 每次运行 npm install 时会自动更新
|
|
12
|
+
*/
|
|
13
|
+
async function generateOpenApi() {
|
|
14
|
+
const app = await NestFactory.create(AppModule, { logger: false });
|
|
15
|
+
const basePath = process.env.CLIENT_BASE_PATH;
|
|
16
|
+
|
|
17
|
+
if (basePath) {
|
|
18
|
+
app.setGlobalPrefix(basePath);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
await DevToolsV2Module.mount(app, {
|
|
22
|
+
basePath,
|
|
23
|
+
docsPath: '/api_docs',
|
|
24
|
+
needSetupServer: false,
|
|
25
|
+
needGenerateClientSdk: true,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
process.exit(0); // 主动退出进程,不等待 app 关闭(用户存在场景,未释放 timer 导致 app 卡死问题)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
generateOpenApi().catch((err) => {
|
|
32
|
+
console.error('[OpenAPI] Failed to generate schema', err);
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/nest-cli",
|
|
3
|
+
"collection": "@nestjs/schematics",
|
|
4
|
+
"sourceRoot": "server",
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"deleteOutDir": false,
|
|
7
|
+
"tsConfigPath": "tsconfig.node.json",
|
|
8
|
+
"assets": [
|
|
9
|
+
{
|
|
10
|
+
"include": "capabilities/**/*.json",
|
|
11
|
+
"outDir": "dist/server",
|
|
12
|
+
"watchAssets": true
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"plugins": [
|
|
16
|
+
{
|
|
17
|
+
"name": "@nestjs/swagger",
|
|
18
|
+
"options": {
|
|
19
|
+
"introspectComments": true,
|
|
20
|
+
"classValidatorShim": true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# This file is auto-generated by @lark-apaas/fullstack-cli
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
ROOT_DIR="$(pwd)"
|
|
6
|
+
DIST_DIR="$ROOT_DIR/dist"
|
|
7
|
+
|
|
8
|
+
# 记录总开始时间
|
|
9
|
+
TOTAL_START=$(node -e "console.log(Date.now())")
|
|
10
|
+
|
|
11
|
+
# 打印耗时的辅助函数
|
|
12
|
+
print_time() {
|
|
13
|
+
local start=$1
|
|
14
|
+
local end=$(node -e "console.log(Date.now())")
|
|
15
|
+
local elapsed=$((end - start))
|
|
16
|
+
local seconds=$((elapsed / 1000))
|
|
17
|
+
local ms=$((elapsed % 1000))
|
|
18
|
+
echo " ⏱️ 耗时: ${seconds}.$(printf "%03d" $ms)s"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
# ==================== 步骤 0 ====================
|
|
22
|
+
echo "🗑️ [0/6] 安装插件"
|
|
23
|
+
STEP_START=$(node -e "console.log(Date.now())")
|
|
24
|
+
npx fullstack-cli action-plugin init
|
|
25
|
+
print_time $STEP_START
|
|
26
|
+
echo ""
|
|
27
|
+
|
|
28
|
+
# ==================== 步骤 1 ====================
|
|
29
|
+
echo "📝 [1/6] 更新 openapi 代码"
|
|
30
|
+
STEP_START=$(node -e "console.log(Date.now())")
|
|
31
|
+
npm run gen:openapi
|
|
32
|
+
print_time $STEP_START
|
|
33
|
+
echo ""
|
|
34
|
+
|
|
35
|
+
# ==================== 步骤 2 ====================
|
|
36
|
+
echo "🗑️ [2/6] 清理 dist 目录"
|
|
37
|
+
STEP_START=$(node -e "console.log(Date.now())")
|
|
38
|
+
rm -rf "$ROOT_DIR/dist"
|
|
39
|
+
print_time $STEP_START
|
|
40
|
+
echo ""
|
|
41
|
+
|
|
42
|
+
# ==================== 步骤 3 ====================
|
|
43
|
+
echo "🗺️ [3/6] 生成路由定义"
|
|
44
|
+
STEP_START=$(node -e "console.log(Date.now())")
|
|
45
|
+
|
|
46
|
+
# 在 client/server 构建之前生成到 dist/,供 DefinePlugin 注入前端 bundle
|
|
47
|
+
# 注意:nest-cli.json 中 deleteOutDir 必须为 false(模板默认值),否则 nest build 会清掉 dist/
|
|
48
|
+
echo " ├─ 生成 API 路由定义..."
|
|
49
|
+
npx generate-api-routes --server-dir ./server --out-dir ./dist > /tmp/gen-api-routes.log 2>&1 &
|
|
50
|
+
API_ROUTES_PID=$!
|
|
51
|
+
|
|
52
|
+
echo " ├─ 生成页面路由定义..."
|
|
53
|
+
npx generate-page-routes --app-path ./client/src/app.tsx --out-dir ./dist > /tmp/gen-page-routes.log 2>&1 &
|
|
54
|
+
PAGE_ROUTES_PID=$!
|
|
55
|
+
|
|
56
|
+
API_ROUTES_EXIT=0
|
|
57
|
+
PAGE_ROUTES_EXIT=0
|
|
58
|
+
|
|
59
|
+
wait $API_ROUTES_PID || API_ROUTES_EXIT=$?
|
|
60
|
+
wait $PAGE_ROUTES_PID || PAGE_ROUTES_EXIT=$?
|
|
61
|
+
|
|
62
|
+
if [ $API_ROUTES_EXIT -ne 0 ]; then
|
|
63
|
+
echo " ⚠️ API 路由生成失败(不影响构建)"
|
|
64
|
+
cat /tmp/gen-api-routes.log
|
|
65
|
+
else
|
|
66
|
+
echo " ✅ API 路由生成完成"
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
if [ $PAGE_ROUTES_EXIT -ne 0 ]; then
|
|
70
|
+
echo " ⚠️ 页面路由生成失败(不影响构建)"
|
|
71
|
+
cat /tmp/gen-page-routes.log
|
|
72
|
+
else
|
|
73
|
+
echo " ✅ 页面路由生成完成"
|
|
74
|
+
fi
|
|
75
|
+
print_time $STEP_START
|
|
76
|
+
echo ""
|
|
77
|
+
|
|
78
|
+
# ==================== 步骤 4 ====================
|
|
79
|
+
echo "🔨 [4/6] 并行构建 server 和 client"
|
|
80
|
+
STEP_START=$(node -e "console.log(Date.now())")
|
|
81
|
+
|
|
82
|
+
# 给 server/client 构建子进程预留 8GB heap,缓解 vite build transform 阶段 OOM
|
|
83
|
+
# (典型错误:Reached heap limit Allocation failed)。
|
|
84
|
+
# 仅在外部未设置 NODE_OPTIONS 时注入,允许 CI / 用户通过外部环境变量完全覆盖
|
|
85
|
+
BUILD_NODE_OPTIONS="${NODE_OPTIONS:---max-old-space-size=8192}"
|
|
86
|
+
|
|
87
|
+
# 根据 only_frontend_change 决定是否构建 server
|
|
88
|
+
if [[ "${only_frontend_change:-false}" == "true" ]]; then
|
|
89
|
+
echo "🔨 [4/6] 仅构建 client (only_frontend_change=true)"
|
|
90
|
+
|
|
91
|
+
echo " ├─ 启动 client 构建..."
|
|
92
|
+
NODE_OPTIONS="$BUILD_NODE_OPTIONS" npm run build:client > /tmp/build-client.log 2>&1
|
|
93
|
+
CLIENT_EXIT=$?
|
|
94
|
+
|
|
95
|
+
if [ $CLIENT_EXIT -ne 0 ]; then
|
|
96
|
+
echo " ❌ Client 构建失败"
|
|
97
|
+
cat /tmp/build-client.log
|
|
98
|
+
exit 1
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
echo " ✅ Client 构建完成"
|
|
102
|
+
else
|
|
103
|
+
echo "🔨 [4/6] 并行构建 server 和 client"
|
|
104
|
+
|
|
105
|
+
# 并行构建
|
|
106
|
+
echo " ├─ 启动 server 构建..."
|
|
107
|
+
NODE_OPTIONS="$BUILD_NODE_OPTIONS" npm run build:server > /tmp/build-server.log 2>&1 &
|
|
108
|
+
SERVER_PID=$!
|
|
109
|
+
|
|
110
|
+
echo " ├─ 启动 client 构建..."
|
|
111
|
+
NODE_OPTIONS="$BUILD_NODE_OPTIONS" npm run build:client > /tmp/build-client.log 2>&1 &
|
|
112
|
+
CLIENT_PID=$!
|
|
113
|
+
|
|
114
|
+
# 等待两个构建完成
|
|
115
|
+
SERVER_EXIT=0
|
|
116
|
+
CLIENT_EXIT=0
|
|
117
|
+
|
|
118
|
+
wait $SERVER_PID || SERVER_EXIT=$?
|
|
119
|
+
wait $CLIENT_PID || CLIENT_EXIT=$?
|
|
120
|
+
|
|
121
|
+
# 检查构建结果
|
|
122
|
+
if [ $SERVER_EXIT -ne 0 ]; then
|
|
123
|
+
echo " ❌ Server 构建失败"
|
|
124
|
+
cat /tmp/build-server.log
|
|
125
|
+
exit 1
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
if [ $CLIENT_EXIT -ne 0 ]; then
|
|
129
|
+
echo " ❌ Client 构建失败"
|
|
130
|
+
cat /tmp/build-client.log
|
|
131
|
+
exit 1
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
echo " ✅ Server 构建完成"
|
|
135
|
+
echo " ✅ Client 构建完成"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
print_time $STEP_START
|
|
139
|
+
echo ""
|
|
140
|
+
|
|
141
|
+
# ==================== 步骤 5 ====================
|
|
142
|
+
echo "📦 [5/6] 准备产物"
|
|
143
|
+
STEP_START=$(node -e "console.log(Date.now())")
|
|
144
|
+
|
|
145
|
+
# 移动 client 下的 HTML 文件到 dist/dist/client,保证 views 路径在 dev/prod 下一致
|
|
146
|
+
# 使用 mv 而非 cp:HTML 不能上传到公网 CDN,移走后 dist/client 中不再包含 HTML
|
|
147
|
+
if [ -d "$DIST_DIR/client" ]; then
|
|
148
|
+
mkdir -p "$DIST_DIR/dist/client"
|
|
149
|
+
find "$DIST_DIR/client" -maxdepth 1 -name "*.html" -exec mv {} "$DIST_DIR/dist/client/" \;
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
# server 相关产物准备(only_frontend_change=true 时跳过)
|
|
153
|
+
if [[ "${only_frontend_change:-false}" == "true" ]]; then
|
|
154
|
+
echo " [skip] 跳过 run.sh/.env 复制 (only_frontend_change=true)"
|
|
155
|
+
else
|
|
156
|
+
# 拷贝 run.sh 到 dist/(prod 从 dist/ 启动,确保 cwd 一致性)
|
|
157
|
+
cp "$ROOT_DIR/scripts/run.sh" "$DIST_DIR/"
|
|
158
|
+
|
|
159
|
+
# 拷贝 .env 文件(如果存在)
|
|
160
|
+
if [ -f "$ROOT_DIR/.env" ]; then
|
|
161
|
+
cp "$ROOT_DIR/.env" "$DIST_DIR/"
|
|
162
|
+
fi
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# 清理无用文件
|
|
166
|
+
rm -rf "$DIST_DIR/scripts"
|
|
167
|
+
rm -rf "$DIST_DIR/tsconfig.node.tsbuildinfo"
|
|
168
|
+
|
|
169
|
+
print_time $STEP_START
|
|
170
|
+
echo ""
|
|
171
|
+
|
|
172
|
+
# ==================== 步骤 6 ====================
|
|
173
|
+
echo "✂️ [6/6] 智能依赖裁剪"
|
|
174
|
+
STEP_START=$(node -e "console.log(Date.now())")
|
|
175
|
+
|
|
176
|
+
# 智能依赖裁剪(仅全量构建时执行,纯前端场景不打包 server,无需裁剪)
|
|
177
|
+
if [[ "${only_frontend_change:-false}" == "true" ]]; then
|
|
178
|
+
echo "✂️ [6/6] 跳过智能依赖裁剪 (only_frontend_change=true)"
|
|
179
|
+
else
|
|
180
|
+
echo "✂️ [6/6] 智能依赖裁剪"
|
|
181
|
+
|
|
182
|
+
# 分析实际依赖、复制并裁剪 node_modules、生成精简的 package.json
|
|
183
|
+
node "$ROOT_DIR/scripts/prune-smart.js"
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
print_time $STEP_START
|
|
187
|
+
echo ""
|
|
188
|
+
|
|
189
|
+
# 总耗时
|
|
190
|
+
echo "构建完成"
|
|
191
|
+
print_time $TOTAL_START
|
|
192
|
+
|
|
193
|
+
# 输出产物信息
|
|
194
|
+
DIST_SIZE=$(du -sh "$DIST_DIR" | cut -f1)
|
|
195
|
+
if [[ "${only_frontend_change:-false}" == "true" ]]; then
|
|
196
|
+
echo ""
|
|
197
|
+
echo "📊 构建产物统计:"
|
|
198
|
+
echo " 产物大小: $DIST_SIZE"
|
|
199
|
+
echo ""
|
|
200
|
+
else
|
|
201
|
+
NODE_MODULES_SIZE=$(du -sh "$DIST_DIR/node_modules" | cut -f1)
|
|
202
|
+
echo ""
|
|
203
|
+
echo "📊 构建产物统计:"
|
|
204
|
+
echo " 产物大小: $DIST_SIZE"
|
|
205
|
+
echo " node_modules: $NODE_MODULES_SIZE"
|
|
206
|
+
echo ""
|
|
207
|
+
fi
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ============================================================================
|
|
3
|
+
# 本地 dev 启动脚本(平台控制,通过 `miaoda app upgrade` 同步,请勿手改)
|
|
4
|
+
# Stack: nestjs-react-fullstack
|
|
5
|
+
# 流程:env pull → skills sync → 并发起 server + client
|
|
6
|
+
# ============================================================================
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
9
|
+
cd "$ROOT_DIR"
|
|
10
|
+
|
|
11
|
+
# === Sentinels(必须由本脚本注入,不属于 .env.local 业务范畴)===
|
|
12
|
+
|
|
13
|
+
# Stack 对应 miaoda CLI 的 application scene;沙箱里平台注入,本地脚本兜底,
|
|
14
|
+
# 让后续 miaoda 子命令(skills sync 等)走对的 scene。
|
|
15
|
+
export MIAODA_APP_TYPE="${MIAODA_APP_TYPE:-3}"
|
|
16
|
+
|
|
17
|
+
# 本地开发总开关:SDK(fullstack-vite-preset / fullstack-rspack-preset /
|
|
18
|
+
# fullstack-nestjs-core)据此启用本地兜底逻辑:
|
|
19
|
+
# - vite/rspack-preset:反代 /__runtime__ 到沙箱(带 cookie / webuser header)
|
|
20
|
+
# - nestjs-core:从 cookie 补 csrf header + 注入 webuser header
|
|
21
|
+
# 沙箱 dev / 生产不设此 env,SDK 行为完全不变。
|
|
22
|
+
export MIAODA_LOCAL_DEV=1
|
|
23
|
+
|
|
24
|
+
# 临时:绕 npmmirror/bnpm 内网到 npmjs 的同步延迟,等 coding-steering 正式版去掉。
|
|
25
|
+
export MIAODA_NPM_REGISTRY="${MIAODA_NPM_REGISTRY:-https://registry.npmjs.org/}"
|
|
26
|
+
|
|
27
|
+
# === .env.local / .env 加载由 SDK 侧负责,本脚本不再手工 source ===
|
|
28
|
+
# fullstack-nestjs-core 在 module init 通过 dotenv 读 .env.local + .env;
|
|
29
|
+
# fullstack-{vite,rspack}-preset 的 defineConfig 同理。优先级:shell > .env.local > .env。
|
|
30
|
+
# 历史版本曾在这里用 bash 自写 parser,引号 / 多行 / 行尾注释处理不全且重复造轮子,已下放到 SDK。
|
|
31
|
+
|
|
32
|
+
# 1. 拉本地 dev 所需 ENV(jwt / cookie / sandbox URL 等,写入 .env.local)
|
|
33
|
+
# app_id 从 .spark/meta.json 读 —— `miaoda app init --app-id <id>` 时持久化的权威源,
|
|
34
|
+
# 后续 dev / sync 全部沿用这一个值;不在脚本里 hack 别的推断渠道。
|
|
35
|
+
# lark-cli 子命令真名是 `+env-pull`(带 + 前缀单 token,不是 `env pull` 空格分隔);
|
|
36
|
+
# `--as user` 必须显式:env-pull 只接受 user identity,默认 bot 会校验失败。
|
|
37
|
+
echo "[dev-local] (1/3) env pull..."
|
|
38
|
+
if command -v lark-cli >/dev/null 2>&1; then
|
|
39
|
+
# 用 node 读 .spark/meta.json,不引 python3 依赖(user app 必装 node)。
|
|
40
|
+
APP_ID=$(node -e 'try{process.stdout.write(JSON.parse(require("fs").readFileSync(".spark/meta.json","utf8")).app_id||"")}catch(e){}' 2>/dev/null || echo "")
|
|
41
|
+
if [ -n "$APP_ID" ]; then
|
|
42
|
+
lark-cli apps +env-pull --app-id "$APP_ID" --as user || echo " (env pull 失败,后续按 .env.local 现状继续)"
|
|
43
|
+
else
|
|
44
|
+
echo " (.spark/meta.json 缺 app_id,先跑 \`miaoda app init --app-id <id>\` 写入)"
|
|
45
|
+
fi
|
|
46
|
+
else
|
|
47
|
+
echo " (lark-cli 未装,跳过 env pull;请确保 .env.local 已就绪)"
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# 2. 同步 stack 对应 skills(coding-steering)。走 npx 不依赖用户全局装 miaoda;
|
|
51
|
+
# 钉到 @alpha dist-tag 跟随最新发布,miaoda-cli 通道我们自己控制风险小。
|
|
52
|
+
echo "[dev-local] (2/3) miaoda skills sync..."
|
|
53
|
+
npx -y @lark-apaas/miaoda-cli@alpha skills sync || echo " (skills sync 失败,继续启动)"
|
|
54
|
+
|
|
55
|
+
# 3. 并发起 dev:server(NestJS)+ dev:client(vite/rspack)
|
|
56
|
+
# 端口、SANDBOX_* 等业务 env 由 SDK 内 dotenv 加载,不在 banner 里假装显示。
|
|
57
|
+
# 不走 scripts/dev.js(保活 / restart / 日志写文件那套)—— 本地崩就崩,错日志直接 stdout。
|
|
58
|
+
echo "[dev-local] (3/3) 并发起 dev:server + dev:client"
|
|
59
|
+
exec npx --no-install concurrently \
|
|
60
|
+
--names "server,client" --prefix-colors "blue,green" --kill-others-on-fail \
|
|
61
|
+
"npm run dev:server" "npm run dev:client"
|