@lark-apaas/fullstack-cli 1.1.20 → 1.1.22
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 +417 -104
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import fs22 from "fs";
|
|
3
|
+
import path18 from "path";
|
|
4
4
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
5
5
|
import { config as dotenvConfig } from "dotenv";
|
|
6
6
|
|
|
@@ -3452,59 +3452,344 @@ var capabilityCommandGroup = {
|
|
|
3452
3452
|
commands: [listCommand2]
|
|
3453
3453
|
};
|
|
3454
3454
|
|
|
3455
|
-
// src/commands/
|
|
3455
|
+
// src/commands/component/registry-preparer.ts
|
|
3456
3456
|
import fs10 from "fs";
|
|
3457
3457
|
import path8 from "path";
|
|
3458
|
+
import os from "os";
|
|
3459
|
+
|
|
3460
|
+
// src/commands/component/service.ts
|
|
3461
|
+
import { mapValues } from "es-toolkit";
|
|
3462
|
+
|
|
3463
|
+
// src/commands/component/utils.ts
|
|
3464
|
+
import createDebug from "debug";
|
|
3465
|
+
var debug = createDebug("component");
|
|
3466
|
+
|
|
3467
|
+
// src/commands/component/service.ts
|
|
3468
|
+
async function getComponents(keys) {
|
|
3469
|
+
const client = getHttpClient();
|
|
3470
|
+
debug("\u8C03\u7528 /components/batch_get %o", keys);
|
|
3471
|
+
const response = await client.post(
|
|
3472
|
+
`/api/v1/studio/innerapi/components/batch_get?keys=${keys.join(",")}`
|
|
3473
|
+
);
|
|
3474
|
+
if (response.status !== 200) {
|
|
3475
|
+
throw new Error(
|
|
3476
|
+
`\u83B7\u53D6\u7EC4\u4EF6\u4FE1\u606F\u5931\u8D25\uFF1A${response.status} ${response.statusText}`
|
|
3477
|
+
);
|
|
3478
|
+
}
|
|
3479
|
+
const result = await response.json();
|
|
3480
|
+
if (result.status_code !== "0") {
|
|
3481
|
+
debug("\u63A5\u53E3\u8FD4\u56DE\u9519\u8BEF\uFF1A%o", result);
|
|
3482
|
+
throw new Error(`\u83B7\u53D6\u7EC4\u4EF6\u4FE1\u606F\u5931\u8D25\uFF1A${result.error_msg}`);
|
|
3483
|
+
}
|
|
3484
|
+
return mapValues(result.data.components, ([component]) => component);
|
|
3485
|
+
}
|
|
3486
|
+
async function getRegistryItem(url) {
|
|
3487
|
+
const client = getHttpClient();
|
|
3488
|
+
debug("\u4E0B\u8F7D registry-item.json\uFF1A%s", url);
|
|
3489
|
+
const response = await client.get(url);
|
|
3490
|
+
if (!response.ok) {
|
|
3491
|
+
throw new Error(
|
|
3492
|
+
`\u4E0B\u8F7D registry-item.json \u5931\u8D25\uFF1A${response.status} ${response.statusText}`
|
|
3493
|
+
);
|
|
3494
|
+
}
|
|
3495
|
+
const item = await response.json();
|
|
3496
|
+
return item;
|
|
3497
|
+
}
|
|
3498
|
+
async function sendInstallEvent(key) {
|
|
3499
|
+
const client = getHttpClient();
|
|
3500
|
+
await client.post("/api/v1/studio/innerapi/resource_events", {
|
|
3501
|
+
events: [
|
|
3502
|
+
{
|
|
3503
|
+
resourceType: "component",
|
|
3504
|
+
resourceKey: key,
|
|
3505
|
+
eventType: "install",
|
|
3506
|
+
details: {}
|
|
3507
|
+
}
|
|
3508
|
+
]
|
|
3509
|
+
});
|
|
3510
|
+
}
|
|
3511
|
+
|
|
3512
|
+
// src/commands/component/registry-preparer.ts
|
|
3513
|
+
var REGISTRY_TEMP_DIR = path8.join(os.tmpdir(), "miaoda-registry");
|
|
3514
|
+
function parseComponentKey(key) {
|
|
3515
|
+
const match = key.match(/^@([^/]+)\/(.+)$/);
|
|
3516
|
+
if (!match) {
|
|
3517
|
+
throw new Error(
|
|
3518
|
+
`Invalid component key format: ${key}. Expected format: @scope/name`
|
|
3519
|
+
);
|
|
3520
|
+
}
|
|
3521
|
+
return { scope: match[1], name: match[2] };
|
|
3522
|
+
}
|
|
3523
|
+
function getLocalRegistryPath(key) {
|
|
3524
|
+
const { scope, name } = parseComponentKey(key);
|
|
3525
|
+
return path8.join(REGISTRY_TEMP_DIR, scope, `${name}.json`);
|
|
3526
|
+
}
|
|
3527
|
+
function ensureDir(dirPath) {
|
|
3528
|
+
if (!fs10.existsSync(dirPath)) {
|
|
3529
|
+
fs10.mkdirSync(dirPath, { recursive: true });
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
async function prepareRecursive(key, visited) {
|
|
3533
|
+
if (visited.has(key)) {
|
|
3534
|
+
debug("\u8DF3\u8FC7\u5DF2\u5904\u7406\u7684\u7EC4\u4EF6: %s", key);
|
|
3535
|
+
return;
|
|
3536
|
+
}
|
|
3537
|
+
visited.add(key);
|
|
3538
|
+
debug("\u5904\u7406\u7EC4\u4EF6: %s", key);
|
|
3539
|
+
debug("\u83B7\u53D6\u7EC4\u4EF6\u4E0B\u8F7D\u4FE1\u606F...");
|
|
3540
|
+
const infoMap = await getComponents([key]);
|
|
3541
|
+
const info = infoMap[key];
|
|
3542
|
+
debug("\u7EC4\u4EF6\u4FE1\u606F: %o", info);
|
|
3543
|
+
if (!info) {
|
|
3544
|
+
throw new Error(`Component not found: ${key}`);
|
|
3545
|
+
}
|
|
3546
|
+
if (info.status !== "active") {
|
|
3547
|
+
throw new Error(`Component is not active: ${key}`);
|
|
3548
|
+
}
|
|
3549
|
+
debug("\u4E0B\u8F7D registry item: %s", info.downloadURL);
|
|
3550
|
+
const registryItem = await getRegistryItem(info.downloadURL);
|
|
3551
|
+
debug("registry item \u5185\u5BB9: %o", registryItem);
|
|
3552
|
+
const deps = registryItem.registryDependencies || [];
|
|
3553
|
+
debug("\u4F9D\u8D56\u5217\u8868: %o", deps);
|
|
3554
|
+
for (const dep of deps) {
|
|
3555
|
+
await prepareRecursive(dep, visited);
|
|
3556
|
+
}
|
|
3557
|
+
const rewrittenItem = {
|
|
3558
|
+
...registryItem,
|
|
3559
|
+
registryDependencies: deps.map((dep) => getLocalRegistryPath(dep))
|
|
3560
|
+
};
|
|
3561
|
+
const localPath = getLocalRegistryPath(key);
|
|
3562
|
+
ensureDir(path8.dirname(localPath));
|
|
3563
|
+
fs10.writeFileSync(localPath, JSON.stringify(rewrittenItem, null, 2), "utf-8");
|
|
3564
|
+
debug("\u4FDD\u5B58\u5230: %s", localPath);
|
|
3565
|
+
}
|
|
3566
|
+
async function prepareComponentRegistryItems(id) {
|
|
3567
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3568
|
+
await prepareRecursive(id, visited);
|
|
3569
|
+
return getLocalRegistryPath(id);
|
|
3570
|
+
}
|
|
3571
|
+
function cleanupTempDir() {
|
|
3572
|
+
try {
|
|
3573
|
+
if (fs10.existsSync(REGISTRY_TEMP_DIR)) {
|
|
3574
|
+
fs10.rmSync(REGISTRY_TEMP_DIR, { recursive: true, force: true });
|
|
3575
|
+
}
|
|
3576
|
+
} catch {
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
function getDownloadedRegistryItem(itemId) {
|
|
3580
|
+
const localPath = getLocalRegistryPath(itemId);
|
|
3581
|
+
if (!fs10.existsSync(localPath)) {
|
|
3582
|
+
return null;
|
|
3583
|
+
}
|
|
3584
|
+
const content = fs10.readFileSync(localPath, "utf-8");
|
|
3585
|
+
return JSON.parse(content);
|
|
3586
|
+
}
|
|
3587
|
+
|
|
3588
|
+
// src/commands/component/shadcn-executor.ts
|
|
3589
|
+
import * as pty from "@lydell/node-pty";
|
|
3590
|
+
function parseOutput(output) {
|
|
3591
|
+
const state = {
|
|
3592
|
+
currentSection: null,
|
|
3593
|
+
files: /* @__PURE__ */ new Set()
|
|
3594
|
+
};
|
|
3595
|
+
const lines = output.split("\n");
|
|
3596
|
+
for (const line of lines) {
|
|
3597
|
+
const trimmedLine = line.trim();
|
|
3598
|
+
if (/Created \d+ files?:/.test(trimmedLine)) {
|
|
3599
|
+
state.currentSection = "created";
|
|
3600
|
+
continue;
|
|
3601
|
+
}
|
|
3602
|
+
if (/Updated \d+ files?:/.test(trimmedLine)) {
|
|
3603
|
+
state.currentSection = "updated";
|
|
3604
|
+
continue;
|
|
3605
|
+
}
|
|
3606
|
+
if (/Skipped \d+ files?:/.test(trimmedLine)) {
|
|
3607
|
+
state.currentSection = "skipped";
|
|
3608
|
+
continue;
|
|
3609
|
+
}
|
|
3610
|
+
if (state.currentSection && trimmedLine.startsWith("- ")) {
|
|
3611
|
+
const filePath = trimmedLine.slice(2).trim();
|
|
3612
|
+
if (filePath && filePath.includes("/")) {
|
|
3613
|
+
state.files.add(filePath);
|
|
3614
|
+
}
|
|
3615
|
+
}
|
|
3616
|
+
if (state.currentSection && trimmedLine.length > 1 && !trimmedLine.startsWith("- ")) {
|
|
3617
|
+
state.currentSection = null;
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
return Array.from(state.files);
|
|
3621
|
+
}
|
|
3622
|
+
function toFileInfo(filePath) {
|
|
3623
|
+
const name = filePath.split("/").pop() || filePath;
|
|
3624
|
+
return { name, path: filePath };
|
|
3625
|
+
}
|
|
3626
|
+
var PROMPT_PATTERNS = [
|
|
3627
|
+
// 文件覆盖确认 - 回答 n(不覆盖)
|
|
3628
|
+
{ pattern: /overwrite/i, answer: "n\n" },
|
|
3629
|
+
// 主题/样式选择 - 回答 n(不安装额外主题)
|
|
3630
|
+
{ pattern: /theme/i, answer: "n\n" },
|
|
3631
|
+
{ pattern: /style/i, answer: "n\n" },
|
|
3632
|
+
// 继续确认 - 回答 y
|
|
3633
|
+
{ pattern: /continue\?/i, answer: "y\n" },
|
|
3634
|
+
{ pattern: /proceed\?/i, answer: "y\n" }
|
|
3635
|
+
];
|
|
3636
|
+
async function executeShadcnAdd(registryItemPath) {
|
|
3637
|
+
return new Promise((resolve) => {
|
|
3638
|
+
let output = "";
|
|
3639
|
+
const args = ["--yes", "shadcn@3.8.2", "add", registryItemPath];
|
|
3640
|
+
const ptyProcess = pty.spawn("npx", args, {
|
|
3641
|
+
name: "xterm-color",
|
|
3642
|
+
cols: 120,
|
|
3643
|
+
rows: 30,
|
|
3644
|
+
cwd: process.cwd(),
|
|
3645
|
+
env: {
|
|
3646
|
+
...process.env,
|
|
3647
|
+
// 禁用颜色输出以便解析
|
|
3648
|
+
NO_COLOR: "1",
|
|
3649
|
+
FORCE_COLOR: "0"
|
|
3650
|
+
}
|
|
3651
|
+
});
|
|
3652
|
+
ptyProcess.onData((data) => {
|
|
3653
|
+
output += data;
|
|
3654
|
+
for (const { pattern, answer } of PROMPT_PATTERNS) {
|
|
3655
|
+
if (pattern.test(data)) {
|
|
3656
|
+
ptyProcess.write(answer);
|
|
3657
|
+
return;
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3660
|
+
});
|
|
3661
|
+
const timeoutId = setTimeout(() => {
|
|
3662
|
+
ptyProcess.kill();
|
|
3663
|
+
resolve({
|
|
3664
|
+
success: false,
|
|
3665
|
+
files: [],
|
|
3666
|
+
error: "\u6267\u884C\u8D85\u65F6"
|
|
3667
|
+
});
|
|
3668
|
+
}, 3 * 60 * 1e3);
|
|
3669
|
+
ptyProcess.onExit(({ exitCode }) => {
|
|
3670
|
+
clearTimeout(timeoutId);
|
|
3671
|
+
const success = exitCode === 0;
|
|
3672
|
+
const filePaths = parseOutput(output);
|
|
3673
|
+
const files = filePaths.map(toFileInfo);
|
|
3674
|
+
resolve({
|
|
3675
|
+
success,
|
|
3676
|
+
files,
|
|
3677
|
+
error: success ? void 0 : output || `Process exited with code ${exitCode}`
|
|
3678
|
+
});
|
|
3679
|
+
});
|
|
3680
|
+
});
|
|
3681
|
+
}
|
|
3682
|
+
|
|
3683
|
+
// src/commands/component/add.handler.ts
|
|
3684
|
+
function printResult(result) {
|
|
3685
|
+
console.log(JSON.stringify(result, null, 2));
|
|
3686
|
+
}
|
|
3687
|
+
async function addComponent(key) {
|
|
3688
|
+
debug("\u5F00\u59CB\u5B89\u88C5\u7EC4\u4EF6: %s", key);
|
|
3689
|
+
debug("\u51C6\u5907 registry items...");
|
|
3690
|
+
const registryItemPath = await prepareComponentRegistryItems(key);
|
|
3691
|
+
debug("registry item \u8DEF\u5F84: %s", registryItemPath);
|
|
3692
|
+
const registryItem = getDownloadedRegistryItem(key);
|
|
3693
|
+
debug("\u83B7\u53D6\u5230 registry item: %o", registryItem);
|
|
3694
|
+
debug("\u6267\u884C shadcn add...");
|
|
3695
|
+
const executeResult = await executeShadcnAdd(registryItemPath);
|
|
3696
|
+
debug("shadcn \u6267\u884C\u7ED3\u679C: %o", executeResult);
|
|
3697
|
+
if (!executeResult.success) {
|
|
3698
|
+
throw new Error(executeResult.error || "\u5B89\u88C5\u5931\u8D25\uFF0C\u672A\u77E5\u539F\u56E0");
|
|
3699
|
+
}
|
|
3700
|
+
return {
|
|
3701
|
+
success: true,
|
|
3702
|
+
name: key,
|
|
3703
|
+
description: registryItem?.description || "",
|
|
3704
|
+
files: executeResult.files,
|
|
3705
|
+
docs: registryItem?.docs || ""
|
|
3706
|
+
};
|
|
3707
|
+
}
|
|
3708
|
+
async function add(key) {
|
|
3709
|
+
try {
|
|
3710
|
+
const result = await addComponent(key);
|
|
3711
|
+
printResult(result);
|
|
3712
|
+
void sendInstallEvent(key);
|
|
3713
|
+
} catch (error) {
|
|
3714
|
+
const errorMessage = error instanceof Error ? error.message : "\u5B89\u88C5\u5931\u8D25\uFF0C\u539F\u56E0\u672A\u77E5";
|
|
3715
|
+
printResult({
|
|
3716
|
+
success: false,
|
|
3717
|
+
errors: [{ message: errorMessage }]
|
|
3718
|
+
});
|
|
3719
|
+
} finally {
|
|
3720
|
+
cleanupTempDir();
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3723
|
+
|
|
3724
|
+
// src/commands/component/index.ts
|
|
3725
|
+
var addCommand = {
|
|
3726
|
+
name: "add",
|
|
3727
|
+
description: "\u5B89\u88C5\u5999\u642D\u7EC4\u4EF6\u5E02\u573A\u4E2D\u7684\u7EC4\u4EF6",
|
|
3728
|
+
register(program) {
|
|
3729
|
+
program.command(this.name).description(this.description).argument("<component>", "\u7EC4\u4EF6 ID (\u4F8B\u5982 @miaoda/button)").action(async (component) => {
|
|
3730
|
+
await add(component);
|
|
3731
|
+
});
|
|
3732
|
+
}
|
|
3733
|
+
};
|
|
3734
|
+
var componentCommandGroup = {
|
|
3735
|
+
name: "component",
|
|
3736
|
+
description: "\u7EC4\u4EF6\u76F8\u5173\u547D\u4EE4",
|
|
3737
|
+
commands: [addCommand]
|
|
3738
|
+
};
|
|
3739
|
+
|
|
3740
|
+
// src/commands/migration/version-manager.ts
|
|
3741
|
+
import fs11 from "fs";
|
|
3742
|
+
import path9 from "path";
|
|
3458
3743
|
var PACKAGE_JSON = "package.json";
|
|
3459
3744
|
var VERSION_FIELD = "migrationVersion";
|
|
3460
3745
|
function getPackageJsonPath2() {
|
|
3461
|
-
return
|
|
3746
|
+
return path9.join(process.cwd(), PACKAGE_JSON);
|
|
3462
3747
|
}
|
|
3463
3748
|
function getCurrentVersion() {
|
|
3464
3749
|
const pkgPath = getPackageJsonPath2();
|
|
3465
|
-
if (!
|
|
3750
|
+
if (!fs11.existsSync(pkgPath)) {
|
|
3466
3751
|
throw new Error("package.json not found");
|
|
3467
3752
|
}
|
|
3468
|
-
const pkg2 = JSON.parse(
|
|
3753
|
+
const pkg2 = JSON.parse(fs11.readFileSync(pkgPath, "utf-8"));
|
|
3469
3754
|
return pkg2[VERSION_FIELD] ?? 0;
|
|
3470
3755
|
}
|
|
3471
3756
|
function setCurrentVersion(version) {
|
|
3472
3757
|
const pkgPath = getPackageJsonPath2();
|
|
3473
|
-
const pkg2 = JSON.parse(
|
|
3758
|
+
const pkg2 = JSON.parse(fs11.readFileSync(pkgPath, "utf-8"));
|
|
3474
3759
|
pkg2[VERSION_FIELD] = version;
|
|
3475
|
-
|
|
3760
|
+
fs11.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
|
|
3476
3761
|
}
|
|
3477
3762
|
|
|
3478
3763
|
// src/commands/migration/versions/v001_capability/json-migrator/detector.ts
|
|
3479
|
-
import
|
|
3480
|
-
import
|
|
3764
|
+
import fs13 from "fs";
|
|
3765
|
+
import path11 from "path";
|
|
3481
3766
|
|
|
3482
3767
|
// src/commands/migration/versions/v001_capability/utils.ts
|
|
3483
|
-
import
|
|
3484
|
-
import
|
|
3768
|
+
import fs12 from "fs";
|
|
3769
|
+
import path10 from "path";
|
|
3485
3770
|
var CAPABILITIES_DIR2 = "server/capabilities";
|
|
3486
3771
|
function getProjectRoot3() {
|
|
3487
3772
|
return process.cwd();
|
|
3488
3773
|
}
|
|
3489
3774
|
function getCapabilitiesDir2() {
|
|
3490
|
-
return
|
|
3775
|
+
return path10.join(getProjectRoot3(), CAPABILITIES_DIR2);
|
|
3491
3776
|
}
|
|
3492
3777
|
function getPluginManifestPath2(pluginKey) {
|
|
3493
|
-
return
|
|
3778
|
+
return path10.join(getProjectRoot3(), "node_modules", pluginKey, "manifest.json");
|
|
3494
3779
|
}
|
|
3495
3780
|
|
|
3496
3781
|
// src/commands/migration/versions/v001_capability/json-migrator/detector.ts
|
|
3497
3782
|
function detectJsonMigration() {
|
|
3498
3783
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
3499
|
-
const oldFilePath =
|
|
3500
|
-
if (!
|
|
3784
|
+
const oldFilePath = path11.join(capabilitiesDir, "capabilities.json");
|
|
3785
|
+
if (!fs13.existsSync(oldFilePath)) {
|
|
3501
3786
|
return {
|
|
3502
3787
|
needsMigration: false,
|
|
3503
3788
|
reason: "capabilities.json not found"
|
|
3504
3789
|
};
|
|
3505
3790
|
}
|
|
3506
3791
|
try {
|
|
3507
|
-
const content =
|
|
3792
|
+
const content = fs13.readFileSync(oldFilePath, "utf-8");
|
|
3508
3793
|
const parsed = JSON.parse(content);
|
|
3509
3794
|
if (!Array.isArray(parsed)) {
|
|
3510
3795
|
return {
|
|
@@ -3555,8 +3840,8 @@ async function check(options) {
|
|
|
3555
3840
|
}
|
|
3556
3841
|
|
|
3557
3842
|
// src/commands/migration/versions/v001_capability/json-migrator/index.ts
|
|
3558
|
-
import
|
|
3559
|
-
import
|
|
3843
|
+
import fs14 from "fs";
|
|
3844
|
+
import path12 from "path";
|
|
3560
3845
|
|
|
3561
3846
|
// src/commands/migration/versions/v001_capability/mapping.ts
|
|
3562
3847
|
var DEFAULT_PLUGIN_VERSION = "1.0.0";
|
|
@@ -3786,18 +4071,18 @@ function transformCapabilities(oldCapabilities) {
|
|
|
3786
4071
|
// src/commands/migration/versions/v001_capability/json-migrator/index.ts
|
|
3787
4072
|
function loadExistingCapabilities() {
|
|
3788
4073
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
3789
|
-
if (!
|
|
4074
|
+
if (!fs14.existsSync(capabilitiesDir)) {
|
|
3790
4075
|
return [];
|
|
3791
4076
|
}
|
|
3792
|
-
const files =
|
|
4077
|
+
const files = fs14.readdirSync(capabilitiesDir);
|
|
3793
4078
|
const capabilities = [];
|
|
3794
4079
|
for (const file of files) {
|
|
3795
4080
|
if (file === "capabilities.json" || !file.endsWith(".json")) {
|
|
3796
4081
|
continue;
|
|
3797
4082
|
}
|
|
3798
4083
|
try {
|
|
3799
|
-
const filePath =
|
|
3800
|
-
const content =
|
|
4084
|
+
const filePath = path12.join(capabilitiesDir, file);
|
|
4085
|
+
const content = fs14.readFileSync(filePath, "utf-8");
|
|
3801
4086
|
const capability = JSON.parse(content);
|
|
3802
4087
|
if (capability.id && capability.pluginKey) {
|
|
3803
4088
|
capabilities.push(capability);
|
|
@@ -3855,9 +4140,9 @@ async function migrateJsonFiles(options) {
|
|
|
3855
4140
|
}
|
|
3856
4141
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
3857
4142
|
for (const cap of newCapabilities) {
|
|
3858
|
-
const filePath =
|
|
4143
|
+
const filePath = path12.join(capabilitiesDir, `${cap.id}.json`);
|
|
3859
4144
|
const content = JSON.stringify(cap, null, 2);
|
|
3860
|
-
|
|
4145
|
+
fs14.writeFileSync(filePath, content, "utf-8");
|
|
3861
4146
|
console.log(` \u2713 Created: ${cap.id}.json`);
|
|
3862
4147
|
}
|
|
3863
4148
|
return {
|
|
@@ -3869,11 +4154,11 @@ async function migrateJsonFiles(options) {
|
|
|
3869
4154
|
}
|
|
3870
4155
|
|
|
3871
4156
|
// src/commands/migration/versions/v001_capability/plugin-installer/detector.ts
|
|
3872
|
-
import
|
|
4157
|
+
import fs15 from "fs";
|
|
3873
4158
|
function isPluginInstalled2(pluginKey) {
|
|
3874
4159
|
const actionPlugins = readActionPlugins();
|
|
3875
4160
|
const manifestPath = getPluginManifestPath2(pluginKey);
|
|
3876
|
-
return
|
|
4161
|
+
return fs15.existsSync(manifestPath) && !!actionPlugins[pluginKey];
|
|
3877
4162
|
}
|
|
3878
4163
|
function detectPluginsToInstall(capabilities) {
|
|
3879
4164
|
const pluginKeys = /* @__PURE__ */ new Set();
|
|
@@ -3949,12 +4234,12 @@ async function installPlugins(capabilities, options) {
|
|
|
3949
4234
|
}
|
|
3950
4235
|
|
|
3951
4236
|
// src/commands/migration/versions/v001_capability/code-migrator/index.ts
|
|
3952
|
-
import
|
|
4237
|
+
import path14 from "path";
|
|
3953
4238
|
import { Project as Project3 } from "ts-morph";
|
|
3954
4239
|
|
|
3955
4240
|
// src/commands/migration/versions/v001_capability/code-migrator/scanner.ts
|
|
3956
|
-
import
|
|
3957
|
-
import
|
|
4241
|
+
import fs16 from "fs";
|
|
4242
|
+
import path13 from "path";
|
|
3958
4243
|
var EXCLUDED_DIRS = [
|
|
3959
4244
|
"node_modules",
|
|
3960
4245
|
"dist",
|
|
@@ -3969,9 +4254,9 @@ var EXCLUDED_PATTERNS = [
|
|
|
3969
4254
|
/\.d\.ts$/
|
|
3970
4255
|
];
|
|
3971
4256
|
function scanDirectory(dir, files = []) {
|
|
3972
|
-
const entries =
|
|
4257
|
+
const entries = fs16.readdirSync(dir, { withFileTypes: true });
|
|
3973
4258
|
for (const entry of entries) {
|
|
3974
|
-
const fullPath =
|
|
4259
|
+
const fullPath = path13.join(dir, entry.name);
|
|
3975
4260
|
if (entry.isDirectory()) {
|
|
3976
4261
|
if (EXCLUDED_DIRS.includes(entry.name)) {
|
|
3977
4262
|
continue;
|
|
@@ -3987,14 +4272,14 @@ function scanDirectory(dir, files = []) {
|
|
|
3987
4272
|
return files;
|
|
3988
4273
|
}
|
|
3989
4274
|
function scanServerFiles() {
|
|
3990
|
-
const serverDir =
|
|
3991
|
-
if (!
|
|
4275
|
+
const serverDir = path13.join(getProjectRoot3(), "server");
|
|
4276
|
+
if (!fs16.existsSync(serverDir)) {
|
|
3992
4277
|
return [];
|
|
3993
4278
|
}
|
|
3994
4279
|
return scanDirectory(serverDir);
|
|
3995
4280
|
}
|
|
3996
4281
|
function hasCapabilityImport(filePath) {
|
|
3997
|
-
const content =
|
|
4282
|
+
const content = fs16.readFileSync(filePath, "utf-8");
|
|
3998
4283
|
return /import\s+.*from\s+['"][^'"]*capabilities[^'"]*['"]/.test(content);
|
|
3999
4284
|
}
|
|
4000
4285
|
function scanFilesToMigrate() {
|
|
@@ -4371,7 +4656,7 @@ function analyzeFile(project, filePath, actionNameMap) {
|
|
|
4371
4656
|
const callSites = analyzeCallSites(sourceFile, imports);
|
|
4372
4657
|
const classInfo = analyzeClass(sourceFile);
|
|
4373
4658
|
const { canMigrate, reason } = canAutoMigrate(classInfo);
|
|
4374
|
-
const relativePath =
|
|
4659
|
+
const relativePath = path14.relative(getProjectRoot3(), filePath);
|
|
4375
4660
|
return {
|
|
4376
4661
|
filePath: relativePath,
|
|
4377
4662
|
imports,
|
|
@@ -4382,7 +4667,7 @@ function analyzeFile(project, filePath, actionNameMap) {
|
|
|
4382
4667
|
};
|
|
4383
4668
|
}
|
|
4384
4669
|
function migrateFile(project, analysis, dryRun) {
|
|
4385
|
-
const absolutePath =
|
|
4670
|
+
const absolutePath = path14.join(getProjectRoot3(), analysis.filePath);
|
|
4386
4671
|
if (!analysis.canAutoMigrate) {
|
|
4387
4672
|
return {
|
|
4388
4673
|
filePath: analysis.filePath,
|
|
@@ -4485,17 +4770,17 @@ function getSuggestion(analysis) {
|
|
|
4485
4770
|
}
|
|
4486
4771
|
|
|
4487
4772
|
// src/commands/migration/versions/v001_capability/cleanup.ts
|
|
4488
|
-
import
|
|
4489
|
-
import
|
|
4773
|
+
import fs17 from "fs";
|
|
4774
|
+
import path15 from "path";
|
|
4490
4775
|
function cleanupOldFiles(capabilities, dryRun) {
|
|
4491
4776
|
const deletedFiles = [];
|
|
4492
4777
|
const errors = [];
|
|
4493
4778
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
4494
|
-
const oldJsonPath =
|
|
4495
|
-
if (
|
|
4779
|
+
const oldJsonPath = path15.join(capabilitiesDir, "capabilities.json");
|
|
4780
|
+
if (fs17.existsSync(oldJsonPath)) {
|
|
4496
4781
|
try {
|
|
4497
4782
|
if (!dryRun) {
|
|
4498
|
-
|
|
4783
|
+
fs17.unlinkSync(oldJsonPath);
|
|
4499
4784
|
}
|
|
4500
4785
|
deletedFiles.push("capabilities.json");
|
|
4501
4786
|
} catch (error) {
|
|
@@ -4503,11 +4788,11 @@ function cleanupOldFiles(capabilities, dryRun) {
|
|
|
4503
4788
|
}
|
|
4504
4789
|
}
|
|
4505
4790
|
for (const cap of capabilities) {
|
|
4506
|
-
const tsFilePath =
|
|
4507
|
-
if (
|
|
4791
|
+
const tsFilePath = path15.join(capabilitiesDir, `${cap.id}.ts`);
|
|
4792
|
+
if (fs17.existsSync(tsFilePath)) {
|
|
4508
4793
|
try {
|
|
4509
4794
|
if (!dryRun) {
|
|
4510
|
-
|
|
4795
|
+
fs17.unlinkSync(tsFilePath);
|
|
4511
4796
|
}
|
|
4512
4797
|
deletedFiles.push(`${cap.id}.ts`);
|
|
4513
4798
|
} catch (error) {
|
|
@@ -4523,8 +4808,8 @@ function cleanupOldFiles(capabilities, dryRun) {
|
|
|
4523
4808
|
}
|
|
4524
4809
|
|
|
4525
4810
|
// src/commands/migration/versions/v001_capability/report-generator.ts
|
|
4526
|
-
import
|
|
4527
|
-
import
|
|
4811
|
+
import fs18 from "fs";
|
|
4812
|
+
import path16 from "path";
|
|
4528
4813
|
var REPORT_FILE = "capability-migration-report.md";
|
|
4529
4814
|
function printSummary(result) {
|
|
4530
4815
|
const { jsonMigration, pluginInstallation, codeMigration, cleanup } = result;
|
|
@@ -4687,15 +4972,15 @@ async function generateReport(result) {
|
|
|
4687
4972
|
}
|
|
4688
4973
|
lines.push("");
|
|
4689
4974
|
const logDir = process.env.LOG_DIR || "logs";
|
|
4690
|
-
if (!
|
|
4975
|
+
if (!fs18.existsSync(logDir)) {
|
|
4691
4976
|
return;
|
|
4692
4977
|
}
|
|
4693
|
-
const reportDir =
|
|
4694
|
-
if (!
|
|
4695
|
-
|
|
4978
|
+
const reportDir = path16.join(logDir, "migration");
|
|
4979
|
+
if (!fs18.existsSync(reportDir)) {
|
|
4980
|
+
fs18.mkdirSync(reportDir, { recursive: true });
|
|
4696
4981
|
}
|
|
4697
|
-
const reportPath =
|
|
4698
|
-
|
|
4982
|
+
const reportPath = path16.join(reportDir, REPORT_FILE);
|
|
4983
|
+
fs18.writeFileSync(reportPath, lines.join("\n"), "utf-8");
|
|
4699
4984
|
console.log(`\u{1F4C4} Report generated: ${reportPath}`);
|
|
4700
4985
|
}
|
|
4701
4986
|
|
|
@@ -5227,10 +5512,10 @@ var migrationCommand = {
|
|
|
5227
5512
|
};
|
|
5228
5513
|
|
|
5229
5514
|
// src/commands/read-logs/index.ts
|
|
5230
|
-
import
|
|
5515
|
+
import path17 from "path";
|
|
5231
5516
|
|
|
5232
5517
|
// src/commands/read-logs/std-utils.ts
|
|
5233
|
-
import
|
|
5518
|
+
import fs19 from "fs";
|
|
5234
5519
|
function formatStdPrefixTime(localTime) {
|
|
5235
5520
|
const match = localTime.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
|
|
5236
5521
|
if (!match) return localTime;
|
|
@@ -5260,11 +5545,11 @@ function stripPrefixFromStdLine(line) {
|
|
|
5260
5545
|
return `[${time}] ${content}`;
|
|
5261
5546
|
}
|
|
5262
5547
|
function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarker) {
|
|
5263
|
-
const stat =
|
|
5548
|
+
const stat = fs19.statSync(filePath);
|
|
5264
5549
|
if (stat.size === 0) {
|
|
5265
5550
|
return { lines: [], markerFound: false, totalLinesCount: 0 };
|
|
5266
5551
|
}
|
|
5267
|
-
const fd =
|
|
5552
|
+
const fd = fs19.openSync(filePath, "r");
|
|
5268
5553
|
const chunkSize = 64 * 1024;
|
|
5269
5554
|
let position = stat.size;
|
|
5270
5555
|
let remainder = "";
|
|
@@ -5278,7 +5563,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
|
|
|
5278
5563
|
const length = Math.min(chunkSize, position);
|
|
5279
5564
|
position -= length;
|
|
5280
5565
|
const buffer = Buffer.alloc(length);
|
|
5281
|
-
|
|
5566
|
+
fs19.readSync(fd, buffer, 0, length, position);
|
|
5282
5567
|
let chunk = buffer.toString("utf8");
|
|
5283
5568
|
if (remainder) {
|
|
5284
5569
|
chunk += remainder;
|
|
@@ -5320,7 +5605,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
|
|
|
5320
5605
|
}
|
|
5321
5606
|
}
|
|
5322
5607
|
} finally {
|
|
5323
|
-
|
|
5608
|
+
fs19.closeSync(fd);
|
|
5324
5609
|
}
|
|
5325
5610
|
return { lines: collected.reverse(), markerFound, totalLinesCount };
|
|
5326
5611
|
}
|
|
@@ -5341,21 +5626,21 @@ function readServerStdSegment(filePath, maxLines, offset) {
|
|
|
5341
5626
|
}
|
|
5342
5627
|
|
|
5343
5628
|
// src/commands/read-logs/tail.ts
|
|
5344
|
-
import
|
|
5629
|
+
import fs20 from "fs";
|
|
5345
5630
|
function fileExists(filePath) {
|
|
5346
5631
|
try {
|
|
5347
|
-
|
|
5632
|
+
fs20.accessSync(filePath, fs20.constants.F_OK | fs20.constants.R_OK);
|
|
5348
5633
|
return true;
|
|
5349
5634
|
} catch {
|
|
5350
5635
|
return false;
|
|
5351
5636
|
}
|
|
5352
5637
|
}
|
|
5353
5638
|
function readFileTailLines(filePath, maxLines) {
|
|
5354
|
-
const stat =
|
|
5639
|
+
const stat = fs20.statSync(filePath);
|
|
5355
5640
|
if (stat.size === 0) {
|
|
5356
5641
|
return [];
|
|
5357
5642
|
}
|
|
5358
|
-
const fd =
|
|
5643
|
+
const fd = fs20.openSync(filePath, "r");
|
|
5359
5644
|
const chunkSize = 64 * 1024;
|
|
5360
5645
|
const chunks = [];
|
|
5361
5646
|
let position = stat.size;
|
|
@@ -5365,13 +5650,13 @@ function readFileTailLines(filePath, maxLines) {
|
|
|
5365
5650
|
const length = Math.min(chunkSize, position);
|
|
5366
5651
|
position -= length;
|
|
5367
5652
|
const buffer = Buffer.alloc(length);
|
|
5368
|
-
|
|
5653
|
+
fs20.readSync(fd, buffer, 0, length, position);
|
|
5369
5654
|
chunks.unshift(buffer.toString("utf8"));
|
|
5370
5655
|
const chunkLines = buffer.toString("utf8").split("\n").length - 1;
|
|
5371
5656
|
collectedLines += chunkLines;
|
|
5372
5657
|
}
|
|
5373
5658
|
} finally {
|
|
5374
|
-
|
|
5659
|
+
fs20.closeSync(fd);
|
|
5375
5660
|
}
|
|
5376
5661
|
const content = chunks.join("");
|
|
5377
5662
|
const allLines = content.split("\n");
|
|
@@ -5387,11 +5672,11 @@ function readFileTailLines(filePath, maxLines) {
|
|
|
5387
5672
|
return allLines.slice(allLines.length - maxLines);
|
|
5388
5673
|
}
|
|
5389
5674
|
function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
5390
|
-
const stat =
|
|
5675
|
+
const stat = fs20.statSync(filePath);
|
|
5391
5676
|
if (stat.size === 0) {
|
|
5392
5677
|
return { lines: [], totalLinesCount: 0 };
|
|
5393
5678
|
}
|
|
5394
|
-
const fd =
|
|
5679
|
+
const fd = fs20.openSync(filePath, "r");
|
|
5395
5680
|
const chunkSize = 64 * 1024;
|
|
5396
5681
|
let position = stat.size;
|
|
5397
5682
|
let remainder = "";
|
|
@@ -5403,7 +5688,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
|
5403
5688
|
const length = Math.min(chunkSize, position);
|
|
5404
5689
|
position -= length;
|
|
5405
5690
|
const buffer = Buffer.alloc(length);
|
|
5406
|
-
|
|
5691
|
+
fs20.readSync(fd, buffer, 0, length, position);
|
|
5407
5692
|
let chunk = buffer.toString("utf8");
|
|
5408
5693
|
if (remainder) {
|
|
5409
5694
|
chunk += remainder;
|
|
@@ -5434,7 +5719,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
|
5434
5719
|
}
|
|
5435
5720
|
}
|
|
5436
5721
|
} finally {
|
|
5437
|
-
|
|
5722
|
+
fs20.closeSync(fd);
|
|
5438
5723
|
}
|
|
5439
5724
|
return { lines: collected.reverse(), totalLinesCount };
|
|
5440
5725
|
}
|
|
@@ -5447,13 +5732,19 @@ function readClientStdSegment(filePath, maxLines, offset) {
|
|
|
5447
5732
|
function extractClientStdSegment(lines, maxLines, offset) {
|
|
5448
5733
|
const bodyLines = lines.map(stripPrefixFromStdLine);
|
|
5449
5734
|
const hotStartMarkers = [
|
|
5735
|
+
// Webpack markers
|
|
5450
5736
|
/file change detected\..*incremental compilation/i,
|
|
5451
5737
|
/starting incremental compilation/i,
|
|
5452
5738
|
/starting compilation/i,
|
|
5453
5739
|
/\bcompiling\b/i,
|
|
5454
|
-
/\brecompil/i
|
|
5740
|
+
/\brecompil/i,
|
|
5741
|
+
// Vite markers - format: "3:11:46 PM [vite] (client) hmr update ..."
|
|
5742
|
+
/VITE v[\d.]+.*ready/i,
|
|
5743
|
+
/\[vite\].*page reload/i,
|
|
5744
|
+
/\[vite\].*hmr update/i
|
|
5455
5745
|
];
|
|
5456
5746
|
const hotEndMarkers = [
|
|
5747
|
+
// Webpack markers
|
|
5457
5748
|
/file change detected\..*incremental compilation/i,
|
|
5458
5749
|
/\bwebpack compiled\b/i,
|
|
5459
5750
|
/compiled successfully/i,
|
|
@@ -5464,14 +5755,25 @@ function extractClientStdSegment(lines, maxLines, offset) {
|
|
|
5464
5755
|
/\bhmr\b/i,
|
|
5465
5756
|
/hot update/i,
|
|
5466
5757
|
/\bhot reload\b/i,
|
|
5467
|
-
/\bhmr update\b/i
|
|
5758
|
+
/\bhmr update\b/i,
|
|
5759
|
+
// Vite markers
|
|
5760
|
+
/VITE v[\d.]+.*ready/i,
|
|
5761
|
+
/\[vite\].*page reload/i,
|
|
5762
|
+
/\[vite\].*hmr update/i,
|
|
5763
|
+
/\[vite\].*hmr invalidate/i,
|
|
5764
|
+
/\[vite\].*internal server error/i,
|
|
5765
|
+
/\[vite\].*pre-transform error/i
|
|
5468
5766
|
];
|
|
5469
5767
|
const compiledMarkers = [
|
|
5768
|
+
// Webpack markers
|
|
5470
5769
|
/\bwebpack compiled\b/i,
|
|
5471
5770
|
/compiled successfully/i,
|
|
5472
5771
|
/compiled with warnings/i,
|
|
5473
5772
|
/compiled with errors/i,
|
|
5474
|
-
/failed to compile/i
|
|
5773
|
+
/failed to compile/i,
|
|
5774
|
+
// Vite markers
|
|
5775
|
+
/VITE v[\d.]+.*ready/i,
|
|
5776
|
+
/\[vite\].*hmr update/i
|
|
5475
5777
|
];
|
|
5476
5778
|
let startIndex = -1;
|
|
5477
5779
|
for (let i = bodyLines.length - 1; i >= 0; i -= 1) {
|
|
@@ -5524,14 +5826,15 @@ function extractClientStdSegment(lines, maxLines, offset) {
|
|
|
5524
5826
|
}
|
|
5525
5827
|
const segment = startIndex === -1 ? bodyLines : bodyLines.slice(startIndex);
|
|
5526
5828
|
if (segment.length === 0) {
|
|
5527
|
-
return { lines: [], totalLinesCount: 0 };
|
|
5829
|
+
return { lines: [], totalLinesCount: 0, allLines: [] };
|
|
5528
5830
|
}
|
|
5529
5831
|
const totalLinesCount = segment.length;
|
|
5530
5832
|
const endExclusive = Math.max(0, segment.length - offset);
|
|
5531
5833
|
const start = Math.max(0, endExclusive - maxLines);
|
|
5532
5834
|
return {
|
|
5533
5835
|
lines: segment.slice(start, endExclusive),
|
|
5534
|
-
totalLinesCount
|
|
5836
|
+
totalLinesCount,
|
|
5837
|
+
allLines: segment
|
|
5535
5838
|
};
|
|
5536
5839
|
}
|
|
5537
5840
|
|
|
@@ -5558,7 +5861,7 @@ function readDevStdSegment(filePath, maxLines, offset) {
|
|
|
5558
5861
|
}
|
|
5559
5862
|
|
|
5560
5863
|
// src/commands/read-logs/json-lines.ts
|
|
5561
|
-
import
|
|
5864
|
+
import fs21 from "fs";
|
|
5562
5865
|
function normalizePid(value) {
|
|
5563
5866
|
if (typeof value === "number") {
|
|
5564
5867
|
return String(value);
|
|
@@ -5609,11 +5912,11 @@ function buildWantedLevelSet(levels) {
|
|
|
5609
5912
|
return set.size > 0 ? set : null;
|
|
5610
5913
|
}
|
|
5611
5914
|
function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
5612
|
-
const stat =
|
|
5915
|
+
const stat = fs21.statSync(filePath);
|
|
5613
5916
|
if (stat.size === 0) {
|
|
5614
5917
|
return { lines: [], totalLinesCount: 0 };
|
|
5615
5918
|
}
|
|
5616
|
-
const fd =
|
|
5919
|
+
const fd = fs21.openSync(filePath, "r");
|
|
5617
5920
|
const chunkSize = 64 * 1024;
|
|
5618
5921
|
let position = stat.size;
|
|
5619
5922
|
let remainder = "";
|
|
@@ -5628,7 +5931,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
|
5628
5931
|
const length = Math.min(chunkSize, position);
|
|
5629
5932
|
position -= length;
|
|
5630
5933
|
const buffer = Buffer.alloc(length);
|
|
5631
|
-
|
|
5934
|
+
fs21.readSync(fd, buffer, 0, length, position);
|
|
5632
5935
|
let chunk = buffer.toString("utf8");
|
|
5633
5936
|
if (remainder) {
|
|
5634
5937
|
chunk += remainder;
|
|
@@ -5690,7 +5993,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
|
5690
5993
|
}
|
|
5691
5994
|
}
|
|
5692
5995
|
} finally {
|
|
5693
|
-
|
|
5996
|
+
fs21.closeSync(fd);
|
|
5694
5997
|
}
|
|
5695
5998
|
return { lines: collected.reverse(), totalLinesCount };
|
|
5696
5999
|
}
|
|
@@ -5733,11 +6036,11 @@ function extractTraceId(obj) {
|
|
|
5733
6036
|
function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
5734
6037
|
const wanted = traceId.trim();
|
|
5735
6038
|
if (!wanted) return { lines: [], totalLinesCount: 0 };
|
|
5736
|
-
const stat =
|
|
6039
|
+
const stat = fs21.statSync(filePath);
|
|
5737
6040
|
if (stat.size === 0) {
|
|
5738
6041
|
return { lines: [], totalLinesCount: 0 };
|
|
5739
6042
|
}
|
|
5740
|
-
const fd =
|
|
6043
|
+
const fd = fs21.openSync(filePath, "r");
|
|
5741
6044
|
const chunkSize = 64 * 1024;
|
|
5742
6045
|
let position = stat.size;
|
|
5743
6046
|
let remainder = "";
|
|
@@ -5750,7 +6053,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
|
5750
6053
|
const length = Math.min(chunkSize, position);
|
|
5751
6054
|
position -= length;
|
|
5752
6055
|
const buffer = Buffer.alloc(length);
|
|
5753
|
-
|
|
6056
|
+
fs21.readSync(fd, buffer, 0, length, position);
|
|
5754
6057
|
let chunk = buffer.toString("utf8");
|
|
5755
6058
|
if (remainder) {
|
|
5756
6059
|
chunk += remainder;
|
|
@@ -5803,7 +6106,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
|
5803
6106
|
}
|
|
5804
6107
|
}
|
|
5805
6108
|
} finally {
|
|
5806
|
-
|
|
6109
|
+
fs21.closeSync(fd);
|
|
5807
6110
|
}
|
|
5808
6111
|
return { lines: collected.reverse(), totalLinesCount };
|
|
5809
6112
|
}
|
|
@@ -5812,11 +6115,11 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
5812
6115
|
if (!wantedLevelSet) {
|
|
5813
6116
|
return { lines: [], totalLinesCount: 0 };
|
|
5814
6117
|
}
|
|
5815
|
-
const stat =
|
|
6118
|
+
const stat = fs21.statSync(filePath);
|
|
5816
6119
|
if (stat.size === 0) {
|
|
5817
6120
|
return { lines: [], totalLinesCount: 0 };
|
|
5818
6121
|
}
|
|
5819
|
-
const fd =
|
|
6122
|
+
const fd = fs21.openSync(filePath, "r");
|
|
5820
6123
|
const chunkSize = 64 * 1024;
|
|
5821
6124
|
let position = stat.size;
|
|
5822
6125
|
let remainder = "";
|
|
@@ -5828,7 +6131,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
5828
6131
|
const length = Math.min(chunkSize, position);
|
|
5829
6132
|
position -= length;
|
|
5830
6133
|
const buffer = Buffer.alloc(length);
|
|
5831
|
-
|
|
6134
|
+
fs21.readSync(fd, buffer, 0, length, position);
|
|
5832
6135
|
let chunk = buffer.toString("utf8");
|
|
5833
6136
|
if (remainder) {
|
|
5834
6137
|
chunk += remainder;
|
|
@@ -5875,7 +6178,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
5875
6178
|
}
|
|
5876
6179
|
}
|
|
5877
6180
|
} finally {
|
|
5878
|
-
|
|
6181
|
+
fs21.closeSync(fd);
|
|
5879
6182
|
}
|
|
5880
6183
|
return { lines: collected.reverse(), totalLinesCount };
|
|
5881
6184
|
}
|
|
@@ -6068,12 +6371,21 @@ async function readLatestLogLinesMeta(options) {
|
|
|
6068
6371
|
return { lines: [], totalLinesCount: 0 };
|
|
6069
6372
|
}
|
|
6070
6373
|
async function readLogsJsonResult(options) {
|
|
6071
|
-
const { lines, totalLinesCount } = await readLatestLogLinesMeta(options);
|
|
6374
|
+
const { lines, totalLinesCount, allLines } = await readLatestLogLinesMeta(options);
|
|
6072
6375
|
if (options.type === "server-std" || options.type === "client-std" || options.type === "dev" || options.type === "dev-std" || options.type === "install-dep-std") {
|
|
6376
|
+
const linesForErrorCheck = allLines ?? lines;
|
|
6377
|
+
const stackTracePattern = /\bat\s+\S+\s+\([^)]+:\d+:\d+\)/;
|
|
6378
|
+
const linesToFilter = allLines ?? lines;
|
|
6379
|
+
const filteredLines = linesToFilter.filter((line) => !stackTracePattern.test(line));
|
|
6380
|
+
const maxLines = options.maxLines ?? 30;
|
|
6381
|
+
const offset = options.offset ?? 0;
|
|
6382
|
+
const endExclusive = Math.max(0, filteredLines.length - offset);
|
|
6383
|
+
const start = Math.max(0, endExclusive - maxLines);
|
|
6384
|
+
const paginatedLogs = filteredLines.slice(start, endExclusive);
|
|
6073
6385
|
return {
|
|
6074
|
-
hasError: hasErrorInStdLines(
|
|
6075
|
-
totalLinesCount,
|
|
6076
|
-
logs:
|
|
6386
|
+
hasError: hasErrorInStdLines(linesForErrorCheck),
|
|
6387
|
+
totalLinesCount: filteredLines.length,
|
|
6388
|
+
logs: paginatedLogs
|
|
6077
6389
|
};
|
|
6078
6390
|
}
|
|
6079
6391
|
const logs = [];
|
|
@@ -6100,30 +6412,30 @@ async function readLogsJsonResult(options) {
|
|
|
6100
6412
|
};
|
|
6101
6413
|
}
|
|
6102
6414
|
function resolveLogFilePath(logDir, type) {
|
|
6103
|
-
const base =
|
|
6415
|
+
const base = path17.isAbsolute(logDir) ? logDir : path17.join(process.cwd(), logDir);
|
|
6104
6416
|
if (type === "server") {
|
|
6105
|
-
return
|
|
6417
|
+
return path17.join(base, "server.log");
|
|
6106
6418
|
}
|
|
6107
6419
|
if (type === "trace") {
|
|
6108
|
-
return
|
|
6420
|
+
return path17.join(base, "trace.log");
|
|
6109
6421
|
}
|
|
6110
6422
|
if (type === "server-std") {
|
|
6111
|
-
return
|
|
6423
|
+
return path17.join(base, "server.std.log");
|
|
6112
6424
|
}
|
|
6113
6425
|
if (type === "client-std") {
|
|
6114
|
-
return
|
|
6426
|
+
return path17.join(base, "client.std.log");
|
|
6115
6427
|
}
|
|
6116
6428
|
if (type === "dev") {
|
|
6117
|
-
return
|
|
6429
|
+
return path17.join(base, "dev.log");
|
|
6118
6430
|
}
|
|
6119
6431
|
if (type === "dev-std") {
|
|
6120
|
-
return
|
|
6432
|
+
return path17.join(base, "dev.std.log");
|
|
6121
6433
|
}
|
|
6122
6434
|
if (type === "install-dep-std") {
|
|
6123
|
-
return
|
|
6435
|
+
return path17.join(base, "install-dep.std.log");
|
|
6124
6436
|
}
|
|
6125
6437
|
if (type === "browser") {
|
|
6126
|
-
return
|
|
6438
|
+
return path17.join(base, "browser.log");
|
|
6127
6439
|
}
|
|
6128
6440
|
throw new Error(`Unsupported log type: ${type}`);
|
|
6129
6441
|
}
|
|
@@ -6185,17 +6497,18 @@ var commands = [
|
|
|
6185
6497
|
syncCommand,
|
|
6186
6498
|
actionPluginCommandGroup,
|
|
6187
6499
|
capabilityCommandGroup,
|
|
6500
|
+
componentCommandGroup,
|
|
6188
6501
|
migrationCommand,
|
|
6189
6502
|
readLogsCommand
|
|
6190
6503
|
];
|
|
6191
6504
|
|
|
6192
6505
|
// src/index.ts
|
|
6193
|
-
var envPath =
|
|
6194
|
-
if (
|
|
6506
|
+
var envPath = path18.join(process.cwd(), ".env");
|
|
6507
|
+
if (fs22.existsSync(envPath)) {
|
|
6195
6508
|
dotenvConfig({ path: envPath });
|
|
6196
6509
|
}
|
|
6197
|
-
var __dirname =
|
|
6198
|
-
var pkg = JSON.parse(
|
|
6510
|
+
var __dirname = path18.dirname(fileURLToPath4(import.meta.url));
|
|
6511
|
+
var pkg = JSON.parse(fs22.readFileSync(path18.join(__dirname, "../package.json"), "utf-8"));
|
|
6199
6512
|
var cli = new FullstackCLI(pkg.version);
|
|
6200
6513
|
cli.useAll(commands);
|
|
6201
6514
|
cli.run();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lark-apaas/fullstack-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.22",
|
|
4
4
|
"description": "CLI tool for fullstack template management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -32,18 +32,23 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@lark-apaas/http-client": "^0.1.2",
|
|
35
|
+
"@lydell/node-pty": "1.1.0",
|
|
35
36
|
"@vercel/nft": "^0.30.3",
|
|
36
37
|
"commander": "^13.0.0",
|
|
38
|
+
"debug": "^4.4.3",
|
|
37
39
|
"dotenv": "^16.0.0",
|
|
38
40
|
"drizzle-kit": "0.31.5",
|
|
39
41
|
"drizzle-orm": "0.44.6",
|
|
42
|
+
"es-toolkit": "^1.44.0",
|
|
40
43
|
"inflection": "^3.0.2",
|
|
41
44
|
"pinyin-pro": "^3.27.0",
|
|
42
45
|
"postgres": "^3.4.3",
|
|
46
|
+
"shadcn": "3.8.2",
|
|
43
47
|
"ts-morph": "^27.0.0",
|
|
44
48
|
"zod-to-json-schema": "^3.24.1"
|
|
45
49
|
},
|
|
46
50
|
"devDependencies": {
|
|
51
|
+
"@types/debug": "^4",
|
|
47
52
|
"@types/node": "^22.0.0",
|
|
48
53
|
"tsup": "^8.3.5",
|
|
49
54
|
"typescript": "^5.9.2",
|