@lark-apaas/fullstack-cli 1.1.35 → 1.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2363,8 +2363,8 @@ var genDbSchemaCommand = {
2363
2363
  };
2364
2364
 
2365
2365
  // src/commands/sync/run.handler.ts
2366
- import path4 from "path";
2367
- import fs6 from "fs";
2366
+ import path5 from "path";
2367
+ import fs7 from "fs";
2368
2368
  import { fileURLToPath as fileURLToPath3 } from "url";
2369
2369
 
2370
2370
  // src/config/sync.ts
@@ -2525,18 +2525,93 @@ function deepMergeJson(user, template, arrayMerge = {}, currentPath = "") {
2525
2525
  return result;
2526
2526
  }
2527
2527
 
2528
+ // src/utils/package-json.ts
2529
+ import fs6 from "fs";
2530
+ import path4 from "path";
2531
+ var LEGACY_LINT_SCRIPT = 'concurrently "npm run eslint" "npm run type:check" "npm run stylelint"';
2532
+ var PATCHED_LINT_SCRIPT = "node ./scripts/lint.js";
2533
+ function readPackageJson(cwd = process.cwd()) {
2534
+ const pkgPath = path4.join(cwd, "package.json");
2535
+ if (!fs6.existsSync(pkgPath)) {
2536
+ throw new Error(`package.json not found at ${pkgPath}`);
2537
+ }
2538
+ const content = fs6.readFileSync(pkgPath, "utf-8");
2539
+ return JSON.parse(content);
2540
+ }
2541
+ function writePackageJson(pkg2, cwd = process.cwd()) {
2542
+ const pkgPath = path4.join(cwd, "package.json");
2543
+ const content = JSON.stringify(pkg2, null, 2) + "\n";
2544
+ fs6.writeFileSync(pkgPath, content, "utf-8");
2545
+ }
2546
+ function patchLintScriptForFilesSupport(pkg2) {
2547
+ const currentLint = pkg2.scripts?.lint;
2548
+ if (!currentLint) {
2549
+ return "skipped-missing";
2550
+ }
2551
+ if (currentLint === PATCHED_LINT_SCRIPT || currentLint === "node scripts/lint.js") {
2552
+ return "already-patched";
2553
+ }
2554
+ if (currentLint !== LEGACY_LINT_SCRIPT) {
2555
+ return "skipped-custom";
2556
+ }
2557
+ pkg2.scripts = pkg2.scripts || {};
2558
+ pkg2.scripts.lint = PATCHED_LINT_SCRIPT;
2559
+ return "patched";
2560
+ }
2561
+ function removeUpgradeScript(pkg2) {
2562
+ if (!pkg2.scripts?.upgrade) {
2563
+ return false;
2564
+ }
2565
+ delete pkg2.scripts.upgrade;
2566
+ return true;
2567
+ }
2568
+ function cleanDevScript(pkg2) {
2569
+ if (!pkg2.scripts?.dev) {
2570
+ return false;
2571
+ }
2572
+ const originalDev = pkg2.scripts.dev;
2573
+ const cleanedDev = originalDev.replace(/npm\s+run\s+upgrade\s*&&\s*/g, "").replace(/npm\s+run\s+upgrade\s*$/g, "").trim();
2574
+ if (cleanedDev !== originalDev) {
2575
+ pkg2.scripts.dev = cleanedDev;
2576
+ return true;
2577
+ }
2578
+ return false;
2579
+ }
2580
+ function cleanupPackageJson(cwd = process.cwd()) {
2581
+ try {
2582
+ const pkg2 = readPackageJson(cwd);
2583
+ let changed = false;
2584
+ if (removeUpgradeScript(pkg2)) {
2585
+ console.log("[fullstack-cli] \u2713 Removed scripts.upgrade");
2586
+ changed = true;
2587
+ }
2588
+ if (cleanDevScript(pkg2)) {
2589
+ console.log("[fullstack-cli] \u2713 Cleaned scripts.dev (removed npm run upgrade)");
2590
+ changed = true;
2591
+ }
2592
+ if (changed) {
2593
+ writePackageJson(pkg2, cwd);
2594
+ }
2595
+ return changed;
2596
+ } catch (error) {
2597
+ const message = error instanceof Error ? error.message : String(error);
2598
+ console.log(`[fullstack-cli] \u26A0 Could not cleanup package.json: ${message}`);
2599
+ return false;
2600
+ }
2601
+ }
2602
+
2528
2603
  // src/commands/sync/run.handler.ts
2529
2604
  async function run2(options) {
2530
2605
  const userProjectRoot = process.env.INIT_CWD || process.cwd();
2531
2606
  const __filename = fileURLToPath3(import.meta.url);
2532
- const __dirname2 = path4.dirname(__filename);
2533
- const pluginRoot = path4.resolve(__dirname2, "..");
2607
+ const __dirname2 = path5.dirname(__filename);
2608
+ const pluginRoot = path5.resolve(__dirname2, "..");
2534
2609
  if (userProjectRoot === pluginRoot) {
2535
2610
  console.log("[fullstack-cli] Skip syncing (installing plugin itself)");
2536
2611
  process.exit(0);
2537
2612
  }
2538
- const userPackageJson = path4.join(userProjectRoot, "package.json");
2539
- if (!fs6.existsSync(userPackageJson)) {
2613
+ const userPackageJson = path5.join(userProjectRoot, "package.json");
2614
+ if (!fs7.existsSync(userPackageJson)) {
2540
2615
  console.log("[fullstack-cli] Skip syncing (not a valid npm project)");
2541
2616
  process.exit(0);
2542
2617
  }
@@ -2552,6 +2627,7 @@ async function run2(options) {
2552
2627
  for (const rule of config.sync) {
2553
2628
  await syncRule(rule, pluginRoot, userProjectRoot);
2554
2629
  }
2630
+ patchUserPackageJson(userProjectRoot);
2555
2631
  if (config.permissions) {
2556
2632
  setPermissions(config.permissions, userProjectRoot);
2557
2633
  }
@@ -2562,9 +2638,32 @@ async function run2(options) {
2562
2638
  process.exit(1);
2563
2639
  }
2564
2640
  }
2641
+ function patchUserPackageJson(userProjectRoot) {
2642
+ try {
2643
+ const pkg2 = readPackageJson(userProjectRoot);
2644
+ const lintPatchResult = patchLintScriptForFilesSupport(pkg2);
2645
+ if (lintPatchResult === "patched") {
2646
+ writePackageJson(pkg2, userProjectRoot);
2647
+ console.log("[fullstack-cli] \u2713 Patched scripts.lint to support --files");
2648
+ return;
2649
+ }
2650
+ if (lintPatchResult === "already-patched") {
2651
+ console.log("[fullstack-cli] \u25CB scripts.lint already supports --files");
2652
+ return;
2653
+ }
2654
+ if (lintPatchResult === "skipped-custom") {
2655
+ console.warn(
2656
+ "[fullstack-cli] \u26A0 Skipped patching scripts.lint because it has been customized"
2657
+ );
2658
+ }
2659
+ } catch (error) {
2660
+ const message = error instanceof Error ? error.message : String(error);
2661
+ console.warn(`[fullstack-cli] \u26A0 Could not patch package.json: ${message}`);
2662
+ }
2663
+ }
2565
2664
  async function syncRule(rule, pluginRoot, userProjectRoot) {
2566
2665
  if (rule.type === "delete-file" || rule.type === "delete-directory") {
2567
- const destPath2 = path4.join(userProjectRoot, rule.to);
2666
+ const destPath2 = path5.join(userProjectRoot, rule.to);
2568
2667
  if (rule.type === "delete-file") {
2569
2668
  deleteFile(destPath2);
2570
2669
  } else {
@@ -2573,32 +2672,32 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
2573
2672
  return;
2574
2673
  }
2575
2674
  if (rule.type === "remove-line") {
2576
- const destPath2 = path4.join(userProjectRoot, rule.to);
2675
+ const destPath2 = path5.join(userProjectRoot, rule.to);
2577
2676
  removeLineFromFile(destPath2, rule.pattern);
2578
2677
  return;
2579
2678
  }
2580
2679
  if (rule.type === "add-script") {
2581
- const packageJsonPath = path4.join(userProjectRoot, "package.json");
2680
+ const packageJsonPath = path5.join(userProjectRoot, "package.json");
2582
2681
  addScript(packageJsonPath, rule.name, rule.command, rule.overwrite ?? false);
2583
2682
  return;
2584
2683
  }
2585
2684
  if (rule.type === "add-line") {
2586
- const destPath2 = path4.join(userProjectRoot, rule.to);
2685
+ const destPath2 = path5.join(userProjectRoot, rule.to);
2587
2686
  addLineToFile(destPath2, rule.line);
2588
2687
  return;
2589
2688
  }
2590
2689
  if (rule.type === "merge-json") {
2591
- const srcPath2 = path4.join(pluginRoot, rule.from);
2592
- const destPath2 = path4.join(userProjectRoot, rule.to);
2690
+ const srcPath2 = path5.join(pluginRoot, rule.from);
2691
+ const destPath2 = path5.join(userProjectRoot, rule.to);
2593
2692
  mergeJsonFile(srcPath2, destPath2, rule.arrayMerge);
2594
2693
  return;
2595
2694
  }
2596
2695
  if (!("from" in rule)) {
2597
2696
  return;
2598
2697
  }
2599
- const srcPath = path4.join(pluginRoot, rule.from);
2600
- const destPath = path4.join(userProjectRoot, rule.to);
2601
- if (!fs6.existsSync(srcPath)) {
2698
+ const srcPath = path5.join(pluginRoot, rule.from);
2699
+ const destPath = path5.join(userProjectRoot, rule.to);
2700
+ if (!fs7.existsSync(srcPath)) {
2602
2701
  console.warn(`[fullstack-cli] Source not found: ${rule.from}`);
2603
2702
  return;
2604
2703
  }
@@ -2615,68 +2714,68 @@ async function syncRule(rule, pluginRoot, userProjectRoot) {
2615
2714
  }
2616
2715
  }
2617
2716
  function syncFile(src, dest, overwrite = true, onlyIfExists = false) {
2618
- if (onlyIfExists && !fs6.existsSync(dest)) {
2619
- console.log(`[fullstack-cli] \u25CB ${path4.basename(dest)} (skipped, target not exists)`);
2717
+ if (onlyIfExists && !fs7.existsSync(dest)) {
2718
+ console.log(`[fullstack-cli] \u25CB ${path5.basename(dest)} (skipped, target not exists)`);
2620
2719
  return;
2621
2720
  }
2622
- const destDir = path4.dirname(dest);
2623
- if (!fs6.existsSync(destDir)) {
2624
- fs6.mkdirSync(destDir, { recursive: true });
2721
+ const destDir = path5.dirname(dest);
2722
+ if (!fs7.existsSync(destDir)) {
2723
+ fs7.mkdirSync(destDir, { recursive: true });
2625
2724
  }
2626
- if (fs6.existsSync(dest) && !overwrite) {
2627
- console.log(`[fullstack-cli] \u25CB ${path4.basename(dest)} (skipped, already exists)`);
2725
+ if (fs7.existsSync(dest) && !overwrite) {
2726
+ console.log(`[fullstack-cli] \u25CB ${path5.basename(dest)} (skipped, already exists)`);
2628
2727
  return;
2629
2728
  }
2630
- fs6.copyFileSync(src, dest);
2631
- console.log(`[fullstack-cli] \u2713 ${path4.basename(dest)}`);
2729
+ fs7.copyFileSync(src, dest);
2730
+ console.log(`[fullstack-cli] \u2713 ${path5.basename(dest)}`);
2632
2731
  }
2633
2732
  function syncDirectory(src, dest, overwrite = true) {
2634
- if (!fs6.existsSync(dest)) {
2635
- fs6.mkdirSync(dest, { recursive: true });
2733
+ if (!fs7.existsSync(dest)) {
2734
+ fs7.mkdirSync(dest, { recursive: true });
2636
2735
  }
2637
- const files = fs6.readdirSync(src);
2736
+ const files = fs7.readdirSync(src);
2638
2737
  let count = 0;
2639
2738
  files.forEach((file) => {
2640
- const srcFile = path4.join(src, file);
2641
- const destFile = path4.join(dest, file);
2642
- const stats = fs6.statSync(srcFile);
2739
+ const srcFile = path5.join(src, file);
2740
+ const destFile = path5.join(dest, file);
2741
+ const stats = fs7.statSync(srcFile);
2643
2742
  if (stats.isDirectory()) {
2644
2743
  syncDirectory(srcFile, destFile, overwrite);
2645
2744
  } else {
2646
- if (overwrite || !fs6.existsSync(destFile)) {
2647
- fs6.copyFileSync(srcFile, destFile);
2648
- console.log(`[fullstack-cli] \u2713 ${path4.relative(dest, destFile)}`);
2745
+ if (overwrite || !fs7.existsSync(destFile)) {
2746
+ fs7.copyFileSync(srcFile, destFile);
2747
+ console.log(`[fullstack-cli] \u2713 ${path5.relative(dest, destFile)}`);
2649
2748
  count++;
2650
2749
  }
2651
2750
  }
2652
2751
  });
2653
2752
  if (count > 0) {
2654
- console.log(`[fullstack-cli] Synced ${count} files to ${path4.basename(dest)}/`);
2753
+ console.log(`[fullstack-cli] Synced ${count} files to ${path5.basename(dest)}/`);
2655
2754
  }
2656
2755
  }
2657
2756
  function appendToFile(src, dest) {
2658
- const content = fs6.readFileSync(src, "utf-8");
2757
+ const content = fs7.readFileSync(src, "utf-8");
2659
2758
  let existingContent = "";
2660
- if (fs6.existsSync(dest)) {
2661
- existingContent = fs6.readFileSync(dest, "utf-8");
2759
+ if (fs7.existsSync(dest)) {
2760
+ existingContent = fs7.readFileSync(dest, "utf-8");
2662
2761
  }
2663
2762
  if (existingContent.includes(content.trim())) {
2664
- console.log(`[fullstack-cli] \u25CB ${path4.basename(dest)} (already contains content)`);
2763
+ console.log(`[fullstack-cli] \u25CB ${path5.basename(dest)} (already contains content)`);
2665
2764
  return;
2666
2765
  }
2667
- fs6.appendFileSync(dest, content);
2668
- console.log(`[fullstack-cli] \u2713 ${path4.basename(dest)} (appended)`);
2766
+ fs7.appendFileSync(dest, content);
2767
+ console.log(`[fullstack-cli] \u2713 ${path5.basename(dest)} (appended)`);
2669
2768
  }
2670
2769
  function setPermissions(permissions, projectRoot) {
2671
2770
  for (const [pattern, mode] of Object.entries(permissions)) {
2672
2771
  if (pattern === "**/*.sh") {
2673
- const scriptsDir = path4.join(projectRoot, "scripts");
2674
- if (fs6.existsSync(scriptsDir)) {
2675
- const files = fs6.readdirSync(scriptsDir);
2772
+ const scriptsDir = path5.join(projectRoot, "scripts");
2773
+ if (fs7.existsSync(scriptsDir)) {
2774
+ const files = fs7.readdirSync(scriptsDir);
2676
2775
  files.forEach((file) => {
2677
2776
  if (file.endsWith(".sh")) {
2678
- const filePath = path4.join(scriptsDir, file);
2679
- fs6.chmodSync(filePath, mode);
2777
+ const filePath = path5.join(scriptsDir, file);
2778
+ fs7.chmodSync(filePath, mode);
2680
2779
  }
2681
2780
  });
2682
2781
  }
@@ -2684,27 +2783,27 @@ function setPermissions(permissions, projectRoot) {
2684
2783
  }
2685
2784
  }
2686
2785
  function deleteFile(filePath) {
2687
- if (fs6.existsSync(filePath)) {
2688
- fs6.unlinkSync(filePath);
2689
- console.log(`[fullstack-cli] \u2713 ${path4.basename(filePath)} (deleted)`);
2786
+ if (fs7.existsSync(filePath)) {
2787
+ fs7.unlinkSync(filePath);
2788
+ console.log(`[fullstack-cli] \u2713 ${path5.basename(filePath)} (deleted)`);
2690
2789
  } else {
2691
- console.log(`[fullstack-cli] \u25CB ${path4.basename(filePath)} (not found)`);
2790
+ console.log(`[fullstack-cli] \u25CB ${path5.basename(filePath)} (not found)`);
2692
2791
  }
2693
2792
  }
2694
2793
  function deleteDirectory(dirPath) {
2695
- if (fs6.existsSync(dirPath)) {
2696
- fs6.rmSync(dirPath, { recursive: true });
2697
- console.log(`[fullstack-cli] \u2713 ${path4.basename(dirPath)} (deleted)`);
2794
+ if (fs7.existsSync(dirPath)) {
2795
+ fs7.rmSync(dirPath, { recursive: true });
2796
+ console.log(`[fullstack-cli] \u2713 ${path5.basename(dirPath)} (deleted)`);
2698
2797
  } else {
2699
- console.log(`[fullstack-cli] \u25CB ${path4.basename(dirPath)} (not found)`);
2798
+ console.log(`[fullstack-cli] \u25CB ${path5.basename(dirPath)} (not found)`);
2700
2799
  }
2701
2800
  }
2702
2801
  function addScript(packageJsonPath, name, command, overwrite) {
2703
- if (!fs6.existsSync(packageJsonPath)) {
2802
+ if (!fs7.existsSync(packageJsonPath)) {
2704
2803
  console.log(`[fullstack-cli] \u25CB package.json (not found)`);
2705
2804
  return;
2706
2805
  }
2707
- const content = fs6.readFileSync(packageJsonPath, "utf-8");
2806
+ const content = fs7.readFileSync(packageJsonPath, "utf-8");
2708
2807
  const pkg2 = JSON.parse(content);
2709
2808
  if (!pkg2.scripts) {
2710
2809
  pkg2.scripts = {};
@@ -2716,42 +2815,42 @@ function addScript(packageJsonPath, name, command, overwrite) {
2716
2815
  }
2717
2816
  }
2718
2817
  pkg2.scripts[name] = command;
2719
- fs6.writeFileSync(packageJsonPath, JSON.stringify(pkg2, null, 2) + "\n");
2818
+ fs7.writeFileSync(packageJsonPath, JSON.stringify(pkg2, null, 2) + "\n");
2720
2819
  console.log(`[fullstack-cli] \u2713 scripts.${name}`);
2721
2820
  }
2722
2821
  function addLineToFile(filePath, line) {
2723
- const fileName = path4.basename(filePath);
2724
- if (!fs6.existsSync(filePath)) {
2822
+ const fileName = path5.basename(filePath);
2823
+ if (!fs7.existsSync(filePath)) {
2725
2824
  console.log(`[fullstack-cli] \u25CB ${fileName} (not found, skipped)`);
2726
2825
  return;
2727
2826
  }
2728
- const content = fs6.readFileSync(filePath, "utf-8");
2827
+ const content = fs7.readFileSync(filePath, "utf-8");
2729
2828
  const lines = content.split("\n").map((l) => l.trim());
2730
2829
  if (lines.includes(line)) {
2731
2830
  console.log(`[fullstack-cli] \u25CB ${fileName} (line already exists: ${line})`);
2732
2831
  return;
2733
2832
  }
2734
2833
  const appendContent = (content.endsWith("\n") ? "" : "\n") + line + "\n";
2735
- fs6.appendFileSync(filePath, appendContent);
2834
+ fs7.appendFileSync(filePath, appendContent);
2736
2835
  console.log(`[fullstack-cli] \u2713 ${fileName} (added: ${line})`);
2737
2836
  }
2738
2837
  function mergeJsonFile(src, dest, arrayMerge) {
2739
- const fileName = path4.basename(dest);
2740
- if (!fs6.existsSync(src)) {
2838
+ const fileName = path5.basename(dest);
2839
+ if (!fs7.existsSync(src)) {
2741
2840
  console.warn(`[fullstack-cli] Source not found: ${src}`);
2742
2841
  return;
2743
2842
  }
2744
- const templateContent = JSON.parse(fs6.readFileSync(src, "utf-8"));
2745
- if (!fs6.existsSync(dest)) {
2746
- const destDir = path4.dirname(dest);
2747
- if (!fs6.existsSync(destDir)) {
2748
- fs6.mkdirSync(destDir, { recursive: true });
2843
+ const templateContent = JSON.parse(fs7.readFileSync(src, "utf-8"));
2844
+ if (!fs7.existsSync(dest)) {
2845
+ const destDir = path5.dirname(dest);
2846
+ if (!fs7.existsSync(destDir)) {
2847
+ fs7.mkdirSync(destDir, { recursive: true });
2749
2848
  }
2750
- fs6.writeFileSync(dest, JSON.stringify(templateContent, null, 2) + "\n");
2849
+ fs7.writeFileSync(dest, JSON.stringify(templateContent, null, 2) + "\n");
2751
2850
  console.log(`[fullstack-cli] \u2713 ${fileName} (created)`);
2752
2851
  return;
2753
2852
  }
2754
- const userContent = JSON.parse(fs6.readFileSync(dest, "utf-8"));
2853
+ const userContent = JSON.parse(fs7.readFileSync(dest, "utf-8"));
2755
2854
  const merged = deepMergeJson(userContent, templateContent, arrayMerge ?? {});
2756
2855
  const userStr = JSON.stringify(userContent, null, 2);
2757
2856
  const mergedStr = JSON.stringify(merged, null, 2);
@@ -2759,7 +2858,7 @@ function mergeJsonFile(src, dest, arrayMerge) {
2759
2858
  console.log(`[fullstack-cli] \u25CB ${fileName} (already up to date)`);
2760
2859
  return;
2761
2860
  }
2762
- fs6.writeFileSync(dest, mergedStr + "\n");
2861
+ fs7.writeFileSync(dest, mergedStr + "\n");
2763
2862
  console.log(`[fullstack-cli] \u2713 ${fileName} (merged)`);
2764
2863
  }
2765
2864
 
@@ -2820,12 +2919,12 @@ async function reportCreateInstanceEvent(pluginKey, version) {
2820
2919
 
2821
2920
  // src/utils/git.ts
2822
2921
  import { execSync, spawnSync as spawnSync2 } from "child_process";
2823
- import fs7 from "fs";
2824
- import path5 from "path";
2922
+ import fs8 from "fs";
2923
+ import path6 from "path";
2825
2924
  function isGitRepository(cwd = process.cwd()) {
2826
2925
  try {
2827
- const gitDir = path5.join(cwd, ".git");
2828
- if (fs7.existsSync(gitDir)) {
2926
+ const gitDir = path6.join(cwd, ".git");
2927
+ if (fs8.existsSync(gitDir)) {
2829
2928
  return true;
2830
2929
  }
2831
2930
  const result = spawnSync2("git", ["rev-parse", "--git-dir"], {
@@ -2854,7 +2953,7 @@ function getChangedFiles(cwd = process.cwd()) {
2854
2953
  function gitAddUpgradeFiles(cwd = process.cwd(), filesToStage) {
2855
2954
  const filteredFiles = [];
2856
2955
  for (const filePath of filesToStage) {
2857
- if (fs7.existsSync(path5.join(cwd, filePath))) {
2956
+ if (fs8.existsSync(path6.join(cwd, filePath))) {
2858
2957
  filteredFiles.push(filePath);
2859
2958
  continue;
2860
2959
  }
@@ -2938,64 +3037,6 @@ Auto-committed by fullstack-cli`;
2938
3037
  }
2939
3038
  }
2940
3039
 
2941
- // src/utils/package-json.ts
2942
- import fs8 from "fs";
2943
- import path6 from "path";
2944
- function readPackageJson(cwd = process.cwd()) {
2945
- const pkgPath = path6.join(cwd, "package.json");
2946
- if (!fs8.existsSync(pkgPath)) {
2947
- throw new Error(`package.json not found at ${pkgPath}`);
2948
- }
2949
- const content = fs8.readFileSync(pkgPath, "utf-8");
2950
- return JSON.parse(content);
2951
- }
2952
- function writePackageJson(pkg2, cwd = process.cwd()) {
2953
- const pkgPath = path6.join(cwd, "package.json");
2954
- const content = JSON.stringify(pkg2, null, 2) + "\n";
2955
- fs8.writeFileSync(pkgPath, content, "utf-8");
2956
- }
2957
- function removeUpgradeScript(pkg2) {
2958
- if (!pkg2.scripts?.upgrade) {
2959
- return false;
2960
- }
2961
- delete pkg2.scripts.upgrade;
2962
- return true;
2963
- }
2964
- function cleanDevScript(pkg2) {
2965
- if (!pkg2.scripts?.dev) {
2966
- return false;
2967
- }
2968
- const originalDev = pkg2.scripts.dev;
2969
- const cleanedDev = originalDev.replace(/npm\s+run\s+upgrade\s*&&\s*/g, "").replace(/npm\s+run\s+upgrade\s*$/g, "").trim();
2970
- if (cleanedDev !== originalDev) {
2971
- pkg2.scripts.dev = cleanedDev;
2972
- return true;
2973
- }
2974
- return false;
2975
- }
2976
- function cleanupPackageJson(cwd = process.cwd()) {
2977
- try {
2978
- const pkg2 = readPackageJson(cwd);
2979
- let changed = false;
2980
- if (removeUpgradeScript(pkg2)) {
2981
- console.log("[fullstack-cli] \u2713 Removed scripts.upgrade");
2982
- changed = true;
2983
- }
2984
- if (cleanDevScript(pkg2)) {
2985
- console.log("[fullstack-cli] \u2713 Cleaned scripts.dev (removed npm run upgrade)");
2986
- changed = true;
2987
- }
2988
- if (changed) {
2989
- writePackageJson(pkg2, cwd);
2990
- }
2991
- return changed;
2992
- } catch (error) {
2993
- const message = error instanceof Error ? error.message : String(error);
2994
- console.log(`[fullstack-cli] \u26A0 Could not cleanup package.json: ${message}`);
2995
- return false;
2996
- }
2997
- }
2998
-
2999
3040
  // src/commands/upgrade/shared/utils.ts
3000
3041
  import path7 from "path";
3001
3042
  import fs9 from "fs";
@@ -7264,48 +7305,26 @@ var UPLOAD_STATIC_DEFAULTS = {
7264
7305
  };
7265
7306
 
7266
7307
  // src/commands/build/api-client.ts
7267
- var ERROR_RESPONSE_PREVIEW_LIMIT = 2e3;
7268
- async function getErrorResponseDetails(response) {
7269
- try {
7270
- if (typeof response.text === "function") {
7271
- const text = await response.text();
7272
- if (!text) {
7273
- return "";
7274
- }
7275
- return `, response: ${text.slice(0, ERROR_RESPONSE_PREVIEW_LIMIT)}`;
7276
- }
7277
- if (typeof response.json === "function") {
7278
- const data = await response.json();
7279
- const serialized = JSON.stringify(data);
7280
- if (!serialized) {
7281
- return "";
7282
- }
7283
- return `, response: ${serialized.slice(0, ERROR_RESPONSE_PREVIEW_LIMIT)}`;
7284
- }
7285
- } catch {
7286
- return "";
7287
- }
7288
- return "";
7289
- }
7290
- async function throwIfResponseNotOk(response, message) {
7291
- if (response.ok && response.status === 200) {
7292
- return;
7293
- }
7294
- const details = await getErrorResponseDetails(response);
7295
- throw new Error(`${message}: ${response.status} ${response.statusText}${details}`);
7296
- }
7297
7308
  async function genArtifactUploadCredential(appId, body) {
7298
7309
  const client = getHttpClient();
7299
7310
  const url = `/v1/app/${appId}/pipeline/gen_artifact_upload_credential`;
7300
7311
  const response = await client.post(url, body);
7301
- await throwIfResponseNotOk(response, "gen_artifact_upload_credential \u8BF7\u6C42\u5931\u8D25");
7312
+ if (!response.ok || response.status !== 200) {
7313
+ throw new Error(
7314
+ `gen_artifact_upload_credential \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
7315
+ );
7316
+ }
7302
7317
  return response.json();
7303
7318
  }
7304
7319
  async function getDefaultBucketId(appId) {
7305
7320
  const client = getHttpClient();
7306
7321
  const url = `/v1/app/${appId}/storage/inner/staticBucket`;
7307
7322
  const response = await client.post(url, {});
7308
- await throwIfResponseNotOk(response, "getOrCreateStaticBucket \u8BF7\u6C42\u5931\u8D25");
7323
+ if (!response.ok || response.status !== 200) {
7324
+ throw new Error(
7325
+ `getOrCreateStaticBucket \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
7326
+ );
7327
+ }
7309
7328
  const data = await response.json();
7310
7329
  if (data.status_code !== "0") {
7311
7330
  throw new Error(`getOrCreateStaticBucket \u8FD4\u56DE\u5F02\u5E38, status_code: ${data.status_code}`);
@@ -7320,14 +7339,22 @@ async function preUploadStaticAttachment(appId, bucketId) {
7320
7339
  const client = getHttpClient();
7321
7340
  const url = `/v1/app/${appId}/storage/bucket/${bucketId}/preUploadStatic`;
7322
7341
  const response = await client.post(url, {});
7323
- await throwIfResponseNotOk(response, "preUploadStatic \u8BF7\u6C42\u5931\u8D25");
7342
+ if (!response.ok || response.status !== 200) {
7343
+ throw new Error(
7344
+ `preUploadStatic \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
7345
+ );
7346
+ }
7324
7347
  return response.json();
7325
7348
  }
7326
7349
  async function uploadStaticAttachmentCallback(appId, bucketId, body) {
7327
7350
  const client = getHttpClient();
7328
7351
  const url = `/v1/app/${appId}/storage/bucket/${bucketId}/object/callbackStatic`;
7329
7352
  const response = await client.post(url, body);
7330
- await throwIfResponseNotOk(response, "callbackStatic \u8BF7\u6C42\u5931\u8D25");
7353
+ if (!response.ok || response.status !== 200) {
7354
+ throw new Error(
7355
+ `callbackStatic \u8BF7\u6C42\u5931\u8D25: ${response.status} ${response.statusText}`
7356
+ );
7357
+ }
7331
7358
  return response.json();
7332
7359
  }
7333
7360
 
@@ -7368,7 +7395,6 @@ import * as fs25 from "fs";
7368
7395
  import * as os2 from "os";
7369
7396
  import * as path21 from "path";
7370
7397
  import { execFileSync } from "child_process";
7371
- import { HttpError } from "@lark-apaas/http-client";
7372
7398
  function readCredentialsFromEnv() {
7373
7399
  const uploadPrefix = process.env.STATIC_UPLOAD_PREFIX;
7374
7400
  const uploadID = process.env.STATIC_UPLOAD_ID;
@@ -7448,7 +7474,7 @@ async function uploadStatic(options) {
7448
7474
  console.error(`${LOG_PREFIX} \u8C03\u7528 callbackStatic (uploadID: ${uploadID})...`);
7449
7475
  const callbackResp = await uploadStaticAttachmentCallback(appId, bucketId, { uploadID });
7450
7476
  if (callbackResp.status_code !== "0") {
7451
- throw new Error(`callbackStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${callbackResp.status_code}, response: ${JSON.stringify(callbackResp)}`);
7477
+ throw new Error(`callbackStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${callbackResp.status_code}`);
7452
7478
  }
7453
7479
  const attachments = callbackResp.data?.attachments || [];
7454
7480
  console.error(`${LOG_PREFIX} \u4E0A\u4F20\u5B8C\u6210\uFF0C\u5171 ${attachments.length} \u4E2A\u6587\u4EF6`);
@@ -7456,23 +7482,7 @@ async function uploadStatic(options) {
7456
7482
  } catch (error) {
7457
7483
  const message = error instanceof Error ? error.message : String(error);
7458
7484
  console.error(`${LOG_PREFIX} Error: ${message}`);
7459
- if (error instanceof HttpError && error.response) {
7460
- const logId = error.response.headers.get("x-tt-logid") || error.response.headers.get("X-Tt-Logid");
7461
- if (logId) {
7462
- console.error(`${LOG_PREFIX} logid: ${logId}`);
7463
- }
7464
- try {
7465
- const responseText = await error.response.text();
7466
- if (responseText) {
7467
- console.error(`${LOG_PREFIX} response: ${responseText}`);
7468
- }
7469
- } catch {
7470
- }
7471
- if (error.config?.url) {
7472
- console.error(`${LOG_PREFIX} request url: ${error.config.url}`);
7473
- }
7474
- }
7475
- process.exitCode = 1;
7485
+ process.exit(1);
7476
7486
  }
7477
7487
  }
7478
7488
  function resolveTosutilPath(tosutilPath) {
@@ -7489,14 +7499,14 @@ function resolveTosutilPath(tosutilPath) {
7489
7499
  async function fetchPreUpload(appId, bucketId) {
7490
7500
  const response = await preUploadStaticAttachment(appId, bucketId);
7491
7501
  if (response.status_code !== "0") {
7492
- throw new Error(`preUploadStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${response.status_code}, response: ${JSON.stringify(response)}`);
7502
+ throw new Error(`preUploadStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${response.status_code}`);
7493
7503
  }
7494
7504
  const { uploadPrefix, uploadID, uploadCredential } = response.data || {};
7495
7505
  if (!uploadPrefix || !uploadID) {
7496
- throw new Error(`preUploadStatic \u8FD4\u56DE\u6570\u636E\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11 uploadPrefix \u6216 uploadID, response: ${JSON.stringify(response)}`);
7506
+ throw new Error("preUploadStatic \u8FD4\u56DE\u6570\u636E\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11 uploadPrefix \u6216 uploadID");
7497
7507
  }
7498
7508
  if (!uploadCredential?.AccessKeyID || !uploadCredential?.SecretAccessKey || !uploadCredential?.SessionToken) {
7499
- throw new Error(`preUploadStatic \u8FD4\u56DE\u7684\u51ED\u8BC1\u5B57\u6BB5\u4E0D\u5B8C\u6574, response: ${JSON.stringify(response)}`);
7509
+ throw new Error("preUploadStatic \u8FD4\u56DE\u7684\u51ED\u8BC1\u5B57\u6BB5\u4E0D\u5B8C\u6574");
7500
7510
  }
7501
7511
  return response;
7502
7512
  }
@@ -7541,18 +7551,15 @@ async function preUploadStatic(options) {
7541
7551
  const response = await preUploadStaticAttachment(appId, bucketId);
7542
7552
  if (response.status_code !== "0") {
7543
7553
  console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u5F02\u5E38, status_code: ${response.status_code}`);
7544
- console.error(`${LOG_PREFIX2} preUploadStatic \u54CD\u5E94: ${JSON.stringify(response)}`);
7545
7554
  return;
7546
7555
  }
7547
7556
  const { downloadURLPrefix, uploadPrefix, uploadID, uploadCredential } = response.data || {};
7548
7557
  if (!downloadURLPrefix || !uploadPrefix || !uploadID) {
7549
7558
  console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u6570\u636E\u4E0D\u5B8C\u6574`);
7550
- console.error(`${LOG_PREFIX2} preUploadStatic \u54CD\u5E94: ${JSON.stringify(response)}`);
7551
7559
  return;
7552
7560
  }
7553
7561
  if (!uploadCredential?.AccessKeyID || !uploadCredential?.SecretAccessKey || !uploadCredential?.SessionToken) {
7554
7562
  console.error(`${LOG_PREFIX2} preUploadStatic \u8FD4\u56DE\u7684\u51ED\u8BC1\u5B57\u6BB5\u4E0D\u5B8C\u6574`);
7555
- console.error(`${LOG_PREFIX2} preUploadStatic \u54CD\u5E94: ${JSON.stringify(response)}`);
7556
7563
  return;
7557
7564
  }
7558
7565
  console.log(`export STATIC_ASSETS_BASE_URL="${shellEscape(downloadURLPrefix)}"`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/fullstack-cli",
3
- "version": "1.1.35",
3
+ "version": "1.1.36",
4
4
  "description": "CLI tool for fullstack template management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('node:path');
4
+ const { spawn } = require('node:child_process');
5
+ const fs = require('node:fs');
6
+
7
+ const cwd = process.cwd();
8
+
9
+ function getBinName(name) {
10
+ return process.platform === 'win32' ? `${name}.cmd` : name;
11
+ }
12
+
13
+ function runCommand(command, args) {
14
+ return new Promise((resolve) => {
15
+ const child = spawn(command, args, {
16
+ cwd,
17
+ stdio: 'inherit',
18
+ shell: false,
19
+ });
20
+
21
+ child.on('close', (code) => resolve(code || 0));
22
+ child.on('error', () => resolve(1));
23
+ });
24
+ }
25
+
26
+ function normalizeProjectFile(filePath) {
27
+ const absolutePath = path.isAbsolute(filePath)
28
+ ? filePath
29
+ : path.resolve(cwd, filePath);
30
+
31
+ if (!fs.existsSync(absolutePath)) {
32
+ console.warn(`[lint] Skip missing file: ${filePath}`);
33
+ return null;
34
+ }
35
+
36
+ const relativePath = path.relative(cwd, absolutePath);
37
+ if (relativePath.startsWith('..')) {
38
+ console.warn(`[lint] Skip file outside project: ${filePath}`);
39
+ return null;
40
+ }
41
+
42
+ return relativePath.split(path.sep).join('/');
43
+ }
44
+
45
+ function parseFilesArg(argv) {
46
+ const filesIndex = argv.indexOf('--files');
47
+ if (filesIndex === -1) {
48
+ return null;
49
+ }
50
+
51
+ return argv.slice(filesIndex + 1).filter(Boolean);
52
+ }
53
+
54
+ function isEslintTarget(filePath) {
55
+ return /\.(c|m)?(j|t)sx?$/.test(filePath);
56
+ }
57
+
58
+ function isTypeCheckTarget(filePath) {
59
+ return /\.(ts|tsx|mts|cts)$/.test(filePath);
60
+ }
61
+
62
+ function isStylelintTarget(filePath) {
63
+ return filePath.endsWith('.css');
64
+ }
65
+
66
+ async function runDefaultLint() {
67
+ const code = await runCommand(getBinName('npx'), [
68
+ 'concurrently',
69
+ 'npm run eslint',
70
+ 'npm run type:check',
71
+ 'npm run stylelint',
72
+ ]);
73
+ process.exit(code);
74
+ }
75
+
76
+ async function runSelectiveLint(inputFiles) {
77
+ const normalizedFiles = Array.from(
78
+ new Set(inputFiles.map(normalizeProjectFile).filter(Boolean)),
79
+ );
80
+
81
+ if (normalizedFiles.length === 0) {
82
+ console.log('[lint] No supported project files found');
83
+ process.exit(0);
84
+ }
85
+
86
+ const eslintFiles = normalizedFiles.filter(isEslintTarget);
87
+ const stylelintFiles = normalizedFiles.filter(isStylelintTarget);
88
+ const typeCheckFiles = normalizedFiles.filter(isTypeCheckTarget);
89
+
90
+ const clientTypeFiles = [];
91
+ const serverTypeFiles = [];
92
+
93
+ for (const filePath of typeCheckFiles) {
94
+ if (filePath.startsWith('client/')) {
95
+ clientTypeFiles.push(filePath);
96
+ } else if (filePath.startsWith('server/')) {
97
+ serverTypeFiles.push(filePath);
98
+ } else if (filePath.startsWith('shared/')) {
99
+ clientTypeFiles.push(filePath);
100
+ serverTypeFiles.push(filePath);
101
+ }
102
+ }
103
+
104
+ const tasks = [];
105
+
106
+ if (eslintFiles.length > 0) {
107
+ tasks.push(runCommand(getBinName('npx'), ['eslint', '--quiet', ...eslintFiles]));
108
+ }
109
+
110
+ if (stylelintFiles.length > 0) {
111
+ tasks.push(runCommand(getBinName('npx'), ['stylelint', '--quiet', ...stylelintFiles]));
112
+ }
113
+
114
+ if (clientTypeFiles.length > 0) {
115
+ tasks.push(runCommand(getBinName('npm'), ['run', 'type:check:client']));
116
+ }
117
+
118
+ if (serverTypeFiles.length > 0) {
119
+ tasks.push(runCommand(getBinName('npm'), ['run', 'type:check:server']));
120
+ }
121
+
122
+ if (tasks.length === 0) {
123
+ console.log('[lint] No supported files matched for lint');
124
+ process.exit(0);
125
+ }
126
+
127
+ const results = await Promise.all(tasks);
128
+ process.exit(results.some(code => code !== 0) ? 1 : 0);
129
+ }
130
+
131
+ async function main() {
132
+ const files = parseFilesArg(process.argv.slice(2));
133
+ if (files === null) {
134
+ await runDefaultLint();
135
+ return;
136
+ }
137
+
138
+ if (files.length === 0) {
139
+ console.error('[lint] --files requires at least one file path');
140
+ process.exit(1);
141
+ }
142
+
143
+ await runSelectiveLint(files);
144
+ }
145
+
146
+ main().catch((error) => {
147
+ const message = error instanceof Error ? error.message : String(error);
148
+ console.error(`[lint] Failed to run lint: ${message}`);
149
+ process.exit(1);
150
+ });