@lark-apaas/fullstack-cli 1.1.28-alpha.0 → 1.1.28-alpha.2
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 +228 -13
- package/package.json +1 -1
- package/templates/scripts/build.sh +2 -7
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import
|
|
3
|
-
import
|
|
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((
|
|
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
|
-
|
|
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
|
-
|
|
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((
|
|
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
|
-
|
|
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
|
-
`
|
|
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,165 @@ 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 { execSync as execSync3 } 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
|
+
execSync3(
|
|
7354
|
+
`${tosutilPath} config -e ${endpoint} -i ${accessKeyID} -k ${secretAccessKey} -t ${sessionToken} -re ${region}`,
|
|
7355
|
+
{ stdio: "pipe" }
|
|
7356
|
+
);
|
|
7357
|
+
}
|
|
7358
|
+
function uploadToTos(tosutilPath, sourceDir, destUrl) {
|
|
7359
|
+
execSync3(
|
|
7360
|
+
`${tosutilPath} cp "${sourceDir}" "${destUrl}" -r -flat -j 5 -p 3 -ps 10485760 -f`,
|
|
7361
|
+
{ stdio: "inherit" }
|
|
7362
|
+
);
|
|
7363
|
+
}
|
|
7364
|
+
async function resolveBucketId(appId) {
|
|
7365
|
+
console.error(`${LOG_PREFIX} \u83B7\u53D6\u9ED8\u8BA4\u5B58\u50A8\u6876...`);
|
|
7366
|
+
const bucketId = await getDefaultBucketId(appId);
|
|
7367
|
+
console.error(`${LOG_PREFIX} \u9ED8\u8BA4\u5B58\u50A8\u6876: ${bucketId}`);
|
|
7368
|
+
return bucketId;
|
|
7369
|
+
}
|
|
7370
|
+
function isDirEmpty(dirPath) {
|
|
7371
|
+
const entries = fs25.readdirSync(dirPath);
|
|
7372
|
+
return entries.length === 0;
|
|
7373
|
+
}
|
|
7374
|
+
|
|
7375
|
+
// src/commands/build/pre-upload-static.handler.ts
|
|
7376
|
+
var LOG_PREFIX2 = "[pre-upload-static]";
|
|
7377
|
+
async function preUploadStatic(options) {
|
|
7378
|
+
try {
|
|
7379
|
+
const { appId } = options;
|
|
7380
|
+
console.error(`${LOG_PREFIX2} \u83B7\u53D6\u9ED8\u8BA4\u5B58\u50A8\u6876...`);
|
|
7381
|
+
const bucketId = await getDefaultBucketId(appId);
|
|
7382
|
+
console.error(`${LOG_PREFIX2} \u9ED8\u8BA4\u5B58\u50A8\u6876: ${bucketId}`);
|
|
7383
|
+
console.error(`${LOG_PREFIX2} \u8C03\u7528 preUploadStatic...`);
|
|
7384
|
+
const response = await preUploadStaticAttachment(appId, bucketId);
|
|
7385
|
+
if (response.status_code !== "0") {
|
|
7386
|
+
console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${response.status_code}`);
|
|
7387
|
+
return;
|
|
7388
|
+
}
|
|
7389
|
+
const { downloadUrlPrefix, uploadPrefix, uploadID, uploadCredential } = response.data || {};
|
|
7390
|
+
if (!downloadUrlPrefix || !uploadPrefix || !uploadID) {
|
|
7391
|
+
console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u6570\u636E\u4E0D\u5B8C\u6574`);
|
|
7392
|
+
return;
|
|
7393
|
+
}
|
|
7394
|
+
if (!uploadCredential?.AccessKeyID || !uploadCredential?.SecretAccessKey || !uploadCredential?.SessionToken) {
|
|
7395
|
+
console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u7684\u51ED\u8BC1\u5B57\u6BB5\u4E0D\u5B8C\u6574`);
|
|
7396
|
+
return;
|
|
7397
|
+
}
|
|
7398
|
+
console.log(`export STATIC_ASSETS_BASE_URL="${downloadUrlPrefix}"`);
|
|
7399
|
+
console.log(`export STATIC_UPLOAD_PREFIX="${uploadPrefix}"`);
|
|
7400
|
+
console.log(`export STATIC_UPLOAD_ID="${uploadID}"`);
|
|
7401
|
+
console.log(`export STATIC_UPLOAD_AK="${uploadCredential.AccessKeyID}"`);
|
|
7402
|
+
console.log(`export STATIC_UPLOAD_SK="${uploadCredential.SecretAccessKey}"`);
|
|
7403
|
+
console.log(`export STATIC_UPLOAD_TOKEN="${uploadCredential.SessionToken}"`);
|
|
7404
|
+
console.log(`export STATIC_UPLOAD_BUCKET_ID="${bucketId}"`);
|
|
7405
|
+
console.error(`${LOG_PREFIX2} \u73AF\u5883\u53D8\u91CF\u5DF2\u8F93\u51FA`);
|
|
7406
|
+
} catch (error) {
|
|
7407
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7408
|
+
console.error(`${LOG_PREFIX2} Warning: ${message}`);
|
|
7409
|
+
}
|
|
7410
|
+
}
|
|
7411
|
+
|
|
7215
7412
|
// src/commands/build/index.ts
|
|
7216
7413
|
var getTokenCommand = {
|
|
7217
7414
|
name: "get-token",
|
|
@@ -7222,10 +7419,28 @@ var getTokenCommand = {
|
|
|
7222
7419
|
});
|
|
7223
7420
|
}
|
|
7224
7421
|
};
|
|
7422
|
+
var uploadStaticCommand = {
|
|
7423
|
+
name: "upload-static",
|
|
7424
|
+
description: "Upload shared/static files to TOS",
|
|
7425
|
+
register(program) {
|
|
7426
|
+
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) => {
|
|
7427
|
+
await uploadStatic(options);
|
|
7428
|
+
});
|
|
7429
|
+
}
|
|
7430
|
+
};
|
|
7431
|
+
var preUploadStaticCommand = {
|
|
7432
|
+
name: "pre-upload-static",
|
|
7433
|
+
description: "Get TOS upload info and output as env vars for build.sh eval",
|
|
7434
|
+
register(program) {
|
|
7435
|
+
program.command(this.name).description(this.description).requiredOption("--app-id <id>", "Application ID").action(async (options) => {
|
|
7436
|
+
await preUploadStatic(options);
|
|
7437
|
+
});
|
|
7438
|
+
}
|
|
7439
|
+
};
|
|
7225
7440
|
var buildCommandGroup = {
|
|
7226
7441
|
name: "build",
|
|
7227
7442
|
description: "Build related commands",
|
|
7228
|
-
commands: [getTokenCommand]
|
|
7443
|
+
commands: [getTokenCommand, uploadStaticCommand, preUploadStaticCommand]
|
|
7229
7444
|
};
|
|
7230
7445
|
|
|
7231
7446
|
// src/commands/index.ts
|
|
@@ -7242,12 +7457,12 @@ var commands = [
|
|
|
7242
7457
|
];
|
|
7243
7458
|
|
|
7244
7459
|
// src/index.ts
|
|
7245
|
-
var envPath =
|
|
7246
|
-
if (
|
|
7460
|
+
var envPath = path22.join(process.cwd(), ".env");
|
|
7461
|
+
if (fs26.existsSync(envPath)) {
|
|
7247
7462
|
dotenvConfig({ path: envPath });
|
|
7248
7463
|
}
|
|
7249
|
-
var __dirname =
|
|
7250
|
-
var pkg = JSON.parse(
|
|
7464
|
+
var __dirname = path22.dirname(fileURLToPath5(import.meta.url));
|
|
7465
|
+
var pkg = JSON.parse(fs26.readFileSync(path22.join(__dirname, "../package.json"), "utf-8"));
|
|
7251
7466
|
var cli = new FullstackCLI(pkg.version);
|
|
7252
7467
|
cli.useAll(commands);
|
|
7253
7468
|
cli.run();
|
package/package.json
CHANGED
|
@@ -83,17 +83,12 @@ STEP_START=$(node -e "console.log(Date.now())")
|
|
|
83
83
|
|
|
84
84
|
mkdir -p "$OUT_DIR/dist/client"
|
|
85
85
|
|
|
86
|
-
#
|
|
87
|
-
|
|
86
|
+
# 拷贝 HTML
|
|
87
|
+
cp "$ROOT_DIR/dist/client/"*.html "$OUT_DIR/dist/client/" || true
|
|
88
88
|
|
|
89
89
|
# 拷贝 run.sh 文件
|
|
90
90
|
cp "$ROOT_DIR/scripts/run.sh" "$OUT_DIR/"
|
|
91
91
|
|
|
92
|
-
# 拷贝 .env 文件(如果存在)
|
|
93
|
-
if [ -f "$ROOT_DIR/.env" ]; then
|
|
94
|
-
cp "$ROOT_DIR/.env" "$OUT_DIR/"
|
|
95
|
-
fi
|
|
96
|
-
|
|
97
92
|
# 清理无用文件
|
|
98
93
|
rm -rf "$ROOT_DIR/dist/scripts"
|
|
99
94
|
rm -rf "$ROOT_DIR/dist/tsconfig.node.tsbuildinfo"
|