@lark-apaas/fullstack-cli 1.1.32 → 1.1.34-alpha.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/dist/index.js CHANGED
@@ -1414,14 +1414,15 @@ async function fetchSyncedTables(appId, workspace) {
1414
1414
  DEFAULT_TIMEOUT_MS2
1415
1415
  );
1416
1416
  });
1417
+ const dbBranch = process.env.FORCE_DB_BRANCH || "main";
1417
1418
  const start = Date.now();
1418
1419
  console.log(
1419
- `[fetchSyncedTables] \u2192 GET listTableView (dbBranch=main) appId=${appId ? "set" : "unset"} workspace=${workspace ? "set" : "unset"}`
1420
+ `[fetchSyncedTables] \u2192 GET listTableView (dbBranch=${dbBranch}) appId=${appId ? "set" : "unset"} workspace=${workspace ? "set" : "unset"}`
1420
1421
  );
1421
1422
  const response = await Promise.race([
1422
1423
  client.get(
1423
1424
  `/api/v1/dataloom/inner/app/${appId}/workspaces/${workspace}/listTableView`,
1424
- { params: { dbBranch: "main" }, headers: { "x-supaas-bizsource": "miaoda" } }
1425
+ { params: { dbBranch }, headers: { "x-supaas-bizsource": "miaoda" } }
1425
1426
  ),
1426
1427
  timeoutPromise
1427
1428
  ]);
@@ -7255,6 +7256,12 @@ var SCENE_CONFIGS = {
7255
7256
  buildRequestBody: () => ({ commitID: "" })
7256
7257
  }
7257
7258
  };
7259
+ var UPLOAD_STATIC_DEFAULTS = {
7260
+ staticDir: "shared/static",
7261
+ tosutilPath: "tosutil",
7262
+ endpoint: "tos-cn-beijing.volces.com",
7263
+ region: "cn-beijing"
7264
+ };
7258
7265
 
7259
7266
  // src/commands/build/api-client.ts
7260
7267
  async function genArtifactUploadCredential(appId, body) {
@@ -7270,17 +7277,20 @@ async function genArtifactUploadCredential(appId, body) {
7270
7277
  }
7271
7278
  async function getDefaultBucketId(appId) {
7272
7279
  const client = getHttpClient();
7273
- const url = `/b/${appId}/get_published_v2`;
7274
- const response = await client.get(url);
7280
+ const url = `/v1/app/${appId}/storage/inner/staticBucket`;
7281
+ const response = await client.post(url, {});
7275
7282
  if (!response.ok || response.status !== 200) {
7276
7283
  throw new Error(
7277
- `get_published_v2 \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
7284
+ `getOrCreateStaticBucket \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
7278
7285
  );
7279
7286
  }
7280
7287
  const data = await response.json();
7281
- const bucketId = data?.data?.app_runtime_extra?.bucket?.default_bucket_id;
7288
+ if (data.status_code !== "0") {
7289
+ throw new Error(`getOrCreateStaticBucket \u8FD4\u56DE\u5F02\u5E38, status_code: ${data.status_code}`);
7290
+ }
7291
+ const bucketId = data?.data?.bucketID;
7282
7292
  if (!bucketId) {
7283
- throw new Error(`\u672A\u627E\u5230\u5E94\u7528 ${appId} \u7684\u9ED8\u8BA4\u5B58\u50A8\u6876`);
7293
+ throw new Error(`\u672A\u627E\u5230\u5E94\u7528 ${appId} \u7684\u9759\u6001\u8D44\u6E90\u5B58\u50A8\u6876`);
7284
7294
  }
7285
7295
  return bucketId;
7286
7296
  }
@@ -7341,6 +7351,7 @@ function camelToKebab(str) {
7341
7351
 
7342
7352
  // src/commands/build/upload-static.handler.ts
7343
7353
  import * as fs25 from "fs";
7354
+ import * as os2 from "os";
7344
7355
  import * as path21 from "path";
7345
7356
  import { execFileSync } from "child_process";
7346
7357
  function readCredentialsFromEnv() {
@@ -7360,10 +7371,10 @@ async function uploadStatic(options) {
7360
7371
  try {
7361
7372
  const {
7362
7373
  appId,
7363
- staticDir = "shared/static",
7364
- tosutilPath = "/workspace/tosutil",
7365
- endpoint = "tos-cn-beijing.volces.com",
7366
- region = "cn-beijing"
7374
+ staticDir = UPLOAD_STATIC_DEFAULTS.staticDir,
7375
+ tosutilPath = UPLOAD_STATIC_DEFAULTS.tosutilPath,
7376
+ endpoint = UPLOAD_STATIC_DEFAULTS.endpoint,
7377
+ region = UPLOAD_STATIC_DEFAULTS.region
7367
7378
  } = options;
7368
7379
  const resolvedStaticDir = path21.resolve(staticDir);
7369
7380
  if (!fs25.existsSync(resolvedStaticDir)) {
@@ -7374,9 +7385,10 @@ async function uploadStatic(options) {
7374
7385
  console.error(`${LOG_PREFIX} \u76EE\u5F55\u4E3A\u7A7A: ${resolvedStaticDir}\uFF0C\u8DF3\u8FC7\u4E0A\u4F20`);
7375
7386
  return;
7376
7387
  }
7377
- if (!fs25.existsSync(tosutilPath)) {
7388
+ const resolvedTosutil = resolveTosutilPath(tosutilPath);
7389
+ if (!resolvedTosutil) {
7378
7390
  throw new Error(
7379
- `tosutil \u4E0D\u5B58\u5728: ${tosutilPath}\u3002\u8BF7\u786E\u4FDD\u6D41\u6C34\u7EBF\u5DF2\u5728"\u4EA7\u7269\u6253\u5305\u4E0A\u4F20"\u6B65\u9AA4\u4E2D\u4E0B\u8F7D tosutil\u3002`
7391
+ `tosutil \u4E0D\u5B58\u5728: ${tosutilPath}\u3002\u8BF7\u786E\u4FDD tosutil \u5DF2\u5B89\u88C5\u5728\u7CFB\u7EDF PATH \u4E2D\u6216\u901A\u8FC7 --tosutil-path \u6307\u5B9A\u8DEF\u5F84\u3002`
7380
7392
  );
7381
7393
  }
7382
7394
  let uploadPrefix;
@@ -7398,16 +7410,25 @@ async function uploadStatic(options) {
7398
7410
  ({ AccessKeyID: accessKeyID, SecretAccessKey: secretAccessKey, SessionToken: sessionToken } = uploadCredential);
7399
7411
  }
7400
7412
  console.error(`${LOG_PREFIX} \u4E0A\u4F20\u76EE\u6807: ${uploadPrefix}`);
7401
- console.error(`${LOG_PREFIX} \u914D\u7F6E tosutil...`);
7402
- configureTosutil(tosutilPath, {
7403
- endpoint,
7404
- region,
7405
- accessKeyID,
7406
- secretAccessKey,
7407
- sessionToken
7408
- });
7409
- console.error(`${LOG_PREFIX} \u4E0A\u4F20 ${resolvedStaticDir} -> ${uploadPrefix}`);
7410
- uploadToTos(tosutilPath, resolvedStaticDir, uploadPrefix);
7413
+ const confPath = path21.join(os2.tmpdir(), `.tosutilconfig-static-${process.pid}`);
7414
+ fs25.writeFileSync(confPath, "");
7415
+ try {
7416
+ console.error(`${LOG_PREFIX} \u914D\u7F6E tosutil...`);
7417
+ configureTosutil(resolvedTosutil, confPath, {
7418
+ endpoint,
7419
+ region,
7420
+ accessKeyID,
7421
+ secretAccessKey,
7422
+ sessionToken
7423
+ });
7424
+ console.error(`${LOG_PREFIX} \u4E0A\u4F20 ${resolvedStaticDir} -> ${uploadPrefix}`);
7425
+ uploadToTos(resolvedTosutil, confPath, resolvedStaticDir, uploadPrefix);
7426
+ } finally {
7427
+ try {
7428
+ fs25.unlinkSync(confPath);
7429
+ } catch {
7430
+ }
7431
+ }
7411
7432
  console.error(`${LOG_PREFIX} tosutil \u4E0A\u4F20\u5B8C\u6210`);
7412
7433
  console.error(`${LOG_PREFIX} \u8C03\u7528 callbackStatic (uploadID: ${uploadID})...`);
7413
7434
  const callbackResp = await uploadStaticAttachmentCallback(appId, bucketId, { uploadID });
@@ -7423,6 +7444,17 @@ async function uploadStatic(options) {
7423
7444
  process.exit(1);
7424
7445
  }
7425
7446
  }
7447
+ function resolveTosutilPath(tosutilPath) {
7448
+ if (path21.isAbsolute(tosutilPath)) {
7449
+ return fs25.existsSync(tosutilPath) ? tosutilPath : null;
7450
+ }
7451
+ try {
7452
+ const resolved = execFileSync("which", [tosutilPath], { encoding: "utf-8" }).trim();
7453
+ return resolved || null;
7454
+ } catch {
7455
+ return null;
7456
+ }
7457
+ }
7426
7458
  async function fetchPreUpload(appId, bucketId) {
7427
7459
  const response = await preUploadStaticAttachment(appId, bucketId);
7428
7460
  if (response.status_code !== "0") {
@@ -7437,18 +7469,18 @@ async function fetchPreUpload(appId, bucketId) {
7437
7469
  }
7438
7470
  return response;
7439
7471
  }
7440
- function configureTosutil(tosutilPath, config) {
7472
+ function configureTosutil(tosutilPath, confPath, config) {
7441
7473
  const { endpoint, region, accessKeyID, secretAccessKey, sessionToken } = config;
7442
7474
  execFileSync(
7443
7475
  tosutilPath,
7444
- ["config", "-e", endpoint, "-i", accessKeyID, "-k", secretAccessKey, "-t", sessionToken, "-re", region],
7476
+ ["config", "-conf", confPath, "-e", endpoint, "-i", accessKeyID, "-k", secretAccessKey, "-t", sessionToken, "-re", region],
7445
7477
  { stdio: "pipe" }
7446
7478
  );
7447
7479
  }
7448
- function uploadToTos(tosutilPath, sourceDir, destUrl) {
7480
+ function uploadToTos(tosutilPath, confPath, sourceDir, destUrl) {
7449
7481
  execFileSync(
7450
7482
  tosutilPath,
7451
- ["cp", sourceDir, destUrl, "-r", "-flat", "-j", "5", "-p", "3", "-ps", "10485760", "-f"],
7483
+ ["cp", "-conf", confPath, sourceDir, destUrl, "-r", "-flat", "-j", "5", "-p", "3", "-ps", "10485760", "-f"],
7452
7484
  { stdio: "inherit" }
7453
7485
  );
7454
7486
  }
@@ -7517,7 +7549,7 @@ var uploadStaticCommand = {
7517
7549
  name: "upload-static",
7518
7550
  description: "Upload shared/static files to TOS",
7519
7551
  register(program) {
7520
- program.command(this.name).description(this.description).requiredOption("--app-id <id>", "Application ID").option("--static-dir <dir>", "Static files directory", "shared/static").option("--tosutil-path <path>", "Path to tosutil binary", "/workspace/tosutil").option("--endpoint <endpoint>", "TOS endpoint", "tos-cn-beijing.volces.com").option("--region <region>", "TOS region", "cn-beijing").action(async (options) => {
7552
+ program.command(this.name).description(this.description).requiredOption("--app-id <id>", "Application ID").option("--static-dir <dir>", "Static files directory", UPLOAD_STATIC_DEFAULTS.staticDir).option("--tosutil-path <path>", "Path to tosutil binary", UPLOAD_STATIC_DEFAULTS.tosutilPath).option("--endpoint <endpoint>", "TOS endpoint", UPLOAD_STATIC_DEFAULTS.endpoint).option("--region <region>", "TOS region", UPLOAD_STATIC_DEFAULTS.region).action(async (options) => {
7521
7553
  await uploadStatic(options);
7522
7554
  });
7523
7555
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/fullstack-cli",
3
- "version": "1.1.32",
3
+ "version": "1.1.34-alpha.0",
4
4
  "description": "CLI tool for fullstack template management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -52,7 +52,7 @@
52
52
  "@types/node": "^22.0.0",
53
53
  "tsup": "^8.3.5",
54
54
  "typescript": "^5.9.2",
55
- "vitest": "^2.1.8"
55
+ "vitest": "^3.2.4"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "typescript": "^5.9.2"
@@ -40,40 +40,59 @@ print_time $STEP_START
40
40
  echo ""
41
41
 
42
42
  # ==================== 步骤 3 ====================
43
- echo "🔨 [3/5] 并行构建 server 和 client"
44
43
  STEP_START=$(node -e "console.log(Date.now())")
45
44
 
46
- # 并行构建
47
- echo " ├─ 启动 server 构建..."
48
- npm run build:server > /tmp/build-server.log 2>&1 &
49
- SERVER_PID=$!
50
-
51
- echo " ├─ 启动 client 构建..."
52
- npm run build:client > /tmp/build-client.log 2>&1 &
53
- CLIENT_PID=$!
54
-
55
- # 等待两个构建完成
56
- SERVER_EXIT=0
57
- CLIENT_EXIT=0
58
-
59
- wait $SERVER_PID || SERVER_EXIT=$?
60
- wait $CLIENT_PID || CLIENT_EXIT=$?
61
-
62
- # 检查构建结果
63
- if [ $SERVER_EXIT -ne 0 ]; then
64
- echo " ❌ Server 构建失败"
65
- cat /tmp/build-server.log
66
- exit 1
45
+ # 根据 deploy_faas 决定是否构建 server
46
+ if [[ "${deploy_faas:-true}" == "false" ]]; then
47
+ echo "🔨 [3/5] 仅构建 client (deploy_faas=false)"
48
+
49
+ echo " ├─ 启动 client 构建..."
50
+ npm run build:client > /tmp/build-client.log 2>&1
51
+ CLIENT_EXIT=$?
52
+
53
+ if [ $CLIENT_EXIT -ne 0 ]; then
54
+ echo " ❌ Client 构建失败"
55
+ cat /tmp/build-client.log
56
+ exit 1
57
+ fi
58
+
59
+ echo " ✅ Client 构建完成"
60
+ else
61
+ echo "🔨 [3/5] 并行构建 server 和 client"
62
+
63
+ # 并行构建
64
+ echo " ├─ 启动 server 构建..."
65
+ npm run build:server > /tmp/build-server.log 2>&1 &
66
+ SERVER_PID=$!
67
+
68
+ echo " ├─ 启动 client 构建..."
69
+ npm run build:client > /tmp/build-client.log 2>&1 &
70
+ CLIENT_PID=$!
71
+
72
+ # 等待两个构建完成
73
+ SERVER_EXIT=0
74
+ CLIENT_EXIT=0
75
+
76
+ wait $SERVER_PID || SERVER_EXIT=$?
77
+ wait $CLIENT_PID || CLIENT_EXIT=$?
78
+
79
+ # 检查构建结果
80
+ if [ $SERVER_EXIT -ne 0 ]; then
81
+ echo " ❌ Server 构建失败"
82
+ cat /tmp/build-server.log
83
+ exit 1
84
+ fi
85
+
86
+ if [ $CLIENT_EXIT -ne 0 ]; then
87
+ echo " ❌ Client 构建失败"
88
+ cat /tmp/build-client.log
89
+ exit 1
90
+ fi
91
+
92
+ echo " ✅ Server 构建完成"
93
+ echo " ✅ Client 构建完成"
67
94
  fi
68
95
 
69
- if [ $CLIENT_EXIT -ne 0 ]; then
70
- echo " ❌ Client 构建失败"
71
- cat /tmp/build-client.log
72
- exit 1
73
- fi
74
-
75
- echo " ✅ Server 构建完成"
76
- echo " ✅ Client 构建完成"
77
96
  print_time $STEP_START
78
97
  echo ""
79
98
 
@@ -81,20 +100,26 @@ echo ""
81
100
  echo "📦 [4/5] 准备产物"
82
101
  STEP_START=$(node -e "console.log(Date.now())")
83
102
 
84
- # 拷贝 run.sh 到 dist/(prod 从 dist/ 启动,确保 cwd 一致性)
85
- cp "$ROOT_DIR/scripts/run.sh" "$DIST_DIR/"
86
-
87
- # 拷贝 .env 文件(如果存在)
88
- if [ -f "$ROOT_DIR/.env" ]; then
89
- cp "$ROOT_DIR/.env" "$DIST_DIR/"
90
- fi
91
-
92
103
  # 移动 client 下的 HTML 文件到 dist/dist/client,保证 views 路径在 dev/prod 下一致
104
+ # HTML 文件属于前端产物,始终执行
93
105
  if [ -d "$DIST_DIR/client" ]; then
94
106
  mkdir -p "$DIST_DIR/dist/client"
95
107
  find "$DIST_DIR/client" -maxdepth 1 -name "*.html" -exec mv {} "$DIST_DIR/dist/client/" \;
96
108
  fi
97
109
 
110
+ # server 相关产物准备(deploy_faas=false 时跳过)
111
+ if [[ "${deploy_faas:-true}" == "false" ]]; then
112
+ echo " [skip] 跳过 run.sh/.env 复制 (deploy_faas=false)"
113
+ else
114
+ # 拷贝 run.sh 到 dist/(prod 从 dist/ 启动,确保 cwd 一致性)
115
+ cp "$ROOT_DIR/scripts/run.sh" "$DIST_DIR/"
116
+
117
+ # 拷贝 .env 文件(如果存在)
118
+ if [ -f "$ROOT_DIR/.env" ]; then
119
+ cp "$ROOT_DIR/.env" "$DIST_DIR/"
120
+ fi
121
+ fi
122
+
98
123
  # 清理无用文件
99
124
  rm -rf "$DIST_DIR/scripts"
100
125
  rm -rf "$DIST_DIR/tsconfig.node.tsbuildinfo"
@@ -103,11 +128,17 @@ print_time $STEP_START
103
128
  echo ""
104
129
 
105
130
  # ==================== 步骤 5 ====================
106
- echo "✂️ [5/5] 智能依赖裁剪"
107
131
  STEP_START=$(node -e "console.log(Date.now())")
108
132
 
109
- # 分析实际依赖、复制并裁剪 node_modules、生成精简的 package.json
110
- node "$ROOT_DIR/scripts/prune-smart.js"
133
+ # 智能依赖裁剪(仅全量构建时执行,纯前端场景不打包 server,无需裁剪)
134
+ if [[ "${deploy_faas:-true}" == "false" ]]; then
135
+ echo "✂️ [5/5] 跳过智能依赖裁剪 (deploy_faas=false)"
136
+ else
137
+ echo "✂️ [5/5] 智能依赖裁剪"
138
+
139
+ # 分析实际依赖、复制并裁剪 node_modules、生成精简的 package.json
140
+ node "$ROOT_DIR/scripts/prune-smart.js"
141
+ fi
111
142
 
112
143
  print_time $STEP_START
113
144
  echo ""
@@ -118,9 +149,16 @@ print_time $TOTAL_START
118
149
 
119
150
  # 输出产物信息
120
151
  DIST_SIZE=$(du -sh "$DIST_DIR" | cut -f1)
121
- NODE_MODULES_SIZE=$(du -sh "$DIST_DIR/node_modules" | cut -f1)
122
- echo ""
123
- echo "📊 构建产物统计:"
124
- echo " 产物大小: $DIST_SIZE"
125
- echo " node_modules: $NODE_MODULES_SIZE"
126
- echo ""
152
+ if [[ "${deploy_faas:-true}" == "false" ]]; then
153
+ echo ""
154
+ echo "📊 构建产物统计:"
155
+ echo " 产物大小: $DIST_SIZE"
156
+ echo ""
157
+ else
158
+ NODE_MODULES_SIZE=$(du -sh "$DIST_DIR/node_modules" | cut -f1)
159
+ echo ""
160
+ echo "📊 构建产物统计:"
161
+ echo " 产物大小: $DIST_SIZE"
162
+ echo " node_modules: $NODE_MODULES_SIZE"
163
+ echo ""
164
+ fi