@lark-apaas/fullstack-cli 1.1.45-alpha.2 → 1.1.45-alpha.3
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 +516 -306
- package/package.json +2 -2
- package/templates/.husky/pre-commit +4 -0
- package/templates/scripts/hooks/run-precommit.js +86 -0
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import fs29 from "fs";
|
|
3
|
+
import path25 from "path";
|
|
4
4
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
5
5
|
import { config as dotenvConfig } from "dotenv";
|
|
6
6
|
|
|
@@ -2365,21 +2365,43 @@ var genDbSchemaCommand = {
|
|
|
2365
2365
|
};
|
|
2366
2366
|
|
|
2367
2367
|
// src/commands/sync/run.handler.ts
|
|
2368
|
-
import
|
|
2369
|
-
import
|
|
2368
|
+
import path6 from "path";
|
|
2369
|
+
import fs8 from "fs";
|
|
2370
2370
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2371
2371
|
|
|
2372
2372
|
// src/config/sync.ts
|
|
2373
2373
|
var syncConfig = {
|
|
2374
2374
|
// 派生规则
|
|
2375
2375
|
sync: [
|
|
2376
|
-
// 1. 派生 scripts
|
|
2376
|
+
// 1. 派生 scripts 目录(总是覆盖;递归同步,包含 scripts/hooks/run-precommit.js)
|
|
2377
2377
|
{
|
|
2378
2378
|
from: "templates/scripts",
|
|
2379
2379
|
to: "scripts",
|
|
2380
2380
|
type: "directory",
|
|
2381
2381
|
overwrite: true
|
|
2382
2382
|
},
|
|
2383
|
+
// 1a. 同步 .husky 目录(hook 入口,可执行 sh 脚本)
|
|
2384
|
+
{
|
|
2385
|
+
from: "templates/.husky",
|
|
2386
|
+
to: ".husky",
|
|
2387
|
+
type: "directory",
|
|
2388
|
+
overwrite: true
|
|
2389
|
+
},
|
|
2390
|
+
// 1b. scripts.prepare:npm install 后自动激活 git hooks(不依赖 husky 库)
|
|
2391
|
+
// 直接写 core.hooksPath,并保底给 pre-commit 加执行位;非 git 仓库下静默退出
|
|
2392
|
+
{
|
|
2393
|
+
type: "add-script",
|
|
2394
|
+
name: "prepare",
|
|
2395
|
+
command: "chmod +x .husky/pre-commit 2>/dev/null; git config core.hooksPath .husky 2>/dev/null || true",
|
|
2396
|
+
overwrite: false
|
|
2397
|
+
},
|
|
2398
|
+
// 1c. scripts.precommit = pre-commit 真正的执行体(npm run lint + read-logs ×5)
|
|
2399
|
+
{
|
|
2400
|
+
type: "add-script",
|
|
2401
|
+
name: "precommit",
|
|
2402
|
+
command: "node scripts/hooks/run-precommit.js",
|
|
2403
|
+
overwrite: false
|
|
2404
|
+
},
|
|
2383
2405
|
// 2. 智能合并 nest-cli.json 配置(保留用户自定义的 assets、plugins 等)
|
|
2384
2406
|
{
|
|
2385
2407
|
from: "templates/nest-cli.json",
|
|
@@ -2602,18 +2624,42 @@ function cleanupPackageJson(cwd = process.cwd()) {
|
|
|
2602
2624
|
}
|
|
2603
2625
|
}
|
|
2604
2626
|
|
|
2627
|
+
// src/commands/sync/install-husky.ts
|
|
2628
|
+
import fs7 from "fs";
|
|
2629
|
+
import path5 from "path";
|
|
2630
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
2631
|
+
function activateGitHooks(userProjectRoot) {
|
|
2632
|
+
if (!fs7.existsSync(path5.join(userProjectRoot, ".git"))) {
|
|
2633
|
+
return { action: "skipped-no-git" };
|
|
2634
|
+
}
|
|
2635
|
+
const hookFile = path5.join(userProjectRoot, ".husky", "pre-commit");
|
|
2636
|
+
if (!fs7.existsSync(hookFile)) {
|
|
2637
|
+
return { action: "skipped-no-hook-file" };
|
|
2638
|
+
}
|
|
2639
|
+
fs7.chmodSync(hookFile, 493);
|
|
2640
|
+
const res = spawnSync2("git", ["config", "core.hooksPath", ".husky"], {
|
|
2641
|
+
cwd: userProjectRoot,
|
|
2642
|
+
stdio: ["ignore", "inherit", "inherit"]
|
|
2643
|
+
});
|
|
2644
|
+
if (res.status !== 0) {
|
|
2645
|
+
throw new Error(`git config core.hooksPath exited with ${String(res.status)}`);
|
|
2646
|
+
}
|
|
2647
|
+
console.log("[fullstack-cli] \u2713 git hooks activated (core.hooksPath -> .husky)");
|
|
2648
|
+
return { action: "activated" };
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2605
2651
|
// src/commands/sync/run.handler.ts
|
|
2606
2652
|
async function run2(options) {
|
|
2607
2653
|
const userProjectRoot = process.env.INIT_CWD || process.cwd();
|
|
2608
2654
|
const __filename = fileURLToPath3(import.meta.url);
|
|
2609
|
-
const __dirname2 =
|
|
2610
|
-
const pluginRoot =
|
|
2655
|
+
const __dirname2 = path6.dirname(__filename);
|
|
2656
|
+
const pluginRoot = path6.resolve(__dirname2, "..");
|
|
2611
2657
|
if (userProjectRoot === pluginRoot) {
|
|
2612
2658
|
console.log("[fullstack-cli] Skip syncing (installing plugin itself)");
|
|
2613
2659
|
process.exit(0);
|
|
2614
2660
|
}
|
|
2615
|
-
const userPackageJson =
|
|
2616
|
-
if (!
|
|
2661
|
+
const userPackageJson = path6.join(userProjectRoot, "package.json");
|
|
2662
|
+
if (!fs8.existsSync(userPackageJson)) {
|
|
2617
2663
|
console.log("[fullstack-cli] Skip syncing (not a valid npm project)");
|
|
2618
2664
|
process.exit(0);
|
|
2619
2665
|
}
|
|
@@ -2633,6 +2679,12 @@ async function run2(options) {
|
|
|
2633
2679
|
if (config.permissions) {
|
|
2634
2680
|
setPermissions(config.permissions, userProjectRoot);
|
|
2635
2681
|
}
|
|
2682
|
+
try {
|
|
2683
|
+
activateGitHooks(userProjectRoot);
|
|
2684
|
+
} catch (error) {
|
|
2685
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2686
|
+
console.warn(`[fullstack-cli] \u26A0 Failed to activate git hooks: ${message}`);
|
|
2687
|
+
}
|
|
2636
2688
|
console.log("[fullstack-cli] Sync completed successfully \u2705");
|
|
2637
2689
|
} catch (error) {
|
|
2638
2690
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -2644,28 +2696,51 @@ function patchUserPackageJson(userProjectRoot) {
|
|
|
2644
2696
|
try {
|
|
2645
2697
|
const pkg2 = readPackageJson(userProjectRoot);
|
|
2646
2698
|
const lintPatchResult = patchLintScriptForFilesSupport(pkg2);
|
|
2699
|
+
const huskyMigrated = migrateLegacyHuskySetup(pkg2);
|
|
2700
|
+
let needsWrite = false;
|
|
2701
|
+
let logMessage = "";
|
|
2647
2702
|
if (lintPatchResult === "patched") {
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
}
|
|
2652
|
-
if (lintPatchResult === "already-patched") {
|
|
2703
|
+
needsWrite = true;
|
|
2704
|
+
logMessage = "[fullstack-cli] \u2713 Patched scripts.lint to support --files";
|
|
2705
|
+
} else if (lintPatchResult === "already-patched") {
|
|
2653
2706
|
console.log("[fullstack-cli] \u25CB scripts.lint already supports --files");
|
|
2654
|
-
|
|
2655
|
-
}
|
|
2656
|
-
if (lintPatchResult === "skipped-custom") {
|
|
2707
|
+
} else if (lintPatchResult === "skipped-custom") {
|
|
2657
2708
|
console.warn(
|
|
2658
2709
|
"[fullstack-cli] \u26A0 Skipped patching scripts.lint because it has been customized"
|
|
2659
2710
|
);
|
|
2660
2711
|
}
|
|
2712
|
+
if (huskyMigrated) {
|
|
2713
|
+
needsWrite = true;
|
|
2714
|
+
}
|
|
2715
|
+
if (needsWrite) {
|
|
2716
|
+
writePackageJson(pkg2, userProjectRoot);
|
|
2717
|
+
if (logMessage) console.log(logMessage);
|
|
2718
|
+
}
|
|
2661
2719
|
} catch (error) {
|
|
2662
2720
|
const message = error instanceof Error ? error.message : String(error);
|
|
2663
2721
|
console.warn(`[fullstack-cli] \u26A0 Could not patch package.json: ${message}`);
|
|
2664
2722
|
}
|
|
2665
2723
|
}
|
|
2724
|
+
function migrateLegacyHuskySetup(pkg2) {
|
|
2725
|
+
let changed = false;
|
|
2726
|
+
const newPrepare = "chmod +x .husky/pre-commit 2>/dev/null; git config core.hooksPath .husky 2>/dev/null || true";
|
|
2727
|
+
const scripts = pkg2.scripts;
|
|
2728
|
+
if (scripts && scripts.prepare === "husky") {
|
|
2729
|
+
scripts.prepare = newPrepare;
|
|
2730
|
+
console.log("[fullstack-cli] \u2713 Migrated scripts.prepare from husky to native git config");
|
|
2731
|
+
changed = true;
|
|
2732
|
+
}
|
|
2733
|
+
const devDeps = pkg2.devDependencies;
|
|
2734
|
+
if (devDeps && devDeps.husky) {
|
|
2735
|
+
delete devDeps.husky;
|
|
2736
|
+
console.log("[fullstack-cli] \u2713 Removed legacy husky devDependency");
|
|
2737
|
+
changed = true;
|
|
2738
|
+
}
|
|
2739
|
+
return changed;
|
|
2740
|
+
}
|
|
2666
2741
|
async function syncRule(rule, pluginRoot, userProjectRoot) {
|
|
2667
2742
|
if (rule.type === "delete-file" || rule.type === "delete-directory") {
|
|
2668
|
-
const destPath2 =
|
|
2743
|
+
const destPath2 = path6.join(userProjectRoot, rule.to);
|
|
2669
2744
|
if (rule.type === "delete-file") {
|
|
2670
2745
|
deleteFile(destPath2);
|
|
2671
2746
|
} else {
|
|
@@ -2674,32 +2749,32 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
|
|
|
2674
2749
|
return;
|
|
2675
2750
|
}
|
|
2676
2751
|
if (rule.type === "remove-line") {
|
|
2677
|
-
const destPath2 =
|
|
2752
|
+
const destPath2 = path6.join(userProjectRoot, rule.to);
|
|
2678
2753
|
removeLineFromFile(destPath2, rule.pattern);
|
|
2679
2754
|
return;
|
|
2680
2755
|
}
|
|
2681
2756
|
if (rule.type === "add-script") {
|
|
2682
|
-
const packageJsonPath =
|
|
2757
|
+
const packageJsonPath = path6.join(userProjectRoot, "package.json");
|
|
2683
2758
|
addScript(packageJsonPath, rule.name, rule.command, rule.overwrite ?? false);
|
|
2684
2759
|
return;
|
|
2685
2760
|
}
|
|
2686
2761
|
if (rule.type === "add-line") {
|
|
2687
|
-
const destPath2 =
|
|
2762
|
+
const destPath2 = path6.join(userProjectRoot, rule.to);
|
|
2688
2763
|
addLineToFile(destPath2, rule.line);
|
|
2689
2764
|
return;
|
|
2690
2765
|
}
|
|
2691
2766
|
if (rule.type === "merge-json") {
|
|
2692
|
-
const srcPath2 =
|
|
2693
|
-
const destPath2 =
|
|
2767
|
+
const srcPath2 = path6.join(pluginRoot, rule.from);
|
|
2768
|
+
const destPath2 = path6.join(userProjectRoot, rule.to);
|
|
2694
2769
|
mergeJsonFile(srcPath2, destPath2, rule.arrayMerge);
|
|
2695
2770
|
return;
|
|
2696
2771
|
}
|
|
2697
2772
|
if (!("from" in rule)) {
|
|
2698
2773
|
return;
|
|
2699
2774
|
}
|
|
2700
|
-
const srcPath =
|
|
2701
|
-
const destPath =
|
|
2702
|
-
if (!
|
|
2775
|
+
const srcPath = path6.join(pluginRoot, rule.from);
|
|
2776
|
+
const destPath = path6.join(userProjectRoot, rule.to);
|
|
2777
|
+
if (!fs8.existsSync(srcPath)) {
|
|
2703
2778
|
console.warn(`[fullstack-cli] Source not found: ${rule.from}`);
|
|
2704
2779
|
return;
|
|
2705
2780
|
}
|
|
@@ -2716,68 +2791,68 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
|
|
|
2716
2791
|
}
|
|
2717
2792
|
}
|
|
2718
2793
|
function syncFile(src, dest, overwrite = true, onlyIfExists = false) {
|
|
2719
|
-
if (onlyIfExists && !
|
|
2720
|
-
console.log(`[fullstack-cli] \u25CB ${
|
|
2794
|
+
if (onlyIfExists && !fs8.existsSync(dest)) {
|
|
2795
|
+
console.log(`[fullstack-cli] \u25CB ${path6.basename(dest)} (skipped, target not exists)`);
|
|
2721
2796
|
return;
|
|
2722
2797
|
}
|
|
2723
|
-
const destDir =
|
|
2724
|
-
if (!
|
|
2725
|
-
|
|
2798
|
+
const destDir = path6.dirname(dest);
|
|
2799
|
+
if (!fs8.existsSync(destDir)) {
|
|
2800
|
+
fs8.mkdirSync(destDir, { recursive: true });
|
|
2726
2801
|
}
|
|
2727
|
-
if (
|
|
2728
|
-
console.log(`[fullstack-cli] \u25CB ${
|
|
2802
|
+
if (fs8.existsSync(dest) && !overwrite) {
|
|
2803
|
+
console.log(`[fullstack-cli] \u25CB ${path6.basename(dest)} (skipped, already exists)`);
|
|
2729
2804
|
return;
|
|
2730
2805
|
}
|
|
2731
|
-
|
|
2732
|
-
console.log(`[fullstack-cli] \u2713 ${
|
|
2806
|
+
fs8.copyFileSync(src, dest);
|
|
2807
|
+
console.log(`[fullstack-cli] \u2713 ${path6.basename(dest)}`);
|
|
2733
2808
|
}
|
|
2734
2809
|
function syncDirectory(src, dest, overwrite = true) {
|
|
2735
|
-
if (!
|
|
2736
|
-
|
|
2810
|
+
if (!fs8.existsSync(dest)) {
|
|
2811
|
+
fs8.mkdirSync(dest, { recursive: true });
|
|
2737
2812
|
}
|
|
2738
|
-
const files =
|
|
2813
|
+
const files = fs8.readdirSync(src);
|
|
2739
2814
|
let count = 0;
|
|
2740
2815
|
files.forEach((file) => {
|
|
2741
|
-
const srcFile =
|
|
2742
|
-
const destFile =
|
|
2743
|
-
const stats =
|
|
2816
|
+
const srcFile = path6.join(src, file);
|
|
2817
|
+
const destFile = path6.join(dest, file);
|
|
2818
|
+
const stats = fs8.statSync(srcFile);
|
|
2744
2819
|
if (stats.isDirectory()) {
|
|
2745
2820
|
syncDirectory(srcFile, destFile, overwrite);
|
|
2746
2821
|
} else {
|
|
2747
|
-
if (overwrite || !
|
|
2748
|
-
|
|
2749
|
-
console.log(`[fullstack-cli] \u2713 ${
|
|
2822
|
+
if (overwrite || !fs8.existsSync(destFile)) {
|
|
2823
|
+
fs8.copyFileSync(srcFile, destFile);
|
|
2824
|
+
console.log(`[fullstack-cli] \u2713 ${path6.relative(dest, destFile)}`);
|
|
2750
2825
|
count++;
|
|
2751
2826
|
}
|
|
2752
2827
|
}
|
|
2753
2828
|
});
|
|
2754
2829
|
if (count > 0) {
|
|
2755
|
-
console.log(`[fullstack-cli] Synced ${count} files to ${
|
|
2830
|
+
console.log(`[fullstack-cli] Synced ${count} files to ${path6.basename(dest)}/`);
|
|
2756
2831
|
}
|
|
2757
2832
|
}
|
|
2758
2833
|
function appendToFile(src, dest) {
|
|
2759
|
-
const content =
|
|
2834
|
+
const content = fs8.readFileSync(src, "utf-8");
|
|
2760
2835
|
let existingContent = "";
|
|
2761
|
-
if (
|
|
2762
|
-
existingContent =
|
|
2836
|
+
if (fs8.existsSync(dest)) {
|
|
2837
|
+
existingContent = fs8.readFileSync(dest, "utf-8");
|
|
2763
2838
|
}
|
|
2764
2839
|
if (existingContent.includes(content.trim())) {
|
|
2765
|
-
console.log(`[fullstack-cli] \u25CB ${
|
|
2840
|
+
console.log(`[fullstack-cli] \u25CB ${path6.basename(dest)} (already contains content)`);
|
|
2766
2841
|
return;
|
|
2767
2842
|
}
|
|
2768
|
-
|
|
2769
|
-
console.log(`[fullstack-cli] \u2713 ${
|
|
2843
|
+
fs8.appendFileSync(dest, content);
|
|
2844
|
+
console.log(`[fullstack-cli] \u2713 ${path6.basename(dest)} (appended)`);
|
|
2770
2845
|
}
|
|
2771
2846
|
function setPermissions(permissions, projectRoot) {
|
|
2772
2847
|
for (const [pattern, mode] of Object.entries(permissions)) {
|
|
2773
2848
|
if (pattern === "**/*.sh") {
|
|
2774
|
-
const scriptsDir =
|
|
2775
|
-
if (
|
|
2776
|
-
const files =
|
|
2849
|
+
const scriptsDir = path6.join(projectRoot, "scripts");
|
|
2850
|
+
if (fs8.existsSync(scriptsDir)) {
|
|
2851
|
+
const files = fs8.readdirSync(scriptsDir);
|
|
2777
2852
|
files.forEach((file) => {
|
|
2778
2853
|
if (file.endsWith(".sh")) {
|
|
2779
|
-
const filePath =
|
|
2780
|
-
|
|
2854
|
+
const filePath = path6.join(scriptsDir, file);
|
|
2855
|
+
fs8.chmodSync(filePath, mode);
|
|
2781
2856
|
}
|
|
2782
2857
|
});
|
|
2783
2858
|
}
|
|
@@ -2785,27 +2860,27 @@ function setPermissions(permissions, projectRoot) {
|
|
|
2785
2860
|
}
|
|
2786
2861
|
}
|
|
2787
2862
|
function deleteFile(filePath) {
|
|
2788
|
-
if (
|
|
2789
|
-
|
|
2790
|
-
console.log(`[fullstack-cli] \u2713 ${
|
|
2863
|
+
if (fs8.existsSync(filePath)) {
|
|
2864
|
+
fs8.unlinkSync(filePath);
|
|
2865
|
+
console.log(`[fullstack-cli] \u2713 ${path6.basename(filePath)} (deleted)`);
|
|
2791
2866
|
} else {
|
|
2792
|
-
console.log(`[fullstack-cli] \u25CB ${
|
|
2867
|
+
console.log(`[fullstack-cli] \u25CB ${path6.basename(filePath)} (not found)`);
|
|
2793
2868
|
}
|
|
2794
2869
|
}
|
|
2795
2870
|
function deleteDirectory(dirPath) {
|
|
2796
|
-
if (
|
|
2797
|
-
|
|
2798
|
-
console.log(`[fullstack-cli] \u2713 ${
|
|
2871
|
+
if (fs8.existsSync(dirPath)) {
|
|
2872
|
+
fs8.rmSync(dirPath, { recursive: true });
|
|
2873
|
+
console.log(`[fullstack-cli] \u2713 ${path6.basename(dirPath)} (deleted)`);
|
|
2799
2874
|
} else {
|
|
2800
|
-
console.log(`[fullstack-cli] \u25CB ${
|
|
2875
|
+
console.log(`[fullstack-cli] \u25CB ${path6.basename(dirPath)} (not found)`);
|
|
2801
2876
|
}
|
|
2802
2877
|
}
|
|
2803
2878
|
function addScript(packageJsonPath, name, command, overwrite) {
|
|
2804
|
-
if (!
|
|
2879
|
+
if (!fs8.existsSync(packageJsonPath)) {
|
|
2805
2880
|
console.log(`[fullstack-cli] \u25CB package.json (not found)`);
|
|
2806
2881
|
return;
|
|
2807
2882
|
}
|
|
2808
|
-
const content =
|
|
2883
|
+
const content = fs8.readFileSync(packageJsonPath, "utf-8");
|
|
2809
2884
|
const pkg2 = JSON.parse(content);
|
|
2810
2885
|
if (!pkg2.scripts) {
|
|
2811
2886
|
pkg2.scripts = {};
|
|
@@ -2817,42 +2892,42 @@ function addScript(packageJsonPath, name, command, overwrite) {
|
|
|
2817
2892
|
}
|
|
2818
2893
|
}
|
|
2819
2894
|
pkg2.scripts[name] = command;
|
|
2820
|
-
|
|
2895
|
+
fs8.writeFileSync(packageJsonPath, JSON.stringify(pkg2, null, 2) + "\n");
|
|
2821
2896
|
console.log(`[fullstack-cli] \u2713 scripts.${name}`);
|
|
2822
2897
|
}
|
|
2823
2898
|
function addLineToFile(filePath, line) {
|
|
2824
|
-
const fileName =
|
|
2825
|
-
if (!
|
|
2899
|
+
const fileName = path6.basename(filePath);
|
|
2900
|
+
if (!fs8.existsSync(filePath)) {
|
|
2826
2901
|
console.log(`[fullstack-cli] \u25CB ${fileName} (not found, skipped)`);
|
|
2827
2902
|
return;
|
|
2828
2903
|
}
|
|
2829
|
-
const content =
|
|
2904
|
+
const content = fs8.readFileSync(filePath, "utf-8");
|
|
2830
2905
|
const lines = content.split("\n").map((l) => l.trim());
|
|
2831
2906
|
if (lines.includes(line)) {
|
|
2832
2907
|
console.log(`[fullstack-cli] \u25CB ${fileName} (line already exists: ${line})`);
|
|
2833
2908
|
return;
|
|
2834
2909
|
}
|
|
2835
2910
|
const appendContent = (content.endsWith("\n") ? "" : "\n") + line + "\n";
|
|
2836
|
-
|
|
2911
|
+
fs8.appendFileSync(filePath, appendContent);
|
|
2837
2912
|
console.log(`[fullstack-cli] \u2713 ${fileName} (added: ${line})`);
|
|
2838
2913
|
}
|
|
2839
2914
|
function mergeJsonFile(src, dest, arrayMerge) {
|
|
2840
|
-
const fileName =
|
|
2841
|
-
if (!
|
|
2915
|
+
const fileName = path6.basename(dest);
|
|
2916
|
+
if (!fs8.existsSync(src)) {
|
|
2842
2917
|
console.warn(`[fullstack-cli] Source not found: ${src}`);
|
|
2843
2918
|
return;
|
|
2844
2919
|
}
|
|
2845
|
-
const templateContent = JSON.parse(
|
|
2846
|
-
if (!
|
|
2847
|
-
const destDir =
|
|
2848
|
-
if (!
|
|
2849
|
-
|
|
2920
|
+
const templateContent = JSON.parse(fs8.readFileSync(src, "utf-8"));
|
|
2921
|
+
if (!fs8.existsSync(dest)) {
|
|
2922
|
+
const destDir = path6.dirname(dest);
|
|
2923
|
+
if (!fs8.existsSync(destDir)) {
|
|
2924
|
+
fs8.mkdirSync(destDir, { recursive: true });
|
|
2850
2925
|
}
|
|
2851
|
-
|
|
2926
|
+
fs8.writeFileSync(dest, JSON.stringify(templateContent, null, 2) + "\n");
|
|
2852
2927
|
console.log(`[fullstack-cli] \u2713 ${fileName} (created)`);
|
|
2853
2928
|
return;
|
|
2854
2929
|
}
|
|
2855
|
-
const userContent = JSON.parse(
|
|
2930
|
+
const userContent = JSON.parse(fs8.readFileSync(dest, "utf-8"));
|
|
2856
2931
|
const merged = deepMergeJson(userContent, templateContent, arrayMerge ?? {});
|
|
2857
2932
|
const userStr = JSON.stringify(userContent, null, 2);
|
|
2858
2933
|
const mergedStr = JSON.stringify(merged, null, 2);
|
|
@@ -2860,7 +2935,7 @@ function mergeJsonFile(src, dest, arrayMerge) {
|
|
|
2860
2935
|
console.log(`[fullstack-cli] \u25CB ${fileName} (already up to date)`);
|
|
2861
2936
|
return;
|
|
2862
2937
|
}
|
|
2863
|
-
|
|
2938
|
+
fs8.writeFileSync(dest, mergedStr + "\n");
|
|
2864
2939
|
console.log(`[fullstack-cli] \u2713 ${fileName} (merged)`);
|
|
2865
2940
|
}
|
|
2866
2941
|
|
|
@@ -2920,16 +2995,16 @@ async function reportCreateInstanceEvent(pluginKey, version) {
|
|
|
2920
2995
|
}
|
|
2921
2996
|
|
|
2922
2997
|
// src/utils/git.ts
|
|
2923
|
-
import { execSync, spawnSync as
|
|
2924
|
-
import
|
|
2925
|
-
import
|
|
2998
|
+
import { execSync, spawnSync as spawnSync3 } from "child_process";
|
|
2999
|
+
import fs9 from "fs";
|
|
3000
|
+
import path7 from "path";
|
|
2926
3001
|
function isGitRepository(cwd = process.cwd()) {
|
|
2927
3002
|
try {
|
|
2928
|
-
const gitDir =
|
|
2929
|
-
if (
|
|
3003
|
+
const gitDir = path7.join(cwd, ".git");
|
|
3004
|
+
if (fs9.existsSync(gitDir)) {
|
|
2930
3005
|
return true;
|
|
2931
3006
|
}
|
|
2932
|
-
const result =
|
|
3007
|
+
const result = spawnSync3("git", ["rev-parse", "--git-dir"], {
|
|
2933
3008
|
cwd,
|
|
2934
3009
|
stdio: "pipe",
|
|
2935
3010
|
encoding: "utf-8"
|
|
@@ -2955,11 +3030,11 @@ function getChangedFiles(cwd = process.cwd()) {
|
|
|
2955
3030
|
function gitAddUpgradeFiles(cwd = process.cwd(), filesToStage) {
|
|
2956
3031
|
const filteredFiles = [];
|
|
2957
3032
|
for (const filePath of filesToStage) {
|
|
2958
|
-
if (
|
|
3033
|
+
if (fs9.existsSync(path7.join(cwd, filePath))) {
|
|
2959
3034
|
filteredFiles.push(filePath);
|
|
2960
3035
|
continue;
|
|
2961
3036
|
}
|
|
2962
|
-
const tracked =
|
|
3037
|
+
const tracked = spawnSync3("git", ["ls-files", "--error-unmatch", "--", filePath], {
|
|
2963
3038
|
cwd,
|
|
2964
3039
|
stdio: "pipe",
|
|
2965
3040
|
encoding: "utf-8"
|
|
@@ -2971,7 +3046,7 @@ function gitAddUpgradeFiles(cwd = process.cwd(), filesToStage) {
|
|
|
2971
3046
|
if (filteredFiles.length === 0) {
|
|
2972
3047
|
return;
|
|
2973
3048
|
}
|
|
2974
|
-
const result =
|
|
3049
|
+
const result = spawnSync3("git", ["add", "--", ...filteredFiles], {
|
|
2975
3050
|
cwd,
|
|
2976
3051
|
stdio: "pipe",
|
|
2977
3052
|
encoding: "utf-8"
|
|
@@ -2982,7 +3057,7 @@ function gitAddUpgradeFiles(cwd = process.cwd(), filesToStage) {
|
|
|
2982
3057
|
}
|
|
2983
3058
|
}
|
|
2984
3059
|
function hasStagedChanges(cwd = process.cwd()) {
|
|
2985
|
-
const result =
|
|
3060
|
+
const result = spawnSync3("git", ["diff", "--cached", "--quiet"], {
|
|
2986
3061
|
cwd,
|
|
2987
3062
|
stdio: "pipe",
|
|
2988
3063
|
encoding: "utf-8"
|
|
@@ -2997,7 +3072,7 @@ function hasStagedChanges(cwd = process.cwd()) {
|
|
|
2997
3072
|
throw new Error(`Failed to check staged changes: ${errorMsg}`);
|
|
2998
3073
|
}
|
|
2999
3074
|
function gitCommit(message, cwd = process.cwd()) {
|
|
3000
|
-
const result =
|
|
3075
|
+
const result = spawnSync3("git", ["commit", "-m", message], {
|
|
3001
3076
|
cwd,
|
|
3002
3077
|
stdio: "pipe",
|
|
3003
3078
|
encoding: "utf-8"
|
|
@@ -3040,15 +3115,15 @@ Auto-committed by fullstack-cli`;
|
|
|
3040
3115
|
}
|
|
3041
3116
|
|
|
3042
3117
|
// src/commands/upgrade/shared/utils.ts
|
|
3043
|
-
import
|
|
3044
|
-
import
|
|
3118
|
+
import path8 from "path";
|
|
3119
|
+
import fs10 from "fs";
|
|
3045
3120
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3046
3121
|
function getCliVersion() {
|
|
3047
3122
|
try {
|
|
3048
3123
|
const __filename = fileURLToPath4(import.meta.url);
|
|
3049
|
-
const __dirname2 =
|
|
3050
|
-
const pkgPath =
|
|
3051
|
-
const pkgContent =
|
|
3124
|
+
const __dirname2 = path8.dirname(__filename);
|
|
3125
|
+
const pkgPath = path8.resolve(__dirname2, "../../../package.json");
|
|
3126
|
+
const pkgContent = fs10.readFileSync(pkgPath, "utf-8");
|
|
3052
3127
|
const pkg2 = JSON.parse(pkgContent);
|
|
3053
3128
|
return pkg2.version || "unknown";
|
|
3054
3129
|
} catch {
|
|
@@ -3106,31 +3181,47 @@ async function run3(options = {}) {
|
|
|
3106
3181
|
}
|
|
3107
3182
|
|
|
3108
3183
|
// src/commands/upgrade/deps/run.handler.ts
|
|
3109
|
-
import { spawnSync as
|
|
3110
|
-
import
|
|
3111
|
-
import
|
|
3184
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
3185
|
+
import fs11 from "fs";
|
|
3186
|
+
import path9 from "path";
|
|
3112
3187
|
|
|
3113
3188
|
// src/utils/grayscale/config.ts
|
|
3114
3189
|
function getGrayscaleConfig(configJson) {
|
|
3115
3190
|
if (!configJson) {
|
|
3116
3191
|
return null;
|
|
3117
3192
|
}
|
|
3193
|
+
let parsed;
|
|
3118
3194
|
try {
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3195
|
+
parsed = JSON.parse(configJson);
|
|
3196
|
+
} catch {
|
|
3197
|
+
console.warn("[grayscale] Failed to parse grayscale config");
|
|
3198
|
+
return null;
|
|
3199
|
+
}
|
|
3200
|
+
if (parsed && parsed.target_versions && typeof parsed.target_versions === "object") {
|
|
3201
|
+
const entries = Object.entries(parsed.target_versions).filter(
|
|
3202
|
+
([, v]) => typeof v === "string" && v.length > 0
|
|
3203
|
+
);
|
|
3204
|
+
if (entries.length === 0) {
|
|
3205
|
+
console.log("[grayscale] target_versions present but empty, skip");
|
|
3122
3206
|
return null;
|
|
3123
3207
|
}
|
|
3124
3208
|
return {
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
xTtEnv: parsed.x_tt_env || void 0
|
|
3209
|
+
kind: "resolved",
|
|
3210
|
+
targetVersions: new Map(entries),
|
|
3211
|
+
matchedChannel: typeof parsed.matched_channel === "string" ? parsed.matched_channel : void 0
|
|
3129
3212
|
};
|
|
3130
|
-
}
|
|
3131
|
-
|
|
3213
|
+
}
|
|
3214
|
+
const config = parsed?.config;
|
|
3215
|
+
if (!config || !config.enabled) {
|
|
3132
3216
|
return null;
|
|
3133
3217
|
}
|
|
3218
|
+
return {
|
|
3219
|
+
kind: "legacy",
|
|
3220
|
+
config,
|
|
3221
|
+
tenantId: parsed.tenant_id != null ? String(parsed.tenant_id) : void 0,
|
|
3222
|
+
appId: parsed.app_id || void 0,
|
|
3223
|
+
xTtEnv: parsed.x_tt_env || void 0
|
|
3224
|
+
};
|
|
3134
3225
|
}
|
|
3135
3226
|
|
|
3136
3227
|
// src/utils/grayscale/identity.ts
|
|
@@ -3218,6 +3309,19 @@ function resolveGrayscaleVersions(_cwd, configJson) {
|
|
|
3218
3309
|
console.log("[grayscale] Config not available, skipping grayscale");
|
|
3219
3310
|
return null;
|
|
3220
3311
|
}
|
|
3312
|
+
if (result.kind === "resolved") {
|
|
3313
|
+
console.log(
|
|
3314
|
+
`[grayscale] Using server-resolved versions (matched channel: ${result.matchedChannel || "(stable)"})`
|
|
3315
|
+
);
|
|
3316
|
+
console.log(`[grayscale] Resolved ${result.targetVersions.size} package version(s):`);
|
|
3317
|
+
for (const [pkg2, ver] of result.targetVersions) {
|
|
3318
|
+
console.log(`[grayscale] ${pkg2} -> ${ver}`);
|
|
3319
|
+
}
|
|
3320
|
+
return result.targetVersions;
|
|
3321
|
+
}
|
|
3322
|
+
console.warn(
|
|
3323
|
+
"[grayscale] Received legacy payload (full TCC config). This path is deprecated; sandbox_console should be upgraded to server-side resolution."
|
|
3324
|
+
);
|
|
3221
3325
|
const { config, tenantId: payloadTenantId, appId: payloadAppId, xTtEnv: payloadXTtEnv } = result;
|
|
3222
3326
|
const envIdentity = readProjectIdentity();
|
|
3223
3327
|
const identity = {
|
|
@@ -3298,7 +3402,7 @@ function upgradePackages(packages, version, cwd) {
|
|
|
3298
3402
|
packages.forEach((pkg2) => {
|
|
3299
3403
|
const target = `${pkg2}@${version}`;
|
|
3300
3404
|
console.log(`[fullstack-cli] Installing ${target}...`);
|
|
3301
|
-
const result =
|
|
3405
|
+
const result = spawnSync4("npm", ["install", target], {
|
|
3302
3406
|
cwd,
|
|
3303
3407
|
stdio: "inherit"
|
|
3304
3408
|
});
|
|
@@ -3310,7 +3414,7 @@ function upgradePackages(packages, version, cwd) {
|
|
|
3310
3414
|
console.log("[fullstack-cli] Upgrading to latest compatible versions...");
|
|
3311
3415
|
packages.forEach((pkg2) => {
|
|
3312
3416
|
console.log(`[fullstack-cli] Updating ${pkg2}...`);
|
|
3313
|
-
const result =
|
|
3417
|
+
const result = spawnSync4("npm", ["update", pkg2], {
|
|
3314
3418
|
cwd,
|
|
3315
3419
|
stdio: "inherit"
|
|
3316
3420
|
});
|
|
@@ -3327,8 +3431,8 @@ function installGrayscaleVersions(packages, grayscaleVersions, cwd, dryRun, mode
|
|
|
3327
3431
|
if (version) {
|
|
3328
3432
|
let current = "";
|
|
3329
3433
|
try {
|
|
3330
|
-
const installedPkgPath =
|
|
3331
|
-
const installedPkg = JSON.parse(
|
|
3434
|
+
const installedPkgPath = path9.join(cwd, "node_modules", pkg2, "package.json");
|
|
3435
|
+
const installedPkg = JSON.parse(fs11.readFileSync(installedPkgPath, "utf-8"));
|
|
3332
3436
|
current = installedPkg.version || "";
|
|
3333
3437
|
} catch (err) {
|
|
3334
3438
|
const code = err?.code;
|
|
@@ -3371,7 +3475,7 @@ function installGrayscaleVersions(packages, grayscaleVersions, cwd, dryRun, mode
|
|
|
3371
3475
|
}
|
|
3372
3476
|
const targets = upgradePlan.map(({ pkg: pkg2, version }) => `${pkg2}@${version}`);
|
|
3373
3477
|
console.log(`[fullstack-cli] Installing ${targets.join(" ")}...`);
|
|
3374
|
-
const result =
|
|
3478
|
+
const result = spawnSync4("npm", ["install", ...targets], {
|
|
3375
3479
|
cwd,
|
|
3376
3480
|
stdio: "inherit"
|
|
3377
3481
|
});
|
|
@@ -3444,6 +3548,111 @@ var depsCommand = {
|
|
|
3444
3548
|
}
|
|
3445
3549
|
};
|
|
3446
3550
|
|
|
3551
|
+
// src/commands/upgrade/global-deps/run.handler.ts
|
|
3552
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
3553
|
+
import fs12 from "fs";
|
|
3554
|
+
import path10 from "path";
|
|
3555
|
+
var MANAGED_GLOBAL_CLIS = [
|
|
3556
|
+
"@lark-apaas/fullstack-cli",
|
|
3557
|
+
"@lark-apaas/miaoda-cli"
|
|
3558
|
+
];
|
|
3559
|
+
function readGlobalInstalledVersion(pkg2) {
|
|
3560
|
+
const candidates = [];
|
|
3561
|
+
if (process.env.npm_config_prefix) candidates.push(process.env.npm_config_prefix);
|
|
3562
|
+
if (process.env.NPM_CONFIG_PREFIX) candidates.push(process.env.NPM_CONFIG_PREFIX);
|
|
3563
|
+
candidates.push("/usr");
|
|
3564
|
+
candidates.push("/usr/local");
|
|
3565
|
+
if (process.env.HOME) candidates.push(path10.join(process.env.HOME, ".npm-global"));
|
|
3566
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3567
|
+
for (const prefix of candidates) {
|
|
3568
|
+
if (seen.has(prefix)) continue;
|
|
3569
|
+
seen.add(prefix);
|
|
3570
|
+
try {
|
|
3571
|
+
const pkgPath = path10.join(prefix, "lib", "node_modules", pkg2, "package.json");
|
|
3572
|
+
if (fs12.existsSync(pkgPath)) {
|
|
3573
|
+
const meta = JSON.parse(fs12.readFileSync(pkgPath, "utf-8"));
|
|
3574
|
+
if (meta && typeof meta.version === "string") return meta.version;
|
|
3575
|
+
}
|
|
3576
|
+
} catch (err) {
|
|
3577
|
+
console.warn(
|
|
3578
|
+
`[fullstack-cli] readGlobalInstalledVersion(${pkg2}) failed at prefix=${prefix}: ${err instanceof Error ? err.message : String(err)}`
|
|
3579
|
+
);
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
return "";
|
|
3583
|
+
}
|
|
3584
|
+
function buildGlobalUpgradePlan(managed, resolvedVersions, readVersion) {
|
|
3585
|
+
const plan = [];
|
|
3586
|
+
for (const pkg2 of managed) {
|
|
3587
|
+
const target = resolvedVersions.get(pkg2);
|
|
3588
|
+
if (!target) {
|
|
3589
|
+
console.log(`[fullstack-cli] ${pkg2}: no target version in grayscale config, skip`);
|
|
3590
|
+
continue;
|
|
3591
|
+
}
|
|
3592
|
+
const current = readVersion(pkg2);
|
|
3593
|
+
if (current && current === target) {
|
|
3594
|
+
console.log(`[fullstack-cli] ${pkg2}@${target} (already installed, skip)`);
|
|
3595
|
+
continue;
|
|
3596
|
+
}
|
|
3597
|
+
plan.push({ pkg: pkg2, current, target });
|
|
3598
|
+
}
|
|
3599
|
+
return plan;
|
|
3600
|
+
}
|
|
3601
|
+
async function run5(options = {}) {
|
|
3602
|
+
console.log("[fullstack-cli] Starting global CLI upgrade...");
|
|
3603
|
+
if (!options.grayscaleConfig) {
|
|
3604
|
+
console.log("[fullstack-cli] No grayscale config, skip global upgrade");
|
|
3605
|
+
return;
|
|
3606
|
+
}
|
|
3607
|
+
const grayscaleVersions = resolveGrayscaleVersions("/", options.grayscaleConfig);
|
|
3608
|
+
if (!grayscaleVersions) {
|
|
3609
|
+
console.log("[fullstack-cli] Grayscale config not available, skip global upgrade");
|
|
3610
|
+
return;
|
|
3611
|
+
}
|
|
3612
|
+
const plan = buildGlobalUpgradePlan(MANAGED_GLOBAL_CLIS, grayscaleVersions, readGlobalInstalledVersion);
|
|
3613
|
+
if (plan.length === 0) {
|
|
3614
|
+
console.log("[fullstack-cli] No global CLI upgrade needed");
|
|
3615
|
+
return;
|
|
3616
|
+
}
|
|
3617
|
+
console.log(`[fullstack-cli] Global upgrade plan (${plan.length} package(s)):`);
|
|
3618
|
+
plan.forEach(({ pkg: pkg2, current, target }) => {
|
|
3619
|
+
console.log(` - ${pkg2} ${current || "(not installed)"} -> ${target}`);
|
|
3620
|
+
});
|
|
3621
|
+
if (options.dryRun) {
|
|
3622
|
+
console.log("[fullstack-cli] Dry run mode, skipping actual installation");
|
|
3623
|
+
return;
|
|
3624
|
+
}
|
|
3625
|
+
const targets = plan.map(({ pkg: pkg2, target }) => `${pkg2}@${target}`);
|
|
3626
|
+
const npmArgs = ["install", "-g", ...targets];
|
|
3627
|
+
if (options.registry) {
|
|
3628
|
+
npmArgs.push("--registry", options.registry);
|
|
3629
|
+
}
|
|
3630
|
+
console.log(`[fullstack-cli] Running: npm ${npmArgs.join(" ")}`);
|
|
3631
|
+
const result = spawnSync5("npm", npmArgs, { stdio: "inherit" });
|
|
3632
|
+
if (result.error || result.status !== 0) {
|
|
3633
|
+
console.warn(
|
|
3634
|
+
`[fullstack-cli] npm install -g failed: ${result.error?.message ?? `exit ${result.status}`}`
|
|
3635
|
+
);
|
|
3636
|
+
process.exit(1);
|
|
3637
|
+
}
|
|
3638
|
+
console.log("[fullstack-cli] \u2713 Global CLI upgrade completed");
|
|
3639
|
+
}
|
|
3640
|
+
|
|
3641
|
+
// src/commands/upgrade/global-deps/index.ts
|
|
3642
|
+
var globalDepsCommand = {
|
|
3643
|
+
name: "global-deps",
|
|
3644
|
+
description: "Upgrade global @lark-apaas CLIs (fullstack-cli, miaoda-cli) per grayscale config",
|
|
3645
|
+
register(parentCommand) {
|
|
3646
|
+
parentCommand.command(this.name).description(this.description).option("--grayscale-config <json>", "Grayscale config JSON (injected by sandbox_console)").option("--dry-run", "Show upgrade plan without executing").option(
|
|
3647
|
+
"--registry <url>",
|
|
3648
|
+
"npm registry URL (default: https://registry.npmmirror.com/)",
|
|
3649
|
+
"https://registry.npmmirror.com/"
|
|
3650
|
+
).action(async (options) => {
|
|
3651
|
+
await run5(options);
|
|
3652
|
+
});
|
|
3653
|
+
}
|
|
3654
|
+
};
|
|
3655
|
+
|
|
3447
3656
|
// src/commands/upgrade/index.ts
|
|
3448
3657
|
var upgradeCommand = {
|
|
3449
3658
|
name: "upgrade",
|
|
@@ -3453,13 +3662,14 @@ var upgradeCommand = {
|
|
|
3453
3662
|
await run3(options);
|
|
3454
3663
|
});
|
|
3455
3664
|
depsCommand.register(upgradeCmd);
|
|
3665
|
+
globalDepsCommand.register(upgradeCmd);
|
|
3456
3666
|
}
|
|
3457
3667
|
};
|
|
3458
3668
|
|
|
3459
3669
|
// src/commands/action-plugin/utils.ts
|
|
3460
|
-
import
|
|
3461
|
-
import
|
|
3462
|
-
import { spawnSync as
|
|
3670
|
+
import fs13 from "fs";
|
|
3671
|
+
import path11 from "path";
|
|
3672
|
+
import { spawnSync as spawnSync6, execSync as execSync2 } from "child_process";
|
|
3463
3673
|
function parsePluginName(input) {
|
|
3464
3674
|
const match = input.match(/^(@[^/]+\/[^@]+)(?:@(.+))?$/);
|
|
3465
3675
|
if (!match) {
|
|
@@ -3476,18 +3686,18 @@ function getProjectRoot() {
|
|
|
3476
3686
|
return process.cwd();
|
|
3477
3687
|
}
|
|
3478
3688
|
function getPackageJsonPath() {
|
|
3479
|
-
return
|
|
3689
|
+
return path11.join(getProjectRoot(), "package.json");
|
|
3480
3690
|
}
|
|
3481
3691
|
function getPluginPath(pluginName) {
|
|
3482
|
-
return
|
|
3692
|
+
return path11.join(getProjectRoot(), "node_modules", pluginName);
|
|
3483
3693
|
}
|
|
3484
3694
|
function readPackageJson2() {
|
|
3485
3695
|
const pkgPath = getPackageJsonPath();
|
|
3486
|
-
if (!
|
|
3696
|
+
if (!fs13.existsSync(pkgPath)) {
|
|
3487
3697
|
throw new Error("package.json not found in current directory");
|
|
3488
3698
|
}
|
|
3489
3699
|
try {
|
|
3490
|
-
const content =
|
|
3700
|
+
const content = fs13.readFileSync(pkgPath, "utf-8");
|
|
3491
3701
|
return JSON.parse(content);
|
|
3492
3702
|
} catch {
|
|
3493
3703
|
throw new Error("Failed to parse package.json");
|
|
@@ -3495,7 +3705,7 @@ function readPackageJson2() {
|
|
|
3495
3705
|
}
|
|
3496
3706
|
function writePackageJson2(pkg2) {
|
|
3497
3707
|
const pkgPath = getPackageJsonPath();
|
|
3498
|
-
|
|
3708
|
+
fs13.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
|
|
3499
3709
|
}
|
|
3500
3710
|
function readActionPlugins() {
|
|
3501
3711
|
const pkg2 = readPackageJson2();
|
|
@@ -3516,7 +3726,7 @@ function getInstalledPluginVersion(pluginName) {
|
|
|
3516
3726
|
}
|
|
3517
3727
|
function npmInstall(tgzPath) {
|
|
3518
3728
|
console.log(`[action-plugin] Running npm install ${tgzPath}...`);
|
|
3519
|
-
const result =
|
|
3729
|
+
const result = spawnSync6("npm", ["install", tgzPath, "--no-save", "--no-package-lock", "--ignore-scripts"], {
|
|
3520
3730
|
cwd: getProjectRoot(),
|
|
3521
3731
|
stdio: "inherit"
|
|
3522
3732
|
});
|
|
@@ -3528,12 +3738,12 @@ function npmInstall(tgzPath) {
|
|
|
3528
3738
|
}
|
|
3529
3739
|
}
|
|
3530
3740
|
function getPackageVersion(pluginName) {
|
|
3531
|
-
const pkgJsonPath =
|
|
3532
|
-
if (!
|
|
3741
|
+
const pkgJsonPath = path11.join(getPluginPath(pluginName), "package.json");
|
|
3742
|
+
if (!fs13.existsSync(pkgJsonPath)) {
|
|
3533
3743
|
return null;
|
|
3534
3744
|
}
|
|
3535
3745
|
try {
|
|
3536
|
-
const content =
|
|
3746
|
+
const content = fs13.readFileSync(pkgJsonPath, "utf-8");
|
|
3537
3747
|
const pkg2 = JSON.parse(content);
|
|
3538
3748
|
return pkg2.version || null;
|
|
3539
3749
|
} catch {
|
|
@@ -3541,49 +3751,49 @@ function getPackageVersion(pluginName) {
|
|
|
3541
3751
|
}
|
|
3542
3752
|
}
|
|
3543
3753
|
function readPluginPackageJson(pluginPath) {
|
|
3544
|
-
const pkgJsonPath =
|
|
3545
|
-
if (!
|
|
3754
|
+
const pkgJsonPath = path11.join(pluginPath, "package.json");
|
|
3755
|
+
if (!fs13.existsSync(pkgJsonPath)) {
|
|
3546
3756
|
return null;
|
|
3547
3757
|
}
|
|
3548
3758
|
try {
|
|
3549
|
-
const content =
|
|
3759
|
+
const content = fs13.readFileSync(pkgJsonPath, "utf-8");
|
|
3550
3760
|
return JSON.parse(content);
|
|
3551
3761
|
} catch {
|
|
3552
3762
|
return null;
|
|
3553
3763
|
}
|
|
3554
3764
|
}
|
|
3555
3765
|
function extractTgzToNodeModules(tgzPath, pluginName) {
|
|
3556
|
-
const nodeModulesPath =
|
|
3557
|
-
const targetDir =
|
|
3558
|
-
const scopeDir =
|
|
3559
|
-
if (!
|
|
3560
|
-
|
|
3766
|
+
const nodeModulesPath = path11.join(getProjectRoot(), "node_modules");
|
|
3767
|
+
const targetDir = path11.join(nodeModulesPath, pluginName);
|
|
3768
|
+
const scopeDir = path11.dirname(targetDir);
|
|
3769
|
+
if (!fs13.existsSync(scopeDir)) {
|
|
3770
|
+
fs13.mkdirSync(scopeDir, { recursive: true });
|
|
3561
3771
|
}
|
|
3562
|
-
if (
|
|
3563
|
-
|
|
3772
|
+
if (fs13.existsSync(targetDir)) {
|
|
3773
|
+
fs13.rmSync(targetDir, { recursive: true });
|
|
3564
3774
|
}
|
|
3565
|
-
const tempDir =
|
|
3566
|
-
if (
|
|
3567
|
-
|
|
3775
|
+
const tempDir = path11.join(nodeModulesPath, ".cache", "fullstack-cli", "extract-temp");
|
|
3776
|
+
if (fs13.existsSync(tempDir)) {
|
|
3777
|
+
fs13.rmSync(tempDir, { recursive: true });
|
|
3568
3778
|
}
|
|
3569
|
-
|
|
3779
|
+
fs13.mkdirSync(tempDir, { recursive: true });
|
|
3570
3780
|
try {
|
|
3571
3781
|
execSync2(`tar -xzf "${tgzPath}" -C "${tempDir}"`, { stdio: "pipe" });
|
|
3572
|
-
const extractedDir =
|
|
3573
|
-
if (
|
|
3574
|
-
|
|
3782
|
+
const extractedDir = path11.join(tempDir, "package");
|
|
3783
|
+
if (fs13.existsSync(extractedDir)) {
|
|
3784
|
+
fs13.renameSync(extractedDir, targetDir);
|
|
3575
3785
|
} else {
|
|
3576
|
-
const files =
|
|
3786
|
+
const files = fs13.readdirSync(tempDir);
|
|
3577
3787
|
if (files.length === 1) {
|
|
3578
|
-
|
|
3788
|
+
fs13.renameSync(path11.join(tempDir, files[0]), targetDir);
|
|
3579
3789
|
} else {
|
|
3580
3790
|
throw new Error("Unexpected tgz structure");
|
|
3581
3791
|
}
|
|
3582
3792
|
}
|
|
3583
3793
|
return targetDir;
|
|
3584
3794
|
} finally {
|
|
3585
|
-
if (
|
|
3586
|
-
|
|
3795
|
+
if (fs13.existsSync(tempDir)) {
|
|
3796
|
+
fs13.rmSync(tempDir, { recursive: true });
|
|
3587
3797
|
}
|
|
3588
3798
|
}
|
|
3589
3799
|
}
|
|
@@ -3592,10 +3802,10 @@ function checkMissingPeerDeps(peerDeps) {
|
|
|
3592
3802
|
return [];
|
|
3593
3803
|
}
|
|
3594
3804
|
const missing = [];
|
|
3595
|
-
const nodeModulesPath =
|
|
3805
|
+
const nodeModulesPath = path11.join(getProjectRoot(), "node_modules");
|
|
3596
3806
|
for (const [depName, _version] of Object.entries(peerDeps)) {
|
|
3597
|
-
const depPath =
|
|
3598
|
-
if (!
|
|
3807
|
+
const depPath = path11.join(nodeModulesPath, depName);
|
|
3808
|
+
if (!fs13.existsSync(depPath)) {
|
|
3599
3809
|
missing.push(depName);
|
|
3600
3810
|
}
|
|
3601
3811
|
}
|
|
@@ -3606,7 +3816,7 @@ function installMissingDeps(deps) {
|
|
|
3606
3816
|
return;
|
|
3607
3817
|
}
|
|
3608
3818
|
console.log(`[action-plugin] Installing missing dependencies: ${deps.join(", ")}`);
|
|
3609
|
-
const result =
|
|
3819
|
+
const result = spawnSync6("npm", ["install", ...deps, "--no-save", "--no-package-lock"], {
|
|
3610
3820
|
cwd: getProjectRoot(),
|
|
3611
3821
|
stdio: "inherit"
|
|
3612
3822
|
});
|
|
@@ -3619,16 +3829,16 @@ function installMissingDeps(deps) {
|
|
|
3619
3829
|
}
|
|
3620
3830
|
function removePluginDirectory(pluginName) {
|
|
3621
3831
|
const pluginPath = getPluginPath(pluginName);
|
|
3622
|
-
if (
|
|
3623
|
-
|
|
3832
|
+
if (fs13.existsSync(pluginPath)) {
|
|
3833
|
+
fs13.rmSync(pluginPath, { recursive: true });
|
|
3624
3834
|
console.log(`[action-plugin] Removed ${pluginName}`);
|
|
3625
3835
|
}
|
|
3626
3836
|
}
|
|
3627
3837
|
|
|
3628
3838
|
// src/commands/action-plugin/api-client.ts
|
|
3629
3839
|
import { HttpClient as HttpClient2 } from "@lark-apaas/http-client";
|
|
3630
|
-
import
|
|
3631
|
-
import
|
|
3840
|
+
import fs14 from "fs";
|
|
3841
|
+
import path12 from "path";
|
|
3632
3842
|
var PLUGIN_CACHE_DIR = "node_modules/.cache/fullstack-cli/plugins";
|
|
3633
3843
|
async function getPluginVersions(keys, latestOnly = true) {
|
|
3634
3844
|
const client = getHttpClient();
|
|
@@ -3692,19 +3902,19 @@ async function downloadFromPublic(downloadURL) {
|
|
|
3692
3902
|
return Buffer.from(arrayBuffer);
|
|
3693
3903
|
}
|
|
3694
3904
|
function getPluginCacheDir() {
|
|
3695
|
-
return
|
|
3905
|
+
return path12.join(process.cwd(), PLUGIN_CACHE_DIR);
|
|
3696
3906
|
}
|
|
3697
3907
|
function ensureCacheDir() {
|
|
3698
3908
|
const cacheDir = getPluginCacheDir();
|
|
3699
|
-
if (!
|
|
3700
|
-
|
|
3909
|
+
if (!fs14.existsSync(cacheDir)) {
|
|
3910
|
+
fs14.mkdirSync(cacheDir, { recursive: true });
|
|
3701
3911
|
}
|
|
3702
3912
|
}
|
|
3703
3913
|
function getTempFilePath(pluginKey, version) {
|
|
3704
3914
|
ensureCacheDir();
|
|
3705
3915
|
const safeKey = pluginKey.replace(/[/@]/g, "_");
|
|
3706
3916
|
const filename = `${safeKey}@${version}.tgz`;
|
|
3707
|
-
return
|
|
3917
|
+
return path12.join(getPluginCacheDir(), filename);
|
|
3708
3918
|
}
|
|
3709
3919
|
var MAX_RETRIES = 2;
|
|
3710
3920
|
async function withRetry(operation, description, maxRetries = MAX_RETRIES) {
|
|
@@ -3741,7 +3951,7 @@ async function downloadPlugin(pluginKey, requestedVersion) {
|
|
|
3741
3951
|
);
|
|
3742
3952
|
}
|
|
3743
3953
|
const tgzPath = getTempFilePath(pluginKey, pluginInfo.version);
|
|
3744
|
-
|
|
3954
|
+
fs14.writeFileSync(tgzPath, tgzBuffer);
|
|
3745
3955
|
console.log(`[action-plugin] Downloaded to ${tgzPath} (${(tgzBuffer.length / 1024).toFixed(2)} KB)`);
|
|
3746
3956
|
return {
|
|
3747
3957
|
tgzPath,
|
|
@@ -3755,18 +3965,18 @@ function getCachePath(pluginKey, version) {
|
|
|
3755
3965
|
ensureCacheDir();
|
|
3756
3966
|
const safeKey = pluginKey.replace(/[/@]/g, "_");
|
|
3757
3967
|
const filename = `${safeKey}@${version}.tgz`;
|
|
3758
|
-
return
|
|
3968
|
+
return path12.join(getPluginCacheDir(), filename);
|
|
3759
3969
|
}
|
|
3760
3970
|
function hasCachedPlugin(pluginKey, version) {
|
|
3761
3971
|
const cachePath = getCachePath(pluginKey, version);
|
|
3762
|
-
return
|
|
3972
|
+
return fs14.existsSync(cachePath);
|
|
3763
3973
|
}
|
|
3764
3974
|
function listCachedPlugins() {
|
|
3765
3975
|
const cacheDir = getPluginCacheDir();
|
|
3766
|
-
if (!
|
|
3976
|
+
if (!fs14.existsSync(cacheDir)) {
|
|
3767
3977
|
return [];
|
|
3768
3978
|
}
|
|
3769
|
-
const files =
|
|
3979
|
+
const files = fs14.readdirSync(cacheDir);
|
|
3770
3980
|
const result = [];
|
|
3771
3981
|
for (const file of files) {
|
|
3772
3982
|
if (!file.endsWith(".tgz")) continue;
|
|
@@ -3774,8 +3984,8 @@ function listCachedPlugins() {
|
|
|
3774
3984
|
if (!match) continue;
|
|
3775
3985
|
const [, rawName, version] = match;
|
|
3776
3986
|
const name = rawName.replace(/^_/, "@").replace(/_/, "/");
|
|
3777
|
-
const filePath =
|
|
3778
|
-
const stat =
|
|
3987
|
+
const filePath = path12.join(cacheDir, file);
|
|
3988
|
+
const stat = fs14.statSync(filePath);
|
|
3779
3989
|
result.push({
|
|
3780
3990
|
name,
|
|
3781
3991
|
version,
|
|
@@ -3788,14 +3998,14 @@ function listCachedPlugins() {
|
|
|
3788
3998
|
}
|
|
3789
3999
|
function cleanAllCache() {
|
|
3790
4000
|
const cacheDir = getPluginCacheDir();
|
|
3791
|
-
if (!
|
|
4001
|
+
if (!fs14.existsSync(cacheDir)) {
|
|
3792
4002
|
return 0;
|
|
3793
4003
|
}
|
|
3794
|
-
const files =
|
|
4004
|
+
const files = fs14.readdirSync(cacheDir);
|
|
3795
4005
|
let count = 0;
|
|
3796
4006
|
for (const file of files) {
|
|
3797
4007
|
if (file.endsWith(".tgz")) {
|
|
3798
|
-
|
|
4008
|
+
fs14.unlinkSync(path12.join(cacheDir, file));
|
|
3799
4009
|
count++;
|
|
3800
4010
|
}
|
|
3801
4011
|
}
|
|
@@ -3803,21 +4013,21 @@ function cleanAllCache() {
|
|
|
3803
4013
|
}
|
|
3804
4014
|
function cleanPluginCache(pluginKey, version) {
|
|
3805
4015
|
const cacheDir = getPluginCacheDir();
|
|
3806
|
-
if (!
|
|
4016
|
+
if (!fs14.existsSync(cacheDir)) {
|
|
3807
4017
|
return 0;
|
|
3808
4018
|
}
|
|
3809
4019
|
const safeKey = pluginKey.replace(/[/@]/g, "_");
|
|
3810
|
-
const files =
|
|
4020
|
+
const files = fs14.readdirSync(cacheDir);
|
|
3811
4021
|
let count = 0;
|
|
3812
4022
|
for (const file of files) {
|
|
3813
4023
|
if (version) {
|
|
3814
4024
|
if (file === `${safeKey}@${version}.tgz`) {
|
|
3815
|
-
|
|
4025
|
+
fs14.unlinkSync(path12.join(cacheDir, file));
|
|
3816
4026
|
count++;
|
|
3817
4027
|
}
|
|
3818
4028
|
} else {
|
|
3819
4029
|
if (file.startsWith(`${safeKey}@`) && file.endsWith(".tgz")) {
|
|
3820
|
-
|
|
4030
|
+
fs14.unlinkSync(path12.join(cacheDir, file));
|
|
3821
4031
|
count++;
|
|
3822
4032
|
}
|
|
3823
4033
|
}
|
|
@@ -4244,40 +4454,40 @@ var actionPluginCommandGroup = {
|
|
|
4244
4454
|
};
|
|
4245
4455
|
|
|
4246
4456
|
// src/commands/capability/utils.ts
|
|
4247
|
-
import
|
|
4457
|
+
import fs15 from "fs";
|
|
4248
4458
|
import { createRequire as createRequire2 } from "module";
|
|
4249
|
-
import
|
|
4459
|
+
import path13 from "path";
|
|
4250
4460
|
var CAPABILITIES_DIR = "server/capabilities";
|
|
4251
4461
|
function getProjectRoot2() {
|
|
4252
4462
|
return process.cwd();
|
|
4253
4463
|
}
|
|
4254
4464
|
function getCapabilitiesDir() {
|
|
4255
|
-
return
|
|
4465
|
+
return path13.join(getProjectRoot2(), CAPABILITIES_DIR);
|
|
4256
4466
|
}
|
|
4257
4467
|
function getCapabilityPath(id) {
|
|
4258
|
-
return
|
|
4468
|
+
return path13.join(getCapabilitiesDir(), `${id}.json`);
|
|
4259
4469
|
}
|
|
4260
4470
|
function getPluginManifestPath(pluginKey) {
|
|
4261
|
-
return
|
|
4471
|
+
return path13.join(getProjectRoot2(), "node_modules", pluginKey, "manifest.json");
|
|
4262
4472
|
}
|
|
4263
4473
|
function capabilitiesDirExists() {
|
|
4264
|
-
return
|
|
4474
|
+
return fs15.existsSync(getCapabilitiesDir());
|
|
4265
4475
|
}
|
|
4266
4476
|
function listCapabilityIds() {
|
|
4267
4477
|
const dir = getCapabilitiesDir();
|
|
4268
|
-
if (!
|
|
4478
|
+
if (!fs15.existsSync(dir)) {
|
|
4269
4479
|
return [];
|
|
4270
4480
|
}
|
|
4271
|
-
const files =
|
|
4481
|
+
const files = fs15.readdirSync(dir);
|
|
4272
4482
|
return files.filter((f) => f.endsWith(".json") && f !== "capabilities.json").map((f) => f.replace(/\.json$/, ""));
|
|
4273
4483
|
}
|
|
4274
4484
|
function readCapability(id) {
|
|
4275
4485
|
const filePath = getCapabilityPath(id);
|
|
4276
|
-
if (!
|
|
4486
|
+
if (!fs15.existsSync(filePath)) {
|
|
4277
4487
|
throw new Error(`Capability not found: ${id}`);
|
|
4278
4488
|
}
|
|
4279
4489
|
try {
|
|
4280
|
-
const content =
|
|
4490
|
+
const content = fs15.readFileSync(filePath, "utf-8");
|
|
4281
4491
|
return JSON.parse(content);
|
|
4282
4492
|
} catch (error) {
|
|
4283
4493
|
if (error instanceof SyntaxError) {
|
|
@@ -4304,11 +4514,11 @@ function readAllCapabilities() {
|
|
|
4304
4514
|
}
|
|
4305
4515
|
function readPluginManifest(pluginKey) {
|
|
4306
4516
|
const manifestPath = getPluginManifestPath(pluginKey);
|
|
4307
|
-
if (!
|
|
4517
|
+
if (!fs15.existsSync(manifestPath)) {
|
|
4308
4518
|
throw new Error(`Plugin not installed: ${pluginKey} (manifest.json not found)`);
|
|
4309
4519
|
}
|
|
4310
4520
|
try {
|
|
4311
|
-
const content =
|
|
4521
|
+
const content = fs15.readFileSync(manifestPath, "utf-8");
|
|
4312
4522
|
return JSON.parse(content);
|
|
4313
4523
|
} catch (error) {
|
|
4314
4524
|
if (error instanceof SyntaxError) {
|
|
@@ -4325,7 +4535,7 @@ function hasValidParamsSchema(paramsSchema) {
|
|
|
4325
4535
|
}
|
|
4326
4536
|
async function loadPlugin(pluginKey) {
|
|
4327
4537
|
try {
|
|
4328
|
-
const userRequire = createRequire2(
|
|
4538
|
+
const userRequire = createRequire2(path13.join(getProjectRoot2(), "package.json"));
|
|
4329
4539
|
const resolvedPath = userRequire.resolve(pluginKey);
|
|
4330
4540
|
const pluginModule = await import(resolvedPath);
|
|
4331
4541
|
const pluginPackage = pluginModule.default ?? pluginModule;
|
|
@@ -4488,8 +4698,8 @@ var capabilityCommandGroup = {
|
|
|
4488
4698
|
import { execFile } from "child_process";
|
|
4489
4699
|
|
|
4490
4700
|
// src/commands/component/registry-preparer.ts
|
|
4491
|
-
import
|
|
4492
|
-
import
|
|
4701
|
+
import fs16 from "fs";
|
|
4702
|
+
import path14 from "path";
|
|
4493
4703
|
import os from "os";
|
|
4494
4704
|
|
|
4495
4705
|
// src/commands/component/service.ts
|
|
@@ -4545,7 +4755,7 @@ async function sendInstallEvent(key) {
|
|
|
4545
4755
|
}
|
|
4546
4756
|
|
|
4547
4757
|
// src/commands/component/registry-preparer.ts
|
|
4548
|
-
var REGISTRY_TEMP_DIR =
|
|
4758
|
+
var REGISTRY_TEMP_DIR = path14.join(os.tmpdir(), "miaoda-registry");
|
|
4549
4759
|
function parseComponentKey(key) {
|
|
4550
4760
|
const match = key.match(/^@([^/]+)\/(.+)$/);
|
|
4551
4761
|
if (!match) {
|
|
@@ -4557,11 +4767,11 @@ function parseComponentKey(key) {
|
|
|
4557
4767
|
}
|
|
4558
4768
|
function getLocalRegistryPath(key) {
|
|
4559
4769
|
const { scope, name } = parseComponentKey(key);
|
|
4560
|
-
return
|
|
4770
|
+
return path14.join(REGISTRY_TEMP_DIR, scope, `${name}.json`);
|
|
4561
4771
|
}
|
|
4562
4772
|
function ensureDir(dirPath) {
|
|
4563
|
-
if (!
|
|
4564
|
-
|
|
4773
|
+
if (!fs16.existsSync(dirPath)) {
|
|
4774
|
+
fs16.mkdirSync(dirPath, { recursive: true });
|
|
4565
4775
|
}
|
|
4566
4776
|
}
|
|
4567
4777
|
async function prepareRecursive(key, visited) {
|
|
@@ -4594,8 +4804,8 @@ async function prepareRecursive(key, visited) {
|
|
|
4594
4804
|
registryDependencies: deps.map((dep) => getLocalRegistryPath(dep))
|
|
4595
4805
|
};
|
|
4596
4806
|
const localPath = getLocalRegistryPath(key);
|
|
4597
|
-
ensureDir(
|
|
4598
|
-
|
|
4807
|
+
ensureDir(path14.dirname(localPath));
|
|
4808
|
+
fs16.writeFileSync(localPath, JSON.stringify(rewrittenItem, null, 2), "utf-8");
|
|
4599
4809
|
debug("\u4FDD\u5B58\u5230: %s", localPath);
|
|
4600
4810
|
}
|
|
4601
4811
|
async function prepareComponentRegistryItems(id) {
|
|
@@ -4605,18 +4815,18 @@ async function prepareComponentRegistryItems(id) {
|
|
|
4605
4815
|
}
|
|
4606
4816
|
function cleanupTempDir() {
|
|
4607
4817
|
try {
|
|
4608
|
-
if (
|
|
4609
|
-
|
|
4818
|
+
if (fs16.existsSync(REGISTRY_TEMP_DIR)) {
|
|
4819
|
+
fs16.rmSync(REGISTRY_TEMP_DIR, { recursive: true, force: true });
|
|
4610
4820
|
}
|
|
4611
4821
|
} catch {
|
|
4612
4822
|
}
|
|
4613
4823
|
}
|
|
4614
4824
|
function getDownloadedRegistryItem(itemId) {
|
|
4615
4825
|
const localPath = getLocalRegistryPath(itemId);
|
|
4616
|
-
if (!
|
|
4826
|
+
if (!fs16.existsSync(localPath)) {
|
|
4617
4827
|
return null;
|
|
4618
4828
|
}
|
|
4619
|
-
const content =
|
|
4829
|
+
const content = fs16.readFileSync(localPath, "utf-8");
|
|
4620
4830
|
return JSON.parse(content);
|
|
4621
4831
|
}
|
|
4622
4832
|
|
|
@@ -4784,58 +4994,58 @@ var componentCommandGroup = {
|
|
|
4784
4994
|
};
|
|
4785
4995
|
|
|
4786
4996
|
// src/commands/migration/version-manager.ts
|
|
4787
|
-
import
|
|
4788
|
-
import
|
|
4997
|
+
import fs17 from "fs";
|
|
4998
|
+
import path15 from "path";
|
|
4789
4999
|
var PACKAGE_JSON = "package.json";
|
|
4790
5000
|
var VERSION_FIELD = "migrationVersion";
|
|
4791
5001
|
function getPackageJsonPath2() {
|
|
4792
|
-
return
|
|
5002
|
+
return path15.join(process.cwd(), PACKAGE_JSON);
|
|
4793
5003
|
}
|
|
4794
5004
|
function getCurrentVersion() {
|
|
4795
5005
|
const pkgPath = getPackageJsonPath2();
|
|
4796
|
-
if (!
|
|
5006
|
+
if (!fs17.existsSync(pkgPath)) {
|
|
4797
5007
|
throw new Error("package.json not found");
|
|
4798
5008
|
}
|
|
4799
|
-
const pkg2 = JSON.parse(
|
|
5009
|
+
const pkg2 = JSON.parse(fs17.readFileSync(pkgPath, "utf-8"));
|
|
4800
5010
|
return pkg2[VERSION_FIELD] ?? 0;
|
|
4801
5011
|
}
|
|
4802
5012
|
function setCurrentVersion(version) {
|
|
4803
5013
|
const pkgPath = getPackageJsonPath2();
|
|
4804
|
-
const pkg2 = JSON.parse(
|
|
5014
|
+
const pkg2 = JSON.parse(fs17.readFileSync(pkgPath, "utf-8"));
|
|
4805
5015
|
pkg2[VERSION_FIELD] = version;
|
|
4806
|
-
|
|
5016
|
+
fs17.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
|
|
4807
5017
|
}
|
|
4808
5018
|
|
|
4809
5019
|
// src/commands/migration/versions/v001_capability/json-migrator/detector.ts
|
|
4810
|
-
import
|
|
4811
|
-
import
|
|
5020
|
+
import fs19 from "fs";
|
|
5021
|
+
import path17 from "path";
|
|
4812
5022
|
|
|
4813
5023
|
// src/commands/migration/versions/v001_capability/utils.ts
|
|
4814
|
-
import
|
|
4815
|
-
import
|
|
5024
|
+
import fs18 from "fs";
|
|
5025
|
+
import path16 from "path";
|
|
4816
5026
|
var CAPABILITIES_DIR2 = "server/capabilities";
|
|
4817
5027
|
function getProjectRoot3() {
|
|
4818
5028
|
return process.cwd();
|
|
4819
5029
|
}
|
|
4820
5030
|
function getCapabilitiesDir2() {
|
|
4821
|
-
return
|
|
5031
|
+
return path16.join(getProjectRoot3(), CAPABILITIES_DIR2);
|
|
4822
5032
|
}
|
|
4823
5033
|
function getPluginManifestPath2(pluginKey) {
|
|
4824
|
-
return
|
|
5034
|
+
return path16.join(getProjectRoot3(), "node_modules", pluginKey, "manifest.json");
|
|
4825
5035
|
}
|
|
4826
5036
|
|
|
4827
5037
|
// src/commands/migration/versions/v001_capability/json-migrator/detector.ts
|
|
4828
5038
|
function detectJsonMigration() {
|
|
4829
5039
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
4830
|
-
const oldFilePath =
|
|
4831
|
-
if (!
|
|
5040
|
+
const oldFilePath = path17.join(capabilitiesDir, "capabilities.json");
|
|
5041
|
+
if (!fs19.existsSync(oldFilePath)) {
|
|
4832
5042
|
return {
|
|
4833
5043
|
needsMigration: false,
|
|
4834
5044
|
reason: "capabilities.json not found"
|
|
4835
5045
|
};
|
|
4836
5046
|
}
|
|
4837
5047
|
try {
|
|
4838
|
-
const content =
|
|
5048
|
+
const content = fs19.readFileSync(oldFilePath, "utf-8");
|
|
4839
5049
|
const parsed = JSON.parse(content);
|
|
4840
5050
|
if (!Array.isArray(parsed)) {
|
|
4841
5051
|
return {
|
|
@@ -4886,8 +5096,8 @@ async function check(options) {
|
|
|
4886
5096
|
}
|
|
4887
5097
|
|
|
4888
5098
|
// src/commands/migration/versions/v001_capability/json-migrator/index.ts
|
|
4889
|
-
import
|
|
4890
|
-
import
|
|
5099
|
+
import fs20 from "fs";
|
|
5100
|
+
import path18 from "path";
|
|
4891
5101
|
|
|
4892
5102
|
// src/commands/migration/versions/v001_capability/mapping.ts
|
|
4893
5103
|
var DEFAULT_PLUGIN_VERSION = "1.0.0";
|
|
@@ -5117,18 +5327,18 @@ function transformCapabilities(oldCapabilities) {
|
|
|
5117
5327
|
// src/commands/migration/versions/v001_capability/json-migrator/index.ts
|
|
5118
5328
|
function loadExistingCapabilities() {
|
|
5119
5329
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
5120
|
-
if (!
|
|
5330
|
+
if (!fs20.existsSync(capabilitiesDir)) {
|
|
5121
5331
|
return [];
|
|
5122
5332
|
}
|
|
5123
|
-
const files =
|
|
5333
|
+
const files = fs20.readdirSync(capabilitiesDir);
|
|
5124
5334
|
const capabilities = [];
|
|
5125
5335
|
for (const file of files) {
|
|
5126
5336
|
if (file === "capabilities.json" || !file.endsWith(".json")) {
|
|
5127
5337
|
continue;
|
|
5128
5338
|
}
|
|
5129
5339
|
try {
|
|
5130
|
-
const filePath =
|
|
5131
|
-
const content =
|
|
5340
|
+
const filePath = path18.join(capabilitiesDir, file);
|
|
5341
|
+
const content = fs20.readFileSync(filePath, "utf-8");
|
|
5132
5342
|
const capability = JSON.parse(content);
|
|
5133
5343
|
if (capability.id && capability.pluginKey) {
|
|
5134
5344
|
capabilities.push(capability);
|
|
@@ -5186,9 +5396,9 @@ async function migrateJsonFiles(options) {
|
|
|
5186
5396
|
}
|
|
5187
5397
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
5188
5398
|
for (const cap of newCapabilities) {
|
|
5189
|
-
const filePath =
|
|
5399
|
+
const filePath = path18.join(capabilitiesDir, `${cap.id}.json`);
|
|
5190
5400
|
const content = JSON.stringify(cap, null, 2);
|
|
5191
|
-
|
|
5401
|
+
fs20.writeFileSync(filePath, content, "utf-8");
|
|
5192
5402
|
console.log(` \u2713 Created: ${cap.id}.json`);
|
|
5193
5403
|
}
|
|
5194
5404
|
return {
|
|
@@ -5200,11 +5410,11 @@ async function migrateJsonFiles(options) {
|
|
|
5200
5410
|
}
|
|
5201
5411
|
|
|
5202
5412
|
// src/commands/migration/versions/v001_capability/plugin-installer/detector.ts
|
|
5203
|
-
import
|
|
5413
|
+
import fs21 from "fs";
|
|
5204
5414
|
function isPluginInstalled2(pluginKey) {
|
|
5205
5415
|
const actionPlugins = readActionPlugins();
|
|
5206
5416
|
const manifestPath = getPluginManifestPath2(pluginKey);
|
|
5207
|
-
return
|
|
5417
|
+
return fs21.existsSync(manifestPath) && !!actionPlugins[pluginKey];
|
|
5208
5418
|
}
|
|
5209
5419
|
function detectPluginsToInstall(capabilities) {
|
|
5210
5420
|
const pluginKeys = /* @__PURE__ */ new Set();
|
|
@@ -5280,12 +5490,12 @@ async function installPlugins(capabilities, options) {
|
|
|
5280
5490
|
}
|
|
5281
5491
|
|
|
5282
5492
|
// src/commands/migration/versions/v001_capability/code-migrator/index.ts
|
|
5283
|
-
import
|
|
5493
|
+
import path20 from "path";
|
|
5284
5494
|
import { Project as Project3 } from "ts-morph";
|
|
5285
5495
|
|
|
5286
5496
|
// src/commands/migration/versions/v001_capability/code-migrator/scanner.ts
|
|
5287
|
-
import
|
|
5288
|
-
import
|
|
5497
|
+
import fs22 from "fs";
|
|
5498
|
+
import path19 from "path";
|
|
5289
5499
|
var EXCLUDED_DIRS = [
|
|
5290
5500
|
"node_modules",
|
|
5291
5501
|
"dist",
|
|
@@ -5300,9 +5510,9 @@ var EXCLUDED_PATTERNS = [
|
|
|
5300
5510
|
/\.d\.ts$/
|
|
5301
5511
|
];
|
|
5302
5512
|
function scanDirectory(dir, files = []) {
|
|
5303
|
-
const entries =
|
|
5513
|
+
const entries = fs22.readdirSync(dir, { withFileTypes: true });
|
|
5304
5514
|
for (const entry of entries) {
|
|
5305
|
-
const fullPath =
|
|
5515
|
+
const fullPath = path19.join(dir, entry.name);
|
|
5306
5516
|
if (entry.isDirectory()) {
|
|
5307
5517
|
if (EXCLUDED_DIRS.includes(entry.name)) {
|
|
5308
5518
|
continue;
|
|
@@ -5318,14 +5528,14 @@ function scanDirectory(dir, files = []) {
|
|
|
5318
5528
|
return files;
|
|
5319
5529
|
}
|
|
5320
5530
|
function scanServerFiles() {
|
|
5321
|
-
const serverDir =
|
|
5322
|
-
if (!
|
|
5531
|
+
const serverDir = path19.join(getProjectRoot3(), "server");
|
|
5532
|
+
if (!fs22.existsSync(serverDir)) {
|
|
5323
5533
|
return [];
|
|
5324
5534
|
}
|
|
5325
5535
|
return scanDirectory(serverDir);
|
|
5326
5536
|
}
|
|
5327
5537
|
function hasCapabilityImport(filePath) {
|
|
5328
|
-
const content =
|
|
5538
|
+
const content = fs22.readFileSync(filePath, "utf-8");
|
|
5329
5539
|
return /import\s+.*from\s+['"][^'"]*capabilities[^'"]*['"]/.test(content);
|
|
5330
5540
|
}
|
|
5331
5541
|
function scanFilesToMigrate() {
|
|
@@ -5702,7 +5912,7 @@ function analyzeFile(project, filePath, actionNameMap) {
|
|
|
5702
5912
|
const callSites = analyzeCallSites(sourceFile, imports);
|
|
5703
5913
|
const classInfo = analyzeClass(sourceFile);
|
|
5704
5914
|
const { canMigrate, reason } = canAutoMigrate(classInfo);
|
|
5705
|
-
const relativePath =
|
|
5915
|
+
const relativePath = path20.relative(getProjectRoot3(), filePath);
|
|
5706
5916
|
return {
|
|
5707
5917
|
filePath: relativePath,
|
|
5708
5918
|
imports,
|
|
@@ -5713,7 +5923,7 @@ function analyzeFile(project, filePath, actionNameMap) {
|
|
|
5713
5923
|
};
|
|
5714
5924
|
}
|
|
5715
5925
|
function migrateFile(project, analysis, dryRun) {
|
|
5716
|
-
const absolutePath =
|
|
5926
|
+
const absolutePath = path20.join(getProjectRoot3(), analysis.filePath);
|
|
5717
5927
|
if (!analysis.canAutoMigrate) {
|
|
5718
5928
|
return {
|
|
5719
5929
|
filePath: analysis.filePath,
|
|
@@ -5816,17 +6026,17 @@ function getSuggestion(analysis) {
|
|
|
5816
6026
|
}
|
|
5817
6027
|
|
|
5818
6028
|
// src/commands/migration/versions/v001_capability/cleanup.ts
|
|
5819
|
-
import
|
|
5820
|
-
import
|
|
6029
|
+
import fs23 from "fs";
|
|
6030
|
+
import path21 from "path";
|
|
5821
6031
|
function cleanupOldFiles(capabilities, dryRun) {
|
|
5822
6032
|
const deletedFiles = [];
|
|
5823
6033
|
const errors = [];
|
|
5824
6034
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
5825
|
-
const oldJsonPath =
|
|
5826
|
-
if (
|
|
6035
|
+
const oldJsonPath = path21.join(capabilitiesDir, "capabilities.json");
|
|
6036
|
+
if (fs23.existsSync(oldJsonPath)) {
|
|
5827
6037
|
try {
|
|
5828
6038
|
if (!dryRun) {
|
|
5829
|
-
|
|
6039
|
+
fs23.unlinkSync(oldJsonPath);
|
|
5830
6040
|
}
|
|
5831
6041
|
deletedFiles.push("capabilities.json");
|
|
5832
6042
|
} catch (error) {
|
|
@@ -5834,11 +6044,11 @@ function cleanupOldFiles(capabilities, dryRun) {
|
|
|
5834
6044
|
}
|
|
5835
6045
|
}
|
|
5836
6046
|
for (const cap of capabilities) {
|
|
5837
|
-
const tsFilePath =
|
|
5838
|
-
if (
|
|
6047
|
+
const tsFilePath = path21.join(capabilitiesDir, `${cap.id}.ts`);
|
|
6048
|
+
if (fs23.existsSync(tsFilePath)) {
|
|
5839
6049
|
try {
|
|
5840
6050
|
if (!dryRun) {
|
|
5841
|
-
|
|
6051
|
+
fs23.unlinkSync(tsFilePath);
|
|
5842
6052
|
}
|
|
5843
6053
|
deletedFiles.push(`${cap.id}.ts`);
|
|
5844
6054
|
} catch (error) {
|
|
@@ -5854,8 +6064,8 @@ function cleanupOldFiles(capabilities, dryRun) {
|
|
|
5854
6064
|
}
|
|
5855
6065
|
|
|
5856
6066
|
// src/commands/migration/versions/v001_capability/report-generator.ts
|
|
5857
|
-
import
|
|
5858
|
-
import
|
|
6067
|
+
import fs24 from "fs";
|
|
6068
|
+
import path22 from "path";
|
|
5859
6069
|
var REPORT_FILE = "capability-migration-report.md";
|
|
5860
6070
|
function printSummary(result) {
|
|
5861
6071
|
const { jsonMigration, pluginInstallation, codeMigration, cleanup } = result;
|
|
@@ -6018,15 +6228,15 @@ async function generateReport(result) {
|
|
|
6018
6228
|
}
|
|
6019
6229
|
lines.push("");
|
|
6020
6230
|
const logDir = process.env.LOG_DIR || "logs";
|
|
6021
|
-
if (!
|
|
6231
|
+
if (!fs24.existsSync(logDir)) {
|
|
6022
6232
|
return;
|
|
6023
6233
|
}
|
|
6024
|
-
const reportDir =
|
|
6025
|
-
if (!
|
|
6026
|
-
|
|
6234
|
+
const reportDir = path22.join(logDir, "migration");
|
|
6235
|
+
if (!fs24.existsSync(reportDir)) {
|
|
6236
|
+
fs24.mkdirSync(reportDir, { recursive: true });
|
|
6027
6237
|
}
|
|
6028
|
-
const reportPath =
|
|
6029
|
-
|
|
6238
|
+
const reportPath = path22.join(reportDir, REPORT_FILE);
|
|
6239
|
+
fs24.writeFileSync(reportPath, lines.join("\n"), "utf-8");
|
|
6030
6240
|
console.log(`\u{1F4C4} Report generated: ${reportPath}`);
|
|
6031
6241
|
}
|
|
6032
6242
|
|
|
@@ -6203,7 +6413,7 @@ function buildResult(jsonMigration, pluginInstallation, codeMigration, cleanup)
|
|
|
6203
6413
|
}
|
|
6204
6414
|
|
|
6205
6415
|
// src/commands/migration/versions/v001_capability/run.ts
|
|
6206
|
-
async function
|
|
6416
|
+
async function run6(options) {
|
|
6207
6417
|
try {
|
|
6208
6418
|
const migrationOptions = {
|
|
6209
6419
|
dryRun: options.dryRun ?? false
|
|
@@ -6268,7 +6478,7 @@ var v001CapabilityMigration = {
|
|
|
6268
6478
|
name: "capability",
|
|
6269
6479
|
description: "Migrate capability configurations from old format (capabilities.json array) to new format (individual JSON files)",
|
|
6270
6480
|
check,
|
|
6271
|
-
run:
|
|
6481
|
+
run: run6
|
|
6272
6482
|
};
|
|
6273
6483
|
|
|
6274
6484
|
// src/commands/migration/versions/index.ts
|
|
@@ -6558,10 +6768,10 @@ var migrationCommand = {
|
|
|
6558
6768
|
};
|
|
6559
6769
|
|
|
6560
6770
|
// src/commands/read-logs/index.ts
|
|
6561
|
-
import
|
|
6771
|
+
import path23 from "path";
|
|
6562
6772
|
|
|
6563
6773
|
// src/commands/read-logs/std-utils.ts
|
|
6564
|
-
import
|
|
6774
|
+
import fs25 from "fs";
|
|
6565
6775
|
function formatStdPrefixTime(localTime) {
|
|
6566
6776
|
const match = localTime.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
|
|
6567
6777
|
if (!match) return localTime;
|
|
@@ -6591,11 +6801,11 @@ function stripPrefixFromStdLine(line) {
|
|
|
6591
6801
|
return `[${time}] ${content}`;
|
|
6592
6802
|
}
|
|
6593
6803
|
function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarker) {
|
|
6594
|
-
const stat =
|
|
6804
|
+
const stat = fs25.statSync(filePath);
|
|
6595
6805
|
if (stat.size === 0) {
|
|
6596
6806
|
return { lines: [], markerFound: false, totalLinesCount: 0 };
|
|
6597
6807
|
}
|
|
6598
|
-
const fd =
|
|
6808
|
+
const fd = fs25.openSync(filePath, "r");
|
|
6599
6809
|
const chunkSize = 64 * 1024;
|
|
6600
6810
|
let position = stat.size;
|
|
6601
6811
|
let remainder = "";
|
|
@@ -6609,7 +6819,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
|
|
|
6609
6819
|
const length = Math.min(chunkSize, position);
|
|
6610
6820
|
position -= length;
|
|
6611
6821
|
const buffer = Buffer.alloc(length);
|
|
6612
|
-
|
|
6822
|
+
fs25.readSync(fd, buffer, 0, length, position);
|
|
6613
6823
|
let chunk = buffer.toString("utf8");
|
|
6614
6824
|
if (remainder) {
|
|
6615
6825
|
chunk += remainder;
|
|
@@ -6651,7 +6861,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
|
|
|
6651
6861
|
}
|
|
6652
6862
|
}
|
|
6653
6863
|
} finally {
|
|
6654
|
-
|
|
6864
|
+
fs25.closeSync(fd);
|
|
6655
6865
|
}
|
|
6656
6866
|
return { lines: collected.reverse(), markerFound, totalLinesCount };
|
|
6657
6867
|
}
|
|
@@ -6672,21 +6882,21 @@ function readServerStdSegment(filePath, maxLines, offset) {
|
|
|
6672
6882
|
}
|
|
6673
6883
|
|
|
6674
6884
|
// src/commands/read-logs/tail.ts
|
|
6675
|
-
import
|
|
6885
|
+
import fs26 from "fs";
|
|
6676
6886
|
function fileExists(filePath) {
|
|
6677
6887
|
try {
|
|
6678
|
-
|
|
6888
|
+
fs26.accessSync(filePath, fs26.constants.F_OK | fs26.constants.R_OK);
|
|
6679
6889
|
return true;
|
|
6680
6890
|
} catch {
|
|
6681
6891
|
return false;
|
|
6682
6892
|
}
|
|
6683
6893
|
}
|
|
6684
6894
|
function readFileTailLines(filePath, maxLines) {
|
|
6685
|
-
const stat =
|
|
6895
|
+
const stat = fs26.statSync(filePath);
|
|
6686
6896
|
if (stat.size === 0) {
|
|
6687
6897
|
return [];
|
|
6688
6898
|
}
|
|
6689
|
-
const fd =
|
|
6899
|
+
const fd = fs26.openSync(filePath, "r");
|
|
6690
6900
|
const chunkSize = 64 * 1024;
|
|
6691
6901
|
const chunks = [];
|
|
6692
6902
|
let position = stat.size;
|
|
@@ -6696,13 +6906,13 @@ function readFileTailLines(filePath, maxLines) {
|
|
|
6696
6906
|
const length = Math.min(chunkSize, position);
|
|
6697
6907
|
position -= length;
|
|
6698
6908
|
const buffer = Buffer.alloc(length);
|
|
6699
|
-
|
|
6909
|
+
fs26.readSync(fd, buffer, 0, length, position);
|
|
6700
6910
|
chunks.unshift(buffer.toString("utf8"));
|
|
6701
6911
|
const chunkLines = buffer.toString("utf8").split("\n").length - 1;
|
|
6702
6912
|
collectedLines += chunkLines;
|
|
6703
6913
|
}
|
|
6704
6914
|
} finally {
|
|
6705
|
-
|
|
6915
|
+
fs26.closeSync(fd);
|
|
6706
6916
|
}
|
|
6707
6917
|
const content = chunks.join("");
|
|
6708
6918
|
const allLines = content.split("\n");
|
|
@@ -6718,11 +6928,11 @@ function readFileTailLines(filePath, maxLines) {
|
|
|
6718
6928
|
return allLines.slice(allLines.length - maxLines);
|
|
6719
6929
|
}
|
|
6720
6930
|
function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
6721
|
-
const stat =
|
|
6931
|
+
const stat = fs26.statSync(filePath);
|
|
6722
6932
|
if (stat.size === 0) {
|
|
6723
6933
|
return { lines: [], totalLinesCount: 0 };
|
|
6724
6934
|
}
|
|
6725
|
-
const fd =
|
|
6935
|
+
const fd = fs26.openSync(filePath, "r");
|
|
6726
6936
|
const chunkSize = 64 * 1024;
|
|
6727
6937
|
let position = stat.size;
|
|
6728
6938
|
let remainder = "";
|
|
@@ -6734,7 +6944,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
|
6734
6944
|
const length = Math.min(chunkSize, position);
|
|
6735
6945
|
position -= length;
|
|
6736
6946
|
const buffer = Buffer.alloc(length);
|
|
6737
|
-
|
|
6947
|
+
fs26.readSync(fd, buffer, 0, length, position);
|
|
6738
6948
|
let chunk = buffer.toString("utf8");
|
|
6739
6949
|
if (remainder) {
|
|
6740
6950
|
chunk += remainder;
|
|
@@ -6765,7 +6975,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
|
6765
6975
|
}
|
|
6766
6976
|
}
|
|
6767
6977
|
} finally {
|
|
6768
|
-
|
|
6978
|
+
fs26.closeSync(fd);
|
|
6769
6979
|
}
|
|
6770
6980
|
return { lines: collected.reverse(), totalLinesCount };
|
|
6771
6981
|
}
|
|
@@ -6907,7 +7117,7 @@ function readDevStdSegment(filePath, maxLines, offset) {
|
|
|
6907
7117
|
}
|
|
6908
7118
|
|
|
6909
7119
|
// src/commands/read-logs/json-lines.ts
|
|
6910
|
-
import
|
|
7120
|
+
import fs27 from "fs";
|
|
6911
7121
|
function normalizePid(value) {
|
|
6912
7122
|
if (typeof value === "number") {
|
|
6913
7123
|
return String(value);
|
|
@@ -6958,11 +7168,11 @@ function buildWantedLevelSet(levels) {
|
|
|
6958
7168
|
return set.size > 0 ? set : null;
|
|
6959
7169
|
}
|
|
6960
7170
|
function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
6961
|
-
const stat =
|
|
7171
|
+
const stat = fs27.statSync(filePath);
|
|
6962
7172
|
if (stat.size === 0) {
|
|
6963
7173
|
return { lines: [], totalLinesCount: 0 };
|
|
6964
7174
|
}
|
|
6965
|
-
const fd =
|
|
7175
|
+
const fd = fs27.openSync(filePath, "r");
|
|
6966
7176
|
const chunkSize = 64 * 1024;
|
|
6967
7177
|
let position = stat.size;
|
|
6968
7178
|
let remainder = "";
|
|
@@ -6977,7 +7187,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
|
6977
7187
|
const length = Math.min(chunkSize, position);
|
|
6978
7188
|
position -= length;
|
|
6979
7189
|
const buffer = Buffer.alloc(length);
|
|
6980
|
-
|
|
7190
|
+
fs27.readSync(fd, buffer, 0, length, position);
|
|
6981
7191
|
let chunk = buffer.toString("utf8");
|
|
6982
7192
|
if (remainder) {
|
|
6983
7193
|
chunk += remainder;
|
|
@@ -7039,7 +7249,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
|
7039
7249
|
}
|
|
7040
7250
|
}
|
|
7041
7251
|
} finally {
|
|
7042
|
-
|
|
7252
|
+
fs27.closeSync(fd);
|
|
7043
7253
|
}
|
|
7044
7254
|
return { lines: collected.reverse(), totalLinesCount };
|
|
7045
7255
|
}
|
|
@@ -7082,11 +7292,11 @@ function extractTraceId(obj) {
|
|
|
7082
7292
|
function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
7083
7293
|
const wanted = traceId.trim();
|
|
7084
7294
|
if (!wanted) return { lines: [], totalLinesCount: 0 };
|
|
7085
|
-
const stat =
|
|
7295
|
+
const stat = fs27.statSync(filePath);
|
|
7086
7296
|
if (stat.size === 0) {
|
|
7087
7297
|
return { lines: [], totalLinesCount: 0 };
|
|
7088
7298
|
}
|
|
7089
|
-
const fd =
|
|
7299
|
+
const fd = fs27.openSync(filePath, "r");
|
|
7090
7300
|
const chunkSize = 64 * 1024;
|
|
7091
7301
|
let position = stat.size;
|
|
7092
7302
|
let remainder = "";
|
|
@@ -7099,7 +7309,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
|
7099
7309
|
const length = Math.min(chunkSize, position);
|
|
7100
7310
|
position -= length;
|
|
7101
7311
|
const buffer = Buffer.alloc(length);
|
|
7102
|
-
|
|
7312
|
+
fs27.readSync(fd, buffer, 0, length, position);
|
|
7103
7313
|
let chunk = buffer.toString("utf8");
|
|
7104
7314
|
if (remainder) {
|
|
7105
7315
|
chunk += remainder;
|
|
@@ -7152,7 +7362,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
|
7152
7362
|
}
|
|
7153
7363
|
}
|
|
7154
7364
|
} finally {
|
|
7155
|
-
|
|
7365
|
+
fs27.closeSync(fd);
|
|
7156
7366
|
}
|
|
7157
7367
|
return { lines: collected.reverse(), totalLinesCount };
|
|
7158
7368
|
}
|
|
@@ -7161,11 +7371,11 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
7161
7371
|
if (!wantedLevelSet) {
|
|
7162
7372
|
return { lines: [], totalLinesCount: 0 };
|
|
7163
7373
|
}
|
|
7164
|
-
const stat =
|
|
7374
|
+
const stat = fs27.statSync(filePath);
|
|
7165
7375
|
if (stat.size === 0) {
|
|
7166
7376
|
return { lines: [], totalLinesCount: 0 };
|
|
7167
7377
|
}
|
|
7168
|
-
const fd =
|
|
7378
|
+
const fd = fs27.openSync(filePath, "r");
|
|
7169
7379
|
const chunkSize = 64 * 1024;
|
|
7170
7380
|
let position = stat.size;
|
|
7171
7381
|
let remainder = "";
|
|
@@ -7177,7 +7387,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
7177
7387
|
const length = Math.min(chunkSize, position);
|
|
7178
7388
|
position -= length;
|
|
7179
7389
|
const buffer = Buffer.alloc(length);
|
|
7180
|
-
|
|
7390
|
+
fs27.readSync(fd, buffer, 0, length, position);
|
|
7181
7391
|
let chunk = buffer.toString("utf8");
|
|
7182
7392
|
if (remainder) {
|
|
7183
7393
|
chunk += remainder;
|
|
@@ -7224,7 +7434,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
7224
7434
|
}
|
|
7225
7435
|
}
|
|
7226
7436
|
} finally {
|
|
7227
|
-
|
|
7437
|
+
fs27.closeSync(fd);
|
|
7228
7438
|
}
|
|
7229
7439
|
return { lines: collected.reverse(), totalLinesCount };
|
|
7230
7440
|
}
|
|
@@ -7458,34 +7668,34 @@ async function readLogsJsonResult(options) {
|
|
|
7458
7668
|
};
|
|
7459
7669
|
}
|
|
7460
7670
|
function resolveLogFilePath(logDir, type) {
|
|
7461
|
-
const base =
|
|
7671
|
+
const base = path23.isAbsolute(logDir) ? logDir : path23.join(process.cwd(), logDir);
|
|
7462
7672
|
if (type === "server") {
|
|
7463
|
-
return
|
|
7673
|
+
return path23.join(base, "server.log");
|
|
7464
7674
|
}
|
|
7465
7675
|
if (type === "trace") {
|
|
7466
|
-
return
|
|
7676
|
+
return path23.join(base, "trace.log");
|
|
7467
7677
|
}
|
|
7468
7678
|
if (type === "server-std") {
|
|
7469
|
-
return
|
|
7679
|
+
return path23.join(base, "server.std.log");
|
|
7470
7680
|
}
|
|
7471
7681
|
if (type === "client-std") {
|
|
7472
|
-
return
|
|
7682
|
+
return path23.join(base, "client.std.log");
|
|
7473
7683
|
}
|
|
7474
7684
|
if (type === "dev") {
|
|
7475
|
-
return
|
|
7685
|
+
return path23.join(base, "dev.log");
|
|
7476
7686
|
}
|
|
7477
7687
|
if (type === "dev-std") {
|
|
7478
|
-
return
|
|
7688
|
+
return path23.join(base, "dev.std.log");
|
|
7479
7689
|
}
|
|
7480
7690
|
if (type === "install-dep-std") {
|
|
7481
|
-
return
|
|
7691
|
+
return path23.join(base, "install-dep.std.log");
|
|
7482
7692
|
}
|
|
7483
7693
|
if (type === "browser") {
|
|
7484
|
-
return
|
|
7694
|
+
return path23.join(base, "browser.log");
|
|
7485
7695
|
}
|
|
7486
7696
|
throw new Error(`Unsupported log type: ${type}`);
|
|
7487
7697
|
}
|
|
7488
|
-
async function
|
|
7698
|
+
async function run7(options) {
|
|
7489
7699
|
const result = await readLogsJsonResult(options);
|
|
7490
7700
|
process.stdout.write(JSON.stringify(result) + "\n");
|
|
7491
7701
|
}
|
|
@@ -7527,7 +7737,7 @@ var readLogsCommand = {
|
|
|
7527
7737
|
const offset = parseNonNegativeInt(rawOptions.offset, "--offset");
|
|
7528
7738
|
const traceId = typeof rawOptions.traceId === "string" ? rawOptions.traceId : void 0;
|
|
7529
7739
|
const levels = parseCommaSeparatedList(rawOptions.level);
|
|
7530
|
-
await
|
|
7740
|
+
await run7({ logDir, type, maxLines, offset, traceId, levels });
|
|
7531
7741
|
} catch (error) {
|
|
7532
7742
|
const message = error instanceof Error ? error.message : String(error);
|
|
7533
7743
|
process.stderr.write(message + "\n");
|
|
@@ -7658,9 +7868,9 @@ function camelToKebab(str) {
|
|
|
7658
7868
|
}
|
|
7659
7869
|
|
|
7660
7870
|
// src/commands/build/upload-static.handler.ts
|
|
7661
|
-
import * as
|
|
7871
|
+
import * as fs28 from "fs";
|
|
7662
7872
|
import * as os2 from "os";
|
|
7663
|
-
import * as
|
|
7873
|
+
import * as path24 from "path";
|
|
7664
7874
|
import { execFileSync } from "child_process";
|
|
7665
7875
|
function readCredentialsFromEnv() {
|
|
7666
7876
|
const uploadPrefix = process.env.STATIC_UPLOAD_PREFIX;
|
|
@@ -7684,8 +7894,8 @@ async function uploadStatic(options) {
|
|
|
7684
7894
|
endpoint = UPLOAD_STATIC_DEFAULTS.endpoint,
|
|
7685
7895
|
region = UPLOAD_STATIC_DEFAULTS.region
|
|
7686
7896
|
} = options;
|
|
7687
|
-
const resolvedStaticDir =
|
|
7688
|
-
if (!
|
|
7897
|
+
const resolvedStaticDir = path24.resolve(staticDir);
|
|
7898
|
+
if (!fs28.existsSync(resolvedStaticDir)) {
|
|
7689
7899
|
console.error(`${LOG_PREFIX} \u76EE\u5F55\u4E0D\u5B58\u5728: ${resolvedStaticDir}\uFF0C\u8DF3\u8FC7\u4E0A\u4F20`);
|
|
7690
7900
|
return;
|
|
7691
7901
|
}
|
|
@@ -7718,8 +7928,8 @@ async function uploadStatic(options) {
|
|
|
7718
7928
|
({ AccessKeyID: accessKeyID, SecretAccessKey: secretAccessKey, SessionToken: sessionToken } = uploadCredential);
|
|
7719
7929
|
}
|
|
7720
7930
|
console.error(`${LOG_PREFIX} \u4E0A\u4F20\u76EE\u6807: ${uploadPrefix}`);
|
|
7721
|
-
const confPath =
|
|
7722
|
-
|
|
7931
|
+
const confPath = path24.join(os2.tmpdir(), `.tosutilconfig-static-${process.pid}`);
|
|
7932
|
+
fs28.writeFileSync(confPath, "");
|
|
7723
7933
|
try {
|
|
7724
7934
|
console.error(`${LOG_PREFIX} \u914D\u7F6E tosutil...`);
|
|
7725
7935
|
configureTosutil(resolvedTosutil, confPath, {
|
|
@@ -7733,7 +7943,7 @@ async function uploadStatic(options) {
|
|
|
7733
7943
|
uploadToTos(resolvedTosutil, confPath, resolvedStaticDir, uploadPrefix);
|
|
7734
7944
|
} finally {
|
|
7735
7945
|
try {
|
|
7736
|
-
|
|
7946
|
+
fs28.unlinkSync(confPath);
|
|
7737
7947
|
} catch {
|
|
7738
7948
|
}
|
|
7739
7949
|
}
|
|
@@ -7753,8 +7963,8 @@ async function uploadStatic(options) {
|
|
|
7753
7963
|
}
|
|
7754
7964
|
}
|
|
7755
7965
|
function resolveTosutilPath(tosutilPath) {
|
|
7756
|
-
if (
|
|
7757
|
-
return
|
|
7966
|
+
if (path24.isAbsolute(tosutilPath)) {
|
|
7967
|
+
return fs28.existsSync(tosutilPath) ? tosutilPath : null;
|
|
7758
7968
|
}
|
|
7759
7969
|
try {
|
|
7760
7970
|
const resolved = execFileSync("which", [tosutilPath], { encoding: "utf-8" }).trim();
|
|
@@ -7799,7 +8009,7 @@ async function resolveBucketId(appId) {
|
|
|
7799
8009
|
return bucketId;
|
|
7800
8010
|
}
|
|
7801
8011
|
function isDirEmpty(dirPath) {
|
|
7802
|
-
const entries =
|
|
8012
|
+
const entries = fs28.readdirSync(dirPath);
|
|
7803
8013
|
return entries.length === 0;
|
|
7804
8014
|
}
|
|
7805
8015
|
|
|
@@ -7894,12 +8104,12 @@ var commands = [
|
|
|
7894
8104
|
];
|
|
7895
8105
|
|
|
7896
8106
|
// src/index.ts
|
|
7897
|
-
var envPath =
|
|
7898
|
-
if (
|
|
8107
|
+
var envPath = path25.join(process.cwd(), ".env");
|
|
8108
|
+
if (fs29.existsSync(envPath)) {
|
|
7899
8109
|
dotenvConfig({ path: envPath });
|
|
7900
8110
|
}
|
|
7901
|
-
var __dirname =
|
|
7902
|
-
var pkg = JSON.parse(
|
|
8111
|
+
var __dirname = path25.dirname(fileURLToPath5(import.meta.url));
|
|
8112
|
+
var pkg = JSON.parse(fs29.readFileSync(path25.join(__dirname, "../package.json"), "utf-8"));
|
|
7903
8113
|
var cli = new FullstackCLI(pkg.version);
|
|
7904
8114
|
cli.useAll(commands);
|
|
7905
8115
|
cli.run();
|