@lark-apaas/fullstack-cli 1.1.28-alpha.0 → 1.1.28-alpha.10

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.
Files changed (2) hide show
  1. package/dist/index.js +233 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.ts
2
- import fs25 from "fs";
3
- import path21 from "path";
2
+ import fs26 from "fs";
3
+ import path22 from "path";
4
4
  import { fileURLToPath as fileURLToPath5 } from "url";
5
5
  import { config as dotenvConfig } from "dotenv";
6
6
 
@@ -4285,7 +4285,7 @@ var PROMPT_PATTERNS = [
4285
4285
  { pattern: /proceed\?/i, answer: "y\n" }
4286
4286
  ];
4287
4287
  async function executeShadcnAdd(registryItemPath) {
4288
- return new Promise((resolve) => {
4288
+ return new Promise((resolve2) => {
4289
4289
  let output = "";
4290
4290
  const args = ["--yes", "shadcn@3.8.2", "add", registryItemPath];
4291
4291
  const ptyProcess = pty.spawn("npx", args, {
@@ -4311,7 +4311,7 @@ async function executeShadcnAdd(registryItemPath) {
4311
4311
  });
4312
4312
  const timeoutId = setTimeout(() => {
4313
4313
  ptyProcess.kill();
4314
- resolve({
4314
+ resolve2({
4315
4315
  success: false,
4316
4316
  files: [],
4317
4317
  error: "\u6267\u884C\u8D85\u65F6"
@@ -4322,7 +4322,7 @@ async function executeShadcnAdd(registryItemPath) {
4322
4322
  const success = exitCode === 0;
4323
4323
  const filePaths = parseOutput(output);
4324
4324
  const files = filePaths.map(toFileInfo);
4325
- resolve({
4325
+ resolve2({
4326
4326
  success,
4327
4327
  files,
4328
4328
  error: success ? void 0 : output || `Process exited with code ${exitCode}`
@@ -4333,12 +4333,12 @@ async function executeShadcnAdd(registryItemPath) {
4333
4333
 
4334
4334
  // src/commands/component/add.handler.ts
4335
4335
  function runActionPluginInit() {
4336
- return new Promise((resolve) => {
4336
+ return new Promise((resolve2) => {
4337
4337
  execFile("fullstack-cli", ["action-plugin", "init"], { cwd: process.cwd(), stdio: "ignore" }, (error) => {
4338
4338
  if (error) {
4339
4339
  debug("action-plugin init \u5931\u8D25: %s", error.message);
4340
4340
  }
4341
- resolve();
4341
+ resolve2();
4342
4342
  });
4343
4343
  });
4344
4344
  }
@@ -7174,7 +7174,45 @@ async function genArtifactUploadCredential(appId, body) {
7174
7174
  const response = await client.post(url, body);
7175
7175
  if (!response.ok || response.status !== 200) {
7176
7176
  throw new Error(
7177
- `API request failed: ${response.status} ${response.statusText}`
7177
+ `gen_artifact_upload_credential \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
7178
+ );
7179
+ }
7180
+ return response.json();
7181
+ }
7182
+ async function getDefaultBucketId(appId) {
7183
+ const client = getHttpClient();
7184
+ const url = `/b/${appId}/get_published_v2`;
7185
+ const response = await client.get(url);
7186
+ if (!response.ok || response.status !== 200) {
7187
+ throw new Error(
7188
+ `get_published_v2 \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
7189
+ );
7190
+ }
7191
+ const data = await response.json();
7192
+ const bucketId = data?.data?.app_runtime_extra?.bucket?.default_bucket_id;
7193
+ if (!bucketId) {
7194
+ throw new Error(`\u672A\u627E\u5230\u5E94\u7528 ${appId} \u7684\u9ED8\u8BA4\u5B58\u50A8\u6876`);
7195
+ }
7196
+ return bucketId;
7197
+ }
7198
+ async function preUploadStaticAttachment(appId, bucketId) {
7199
+ const client = getHttpClient();
7200
+ const url = `/v1/app/${appId}/storage/bucket/${bucketId}/preUploadStatic`;
7201
+ const response = await client.post(url, {});
7202
+ if (!response.ok || response.status !== 200) {
7203
+ throw new Error(
7204
+ `preUploadStatic \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
7205
+ );
7206
+ }
7207
+ return response.json();
7208
+ }
7209
+ async function uploadStaticAttachmentCallback(appId, bucketId, body) {
7210
+ const client = getHttpClient();
7211
+ const url = `/v1/app/${appId}/storage/bucket/${bucketId}/object/callbackStatic`;
7212
+ const response = await client.post(url, body);
7213
+ if (!response.ok || response.status !== 200) {
7214
+ throw new Error(
7215
+ `callbackStatic \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
7178
7216
  );
7179
7217
  }
7180
7218
  return response.json();
@@ -7212,6 +7250,170 @@ function camelToKebab(str) {
7212
7250
  return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
7213
7251
  }
7214
7252
 
7253
+ // src/commands/build/upload-static.handler.ts
7254
+ import * as fs25 from "fs";
7255
+ import * as path21 from "path";
7256
+ import { execFileSync } from "child_process";
7257
+ function readCredentialsFromEnv() {
7258
+ const uploadPrefix = process.env.STATIC_UPLOAD_PREFIX;
7259
+ const uploadID = process.env.STATIC_UPLOAD_ID;
7260
+ const bucketId = process.env.STATIC_UPLOAD_BUCKET_ID;
7261
+ const accessKeyID = process.env.STATIC_UPLOAD_AK;
7262
+ const secretAccessKey = process.env.STATIC_UPLOAD_SK;
7263
+ const sessionToken = process.env.STATIC_UPLOAD_TOKEN;
7264
+ if (!uploadPrefix || !uploadID || !bucketId || !accessKeyID || !secretAccessKey || !sessionToken) {
7265
+ return null;
7266
+ }
7267
+ return { uploadPrefix, uploadID, bucketId, accessKeyID, secretAccessKey, sessionToken };
7268
+ }
7269
+ var LOG_PREFIX = "[upload-static]";
7270
+ async function uploadStatic(options) {
7271
+ try {
7272
+ const {
7273
+ appId,
7274
+ staticDir = "shared/static",
7275
+ tosutilPath = "/workspace/tosutil",
7276
+ endpoint = "tos-cn-beijing.volces.com",
7277
+ region = "cn-beijing"
7278
+ } = options;
7279
+ const resolvedStaticDir = path21.resolve(staticDir);
7280
+ if (!fs25.existsSync(resolvedStaticDir)) {
7281
+ console.error(`${LOG_PREFIX} \u76EE\u5F55\u4E0D\u5B58\u5728: ${resolvedStaticDir}\uFF0C\u8DF3\u8FC7\u4E0A\u4F20`);
7282
+ return;
7283
+ }
7284
+ if (isDirEmpty(resolvedStaticDir)) {
7285
+ console.error(`${LOG_PREFIX} \u76EE\u5F55\u4E3A\u7A7A: ${resolvedStaticDir}\uFF0C\u8DF3\u8FC7\u4E0A\u4F20`);
7286
+ return;
7287
+ }
7288
+ if (!fs25.existsSync(tosutilPath)) {
7289
+ throw new Error(
7290
+ `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`
7291
+ );
7292
+ }
7293
+ let uploadPrefix;
7294
+ let uploadID;
7295
+ let bucketId;
7296
+ let accessKeyID;
7297
+ let secretAccessKey;
7298
+ let sessionToken;
7299
+ const envCredentials = readCredentialsFromEnv();
7300
+ if (envCredentials) {
7301
+ console.error(`${LOG_PREFIX} \u4F7F\u7528\u73AF\u5883\u53D8\u91CF\u4E2D\u7684\u4E0A\u4F20\u51ED\u8BC1`);
7302
+ ({ uploadPrefix, uploadID, bucketId, accessKeyID, secretAccessKey, sessionToken } = envCredentials);
7303
+ } else {
7304
+ console.error(`${LOG_PREFIX} \u73AF\u5883\u53D8\u91CF\u672A\u8BBE\u7F6E\uFF0C\u8C03\u7528 preUploadStatic...`);
7305
+ bucketId = await resolveBucketId(appId);
7306
+ const preUploadResp = await fetchPreUpload(appId, bucketId);
7307
+ const { uploadCredential } = preUploadResp.data;
7308
+ ({ uploadPrefix, uploadID } = preUploadResp.data);
7309
+ ({ AccessKeyID: accessKeyID, SecretAccessKey: secretAccessKey, SessionToken: sessionToken } = uploadCredential);
7310
+ }
7311
+ console.error(`${LOG_PREFIX} \u4E0A\u4F20\u76EE\u6807: ${uploadPrefix}`);
7312
+ console.error(`${LOG_PREFIX} \u914D\u7F6E tosutil...`);
7313
+ configureTosutil(tosutilPath, {
7314
+ endpoint,
7315
+ region,
7316
+ accessKeyID,
7317
+ secretAccessKey,
7318
+ sessionToken
7319
+ });
7320
+ console.error(`${LOG_PREFIX} \u4E0A\u4F20 ${resolvedStaticDir} -> ${uploadPrefix}`);
7321
+ uploadToTos(tosutilPath, resolvedStaticDir, uploadPrefix);
7322
+ console.error(`${LOG_PREFIX} tosutil \u4E0A\u4F20\u5B8C\u6210`);
7323
+ console.error(`${LOG_PREFIX} \u8C03\u7528 callbackStatic (uploadID: ${uploadID})...`);
7324
+ const callbackResp = await uploadStaticAttachmentCallback(appId, bucketId, { uploadID });
7325
+ if (callbackResp.status_code !== "0") {
7326
+ throw new Error(`callbackStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${callbackResp.status_code}`);
7327
+ }
7328
+ const attachments = callbackResp.data?.attachments || [];
7329
+ console.error(`${LOG_PREFIX} \u4E0A\u4F20\u5B8C\u6210\uFF0C\u5171 ${attachments.length} \u4E2A\u6587\u4EF6`);
7330
+ console.log(JSON.stringify(callbackResp));
7331
+ } catch (error) {
7332
+ const message = error instanceof Error ? error.message : String(error);
7333
+ console.error(`${LOG_PREFIX} Error: ${message}`);
7334
+ process.exit(1);
7335
+ }
7336
+ }
7337
+ async function fetchPreUpload(appId, bucketId) {
7338
+ const response = await preUploadStaticAttachment(appId, bucketId);
7339
+ if (response.status_code !== "0") {
7340
+ throw new Error(`preUploadStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${response.status_code}`);
7341
+ }
7342
+ const { uploadPrefix, uploadID, uploadCredential } = response.data || {};
7343
+ if (!uploadPrefix || !uploadID) {
7344
+ throw new Error("preUploadStatic \u8FD4\u56DE\u6570\u636E\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11 uploadPrefix \u6216 uploadID");
7345
+ }
7346
+ if (!uploadCredential?.AccessKeyID || !uploadCredential?.SecretAccessKey || !uploadCredential?.SessionToken) {
7347
+ throw new Error("preUploadStatic \u8FD4\u56DE\u7684\u51ED\u8BC1\u5B57\u6BB5\u4E0D\u5B8C\u6574");
7348
+ }
7349
+ return response;
7350
+ }
7351
+ function configureTosutil(tosutilPath, config) {
7352
+ const { endpoint, region, accessKeyID, secretAccessKey, sessionToken } = config;
7353
+ execFileSync(
7354
+ tosutilPath,
7355
+ ["config", "-e", endpoint, "-i", accessKeyID, "-k", secretAccessKey, "-t", sessionToken, "-re", region],
7356
+ { stdio: "pipe" }
7357
+ );
7358
+ }
7359
+ function uploadToTos(tosutilPath, sourceDir, destUrl) {
7360
+ execFileSync(
7361
+ tosutilPath,
7362
+ ["cp", sourceDir, destUrl, "-r", "-flat", "-j", "5", "-p", "3", "-ps", "10485760", "-f"],
7363
+ { stdio: "inherit" }
7364
+ );
7365
+ }
7366
+ async function resolveBucketId(appId) {
7367
+ console.error(`${LOG_PREFIX} \u83B7\u53D6\u9ED8\u8BA4\u5B58\u50A8\u6876...`);
7368
+ const bucketId = await getDefaultBucketId(appId);
7369
+ console.error(`${LOG_PREFIX} \u9ED8\u8BA4\u5B58\u50A8\u6876: ${bucketId}`);
7370
+ return bucketId;
7371
+ }
7372
+ function isDirEmpty(dirPath) {
7373
+ const entries = fs25.readdirSync(dirPath);
7374
+ return entries.length === 0;
7375
+ }
7376
+
7377
+ // src/commands/build/pre-upload-static.handler.ts
7378
+ var LOG_PREFIX2 = "[pre-upload-static]";
7379
+ function shellEscape(value) {
7380
+ return value.replace(/["\\`$]/g, "\\$&");
7381
+ }
7382
+ async function preUploadStatic(options) {
7383
+ try {
7384
+ const { appId } = options;
7385
+ console.error(`${LOG_PREFIX2} \u83B7\u53D6\u9ED8\u8BA4\u5B58\u50A8\u6876...`);
7386
+ const bucketId = await getDefaultBucketId(appId);
7387
+ console.error(`${LOG_PREFIX2} \u9ED8\u8BA4\u5B58\u50A8\u6876: ${bucketId}`);
7388
+ console.error(`${LOG_PREFIX2} \u8C03\u7528 preUploadStatic...`);
7389
+ const response = await preUploadStaticAttachment(appId, bucketId);
7390
+ if (response.status_code !== "0") {
7391
+ console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${response.status_code}`);
7392
+ return;
7393
+ }
7394
+ const { downloadURLPrefix, uploadPrefix, uploadID, uploadCredential } = response.data || {};
7395
+ if (!downloadURLPrefix || !uploadPrefix || !uploadID) {
7396
+ console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u6570\u636E\u4E0D\u5B8C\u6574`);
7397
+ return;
7398
+ }
7399
+ if (!uploadCredential?.AccessKeyID || !uploadCredential?.SecretAccessKey || !uploadCredential?.SessionToken) {
7400
+ console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u7684\u51ED\u8BC1\u5B57\u6BB5\u4E0D\u5B8C\u6574`);
7401
+ return;
7402
+ }
7403
+ console.log(`export STATIC_ASSETS_BASE_URL="${shellEscape(downloadURLPrefix)}"`);
7404
+ console.log(`export STATIC_UPLOAD_PREFIX="${shellEscape(uploadPrefix)}"`);
7405
+ console.log(`export STATIC_UPLOAD_ID="${shellEscape(uploadID)}"`);
7406
+ console.log(`export STATIC_UPLOAD_AK="${shellEscape(uploadCredential.AccessKeyID)}"`);
7407
+ console.log(`export STATIC_UPLOAD_SK="${shellEscape(uploadCredential.SecretAccessKey)}"`);
7408
+ console.log(`export STATIC_UPLOAD_TOKEN="${shellEscape(uploadCredential.SessionToken)}"`);
7409
+ console.log(`export STATIC_UPLOAD_BUCKET_ID="${shellEscape(bucketId)}"`);
7410
+ console.error(`${LOG_PREFIX2} \u73AF\u5883\u53D8\u91CF\u5DF2\u8F93\u51FA`);
7411
+ } catch (error) {
7412
+ const message = error instanceof Error ? error.message : String(error);
7413
+ console.error(`${LOG_PREFIX2} Warning: ${message}`);
7414
+ }
7415
+ }
7416
+
7215
7417
  // src/commands/build/index.ts
7216
7418
  var getTokenCommand = {
7217
7419
  name: "get-token",
@@ -7222,10 +7424,28 @@ var getTokenCommand = {
7222
7424
  });
7223
7425
  }
7224
7426
  };
7427
+ var uploadStaticCommand = {
7428
+ name: "upload-static",
7429
+ description: "Upload shared/static files to TOS",
7430
+ register(program) {
7431
+ 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) => {
7432
+ await uploadStatic(options);
7433
+ });
7434
+ }
7435
+ };
7436
+ var preUploadStaticCommand = {
7437
+ name: "pre-upload-static",
7438
+ description: "Get TOS upload info and output as env vars for build.sh eval",
7439
+ register(program) {
7440
+ program.command(this.name).description(this.description).requiredOption("--app-id <id>", "Application ID").action(async (options) => {
7441
+ await preUploadStatic(options);
7442
+ });
7443
+ }
7444
+ };
7225
7445
  var buildCommandGroup = {
7226
7446
  name: "build",
7227
7447
  description: "Build related commands",
7228
- commands: [getTokenCommand]
7448
+ commands: [getTokenCommand, uploadStaticCommand, preUploadStaticCommand]
7229
7449
  };
7230
7450
 
7231
7451
  // src/commands/index.ts
@@ -7242,12 +7462,12 @@ var commands = [
7242
7462
  ];
7243
7463
 
7244
7464
  // src/index.ts
7245
- var envPath = path21.join(process.cwd(), ".env");
7246
- if (fs25.existsSync(envPath)) {
7465
+ var envPath = path22.join(process.cwd(), ".env");
7466
+ if (fs26.existsSync(envPath)) {
7247
7467
  dotenvConfig({ path: envPath });
7248
7468
  }
7249
- var __dirname = path21.dirname(fileURLToPath5(import.meta.url));
7250
- var pkg = JSON.parse(fs25.readFileSync(path21.join(__dirname, "../package.json"), "utf-8"));
7469
+ var __dirname = path22.dirname(fileURLToPath5(import.meta.url));
7470
+ var pkg = JSON.parse(fs26.readFileSync(path22.join(__dirname, "../package.json"), "utf-8"));
7251
7471
  var cli = new FullstackCLI(pkg.version);
7252
7472
  cli.useAll(commands);
7253
7473
  cli.run();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/fullstack-cli",
3
- "version": "1.1.28-alpha.0",
3
+ "version": "1.1.28-alpha.10",
4
4
  "description": "CLI tool for fullstack template management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",