@lark-apaas/fullstack-cli 1.1.22-alpha.1 → 1.1.22-alpha.11
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 +784 -259
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { fileURLToPath as
|
|
2
|
+
import fs25 from "fs";
|
|
3
|
+
import path21 from "path";
|
|
4
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
5
5
|
import { config as dotenvConfig } from "dotenv";
|
|
6
6
|
|
|
7
7
|
// src/cli.ts
|
|
@@ -1041,6 +1041,8 @@ async function fetchColumnComments(connectionString, options = {}) {
|
|
|
1041
1041
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
1042
1042
|
const url = new URL(connectionString);
|
|
1043
1043
|
const schemaName = url.searchParams.get("schema") ?? "public";
|
|
1044
|
+
const start = Date.now();
|
|
1045
|
+
console.log(`[fetchColumnComments] \u2192 Querying pg_description for schema=${schemaName} (timeout=${timeoutMs}ms)`);
|
|
1044
1046
|
const sql = postgres(connectionString, {
|
|
1045
1047
|
connect_timeout: Math.ceil(timeoutMs / 1e3),
|
|
1046
1048
|
idle_timeout: Math.ceil(timeoutMs / 1e3)
|
|
@@ -1069,6 +1071,7 @@ async function fetchColumnComments(connectionString, options = {}) {
|
|
|
1069
1071
|
const key = `${row.tableName}.${row.columnName}`;
|
|
1070
1072
|
commentMap.set(key, row.comment);
|
|
1071
1073
|
}
|
|
1074
|
+
console.log(`[fetchColumnComments] \u2190 Fetched ${commentMap.size} column comments (${Date.now() - start}ms)`);
|
|
1072
1075
|
return commentMap;
|
|
1073
1076
|
} finally {
|
|
1074
1077
|
await sql.end().catch(() => {
|
|
@@ -1167,6 +1170,79 @@ function addJsonbTypeComments(source, columnComments) {
|
|
|
1167
1170
|
return { text: result.join("\n"), added };
|
|
1168
1171
|
}
|
|
1169
1172
|
|
|
1173
|
+
// src/commands/db/gen-dbschema/transforms/text/synced-table-comments.ts
|
|
1174
|
+
var TABLE_COMMENT = "Synced table: data is auto-synced from external source. Do not rename or delete this table.";
|
|
1175
|
+
var FIELD_COMMENT = "Synced field: auto-synced, do not modify or delete";
|
|
1176
|
+
var TABLE_DEF_REGEX = /^(export const\s+\w+\s*=\s*(?:pgTable|pgView|pgMaterializedView)\(\s*["'`])([^"'`]+)(["'`])/;
|
|
1177
|
+
var FIELD_WITH_NAME_REGEX = /^\s*[\w"']+\s*:\s*\w+\(\s*["'`]([^"'`]+)["'`]/;
|
|
1178
|
+
var FIELD_PROP_NAME_REGEX = /^\s*([\w]+)\s*:/;
|
|
1179
|
+
function addSyncedTableComments(source, syncedTableMap) {
|
|
1180
|
+
if (!syncedTableMap || syncedTableMap.size === 0) {
|
|
1181
|
+
return { text: source, added: 0 };
|
|
1182
|
+
}
|
|
1183
|
+
const lines = source.split("\n");
|
|
1184
|
+
const result = [];
|
|
1185
|
+
let added = 0;
|
|
1186
|
+
let currentSyncedFields = null;
|
|
1187
|
+
let insideTableBody = false;
|
|
1188
|
+
let braceDepth = 0;
|
|
1189
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1190
|
+
const line = lines[i];
|
|
1191
|
+
const tableMatch = line.match(TABLE_DEF_REGEX);
|
|
1192
|
+
if (tableMatch) {
|
|
1193
|
+
const tableName = tableMatch[2];
|
|
1194
|
+
const syncedFields = syncedTableMap.get(tableName);
|
|
1195
|
+
if (syncedFields) {
|
|
1196
|
+
currentSyncedFields = syncedFields;
|
|
1197
|
+
insideTableBody = true;
|
|
1198
|
+
braceDepth = 0;
|
|
1199
|
+
const prevLine = result[result.length - 1]?.trim() ?? "";
|
|
1200
|
+
if (!prevLine.includes("Synced table")) {
|
|
1201
|
+
const indentMatch = line.match(/^\s*/);
|
|
1202
|
+
const indent = indentMatch ? indentMatch[0] : "";
|
|
1203
|
+
result.push(`${indent}// ${TABLE_COMMENT}`);
|
|
1204
|
+
added++;
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
if (insideTableBody) {
|
|
1209
|
+
for (const ch of line) {
|
|
1210
|
+
if (ch === "{") braceDepth++;
|
|
1211
|
+
if (ch === "}") braceDepth--;
|
|
1212
|
+
}
|
|
1213
|
+
if (braceDepth <= 0) {
|
|
1214
|
+
insideTableBody = false;
|
|
1215
|
+
currentSyncedFields = null;
|
|
1216
|
+
}
|
|
1217
|
+
if (currentSyncedFields && braceDepth >= 1 && !tableMatch) {
|
|
1218
|
+
const columnName = extractColumnName2(line);
|
|
1219
|
+
if (columnName && currentSyncedFields.has(columnName)) {
|
|
1220
|
+
const prevLine = result[result.length - 1]?.trim() ?? "";
|
|
1221
|
+
if (!prevLine.includes("Synced field")) {
|
|
1222
|
+
const indentMatch = line.match(/^\s*/);
|
|
1223
|
+
const indent = indentMatch ? indentMatch[0] : "";
|
|
1224
|
+
result.push(`${indent}// ${FIELD_COMMENT}`);
|
|
1225
|
+
added++;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
result.push(line);
|
|
1231
|
+
}
|
|
1232
|
+
return { text: result.join("\n"), added };
|
|
1233
|
+
}
|
|
1234
|
+
function extractColumnName2(line) {
|
|
1235
|
+
const withNameMatch = line.match(FIELD_WITH_NAME_REGEX);
|
|
1236
|
+
if (withNameMatch) {
|
|
1237
|
+
return withNameMatch[1];
|
|
1238
|
+
}
|
|
1239
|
+
const propMatch = line.match(FIELD_PROP_NAME_REGEX);
|
|
1240
|
+
if (propMatch) {
|
|
1241
|
+
return propMatch[1];
|
|
1242
|
+
}
|
|
1243
|
+
return null;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1170
1246
|
// src/commands/db/gen-dbschema/transforms/text/table-aliases.ts
|
|
1171
1247
|
var TABLE_ALIAS_MARKER = "// table aliases";
|
|
1172
1248
|
function generateTableAliases(source) {
|
|
@@ -1215,13 +1291,16 @@ function postprocessSchema(rawSource, options = {}) {
|
|
|
1215
1291
|
source = inlineCustomTypes(source);
|
|
1216
1292
|
const jsonbCommentsResult = addJsonbTypeComments(source, options.columnComments);
|
|
1217
1293
|
source = jsonbCommentsResult.text;
|
|
1294
|
+
const syncedCommentsResult = addSyncedTableComments(source, options.syncedTableMap);
|
|
1295
|
+
source = syncedCommentsResult.text;
|
|
1218
1296
|
source = generateTableAliases(source);
|
|
1219
1297
|
source = formatSource(source);
|
|
1220
1298
|
return {
|
|
1221
1299
|
source,
|
|
1222
1300
|
astStats,
|
|
1223
1301
|
patchedDefects: patchResult.fixed,
|
|
1224
|
-
addedJsonbComments: jsonbCommentsResult.added
|
|
1302
|
+
addedJsonbComments: jsonbCommentsResult.added,
|
|
1303
|
+
addedSyncedComments: syncedCommentsResult.added
|
|
1225
1304
|
};
|
|
1226
1305
|
}
|
|
1227
1306
|
function logStats(result, prefix = "[postprocess]") {
|
|
@@ -1271,6 +1350,9 @@ function logStats(result, prefix = "[postprocess]") {
|
|
|
1271
1350
|
if (result.addedJsonbComments > 0) {
|
|
1272
1351
|
console.info(`${prefix} Added ${result.addedJsonbComments} JSDoc comments for jsonb fields`);
|
|
1273
1352
|
}
|
|
1353
|
+
if (result.addedSyncedComments > 0) {
|
|
1354
|
+
console.info(`${prefix} Added ${result.addedSyncedComments} comments for synced tables/fields`);
|
|
1355
|
+
}
|
|
1274
1356
|
}
|
|
1275
1357
|
|
|
1276
1358
|
// src/commands/db/gen-dbschema/index.ts
|
|
@@ -1281,7 +1363,10 @@ async function postprocessDrizzleSchema(targetPath, options = {}) {
|
|
|
1281
1363
|
return void 0;
|
|
1282
1364
|
}
|
|
1283
1365
|
const rawSource = fs3.readFileSync(resolvedPath, "utf8");
|
|
1284
|
-
const result = postprocessSchema(rawSource, {
|
|
1366
|
+
const result = postprocessSchema(rawSource, {
|
|
1367
|
+
columnComments: options.columnComments,
|
|
1368
|
+
syncedTableMap: options.syncedTableMap
|
|
1369
|
+
});
|
|
1285
1370
|
fs3.writeFileSync(resolvedPath, result.source, "utf8");
|
|
1286
1371
|
logStats(result, "[postprocess-drizzle-schema]");
|
|
1287
1372
|
return {
|
|
@@ -1291,10 +1376,82 @@ async function postprocessDrizzleSchema(targetPath, options = {}) {
|
|
|
1291
1376
|
patchedDefects: result.patchedDefects,
|
|
1292
1377
|
replacedTimestamps: result.astStats.replacedTimestamp,
|
|
1293
1378
|
replacedDefaultNow: result.astStats.replacedDefaultNow,
|
|
1294
|
-
addedJsonbComments: result.addedJsonbComments
|
|
1379
|
+
addedJsonbComments: result.addedJsonbComments,
|
|
1380
|
+
addedSyncedComments: result.addedSyncedComments
|
|
1295
1381
|
};
|
|
1296
1382
|
}
|
|
1297
1383
|
|
|
1384
|
+
// src/utils/http-client.ts
|
|
1385
|
+
import { HttpClient } from "@lark-apaas/http-client";
|
|
1386
|
+
var clientInstance = null;
|
|
1387
|
+
function getHttpClient() {
|
|
1388
|
+
if (!clientInstance) {
|
|
1389
|
+
clientInstance = new HttpClient({
|
|
1390
|
+
timeout: 3e4,
|
|
1391
|
+
platform: {
|
|
1392
|
+
enabled: true
|
|
1393
|
+
}
|
|
1394
|
+
});
|
|
1395
|
+
const canaryEnv = process.env.FORCE_FRAMEWORK_CLI_CANARY_ENV;
|
|
1396
|
+
if (canaryEnv) {
|
|
1397
|
+
clientInstance.interceptors.request.use((req) => {
|
|
1398
|
+
req.headers["x-tt-env"] = canaryEnv;
|
|
1399
|
+
return req;
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
return clientInstance;
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
// src/commands/db/gen-dbschema/utils/fetch-synced-tables.ts
|
|
1407
|
+
async function fetchSyncedTables(appId, workspace) {
|
|
1408
|
+
const client = getHttpClient();
|
|
1409
|
+
const start = Date.now();
|
|
1410
|
+
console.log(
|
|
1411
|
+
`[fetchSyncedTables] \u2192 GET listTableView (dbBranch=main) appId=${appId} workspace=${workspace}`,
|
|
1412
|
+
process.env.FORCE_AUTHN_ACCESS_SECRET
|
|
1413
|
+
);
|
|
1414
|
+
const response = await client.get(
|
|
1415
|
+
`/api/v1/dataloom/inner/app/${appId}/workspaces/${workspace}/listTableView`
|
|
1416
|
+
);
|
|
1417
|
+
console.log(`[fetchSyncedTables] \u2190 listTableView response: ${response.status} ${response.statusText} (${Date.now() - start}ms)`);
|
|
1418
|
+
const responseXHeaders = Array.from(response.headers.entries()).filter(([key]) => key.toLowerCase().startsWith("x-")).reduce((acc, [key, value]) => {
|
|
1419
|
+
acc[key] = value;
|
|
1420
|
+
return acc;
|
|
1421
|
+
}, {});
|
|
1422
|
+
console.log("[fetchSyncedTables] x-* response headers:", responseXHeaders);
|
|
1423
|
+
if (!response.ok) {
|
|
1424
|
+
throw new Error(`listTableView API failed: ${response.status} ${response.statusText}`);
|
|
1425
|
+
}
|
|
1426
|
+
const json = await response.json();
|
|
1427
|
+
const tableView = json?.data?.data;
|
|
1428
|
+
console.log("[fetchSyncedTables] listTableView raw response:", JSON.stringify(json, null, 2));
|
|
1429
|
+
if (!tableView) {
|
|
1430
|
+
console.warn("[fetchSyncedTables] \u26A0 listTableView response missing data.data, returning empty map");
|
|
1431
|
+
return /* @__PURE__ */ new Map();
|
|
1432
|
+
}
|
|
1433
|
+
const syncedMap = extractSyncedTableMap(tableView);
|
|
1434
|
+
const totalCount = (tableView.table?.data?.length ?? 0) + (tableView.view?.data?.length ?? 0) + (tableView.materializedView?.data?.length ?? 0);
|
|
1435
|
+
console.log(
|
|
1436
|
+
`[fetchSyncedTables] \u2713 Extracted synced tables: ${syncedMap.size}/${totalCount} (elapsed ${Date.now() - start}ms)`
|
|
1437
|
+
);
|
|
1438
|
+
return syncedMap;
|
|
1439
|
+
}
|
|
1440
|
+
function extractSyncedTableMap(tableView) {
|
|
1441
|
+
const syncedMap = /* @__PURE__ */ new Map();
|
|
1442
|
+
const allTables = [
|
|
1443
|
+
...tableView.table?.data ?? [],
|
|
1444
|
+
...tableView.view?.data ?? [],
|
|
1445
|
+
...tableView.materializedView?.data ?? []
|
|
1446
|
+
];
|
|
1447
|
+
for (const table of allTables) {
|
|
1448
|
+
if (table.bitableSyncTask && table.bitableSyncTask.fieldApiNameList?.length > 0) {
|
|
1449
|
+
syncedMap.set(table.tableName, new Set(table.bitableSyncTask.fieldApiNameList));
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
return syncedMap;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1298
1455
|
// src/commands/db/gen-nest-resource/generator.ts
|
|
1299
1456
|
import { pluralize } from "inflection";
|
|
1300
1457
|
|
|
@@ -2017,15 +2174,52 @@ async function run(options = {}) {
|
|
|
2017
2174
|
throw new Error("Unable to locate drizzle-kit package root");
|
|
2018
2175
|
};
|
|
2019
2176
|
let columnComments;
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2177
|
+
let syncedTableMap;
|
|
2178
|
+
const appId = process.env.app_id;
|
|
2179
|
+
const workspace = process.env.suda_workspace_id;
|
|
2180
|
+
console.log(
|
|
2181
|
+
`[gen-db-schema] Pre-fetch info: columnComments=enabled, syncedTables=${Boolean(appId && workspace) ? "enabled" : "skipped"} (app_id=${appId ? "set" : "unset"}, suda_workspace_id=${workspace ? "set" : "unset"})`
|
|
2182
|
+
);
|
|
2183
|
+
const columnCommentsTask = (async () => {
|
|
2184
|
+
const start = Date.now();
|
|
2185
|
+
console.log("[gen-db-schema] \u2192 Fetching column comments...");
|
|
2186
|
+
const res = await fetchColumnComments(databaseUrl, { timeoutMs: 1e4 });
|
|
2187
|
+
console.log(`[gen-db-schema] \u2190 Fetched column comments: ${res.size} items (${Date.now() - start}ms)`);
|
|
2188
|
+
return res;
|
|
2189
|
+
})();
|
|
2190
|
+
const syncedTablesTask = appId && workspace ? (async () => {
|
|
2191
|
+
const start = Date.now();
|
|
2192
|
+
console.log("[gen-db-schema] \u2192 Fetching synced tables from listTableView...");
|
|
2193
|
+
const res = await fetchSyncedTables(appId, workspace);
|
|
2194
|
+
console.log(`[gen-db-schema] \u2190 Fetched synced tables: ${res.size} tables (${Date.now() - start}ms)`);
|
|
2195
|
+
return res;
|
|
2196
|
+
})() : void 0;
|
|
2197
|
+
const fetchTasks = await Promise.allSettled([
|
|
2198
|
+
columnCommentsTask,
|
|
2199
|
+
...syncedTablesTask ? [syncedTablesTask] : []
|
|
2200
|
+
]);
|
|
2201
|
+
if (fetchTasks[0].status === "fulfilled") {
|
|
2202
|
+
columnComments = fetchTasks[0].value;
|
|
2203
|
+
console.log(`[gen-db-schema] \u2713 Column comments ready: ${columnComments.size}`);
|
|
2204
|
+
} else {
|
|
2024
2205
|
console.warn(
|
|
2025
2206
|
"[gen-db-schema] \u26A0 Failed to fetch column comments (skipping):",
|
|
2026
|
-
|
|
2207
|
+
fetchTasks[0].reason instanceof Error ? fetchTasks[0].reason.message : String(fetchTasks[0].reason)
|
|
2027
2208
|
);
|
|
2028
2209
|
}
|
|
2210
|
+
if (appId && workspace) {
|
|
2211
|
+
if (fetchTasks[1]?.status === "fulfilled") {
|
|
2212
|
+
syncedTableMap = fetchTasks[1].value;
|
|
2213
|
+
console.log(`[gen-db-schema] \u2713 Synced tables ready: ${syncedTableMap.size}`);
|
|
2214
|
+
} else if (fetchTasks[1]?.status === "rejected") {
|
|
2215
|
+
console.warn(
|
|
2216
|
+
"[gen-db-schema] \u26A0 Failed to fetch synced tables (skipping):",
|
|
2217
|
+
fetchTasks[1].reason instanceof Error ? fetchTasks[1].reason.message : String(fetchTasks[1].reason)
|
|
2218
|
+
);
|
|
2219
|
+
}
|
|
2220
|
+
} else {
|
|
2221
|
+
console.info("[gen-db-schema] \u2139 Skipping synced table detection (app_id or suda_workspace_id not set)");
|
|
2222
|
+
}
|
|
2029
2223
|
try {
|
|
2030
2224
|
const env = {
|
|
2031
2225
|
...process.env,
|
|
@@ -2050,7 +2244,8 @@ async function run(options = {}) {
|
|
|
2050
2244
|
throw new Error("drizzle-kit introspect failed to generate schema.ts");
|
|
2051
2245
|
}
|
|
2052
2246
|
const stats = await postprocessDrizzleSchema(generatedSchema, {
|
|
2053
|
-
columnComments
|
|
2247
|
+
columnComments,
|
|
2248
|
+
syncedTableMap
|
|
2054
2249
|
});
|
|
2055
2250
|
if (stats?.unmatchedUnknown?.length) {
|
|
2056
2251
|
console.warn("[gen-db-schema] Unmatched custom types detected:", stats.unmatchedUnknown);
|
|
@@ -2419,10 +2614,379 @@ var syncCommand = {
|
|
|
2419
2614
|
}
|
|
2420
2615
|
};
|
|
2421
2616
|
|
|
2422
|
-
// src/
|
|
2617
|
+
// src/utils/telemetry.ts
|
|
2618
|
+
async function reportEvents(events) {
|
|
2619
|
+
if (events.length === 0) {
|
|
2620
|
+
return true;
|
|
2621
|
+
}
|
|
2622
|
+
try {
|
|
2623
|
+
const client = getHttpClient();
|
|
2624
|
+
const response = await client.post("/api/v1/studio/innerapi/resource_events", { events });
|
|
2625
|
+
if (!response.ok) {
|
|
2626
|
+
console.warn(`[telemetry] Failed to report events: ${response.status} ${response.statusText}`);
|
|
2627
|
+
return false;
|
|
2628
|
+
}
|
|
2629
|
+
const result = await response.json();
|
|
2630
|
+
if (result.status_code !== "0") {
|
|
2631
|
+
console.warn(`[telemetry] API error: ${result.message}`);
|
|
2632
|
+
return false;
|
|
2633
|
+
}
|
|
2634
|
+
return true;
|
|
2635
|
+
} catch (error) {
|
|
2636
|
+
console.warn(`[telemetry] Failed to report events: ${error instanceof Error ? error.message : error}`);
|
|
2637
|
+
return false;
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
async function reportInstallEvent(pluginKey, version) {
|
|
2641
|
+
await reportEvents([
|
|
2642
|
+
{
|
|
2643
|
+
resourceType: "plugin",
|
|
2644
|
+
resourceKey: pluginKey,
|
|
2645
|
+
eventType: "install",
|
|
2646
|
+
details: { version }
|
|
2647
|
+
}
|
|
2648
|
+
]);
|
|
2649
|
+
}
|
|
2650
|
+
async function reportCreateInstanceEvent(pluginKey, version) {
|
|
2651
|
+
await reportEvents([
|
|
2652
|
+
{
|
|
2653
|
+
resourceType: "plugin",
|
|
2654
|
+
resourceKey: pluginKey,
|
|
2655
|
+
eventType: "create_instance",
|
|
2656
|
+
details: { version }
|
|
2657
|
+
}
|
|
2658
|
+
]);
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
// src/utils/git.ts
|
|
2662
|
+
import { execSync, spawnSync as spawnSync2 } from "child_process";
|
|
2423
2663
|
import fs7 from "fs";
|
|
2424
2664
|
import path5 from "path";
|
|
2425
|
-
|
|
2665
|
+
function isGitRepository(cwd = process.cwd()) {
|
|
2666
|
+
try {
|
|
2667
|
+
const gitDir = path5.join(cwd, ".git");
|
|
2668
|
+
if (fs7.existsSync(gitDir)) {
|
|
2669
|
+
return true;
|
|
2670
|
+
}
|
|
2671
|
+
const result = spawnSync2("git", ["rev-parse", "--git-dir"], {
|
|
2672
|
+
cwd,
|
|
2673
|
+
stdio: "pipe",
|
|
2674
|
+
encoding: "utf-8"
|
|
2675
|
+
});
|
|
2676
|
+
return result.status === 0;
|
|
2677
|
+
} catch {
|
|
2678
|
+
return false;
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
function getChangedFiles(cwd = process.cwd()) {
|
|
2682
|
+
try {
|
|
2683
|
+
const output = execSync("git status --porcelain", {
|
|
2684
|
+
cwd,
|
|
2685
|
+
stdio: "pipe",
|
|
2686
|
+
encoding: "utf-8"
|
|
2687
|
+
});
|
|
2688
|
+
return output.split("\n").filter((line) => line.trim()).map((line) => line.substring(3));
|
|
2689
|
+
} catch (error) {
|
|
2690
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2691
|
+
throw new Error(`Failed to get changed files: ${message}`);
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
function gitAddUpgradeFiles(cwd = process.cwd(), filesToStage) {
|
|
2695
|
+
const filteredFiles = [];
|
|
2696
|
+
for (const filePath of filesToStage) {
|
|
2697
|
+
if (fs7.existsSync(path5.join(cwd, filePath))) {
|
|
2698
|
+
filteredFiles.push(filePath);
|
|
2699
|
+
continue;
|
|
2700
|
+
}
|
|
2701
|
+
const tracked = spawnSync2("git", ["ls-files", "--error-unmatch", "--", filePath], {
|
|
2702
|
+
cwd,
|
|
2703
|
+
stdio: "pipe",
|
|
2704
|
+
encoding: "utf-8"
|
|
2705
|
+
});
|
|
2706
|
+
if (tracked.status === 0) {
|
|
2707
|
+
filteredFiles.push(filePath);
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
if (filteredFiles.length === 0) {
|
|
2711
|
+
return;
|
|
2712
|
+
}
|
|
2713
|
+
const result = spawnSync2("git", ["add", "--", ...filteredFiles], {
|
|
2714
|
+
cwd,
|
|
2715
|
+
stdio: "pipe",
|
|
2716
|
+
encoding: "utf-8"
|
|
2717
|
+
});
|
|
2718
|
+
if (result.error || result.status !== 0) {
|
|
2719
|
+
const errorMsg = result.stderr || result.error?.message || "Unknown error";
|
|
2720
|
+
throw new Error(`git add failed: ${errorMsg}`);
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
function gitCommit(message, cwd = process.cwd()) {
|
|
2724
|
+
const result = spawnSync2("git", ["commit", "-m", message], {
|
|
2725
|
+
cwd,
|
|
2726
|
+
stdio: "pipe",
|
|
2727
|
+
encoding: "utf-8"
|
|
2728
|
+
});
|
|
2729
|
+
if (result.error || result.status !== 0) {
|
|
2730
|
+
const errorMsg = result.stderr || result.error?.message || "Unknown error";
|
|
2731
|
+
throw new Error(`git commit failed: ${errorMsg}`);
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
function autoCommitUpgradeChanges(version, cwd, filesToStage, commitMessage) {
|
|
2735
|
+
if (!isGitRepository(cwd)) {
|
|
2736
|
+
console.log("[fullstack-cli] \u26A0 Not a git repository, skipping auto-commit");
|
|
2737
|
+
return false;
|
|
2738
|
+
}
|
|
2739
|
+
const changedFiles = getChangedFiles(cwd);
|
|
2740
|
+
if (changedFiles.length === 0) {
|
|
2741
|
+
console.log("[fullstack-cli] No changes to commit");
|
|
2742
|
+
return false;
|
|
2743
|
+
}
|
|
2744
|
+
try {
|
|
2745
|
+
gitAddUpgradeFiles(cwd, filesToStage);
|
|
2746
|
+
const message = commitMessage || `chore(upgrade): auto-upgrade by fullstack-cli
|
|
2747
|
+
|
|
2748
|
+
- Sync template files
|
|
2749
|
+
- Cleanup package.json config
|
|
2750
|
+
- Upgrade @lark-apaas dependencies (if any)
|
|
2751
|
+
|
|
2752
|
+
Auto-committed by fullstack-cli v${version}`;
|
|
2753
|
+
gitCommit(message, cwd);
|
|
2754
|
+
console.log(`[fullstack-cli] \u2713 Auto-committed ${changedFiles.length} changed file(s)`);
|
|
2755
|
+
return true;
|
|
2756
|
+
} catch (error) {
|
|
2757
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2758
|
+
throw new Error(`Failed to auto-commit changes: ${message}`);
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2762
|
+
// src/utils/package-json.ts
|
|
2763
|
+
import fs8 from "fs";
|
|
2764
|
+
import path6 from "path";
|
|
2765
|
+
function readPackageJson(cwd = process.cwd()) {
|
|
2766
|
+
const pkgPath = path6.join(cwd, "package.json");
|
|
2767
|
+
if (!fs8.existsSync(pkgPath)) {
|
|
2768
|
+
throw new Error(`package.json not found at ${pkgPath}`);
|
|
2769
|
+
}
|
|
2770
|
+
const content = fs8.readFileSync(pkgPath, "utf-8");
|
|
2771
|
+
return JSON.parse(content);
|
|
2772
|
+
}
|
|
2773
|
+
function writePackageJson(pkg2, cwd = process.cwd()) {
|
|
2774
|
+
const pkgPath = path6.join(cwd, "package.json");
|
|
2775
|
+
const content = JSON.stringify(pkg2, null, 2) + "\n";
|
|
2776
|
+
fs8.writeFileSync(pkgPath, content, "utf-8");
|
|
2777
|
+
}
|
|
2778
|
+
function removeUpgradeScript(pkg2) {
|
|
2779
|
+
if (!pkg2.scripts?.upgrade) {
|
|
2780
|
+
return false;
|
|
2781
|
+
}
|
|
2782
|
+
delete pkg2.scripts.upgrade;
|
|
2783
|
+
return true;
|
|
2784
|
+
}
|
|
2785
|
+
function cleanDevScript(pkg2) {
|
|
2786
|
+
if (!pkg2.scripts?.dev) {
|
|
2787
|
+
return false;
|
|
2788
|
+
}
|
|
2789
|
+
const originalDev = pkg2.scripts.dev;
|
|
2790
|
+
const cleanedDev = originalDev.replace(/npm\s+run\s+upgrade\s*&&\s*/g, "").replace(/npm\s+run\s+upgrade\s*$/g, "").trim();
|
|
2791
|
+
if (cleanedDev !== originalDev) {
|
|
2792
|
+
pkg2.scripts.dev = cleanedDev;
|
|
2793
|
+
return true;
|
|
2794
|
+
}
|
|
2795
|
+
return false;
|
|
2796
|
+
}
|
|
2797
|
+
function cleanupPackageJson(cwd = process.cwd()) {
|
|
2798
|
+
try {
|
|
2799
|
+
const pkg2 = readPackageJson(cwd);
|
|
2800
|
+
let changed = false;
|
|
2801
|
+
if (removeUpgradeScript(pkg2)) {
|
|
2802
|
+
console.log("[fullstack-cli] \u2713 Removed scripts.upgrade");
|
|
2803
|
+
changed = true;
|
|
2804
|
+
}
|
|
2805
|
+
if (cleanDevScript(pkg2)) {
|
|
2806
|
+
console.log("[fullstack-cli] \u2713 Cleaned scripts.dev (removed npm run upgrade)");
|
|
2807
|
+
changed = true;
|
|
2808
|
+
}
|
|
2809
|
+
if (changed) {
|
|
2810
|
+
writePackageJson(pkg2, cwd);
|
|
2811
|
+
}
|
|
2812
|
+
return changed;
|
|
2813
|
+
} catch (error) {
|
|
2814
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2815
|
+
console.log(`[fullstack-cli] \u26A0 Could not cleanup package.json: ${message}`);
|
|
2816
|
+
return false;
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
|
|
2820
|
+
// src/commands/upgrade/shared/utils.ts
|
|
2821
|
+
import path7 from "path";
|
|
2822
|
+
import fs9 from "fs";
|
|
2823
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
2824
|
+
function getCliVersion() {
|
|
2825
|
+
try {
|
|
2826
|
+
const __filename = fileURLToPath4(import.meta.url);
|
|
2827
|
+
const __dirname2 = path7.dirname(__filename);
|
|
2828
|
+
const pkgPath = path7.resolve(__dirname2, "../../../package.json");
|
|
2829
|
+
const pkgContent = fs9.readFileSync(pkgPath, "utf-8");
|
|
2830
|
+
const pkg2 = JSON.parse(pkgContent);
|
|
2831
|
+
return pkg2.version || "unknown";
|
|
2832
|
+
} catch {
|
|
2833
|
+
return "unknown";
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2836
|
+
|
|
2837
|
+
// src/commands/upgrade/get-upgrade-files.ts
|
|
2838
|
+
function getUpgradeFilesToStage(disableGenOpenapi = true) {
|
|
2839
|
+
const syncConfig2 = genSyncConfig({ disableGenOpenapi });
|
|
2840
|
+
const filesToStage = /* @__PURE__ */ new Set();
|
|
2841
|
+
syncConfig2.sync.forEach((rule) => {
|
|
2842
|
+
if (rule.type === "file" || rule.type === "directory") {
|
|
2843
|
+
filesToStage.add(rule.to);
|
|
2844
|
+
} else if (rule.type === "remove-line" || rule.type === "add-line") {
|
|
2845
|
+
filesToStage.add(rule.to);
|
|
2846
|
+
} else if (rule.type === "add-script") {
|
|
2847
|
+
filesToStage.add("package.json");
|
|
2848
|
+
} else if (rule.type === "delete-file" || rule.type === "delete-directory") {
|
|
2849
|
+
filesToStage.add(rule.to);
|
|
2850
|
+
}
|
|
2851
|
+
});
|
|
2852
|
+
filesToStage.add("package.json");
|
|
2853
|
+
filesToStage.add("package-lock.json");
|
|
2854
|
+
return Array.from(filesToStage);
|
|
2855
|
+
}
|
|
2856
|
+
|
|
2857
|
+
// src/commands/upgrade/run.handler.ts
|
|
2858
|
+
async function run3(options = {}) {
|
|
2859
|
+
const userProjectRoot = process.env.INIT_CWD || process.cwd();
|
|
2860
|
+
console.log("[fullstack-cli] Starting upgrade...");
|
|
2861
|
+
try {
|
|
2862
|
+
console.log("[fullstack-cli] Step 1/3: Syncing template files...");
|
|
2863
|
+
await run2({ disableGenOpenapi: options.disableGenOpenapi ?? true });
|
|
2864
|
+
console.log("[fullstack-cli] Step 2/3: Cleaning up package.json...");
|
|
2865
|
+
const cleaned = cleanupPackageJson(userProjectRoot);
|
|
2866
|
+
if (!cleaned) {
|
|
2867
|
+
console.log("[fullstack-cli] \u25CB No cleanup needed");
|
|
2868
|
+
}
|
|
2869
|
+
const shouldCommit = options.commit ?? true;
|
|
2870
|
+
if (shouldCommit) {
|
|
2871
|
+
console.log("[fullstack-cli] Step 3/3: Committing changes...");
|
|
2872
|
+
const version = getCliVersion();
|
|
2873
|
+
const filesToStage = getUpgradeFilesToStage(options.disableGenOpenapi ?? true);
|
|
2874
|
+
autoCommitUpgradeChanges(version, userProjectRoot, filesToStage);
|
|
2875
|
+
} else {
|
|
2876
|
+
console.log("[fullstack-cli] Step 3/3: Skipping commit (--no-commit flag)");
|
|
2877
|
+
}
|
|
2878
|
+
console.log("[fullstack-cli] Upgrade completed successfully \u2705");
|
|
2879
|
+
} catch (error) {
|
|
2880
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2881
|
+
console.error("[fullstack-cli] Failed to upgrade:", message);
|
|
2882
|
+
process.exit(1);
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
// src/commands/upgrade/deps/run.handler.ts
|
|
2887
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
2888
|
+
function findLarkAapaasPackages(cwd, filterPackages) {
|
|
2889
|
+
const pkg2 = readPackageJson(cwd);
|
|
2890
|
+
const allPackages = /* @__PURE__ */ new Set();
|
|
2891
|
+
if (pkg2.dependencies) {
|
|
2892
|
+
Object.keys(pkg2.dependencies).forEach((name) => {
|
|
2893
|
+
if (name.startsWith("@lark-apaas/")) {
|
|
2894
|
+
allPackages.add(name);
|
|
2895
|
+
}
|
|
2896
|
+
});
|
|
2897
|
+
}
|
|
2898
|
+
if (pkg2.devDependencies) {
|
|
2899
|
+
Object.keys(pkg2.devDependencies).forEach((name) => {
|
|
2900
|
+
if (name.startsWith("@lark-apaas/")) {
|
|
2901
|
+
allPackages.add(name);
|
|
2902
|
+
}
|
|
2903
|
+
});
|
|
2904
|
+
}
|
|
2905
|
+
const packages = Array.from(allPackages);
|
|
2906
|
+
if (filterPackages) {
|
|
2907
|
+
const filter = new Set(filterPackages.split(",").map((p) => p.trim()));
|
|
2908
|
+
return packages.filter((p) => filter.has(p));
|
|
2909
|
+
}
|
|
2910
|
+
return packages;
|
|
2911
|
+
}
|
|
2912
|
+
function upgradePackages(packages, version, cwd) {
|
|
2913
|
+
if (version) {
|
|
2914
|
+
console.log(`[fullstack-cli] Upgrading to version ${version}...`);
|
|
2915
|
+
packages.forEach((pkg2) => {
|
|
2916
|
+
const target = `${pkg2}@${version}`;
|
|
2917
|
+
console.log(`[fullstack-cli] Installing ${target}...`);
|
|
2918
|
+
const result = spawnSync3("npm", ["install", target], {
|
|
2919
|
+
cwd,
|
|
2920
|
+
stdio: "inherit"
|
|
2921
|
+
});
|
|
2922
|
+
if (result.error || result.status !== 0) {
|
|
2923
|
+
throw new Error(`Failed to install ${target}`);
|
|
2924
|
+
}
|
|
2925
|
+
});
|
|
2926
|
+
} else {
|
|
2927
|
+
console.log("[fullstack-cli] Upgrading to latest compatible versions...");
|
|
2928
|
+
packages.forEach((pkg2) => {
|
|
2929
|
+
console.log(`[fullstack-cli] Updating ${pkg2}...`);
|
|
2930
|
+
const result = spawnSync3("npm", ["update", pkg2], {
|
|
2931
|
+
cwd,
|
|
2932
|
+
stdio: "inherit"
|
|
2933
|
+
});
|
|
2934
|
+
if (result.error || result.status !== 0) {
|
|
2935
|
+
throw new Error(`Failed to update ${pkg2}`);
|
|
2936
|
+
}
|
|
2937
|
+
});
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
async function run4(options = {}) {
|
|
2941
|
+
const cwd = process.env.INIT_CWD || process.cwd();
|
|
2942
|
+
console.log("[fullstack-cli] Starting dependencies upgrade...");
|
|
2943
|
+
try {
|
|
2944
|
+
console.log("[fullstack-cli] Step 1/2: Scanning @lark-apaas dependencies...");
|
|
2945
|
+
const packages = findLarkAapaasPackages(cwd, options.packages);
|
|
2946
|
+
if (packages.length === 0) {
|
|
2947
|
+
console.log("[fullstack-cli] No @lark-apaas packages found");
|
|
2948
|
+
return;
|
|
2949
|
+
}
|
|
2950
|
+
console.log(`[fullstack-cli] Found ${packages.length} @lark-apaas package(s):`);
|
|
2951
|
+
packages.forEach((p) => console.log(` - ${p}`));
|
|
2952
|
+
console.log("[fullstack-cli] Step 2/2: Upgrading packages...");
|
|
2953
|
+
upgradePackages(packages, options.version, cwd);
|
|
2954
|
+
console.log(`[fullstack-cli] \u2713 Successfully upgraded ${packages.length} package(s)`);
|
|
2955
|
+
console.log("[fullstack-cli] Dependencies upgrade completed successfully \u2705");
|
|
2956
|
+
} catch (error) {
|
|
2957
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2958
|
+
console.error("[fullstack-cli] Failed to upgrade dependencies:", message);
|
|
2959
|
+
process.exit(1);
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
// src/commands/upgrade/deps/index.ts
|
|
2964
|
+
var depsCommand = {
|
|
2965
|
+
name: "deps",
|
|
2966
|
+
description: "Upgrade @lark-apaas dependencies",
|
|
2967
|
+
register(parentCommand) {
|
|
2968
|
+
parentCommand.command(this.name).description(this.description).option("--version <version>", "Upgrade to specific version").option("--packages <packages>", "Only upgrade specific packages (comma-separated)").action(async (options) => {
|
|
2969
|
+
await run4(options);
|
|
2970
|
+
});
|
|
2971
|
+
}
|
|
2972
|
+
};
|
|
2973
|
+
|
|
2974
|
+
// src/commands/upgrade/index.ts
|
|
2975
|
+
var upgradeCommand = {
|
|
2976
|
+
name: "upgrade",
|
|
2977
|
+
description: "Upgrade template files and auto-commit changes",
|
|
2978
|
+
register(program) {
|
|
2979
|
+
const upgradeCmd = program.command(this.name).description(this.description).option("--disable-gen-openapi", "Disable generating openapi.ts").option("--no-commit", "Skip auto-commit changes").action(async (options) => {
|
|
2980
|
+
await run3(options);
|
|
2981
|
+
});
|
|
2982
|
+
depsCommand.register(upgradeCmd);
|
|
2983
|
+
}
|
|
2984
|
+
};
|
|
2985
|
+
|
|
2986
|
+
// src/commands/action-plugin/utils.ts
|
|
2987
|
+
import fs10 from "fs";
|
|
2988
|
+
import path8 from "path";
|
|
2989
|
+
import { spawnSync as spawnSync4, execSync as execSync2 } from "child_process";
|
|
2426
2990
|
function parsePluginName(input) {
|
|
2427
2991
|
const match = input.match(/^(@[^/]+\/[^@]+)(?:@(.+))?$/);
|
|
2428
2992
|
if (!match) {
|
|
@@ -2439,35 +3003,35 @@ function getProjectRoot() {
|
|
|
2439
3003
|
return process.cwd();
|
|
2440
3004
|
}
|
|
2441
3005
|
function getPackageJsonPath() {
|
|
2442
|
-
return
|
|
3006
|
+
return path8.join(getProjectRoot(), "package.json");
|
|
2443
3007
|
}
|
|
2444
3008
|
function getPluginPath(pluginName) {
|
|
2445
|
-
return
|
|
3009
|
+
return path8.join(getProjectRoot(), "node_modules", pluginName);
|
|
2446
3010
|
}
|
|
2447
|
-
function
|
|
3011
|
+
function readPackageJson2() {
|
|
2448
3012
|
const pkgPath = getPackageJsonPath();
|
|
2449
|
-
if (!
|
|
3013
|
+
if (!fs10.existsSync(pkgPath)) {
|
|
2450
3014
|
throw new Error("package.json not found in current directory");
|
|
2451
3015
|
}
|
|
2452
3016
|
try {
|
|
2453
|
-
const content =
|
|
3017
|
+
const content = fs10.readFileSync(pkgPath, "utf-8");
|
|
2454
3018
|
return JSON.parse(content);
|
|
2455
3019
|
} catch {
|
|
2456
3020
|
throw new Error("Failed to parse package.json");
|
|
2457
3021
|
}
|
|
2458
3022
|
}
|
|
2459
|
-
function
|
|
3023
|
+
function writePackageJson2(pkg2) {
|
|
2460
3024
|
const pkgPath = getPackageJsonPath();
|
|
2461
|
-
|
|
3025
|
+
fs10.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
|
|
2462
3026
|
}
|
|
2463
3027
|
function readActionPlugins() {
|
|
2464
|
-
const pkg2 =
|
|
3028
|
+
const pkg2 = readPackageJson2();
|
|
2465
3029
|
return pkg2.actionPlugins || {};
|
|
2466
3030
|
}
|
|
2467
3031
|
function writeActionPlugins(plugins) {
|
|
2468
|
-
const pkg2 =
|
|
3032
|
+
const pkg2 = readPackageJson2();
|
|
2469
3033
|
pkg2.actionPlugins = plugins;
|
|
2470
|
-
|
|
3034
|
+
writePackageJson2(pkg2);
|
|
2471
3035
|
}
|
|
2472
3036
|
function isPluginInstalled(pluginName) {
|
|
2473
3037
|
const plugins = readActionPlugins();
|
|
@@ -2479,7 +3043,7 @@ function getInstalledPluginVersion(pluginName) {
|
|
|
2479
3043
|
}
|
|
2480
3044
|
function npmInstall(tgzPath) {
|
|
2481
3045
|
console.log(`[action-plugin] Running npm install ${tgzPath}...`);
|
|
2482
|
-
const result =
|
|
3046
|
+
const result = spawnSync4("npm", ["install", tgzPath, "--no-save", "--no-package-lock", "--ignore-scripts"], {
|
|
2483
3047
|
cwd: getProjectRoot(),
|
|
2484
3048
|
stdio: "inherit"
|
|
2485
3049
|
});
|
|
@@ -2491,12 +3055,12 @@ function npmInstall(tgzPath) {
|
|
|
2491
3055
|
}
|
|
2492
3056
|
}
|
|
2493
3057
|
function getPackageVersion(pluginName) {
|
|
2494
|
-
const pkgJsonPath =
|
|
2495
|
-
if (!
|
|
3058
|
+
const pkgJsonPath = path8.join(getPluginPath(pluginName), "package.json");
|
|
3059
|
+
if (!fs10.existsSync(pkgJsonPath)) {
|
|
2496
3060
|
return null;
|
|
2497
3061
|
}
|
|
2498
3062
|
try {
|
|
2499
|
-
const content =
|
|
3063
|
+
const content = fs10.readFileSync(pkgJsonPath, "utf-8");
|
|
2500
3064
|
const pkg2 = JSON.parse(content);
|
|
2501
3065
|
return pkg2.version || null;
|
|
2502
3066
|
} catch {
|
|
@@ -2504,49 +3068,49 @@ function getPackageVersion(pluginName) {
|
|
|
2504
3068
|
}
|
|
2505
3069
|
}
|
|
2506
3070
|
function readPluginPackageJson(pluginPath) {
|
|
2507
|
-
const pkgJsonPath =
|
|
2508
|
-
if (!
|
|
3071
|
+
const pkgJsonPath = path8.join(pluginPath, "package.json");
|
|
3072
|
+
if (!fs10.existsSync(pkgJsonPath)) {
|
|
2509
3073
|
return null;
|
|
2510
3074
|
}
|
|
2511
3075
|
try {
|
|
2512
|
-
const content =
|
|
3076
|
+
const content = fs10.readFileSync(pkgJsonPath, "utf-8");
|
|
2513
3077
|
return JSON.parse(content);
|
|
2514
3078
|
} catch {
|
|
2515
3079
|
return null;
|
|
2516
3080
|
}
|
|
2517
3081
|
}
|
|
2518
3082
|
function extractTgzToNodeModules(tgzPath, pluginName) {
|
|
2519
|
-
const nodeModulesPath =
|
|
2520
|
-
const targetDir =
|
|
2521
|
-
const scopeDir =
|
|
2522
|
-
if (!
|
|
2523
|
-
|
|
3083
|
+
const nodeModulesPath = path8.join(getProjectRoot(), "node_modules");
|
|
3084
|
+
const targetDir = path8.join(nodeModulesPath, pluginName);
|
|
3085
|
+
const scopeDir = path8.dirname(targetDir);
|
|
3086
|
+
if (!fs10.existsSync(scopeDir)) {
|
|
3087
|
+
fs10.mkdirSync(scopeDir, { recursive: true });
|
|
2524
3088
|
}
|
|
2525
|
-
if (
|
|
2526
|
-
|
|
3089
|
+
if (fs10.existsSync(targetDir)) {
|
|
3090
|
+
fs10.rmSync(targetDir, { recursive: true });
|
|
2527
3091
|
}
|
|
2528
|
-
const tempDir =
|
|
2529
|
-
if (
|
|
2530
|
-
|
|
3092
|
+
const tempDir = path8.join(nodeModulesPath, ".cache", "fullstack-cli", "extract-temp");
|
|
3093
|
+
if (fs10.existsSync(tempDir)) {
|
|
3094
|
+
fs10.rmSync(tempDir, { recursive: true });
|
|
2531
3095
|
}
|
|
2532
|
-
|
|
3096
|
+
fs10.mkdirSync(tempDir, { recursive: true });
|
|
2533
3097
|
try {
|
|
2534
|
-
|
|
2535
|
-
const extractedDir =
|
|
2536
|
-
if (
|
|
2537
|
-
|
|
3098
|
+
execSync2(`tar -xzf "${tgzPath}" -C "${tempDir}"`, { stdio: "pipe" });
|
|
3099
|
+
const extractedDir = path8.join(tempDir, "package");
|
|
3100
|
+
if (fs10.existsSync(extractedDir)) {
|
|
3101
|
+
fs10.renameSync(extractedDir, targetDir);
|
|
2538
3102
|
} else {
|
|
2539
|
-
const files =
|
|
3103
|
+
const files = fs10.readdirSync(tempDir);
|
|
2540
3104
|
if (files.length === 1) {
|
|
2541
|
-
|
|
3105
|
+
fs10.renameSync(path8.join(tempDir, files[0]), targetDir);
|
|
2542
3106
|
} else {
|
|
2543
3107
|
throw new Error("Unexpected tgz structure");
|
|
2544
3108
|
}
|
|
2545
3109
|
}
|
|
2546
3110
|
return targetDir;
|
|
2547
3111
|
} finally {
|
|
2548
|
-
if (
|
|
2549
|
-
|
|
3112
|
+
if (fs10.existsSync(tempDir)) {
|
|
3113
|
+
fs10.rmSync(tempDir, { recursive: true });
|
|
2550
3114
|
}
|
|
2551
3115
|
}
|
|
2552
3116
|
}
|
|
@@ -2555,10 +3119,10 @@ function checkMissingPeerDeps(peerDeps) {
|
|
|
2555
3119
|
return [];
|
|
2556
3120
|
}
|
|
2557
3121
|
const missing = [];
|
|
2558
|
-
const nodeModulesPath =
|
|
3122
|
+
const nodeModulesPath = path8.join(getProjectRoot(), "node_modules");
|
|
2559
3123
|
for (const [depName, _version] of Object.entries(peerDeps)) {
|
|
2560
|
-
const depPath =
|
|
2561
|
-
if (!
|
|
3124
|
+
const depPath = path8.join(nodeModulesPath, depName);
|
|
3125
|
+
if (!fs10.existsSync(depPath)) {
|
|
2562
3126
|
missing.push(depName);
|
|
2563
3127
|
}
|
|
2564
3128
|
}
|
|
@@ -2569,7 +3133,7 @@ function installMissingDeps(deps) {
|
|
|
2569
3133
|
return;
|
|
2570
3134
|
}
|
|
2571
3135
|
console.log(`[action-plugin] Installing missing dependencies: ${deps.join(", ")}`);
|
|
2572
|
-
const result =
|
|
3136
|
+
const result = spawnSync4("npm", ["install", ...deps, "--no-save", "--no-package-lock"], {
|
|
2573
3137
|
cwd: getProjectRoot(),
|
|
2574
3138
|
stdio: "inherit"
|
|
2575
3139
|
});
|
|
@@ -2582,76 +3146,16 @@ function installMissingDeps(deps) {
|
|
|
2582
3146
|
}
|
|
2583
3147
|
function removePluginDirectory(pluginName) {
|
|
2584
3148
|
const pluginPath = getPluginPath(pluginName);
|
|
2585
|
-
if (
|
|
2586
|
-
|
|
3149
|
+
if (fs10.existsSync(pluginPath)) {
|
|
3150
|
+
fs10.rmSync(pluginPath, { recursive: true });
|
|
2587
3151
|
console.log(`[action-plugin] Removed ${pluginName}`);
|
|
2588
3152
|
}
|
|
2589
3153
|
}
|
|
2590
3154
|
|
|
2591
3155
|
// src/commands/action-plugin/api-client.ts
|
|
2592
3156
|
import { HttpClient as HttpClient2 } from "@lark-apaas/http-client";
|
|
2593
|
-
import
|
|
2594
|
-
import
|
|
2595
|
-
|
|
2596
|
-
// src/utils/http-client.ts
|
|
2597
|
-
import { HttpClient } from "@lark-apaas/http-client";
|
|
2598
|
-
var clientInstance = null;
|
|
2599
|
-
function getHttpClient() {
|
|
2600
|
-
if (!clientInstance) {
|
|
2601
|
-
clientInstance = new HttpClient({
|
|
2602
|
-
timeout: 3e4,
|
|
2603
|
-
platform: {
|
|
2604
|
-
enabled: true
|
|
2605
|
-
}
|
|
2606
|
-
});
|
|
2607
|
-
const canaryEnv = process.env.FORCE_FRAMEWORK_CLI_CANARY_ENV;
|
|
2608
|
-
if (canaryEnv) {
|
|
2609
|
-
clientInstance.interceptors.request.use((req) => {
|
|
2610
|
-
req.headers["x-tt-env"] = canaryEnv;
|
|
2611
|
-
return req;
|
|
2612
|
-
});
|
|
2613
|
-
}
|
|
2614
|
-
}
|
|
2615
|
-
return clientInstance;
|
|
2616
|
-
}
|
|
2617
|
-
|
|
2618
|
-
// src/utils/telemetry.ts
|
|
2619
|
-
async function reportEvents(events) {
|
|
2620
|
-
if (events.length === 0) {
|
|
2621
|
-
return true;
|
|
2622
|
-
}
|
|
2623
|
-
try {
|
|
2624
|
-
const client = getHttpClient();
|
|
2625
|
-
const response = await client.post("/resource_events", {
|
|
2626
|
-
body: JSON.stringify({ events })
|
|
2627
|
-
});
|
|
2628
|
-
if (!response.ok) {
|
|
2629
|
-
console.warn(`[telemetry] Failed to report events: ${response.status} ${response.statusText}`);
|
|
2630
|
-
return false;
|
|
2631
|
-
}
|
|
2632
|
-
const result = await response.json();
|
|
2633
|
-
if (result.status_code !== "0") {
|
|
2634
|
-
console.warn(`[telemetry] API error: ${result.message}`);
|
|
2635
|
-
return false;
|
|
2636
|
-
}
|
|
2637
|
-
return true;
|
|
2638
|
-
} catch (error) {
|
|
2639
|
-
console.warn(`[telemetry] Failed to report events: ${error instanceof Error ? error.message : error}`);
|
|
2640
|
-
return false;
|
|
2641
|
-
}
|
|
2642
|
-
}
|
|
2643
|
-
async function reportInstallEvent(pluginKey, version) {
|
|
2644
|
-
await reportEvents([
|
|
2645
|
-
{
|
|
2646
|
-
resourceType: "plugin",
|
|
2647
|
-
resourceKey: pluginKey,
|
|
2648
|
-
eventType: "install",
|
|
2649
|
-
details: { version }
|
|
2650
|
-
}
|
|
2651
|
-
]);
|
|
2652
|
-
}
|
|
2653
|
-
|
|
2654
|
-
// src/commands/action-plugin/api-client.ts
|
|
3157
|
+
import fs11 from "fs";
|
|
3158
|
+
import path9 from "path";
|
|
2655
3159
|
var PLUGIN_CACHE_DIR = "node_modules/.cache/fullstack-cli/plugins";
|
|
2656
3160
|
async function getPluginVersions(keys, latestOnly = true) {
|
|
2657
3161
|
const client = getHttpClient();
|
|
@@ -2715,19 +3219,19 @@ async function downloadFromPublic(downloadURL) {
|
|
|
2715
3219
|
return Buffer.from(arrayBuffer);
|
|
2716
3220
|
}
|
|
2717
3221
|
function getPluginCacheDir() {
|
|
2718
|
-
return
|
|
3222
|
+
return path9.join(process.cwd(), PLUGIN_CACHE_DIR);
|
|
2719
3223
|
}
|
|
2720
3224
|
function ensureCacheDir() {
|
|
2721
3225
|
const cacheDir = getPluginCacheDir();
|
|
2722
|
-
if (!
|
|
2723
|
-
|
|
3226
|
+
if (!fs11.existsSync(cacheDir)) {
|
|
3227
|
+
fs11.mkdirSync(cacheDir, { recursive: true });
|
|
2724
3228
|
}
|
|
2725
3229
|
}
|
|
2726
3230
|
function getTempFilePath(pluginKey, version) {
|
|
2727
3231
|
ensureCacheDir();
|
|
2728
3232
|
const safeKey = pluginKey.replace(/[/@]/g, "_");
|
|
2729
3233
|
const filename = `${safeKey}@${version}.tgz`;
|
|
2730
|
-
return
|
|
3234
|
+
return path9.join(getPluginCacheDir(), filename);
|
|
2731
3235
|
}
|
|
2732
3236
|
var MAX_RETRIES = 2;
|
|
2733
3237
|
async function withRetry(operation, description, maxRetries = MAX_RETRIES) {
|
|
@@ -2764,7 +3268,7 @@ async function downloadPlugin(pluginKey, requestedVersion) {
|
|
|
2764
3268
|
);
|
|
2765
3269
|
}
|
|
2766
3270
|
const tgzPath = getTempFilePath(pluginKey, pluginInfo.version);
|
|
2767
|
-
|
|
3271
|
+
fs11.writeFileSync(tgzPath, tgzBuffer);
|
|
2768
3272
|
console.log(`[action-plugin] Downloaded to ${tgzPath} (${(tgzBuffer.length / 1024).toFixed(2)} KB)`);
|
|
2769
3273
|
return {
|
|
2770
3274
|
tgzPath,
|
|
@@ -2778,18 +3282,18 @@ function getCachePath(pluginKey, version) {
|
|
|
2778
3282
|
ensureCacheDir();
|
|
2779
3283
|
const safeKey = pluginKey.replace(/[/@]/g, "_");
|
|
2780
3284
|
const filename = `${safeKey}@${version}.tgz`;
|
|
2781
|
-
return
|
|
3285
|
+
return path9.join(getPluginCacheDir(), filename);
|
|
2782
3286
|
}
|
|
2783
3287
|
function hasCachedPlugin(pluginKey, version) {
|
|
2784
3288
|
const cachePath = getCachePath(pluginKey, version);
|
|
2785
|
-
return
|
|
3289
|
+
return fs11.existsSync(cachePath);
|
|
2786
3290
|
}
|
|
2787
3291
|
function listCachedPlugins() {
|
|
2788
3292
|
const cacheDir = getPluginCacheDir();
|
|
2789
|
-
if (!
|
|
3293
|
+
if (!fs11.existsSync(cacheDir)) {
|
|
2790
3294
|
return [];
|
|
2791
3295
|
}
|
|
2792
|
-
const files =
|
|
3296
|
+
const files = fs11.readdirSync(cacheDir);
|
|
2793
3297
|
const result = [];
|
|
2794
3298
|
for (const file of files) {
|
|
2795
3299
|
if (!file.endsWith(".tgz")) continue;
|
|
@@ -2797,8 +3301,8 @@ function listCachedPlugins() {
|
|
|
2797
3301
|
if (!match) continue;
|
|
2798
3302
|
const [, rawName, version] = match;
|
|
2799
3303
|
const name = rawName.replace(/^_/, "@").replace(/_/, "/");
|
|
2800
|
-
const filePath =
|
|
2801
|
-
const stat =
|
|
3304
|
+
const filePath = path9.join(cacheDir, file);
|
|
3305
|
+
const stat = fs11.statSync(filePath);
|
|
2802
3306
|
result.push({
|
|
2803
3307
|
name,
|
|
2804
3308
|
version,
|
|
@@ -2811,14 +3315,14 @@ function listCachedPlugins() {
|
|
|
2811
3315
|
}
|
|
2812
3316
|
function cleanAllCache() {
|
|
2813
3317
|
const cacheDir = getPluginCacheDir();
|
|
2814
|
-
if (!
|
|
3318
|
+
if (!fs11.existsSync(cacheDir)) {
|
|
2815
3319
|
return 0;
|
|
2816
3320
|
}
|
|
2817
|
-
const files =
|
|
3321
|
+
const files = fs11.readdirSync(cacheDir);
|
|
2818
3322
|
let count = 0;
|
|
2819
3323
|
for (const file of files) {
|
|
2820
3324
|
if (file.endsWith(".tgz")) {
|
|
2821
|
-
|
|
3325
|
+
fs11.unlinkSync(path9.join(cacheDir, file));
|
|
2822
3326
|
count++;
|
|
2823
3327
|
}
|
|
2824
3328
|
}
|
|
@@ -2826,21 +3330,21 @@ function cleanAllCache() {
|
|
|
2826
3330
|
}
|
|
2827
3331
|
function cleanPluginCache(pluginKey, version) {
|
|
2828
3332
|
const cacheDir = getPluginCacheDir();
|
|
2829
|
-
if (!
|
|
3333
|
+
if (!fs11.existsSync(cacheDir)) {
|
|
2830
3334
|
return 0;
|
|
2831
3335
|
}
|
|
2832
3336
|
const safeKey = pluginKey.replace(/[/@]/g, "_");
|
|
2833
|
-
const files =
|
|
3337
|
+
const files = fs11.readdirSync(cacheDir);
|
|
2834
3338
|
let count = 0;
|
|
2835
3339
|
for (const file of files) {
|
|
2836
3340
|
if (version) {
|
|
2837
3341
|
if (file === `${safeKey}@${version}.tgz`) {
|
|
2838
|
-
|
|
3342
|
+
fs11.unlinkSync(path9.join(cacheDir, file));
|
|
2839
3343
|
count++;
|
|
2840
3344
|
}
|
|
2841
3345
|
} else {
|
|
2842
3346
|
if (file.startsWith(`${safeKey}@`) && file.endsWith(".tgz")) {
|
|
2843
|
-
|
|
3347
|
+
fs11.unlinkSync(path9.join(cacheDir, file));
|
|
2844
3348
|
count++;
|
|
2845
3349
|
}
|
|
2846
3350
|
}
|
|
@@ -2934,6 +3438,8 @@ async function installOne(nameWithVersion) {
|
|
|
2934
3438
|
if (actualVersion === requestedVersion) {
|
|
2935
3439
|
console.log(`[action-plugin] Plugin ${name}@${requestedVersion} is already installed`);
|
|
2936
3440
|
syncActionPluginsRecord(name, actualVersion);
|
|
3441
|
+
reportCreateInstanceEvent(name, actualVersion).catch(() => {
|
|
3442
|
+
});
|
|
2937
3443
|
return { name, version: actualVersion, success: true, skipped: true };
|
|
2938
3444
|
}
|
|
2939
3445
|
}
|
|
@@ -2944,6 +3450,8 @@ async function installOne(nameWithVersion) {
|
|
|
2944
3450
|
if (actualVersion === targetVersion) {
|
|
2945
3451
|
console.log(`[action-plugin] Plugin ${name} is already up to date (version: ${actualVersion})`);
|
|
2946
3452
|
syncActionPluginsRecord(name, actualVersion);
|
|
3453
|
+
reportCreateInstanceEvent(name, actualVersion).catch(() => {
|
|
3454
|
+
});
|
|
2947
3455
|
return { name, version: actualVersion, success: true, skipped: true };
|
|
2948
3456
|
}
|
|
2949
3457
|
console.log(`[action-plugin] Found newer version: ${targetVersion} (installed: ${actualVersion || "none"})`);
|
|
@@ -2976,6 +3484,8 @@ async function installOne(nameWithVersion) {
|
|
|
2976
3484
|
console.log(`[action-plugin] Successfully installed ${name}@${installedVersion} (${source})`);
|
|
2977
3485
|
reportInstallEvent(name, installedVersion).catch(() => {
|
|
2978
3486
|
});
|
|
3487
|
+
reportCreateInstanceEvent(name, installedVersion).catch(() => {
|
|
3488
|
+
});
|
|
2979
3489
|
return { name, version: installedVersion, success: true };
|
|
2980
3490
|
} catch (error) {
|
|
2981
3491
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -3261,40 +3771,40 @@ var actionPluginCommandGroup = {
|
|
|
3261
3771
|
};
|
|
3262
3772
|
|
|
3263
3773
|
// src/commands/capability/utils.ts
|
|
3264
|
-
import
|
|
3774
|
+
import fs12 from "fs";
|
|
3265
3775
|
import { createRequire as createRequire2 } from "module";
|
|
3266
|
-
import
|
|
3776
|
+
import path10 from "path";
|
|
3267
3777
|
var CAPABILITIES_DIR = "server/capabilities";
|
|
3268
3778
|
function getProjectRoot2() {
|
|
3269
3779
|
return process.cwd();
|
|
3270
3780
|
}
|
|
3271
3781
|
function getCapabilitiesDir() {
|
|
3272
|
-
return
|
|
3782
|
+
return path10.join(getProjectRoot2(), CAPABILITIES_DIR);
|
|
3273
3783
|
}
|
|
3274
3784
|
function getCapabilityPath(id) {
|
|
3275
|
-
return
|
|
3785
|
+
return path10.join(getCapabilitiesDir(), `${id}.json`);
|
|
3276
3786
|
}
|
|
3277
3787
|
function getPluginManifestPath(pluginKey) {
|
|
3278
|
-
return
|
|
3788
|
+
return path10.join(getProjectRoot2(), "node_modules", pluginKey, "manifest.json");
|
|
3279
3789
|
}
|
|
3280
3790
|
function capabilitiesDirExists() {
|
|
3281
|
-
return
|
|
3791
|
+
return fs12.existsSync(getCapabilitiesDir());
|
|
3282
3792
|
}
|
|
3283
3793
|
function listCapabilityIds() {
|
|
3284
3794
|
const dir = getCapabilitiesDir();
|
|
3285
|
-
if (!
|
|
3795
|
+
if (!fs12.existsSync(dir)) {
|
|
3286
3796
|
return [];
|
|
3287
3797
|
}
|
|
3288
|
-
const files =
|
|
3798
|
+
const files = fs12.readdirSync(dir);
|
|
3289
3799
|
return files.filter((f) => f.endsWith(".json") && f !== "capabilities.json").map((f) => f.replace(/\.json$/, ""));
|
|
3290
3800
|
}
|
|
3291
3801
|
function readCapability(id) {
|
|
3292
3802
|
const filePath = getCapabilityPath(id);
|
|
3293
|
-
if (!
|
|
3803
|
+
if (!fs12.existsSync(filePath)) {
|
|
3294
3804
|
throw new Error(`Capability not found: ${id}`);
|
|
3295
3805
|
}
|
|
3296
3806
|
try {
|
|
3297
|
-
const content =
|
|
3807
|
+
const content = fs12.readFileSync(filePath, "utf-8");
|
|
3298
3808
|
return JSON.parse(content);
|
|
3299
3809
|
} catch (error) {
|
|
3300
3810
|
if (error instanceof SyntaxError) {
|
|
@@ -3321,11 +3831,11 @@ function readAllCapabilities() {
|
|
|
3321
3831
|
}
|
|
3322
3832
|
function readPluginManifest(pluginKey) {
|
|
3323
3833
|
const manifestPath = getPluginManifestPath(pluginKey);
|
|
3324
|
-
if (!
|
|
3834
|
+
if (!fs12.existsSync(manifestPath)) {
|
|
3325
3835
|
throw new Error(`Plugin not installed: ${pluginKey} (manifest.json not found)`);
|
|
3326
3836
|
}
|
|
3327
3837
|
try {
|
|
3328
|
-
const content =
|
|
3838
|
+
const content = fs12.readFileSync(manifestPath, "utf-8");
|
|
3329
3839
|
return JSON.parse(content);
|
|
3330
3840
|
} catch (error) {
|
|
3331
3841
|
if (error instanceof SyntaxError) {
|
|
@@ -3342,7 +3852,7 @@ function hasValidParamsSchema(paramsSchema) {
|
|
|
3342
3852
|
}
|
|
3343
3853
|
async function loadPlugin(pluginKey) {
|
|
3344
3854
|
try {
|
|
3345
|
-
const userRequire = createRequire2(
|
|
3855
|
+
const userRequire = createRequire2(path10.join(getProjectRoot2(), "package.json"));
|
|
3346
3856
|
const resolvedPath = userRequire.resolve(pluginKey);
|
|
3347
3857
|
const pluginModule = await import(resolvedPath);
|
|
3348
3858
|
const pluginPackage = pluginModule.default ?? pluginModule;
|
|
@@ -3501,9 +4011,12 @@ var capabilityCommandGroup = {
|
|
|
3501
4011
|
commands: [listCommand2]
|
|
3502
4012
|
};
|
|
3503
4013
|
|
|
4014
|
+
// src/commands/component/add.handler.ts
|
|
4015
|
+
import { execFile } from "child_process";
|
|
4016
|
+
|
|
3504
4017
|
// src/commands/component/registry-preparer.ts
|
|
3505
|
-
import
|
|
3506
|
-
import
|
|
4018
|
+
import fs13 from "fs";
|
|
4019
|
+
import path11 from "path";
|
|
3507
4020
|
import os from "os";
|
|
3508
4021
|
|
|
3509
4022
|
// src/commands/component/service.ts
|
|
@@ -3559,7 +4072,7 @@ async function sendInstallEvent(key) {
|
|
|
3559
4072
|
}
|
|
3560
4073
|
|
|
3561
4074
|
// src/commands/component/registry-preparer.ts
|
|
3562
|
-
var REGISTRY_TEMP_DIR =
|
|
4075
|
+
var REGISTRY_TEMP_DIR = path11.join(os.tmpdir(), "miaoda-registry");
|
|
3563
4076
|
function parseComponentKey(key) {
|
|
3564
4077
|
const match = key.match(/^@([^/]+)\/(.+)$/);
|
|
3565
4078
|
if (!match) {
|
|
@@ -3571,11 +4084,11 @@ function parseComponentKey(key) {
|
|
|
3571
4084
|
}
|
|
3572
4085
|
function getLocalRegistryPath(key) {
|
|
3573
4086
|
const { scope, name } = parseComponentKey(key);
|
|
3574
|
-
return
|
|
4087
|
+
return path11.join(REGISTRY_TEMP_DIR, scope, `${name}.json`);
|
|
3575
4088
|
}
|
|
3576
4089
|
function ensureDir(dirPath) {
|
|
3577
|
-
if (!
|
|
3578
|
-
|
|
4090
|
+
if (!fs13.existsSync(dirPath)) {
|
|
4091
|
+
fs13.mkdirSync(dirPath, { recursive: true });
|
|
3579
4092
|
}
|
|
3580
4093
|
}
|
|
3581
4094
|
async function prepareRecursive(key, visited) {
|
|
@@ -3608,8 +4121,8 @@ async function prepareRecursive(key, visited) {
|
|
|
3608
4121
|
registryDependencies: deps.map((dep) => getLocalRegistryPath(dep))
|
|
3609
4122
|
};
|
|
3610
4123
|
const localPath = getLocalRegistryPath(key);
|
|
3611
|
-
ensureDir(
|
|
3612
|
-
|
|
4124
|
+
ensureDir(path11.dirname(localPath));
|
|
4125
|
+
fs13.writeFileSync(localPath, JSON.stringify(rewrittenItem, null, 2), "utf-8");
|
|
3613
4126
|
debug("\u4FDD\u5B58\u5230: %s", localPath);
|
|
3614
4127
|
}
|
|
3615
4128
|
async function prepareComponentRegistryItems(id) {
|
|
@@ -3619,18 +4132,18 @@ async function prepareComponentRegistryItems(id) {
|
|
|
3619
4132
|
}
|
|
3620
4133
|
function cleanupTempDir() {
|
|
3621
4134
|
try {
|
|
3622
|
-
if (
|
|
3623
|
-
|
|
4135
|
+
if (fs13.existsSync(REGISTRY_TEMP_DIR)) {
|
|
4136
|
+
fs13.rmSync(REGISTRY_TEMP_DIR, { recursive: true, force: true });
|
|
3624
4137
|
}
|
|
3625
4138
|
} catch {
|
|
3626
4139
|
}
|
|
3627
4140
|
}
|
|
3628
4141
|
function getDownloadedRegistryItem(itemId) {
|
|
3629
4142
|
const localPath = getLocalRegistryPath(itemId);
|
|
3630
|
-
if (!
|
|
4143
|
+
if (!fs13.existsSync(localPath)) {
|
|
3631
4144
|
return null;
|
|
3632
4145
|
}
|
|
3633
|
-
const content =
|
|
4146
|
+
const content = fs13.readFileSync(localPath, "utf-8");
|
|
3634
4147
|
return JSON.parse(content);
|
|
3635
4148
|
}
|
|
3636
4149
|
|
|
@@ -3730,6 +4243,16 @@ async function executeShadcnAdd(registryItemPath) {
|
|
|
3730
4243
|
}
|
|
3731
4244
|
|
|
3732
4245
|
// src/commands/component/add.handler.ts
|
|
4246
|
+
function runActionPluginInit() {
|
|
4247
|
+
return new Promise((resolve) => {
|
|
4248
|
+
execFile("fullstack-cli", ["action-plugin", "init"], { cwd: process.cwd(), stdio: "ignore" }, (error) => {
|
|
4249
|
+
if (error) {
|
|
4250
|
+
debug("action-plugin init \u5931\u8D25: %s", error.message);
|
|
4251
|
+
}
|
|
4252
|
+
resolve();
|
|
4253
|
+
});
|
|
4254
|
+
});
|
|
4255
|
+
}
|
|
3733
4256
|
function printResult(result) {
|
|
3734
4257
|
console.log(JSON.stringify(result, null, 2));
|
|
3735
4258
|
}
|
|
@@ -3766,6 +4289,7 @@ async function add(key) {
|
|
|
3766
4289
|
errors: [{ message: errorMessage }]
|
|
3767
4290
|
});
|
|
3768
4291
|
} finally {
|
|
4292
|
+
await runActionPluginInit();
|
|
3769
4293
|
cleanupTempDir();
|
|
3770
4294
|
}
|
|
3771
4295
|
}
|
|
@@ -3787,58 +4311,58 @@ var componentCommandGroup = {
|
|
|
3787
4311
|
};
|
|
3788
4312
|
|
|
3789
4313
|
// src/commands/migration/version-manager.ts
|
|
3790
|
-
import
|
|
3791
|
-
import
|
|
4314
|
+
import fs14 from "fs";
|
|
4315
|
+
import path12 from "path";
|
|
3792
4316
|
var PACKAGE_JSON = "package.json";
|
|
3793
4317
|
var VERSION_FIELD = "migrationVersion";
|
|
3794
4318
|
function getPackageJsonPath2() {
|
|
3795
|
-
return
|
|
4319
|
+
return path12.join(process.cwd(), PACKAGE_JSON);
|
|
3796
4320
|
}
|
|
3797
4321
|
function getCurrentVersion() {
|
|
3798
4322
|
const pkgPath = getPackageJsonPath2();
|
|
3799
|
-
if (!
|
|
4323
|
+
if (!fs14.existsSync(pkgPath)) {
|
|
3800
4324
|
throw new Error("package.json not found");
|
|
3801
4325
|
}
|
|
3802
|
-
const pkg2 = JSON.parse(
|
|
4326
|
+
const pkg2 = JSON.parse(fs14.readFileSync(pkgPath, "utf-8"));
|
|
3803
4327
|
return pkg2[VERSION_FIELD] ?? 0;
|
|
3804
4328
|
}
|
|
3805
4329
|
function setCurrentVersion(version) {
|
|
3806
4330
|
const pkgPath = getPackageJsonPath2();
|
|
3807
|
-
const pkg2 = JSON.parse(
|
|
4331
|
+
const pkg2 = JSON.parse(fs14.readFileSync(pkgPath, "utf-8"));
|
|
3808
4332
|
pkg2[VERSION_FIELD] = version;
|
|
3809
|
-
|
|
4333
|
+
fs14.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
|
|
3810
4334
|
}
|
|
3811
4335
|
|
|
3812
4336
|
// src/commands/migration/versions/v001_capability/json-migrator/detector.ts
|
|
3813
|
-
import
|
|
3814
|
-
import
|
|
4337
|
+
import fs16 from "fs";
|
|
4338
|
+
import path14 from "path";
|
|
3815
4339
|
|
|
3816
4340
|
// src/commands/migration/versions/v001_capability/utils.ts
|
|
3817
|
-
import
|
|
3818
|
-
import
|
|
4341
|
+
import fs15 from "fs";
|
|
4342
|
+
import path13 from "path";
|
|
3819
4343
|
var CAPABILITIES_DIR2 = "server/capabilities";
|
|
3820
4344
|
function getProjectRoot3() {
|
|
3821
4345
|
return process.cwd();
|
|
3822
4346
|
}
|
|
3823
4347
|
function getCapabilitiesDir2() {
|
|
3824
|
-
return
|
|
4348
|
+
return path13.join(getProjectRoot3(), CAPABILITIES_DIR2);
|
|
3825
4349
|
}
|
|
3826
4350
|
function getPluginManifestPath2(pluginKey) {
|
|
3827
|
-
return
|
|
4351
|
+
return path13.join(getProjectRoot3(), "node_modules", pluginKey, "manifest.json");
|
|
3828
4352
|
}
|
|
3829
4353
|
|
|
3830
4354
|
// src/commands/migration/versions/v001_capability/json-migrator/detector.ts
|
|
3831
4355
|
function detectJsonMigration() {
|
|
3832
4356
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
3833
|
-
const oldFilePath =
|
|
3834
|
-
if (!
|
|
4357
|
+
const oldFilePath = path14.join(capabilitiesDir, "capabilities.json");
|
|
4358
|
+
if (!fs16.existsSync(oldFilePath)) {
|
|
3835
4359
|
return {
|
|
3836
4360
|
needsMigration: false,
|
|
3837
4361
|
reason: "capabilities.json not found"
|
|
3838
4362
|
};
|
|
3839
4363
|
}
|
|
3840
4364
|
try {
|
|
3841
|
-
const content =
|
|
4365
|
+
const content = fs16.readFileSync(oldFilePath, "utf-8");
|
|
3842
4366
|
const parsed = JSON.parse(content);
|
|
3843
4367
|
if (!Array.isArray(parsed)) {
|
|
3844
4368
|
return {
|
|
@@ -3889,8 +4413,8 @@ async function check(options) {
|
|
|
3889
4413
|
}
|
|
3890
4414
|
|
|
3891
4415
|
// src/commands/migration/versions/v001_capability/json-migrator/index.ts
|
|
3892
|
-
import
|
|
3893
|
-
import
|
|
4416
|
+
import fs17 from "fs";
|
|
4417
|
+
import path15 from "path";
|
|
3894
4418
|
|
|
3895
4419
|
// src/commands/migration/versions/v001_capability/mapping.ts
|
|
3896
4420
|
var DEFAULT_PLUGIN_VERSION = "1.0.0";
|
|
@@ -4120,18 +4644,18 @@ function transformCapabilities(oldCapabilities) {
|
|
|
4120
4644
|
// src/commands/migration/versions/v001_capability/json-migrator/index.ts
|
|
4121
4645
|
function loadExistingCapabilities() {
|
|
4122
4646
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
4123
|
-
if (!
|
|
4647
|
+
if (!fs17.existsSync(capabilitiesDir)) {
|
|
4124
4648
|
return [];
|
|
4125
4649
|
}
|
|
4126
|
-
const files =
|
|
4650
|
+
const files = fs17.readdirSync(capabilitiesDir);
|
|
4127
4651
|
const capabilities = [];
|
|
4128
4652
|
for (const file of files) {
|
|
4129
4653
|
if (file === "capabilities.json" || !file.endsWith(".json")) {
|
|
4130
4654
|
continue;
|
|
4131
4655
|
}
|
|
4132
4656
|
try {
|
|
4133
|
-
const filePath =
|
|
4134
|
-
const content =
|
|
4657
|
+
const filePath = path15.join(capabilitiesDir, file);
|
|
4658
|
+
const content = fs17.readFileSync(filePath, "utf-8");
|
|
4135
4659
|
const capability = JSON.parse(content);
|
|
4136
4660
|
if (capability.id && capability.pluginKey) {
|
|
4137
4661
|
capabilities.push(capability);
|
|
@@ -4189,9 +4713,9 @@ async function migrateJsonFiles(options) {
|
|
|
4189
4713
|
}
|
|
4190
4714
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
4191
4715
|
for (const cap of newCapabilities) {
|
|
4192
|
-
const filePath =
|
|
4716
|
+
const filePath = path15.join(capabilitiesDir, `${cap.id}.json`);
|
|
4193
4717
|
const content = JSON.stringify(cap, null, 2);
|
|
4194
|
-
|
|
4718
|
+
fs17.writeFileSync(filePath, content, "utf-8");
|
|
4195
4719
|
console.log(` \u2713 Created: ${cap.id}.json`);
|
|
4196
4720
|
}
|
|
4197
4721
|
return {
|
|
@@ -4203,11 +4727,11 @@ async function migrateJsonFiles(options) {
|
|
|
4203
4727
|
}
|
|
4204
4728
|
|
|
4205
4729
|
// src/commands/migration/versions/v001_capability/plugin-installer/detector.ts
|
|
4206
|
-
import
|
|
4730
|
+
import fs18 from "fs";
|
|
4207
4731
|
function isPluginInstalled2(pluginKey) {
|
|
4208
4732
|
const actionPlugins = readActionPlugins();
|
|
4209
4733
|
const manifestPath = getPluginManifestPath2(pluginKey);
|
|
4210
|
-
return
|
|
4734
|
+
return fs18.existsSync(manifestPath) && !!actionPlugins[pluginKey];
|
|
4211
4735
|
}
|
|
4212
4736
|
function detectPluginsToInstall(capabilities) {
|
|
4213
4737
|
const pluginKeys = /* @__PURE__ */ new Set();
|
|
@@ -4283,12 +4807,12 @@ async function installPlugins(capabilities, options) {
|
|
|
4283
4807
|
}
|
|
4284
4808
|
|
|
4285
4809
|
// src/commands/migration/versions/v001_capability/code-migrator/index.ts
|
|
4286
|
-
import
|
|
4810
|
+
import path17 from "path";
|
|
4287
4811
|
import { Project as Project3 } from "ts-morph";
|
|
4288
4812
|
|
|
4289
4813
|
// src/commands/migration/versions/v001_capability/code-migrator/scanner.ts
|
|
4290
|
-
import
|
|
4291
|
-
import
|
|
4814
|
+
import fs19 from "fs";
|
|
4815
|
+
import path16 from "path";
|
|
4292
4816
|
var EXCLUDED_DIRS = [
|
|
4293
4817
|
"node_modules",
|
|
4294
4818
|
"dist",
|
|
@@ -4303,9 +4827,9 @@ var EXCLUDED_PATTERNS = [
|
|
|
4303
4827
|
/\.d\.ts$/
|
|
4304
4828
|
];
|
|
4305
4829
|
function scanDirectory(dir, files = []) {
|
|
4306
|
-
const entries =
|
|
4830
|
+
const entries = fs19.readdirSync(dir, { withFileTypes: true });
|
|
4307
4831
|
for (const entry of entries) {
|
|
4308
|
-
const fullPath =
|
|
4832
|
+
const fullPath = path16.join(dir, entry.name);
|
|
4309
4833
|
if (entry.isDirectory()) {
|
|
4310
4834
|
if (EXCLUDED_DIRS.includes(entry.name)) {
|
|
4311
4835
|
continue;
|
|
@@ -4321,14 +4845,14 @@ function scanDirectory(dir, files = []) {
|
|
|
4321
4845
|
return files;
|
|
4322
4846
|
}
|
|
4323
4847
|
function scanServerFiles() {
|
|
4324
|
-
const serverDir =
|
|
4325
|
-
if (!
|
|
4848
|
+
const serverDir = path16.join(getProjectRoot3(), "server");
|
|
4849
|
+
if (!fs19.existsSync(serverDir)) {
|
|
4326
4850
|
return [];
|
|
4327
4851
|
}
|
|
4328
4852
|
return scanDirectory(serverDir);
|
|
4329
4853
|
}
|
|
4330
4854
|
function hasCapabilityImport(filePath) {
|
|
4331
|
-
const content =
|
|
4855
|
+
const content = fs19.readFileSync(filePath, "utf-8");
|
|
4332
4856
|
return /import\s+.*from\s+['"][^'"]*capabilities[^'"]*['"]/.test(content);
|
|
4333
4857
|
}
|
|
4334
4858
|
function scanFilesToMigrate() {
|
|
@@ -4705,7 +5229,7 @@ function analyzeFile(project, filePath, actionNameMap) {
|
|
|
4705
5229
|
const callSites = analyzeCallSites(sourceFile, imports);
|
|
4706
5230
|
const classInfo = analyzeClass(sourceFile);
|
|
4707
5231
|
const { canMigrate, reason } = canAutoMigrate(classInfo);
|
|
4708
|
-
const relativePath =
|
|
5232
|
+
const relativePath = path17.relative(getProjectRoot3(), filePath);
|
|
4709
5233
|
return {
|
|
4710
5234
|
filePath: relativePath,
|
|
4711
5235
|
imports,
|
|
@@ -4716,7 +5240,7 @@ function analyzeFile(project, filePath, actionNameMap) {
|
|
|
4716
5240
|
};
|
|
4717
5241
|
}
|
|
4718
5242
|
function migrateFile(project, analysis, dryRun) {
|
|
4719
|
-
const absolutePath =
|
|
5243
|
+
const absolutePath = path17.join(getProjectRoot3(), analysis.filePath);
|
|
4720
5244
|
if (!analysis.canAutoMigrate) {
|
|
4721
5245
|
return {
|
|
4722
5246
|
filePath: analysis.filePath,
|
|
@@ -4819,17 +5343,17 @@ function getSuggestion(analysis) {
|
|
|
4819
5343
|
}
|
|
4820
5344
|
|
|
4821
5345
|
// src/commands/migration/versions/v001_capability/cleanup.ts
|
|
4822
|
-
import
|
|
4823
|
-
import
|
|
5346
|
+
import fs20 from "fs";
|
|
5347
|
+
import path18 from "path";
|
|
4824
5348
|
function cleanupOldFiles(capabilities, dryRun) {
|
|
4825
5349
|
const deletedFiles = [];
|
|
4826
5350
|
const errors = [];
|
|
4827
5351
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
4828
|
-
const oldJsonPath =
|
|
4829
|
-
if (
|
|
5352
|
+
const oldJsonPath = path18.join(capabilitiesDir, "capabilities.json");
|
|
5353
|
+
if (fs20.existsSync(oldJsonPath)) {
|
|
4830
5354
|
try {
|
|
4831
5355
|
if (!dryRun) {
|
|
4832
|
-
|
|
5356
|
+
fs20.unlinkSync(oldJsonPath);
|
|
4833
5357
|
}
|
|
4834
5358
|
deletedFiles.push("capabilities.json");
|
|
4835
5359
|
} catch (error) {
|
|
@@ -4837,11 +5361,11 @@ function cleanupOldFiles(capabilities, dryRun) {
|
|
|
4837
5361
|
}
|
|
4838
5362
|
}
|
|
4839
5363
|
for (const cap of capabilities) {
|
|
4840
|
-
const tsFilePath =
|
|
4841
|
-
if (
|
|
5364
|
+
const tsFilePath = path18.join(capabilitiesDir, `${cap.id}.ts`);
|
|
5365
|
+
if (fs20.existsSync(tsFilePath)) {
|
|
4842
5366
|
try {
|
|
4843
5367
|
if (!dryRun) {
|
|
4844
|
-
|
|
5368
|
+
fs20.unlinkSync(tsFilePath);
|
|
4845
5369
|
}
|
|
4846
5370
|
deletedFiles.push(`${cap.id}.ts`);
|
|
4847
5371
|
} catch (error) {
|
|
@@ -4857,8 +5381,8 @@ function cleanupOldFiles(capabilities, dryRun) {
|
|
|
4857
5381
|
}
|
|
4858
5382
|
|
|
4859
5383
|
// src/commands/migration/versions/v001_capability/report-generator.ts
|
|
4860
|
-
import
|
|
4861
|
-
import
|
|
5384
|
+
import fs21 from "fs";
|
|
5385
|
+
import path19 from "path";
|
|
4862
5386
|
var REPORT_FILE = "capability-migration-report.md";
|
|
4863
5387
|
function printSummary(result) {
|
|
4864
5388
|
const { jsonMigration, pluginInstallation, codeMigration, cleanup } = result;
|
|
@@ -5021,15 +5545,15 @@ async function generateReport(result) {
|
|
|
5021
5545
|
}
|
|
5022
5546
|
lines.push("");
|
|
5023
5547
|
const logDir = process.env.LOG_DIR || "logs";
|
|
5024
|
-
if (!
|
|
5548
|
+
if (!fs21.existsSync(logDir)) {
|
|
5025
5549
|
return;
|
|
5026
5550
|
}
|
|
5027
|
-
const reportDir =
|
|
5028
|
-
if (!
|
|
5029
|
-
|
|
5551
|
+
const reportDir = path19.join(logDir, "migration");
|
|
5552
|
+
if (!fs21.existsSync(reportDir)) {
|
|
5553
|
+
fs21.mkdirSync(reportDir, { recursive: true });
|
|
5030
5554
|
}
|
|
5031
|
-
const reportPath =
|
|
5032
|
-
|
|
5555
|
+
const reportPath = path19.join(reportDir, REPORT_FILE);
|
|
5556
|
+
fs21.writeFileSync(reportPath, lines.join("\n"), "utf-8");
|
|
5033
5557
|
console.log(`\u{1F4C4} Report generated: ${reportPath}`);
|
|
5034
5558
|
}
|
|
5035
5559
|
|
|
@@ -5206,7 +5730,7 @@ function buildResult(jsonMigration, pluginInstallation, codeMigration, cleanup)
|
|
|
5206
5730
|
}
|
|
5207
5731
|
|
|
5208
5732
|
// src/commands/migration/versions/v001_capability/run.ts
|
|
5209
|
-
async function
|
|
5733
|
+
async function run5(options) {
|
|
5210
5734
|
try {
|
|
5211
5735
|
const migrationOptions = {
|
|
5212
5736
|
dryRun: options.dryRun ?? false
|
|
@@ -5271,7 +5795,7 @@ var v001CapabilityMigration = {
|
|
|
5271
5795
|
name: "capability",
|
|
5272
5796
|
description: "Migrate capability configurations from old format (capabilities.json array) to new format (individual JSON files)",
|
|
5273
5797
|
check,
|
|
5274
|
-
run:
|
|
5798
|
+
run: run5
|
|
5275
5799
|
};
|
|
5276
5800
|
|
|
5277
5801
|
// src/commands/migration/versions/index.ts
|
|
@@ -5561,10 +6085,10 @@ var migrationCommand = {
|
|
|
5561
6085
|
};
|
|
5562
6086
|
|
|
5563
6087
|
// src/commands/read-logs/index.ts
|
|
5564
|
-
import
|
|
6088
|
+
import path20 from "path";
|
|
5565
6089
|
|
|
5566
6090
|
// src/commands/read-logs/std-utils.ts
|
|
5567
|
-
import
|
|
6091
|
+
import fs22 from "fs";
|
|
5568
6092
|
function formatStdPrefixTime(localTime) {
|
|
5569
6093
|
const match = localTime.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
|
|
5570
6094
|
if (!match) return localTime;
|
|
@@ -5594,11 +6118,11 @@ function stripPrefixFromStdLine(line) {
|
|
|
5594
6118
|
return `[${time}] ${content}`;
|
|
5595
6119
|
}
|
|
5596
6120
|
function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarker) {
|
|
5597
|
-
const stat =
|
|
6121
|
+
const stat = fs22.statSync(filePath);
|
|
5598
6122
|
if (stat.size === 0) {
|
|
5599
6123
|
return { lines: [], markerFound: false, totalLinesCount: 0 };
|
|
5600
6124
|
}
|
|
5601
|
-
const fd =
|
|
6125
|
+
const fd = fs22.openSync(filePath, "r");
|
|
5602
6126
|
const chunkSize = 64 * 1024;
|
|
5603
6127
|
let position = stat.size;
|
|
5604
6128
|
let remainder = "";
|
|
@@ -5612,7 +6136,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
|
|
|
5612
6136
|
const length = Math.min(chunkSize, position);
|
|
5613
6137
|
position -= length;
|
|
5614
6138
|
const buffer = Buffer.alloc(length);
|
|
5615
|
-
|
|
6139
|
+
fs22.readSync(fd, buffer, 0, length, position);
|
|
5616
6140
|
let chunk = buffer.toString("utf8");
|
|
5617
6141
|
if (remainder) {
|
|
5618
6142
|
chunk += remainder;
|
|
@@ -5654,7 +6178,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
|
|
|
5654
6178
|
}
|
|
5655
6179
|
}
|
|
5656
6180
|
} finally {
|
|
5657
|
-
|
|
6181
|
+
fs22.closeSync(fd);
|
|
5658
6182
|
}
|
|
5659
6183
|
return { lines: collected.reverse(), markerFound, totalLinesCount };
|
|
5660
6184
|
}
|
|
@@ -5675,21 +6199,21 @@ function readServerStdSegment(filePath, maxLines, offset) {
|
|
|
5675
6199
|
}
|
|
5676
6200
|
|
|
5677
6201
|
// src/commands/read-logs/tail.ts
|
|
5678
|
-
import
|
|
6202
|
+
import fs23 from "fs";
|
|
5679
6203
|
function fileExists(filePath) {
|
|
5680
6204
|
try {
|
|
5681
|
-
|
|
6205
|
+
fs23.accessSync(filePath, fs23.constants.F_OK | fs23.constants.R_OK);
|
|
5682
6206
|
return true;
|
|
5683
6207
|
} catch {
|
|
5684
6208
|
return false;
|
|
5685
6209
|
}
|
|
5686
6210
|
}
|
|
5687
6211
|
function readFileTailLines(filePath, maxLines) {
|
|
5688
|
-
const stat =
|
|
6212
|
+
const stat = fs23.statSync(filePath);
|
|
5689
6213
|
if (stat.size === 0) {
|
|
5690
6214
|
return [];
|
|
5691
6215
|
}
|
|
5692
|
-
const fd =
|
|
6216
|
+
const fd = fs23.openSync(filePath, "r");
|
|
5693
6217
|
const chunkSize = 64 * 1024;
|
|
5694
6218
|
const chunks = [];
|
|
5695
6219
|
let position = stat.size;
|
|
@@ -5699,13 +6223,13 @@ function readFileTailLines(filePath, maxLines) {
|
|
|
5699
6223
|
const length = Math.min(chunkSize, position);
|
|
5700
6224
|
position -= length;
|
|
5701
6225
|
const buffer = Buffer.alloc(length);
|
|
5702
|
-
|
|
6226
|
+
fs23.readSync(fd, buffer, 0, length, position);
|
|
5703
6227
|
chunks.unshift(buffer.toString("utf8"));
|
|
5704
6228
|
const chunkLines = buffer.toString("utf8").split("\n").length - 1;
|
|
5705
6229
|
collectedLines += chunkLines;
|
|
5706
6230
|
}
|
|
5707
6231
|
} finally {
|
|
5708
|
-
|
|
6232
|
+
fs23.closeSync(fd);
|
|
5709
6233
|
}
|
|
5710
6234
|
const content = chunks.join("");
|
|
5711
6235
|
const allLines = content.split("\n");
|
|
@@ -5721,11 +6245,11 @@ function readFileTailLines(filePath, maxLines) {
|
|
|
5721
6245
|
return allLines.slice(allLines.length - maxLines);
|
|
5722
6246
|
}
|
|
5723
6247
|
function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
5724
|
-
const stat =
|
|
6248
|
+
const stat = fs23.statSync(filePath);
|
|
5725
6249
|
if (stat.size === 0) {
|
|
5726
6250
|
return { lines: [], totalLinesCount: 0 };
|
|
5727
6251
|
}
|
|
5728
|
-
const fd =
|
|
6252
|
+
const fd = fs23.openSync(filePath, "r");
|
|
5729
6253
|
const chunkSize = 64 * 1024;
|
|
5730
6254
|
let position = stat.size;
|
|
5731
6255
|
let remainder = "";
|
|
@@ -5737,7 +6261,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
|
5737
6261
|
const length = Math.min(chunkSize, position);
|
|
5738
6262
|
position -= length;
|
|
5739
6263
|
const buffer = Buffer.alloc(length);
|
|
5740
|
-
|
|
6264
|
+
fs23.readSync(fd, buffer, 0, length, position);
|
|
5741
6265
|
let chunk = buffer.toString("utf8");
|
|
5742
6266
|
if (remainder) {
|
|
5743
6267
|
chunk += remainder;
|
|
@@ -5768,7 +6292,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
|
5768
6292
|
}
|
|
5769
6293
|
}
|
|
5770
6294
|
} finally {
|
|
5771
|
-
|
|
6295
|
+
fs23.closeSync(fd);
|
|
5772
6296
|
}
|
|
5773
6297
|
return { lines: collected.reverse(), totalLinesCount };
|
|
5774
6298
|
}
|
|
@@ -5910,7 +6434,7 @@ function readDevStdSegment(filePath, maxLines, offset) {
|
|
|
5910
6434
|
}
|
|
5911
6435
|
|
|
5912
6436
|
// src/commands/read-logs/json-lines.ts
|
|
5913
|
-
import
|
|
6437
|
+
import fs24 from "fs";
|
|
5914
6438
|
function normalizePid(value) {
|
|
5915
6439
|
if (typeof value === "number") {
|
|
5916
6440
|
return String(value);
|
|
@@ -5961,11 +6485,11 @@ function buildWantedLevelSet(levels) {
|
|
|
5961
6485
|
return set.size > 0 ? set : null;
|
|
5962
6486
|
}
|
|
5963
6487
|
function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
5964
|
-
const stat =
|
|
6488
|
+
const stat = fs24.statSync(filePath);
|
|
5965
6489
|
if (stat.size === 0) {
|
|
5966
6490
|
return { lines: [], totalLinesCount: 0 };
|
|
5967
6491
|
}
|
|
5968
|
-
const fd =
|
|
6492
|
+
const fd = fs24.openSync(filePath, "r");
|
|
5969
6493
|
const chunkSize = 64 * 1024;
|
|
5970
6494
|
let position = stat.size;
|
|
5971
6495
|
let remainder = "";
|
|
@@ -5980,7 +6504,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
|
5980
6504
|
const length = Math.min(chunkSize, position);
|
|
5981
6505
|
position -= length;
|
|
5982
6506
|
const buffer = Buffer.alloc(length);
|
|
5983
|
-
|
|
6507
|
+
fs24.readSync(fd, buffer, 0, length, position);
|
|
5984
6508
|
let chunk = buffer.toString("utf8");
|
|
5985
6509
|
if (remainder) {
|
|
5986
6510
|
chunk += remainder;
|
|
@@ -6042,7 +6566,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
|
6042
6566
|
}
|
|
6043
6567
|
}
|
|
6044
6568
|
} finally {
|
|
6045
|
-
|
|
6569
|
+
fs24.closeSync(fd);
|
|
6046
6570
|
}
|
|
6047
6571
|
return { lines: collected.reverse(), totalLinesCount };
|
|
6048
6572
|
}
|
|
@@ -6085,11 +6609,11 @@ function extractTraceId(obj) {
|
|
|
6085
6609
|
function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
6086
6610
|
const wanted = traceId.trim();
|
|
6087
6611
|
if (!wanted) return { lines: [], totalLinesCount: 0 };
|
|
6088
|
-
const stat =
|
|
6612
|
+
const stat = fs24.statSync(filePath);
|
|
6089
6613
|
if (stat.size === 0) {
|
|
6090
6614
|
return { lines: [], totalLinesCount: 0 };
|
|
6091
6615
|
}
|
|
6092
|
-
const fd =
|
|
6616
|
+
const fd = fs24.openSync(filePath, "r");
|
|
6093
6617
|
const chunkSize = 64 * 1024;
|
|
6094
6618
|
let position = stat.size;
|
|
6095
6619
|
let remainder = "";
|
|
@@ -6102,7 +6626,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
|
6102
6626
|
const length = Math.min(chunkSize, position);
|
|
6103
6627
|
position -= length;
|
|
6104
6628
|
const buffer = Buffer.alloc(length);
|
|
6105
|
-
|
|
6629
|
+
fs24.readSync(fd, buffer, 0, length, position);
|
|
6106
6630
|
let chunk = buffer.toString("utf8");
|
|
6107
6631
|
if (remainder) {
|
|
6108
6632
|
chunk += remainder;
|
|
@@ -6155,7 +6679,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
|
6155
6679
|
}
|
|
6156
6680
|
}
|
|
6157
6681
|
} finally {
|
|
6158
|
-
|
|
6682
|
+
fs24.closeSync(fd);
|
|
6159
6683
|
}
|
|
6160
6684
|
return { lines: collected.reverse(), totalLinesCount };
|
|
6161
6685
|
}
|
|
@@ -6164,11 +6688,11 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
6164
6688
|
if (!wantedLevelSet) {
|
|
6165
6689
|
return { lines: [], totalLinesCount: 0 };
|
|
6166
6690
|
}
|
|
6167
|
-
const stat =
|
|
6691
|
+
const stat = fs24.statSync(filePath);
|
|
6168
6692
|
if (stat.size === 0) {
|
|
6169
6693
|
return { lines: [], totalLinesCount: 0 };
|
|
6170
6694
|
}
|
|
6171
|
-
const fd =
|
|
6695
|
+
const fd = fs24.openSync(filePath, "r");
|
|
6172
6696
|
const chunkSize = 64 * 1024;
|
|
6173
6697
|
let position = stat.size;
|
|
6174
6698
|
let remainder = "";
|
|
@@ -6180,7 +6704,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
6180
6704
|
const length = Math.min(chunkSize, position);
|
|
6181
6705
|
position -= length;
|
|
6182
6706
|
const buffer = Buffer.alloc(length);
|
|
6183
|
-
|
|
6707
|
+
fs24.readSync(fd, buffer, 0, length, position);
|
|
6184
6708
|
let chunk = buffer.toString("utf8");
|
|
6185
6709
|
if (remainder) {
|
|
6186
6710
|
chunk += remainder;
|
|
@@ -6227,7 +6751,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
6227
6751
|
}
|
|
6228
6752
|
}
|
|
6229
6753
|
} finally {
|
|
6230
|
-
|
|
6754
|
+
fs24.closeSync(fd);
|
|
6231
6755
|
}
|
|
6232
6756
|
return { lines: collected.reverse(), totalLinesCount };
|
|
6233
6757
|
}
|
|
@@ -6461,34 +6985,34 @@ async function readLogsJsonResult(options) {
|
|
|
6461
6985
|
};
|
|
6462
6986
|
}
|
|
6463
6987
|
function resolveLogFilePath(logDir, type) {
|
|
6464
|
-
const base =
|
|
6988
|
+
const base = path20.isAbsolute(logDir) ? logDir : path20.join(process.cwd(), logDir);
|
|
6465
6989
|
if (type === "server") {
|
|
6466
|
-
return
|
|
6990
|
+
return path20.join(base, "server.log");
|
|
6467
6991
|
}
|
|
6468
6992
|
if (type === "trace") {
|
|
6469
|
-
return
|
|
6993
|
+
return path20.join(base, "trace.log");
|
|
6470
6994
|
}
|
|
6471
6995
|
if (type === "server-std") {
|
|
6472
|
-
return
|
|
6996
|
+
return path20.join(base, "server.std.log");
|
|
6473
6997
|
}
|
|
6474
6998
|
if (type === "client-std") {
|
|
6475
|
-
return
|
|
6999
|
+
return path20.join(base, "client.std.log");
|
|
6476
7000
|
}
|
|
6477
7001
|
if (type === "dev") {
|
|
6478
|
-
return
|
|
7002
|
+
return path20.join(base, "dev.log");
|
|
6479
7003
|
}
|
|
6480
7004
|
if (type === "dev-std") {
|
|
6481
|
-
return
|
|
7005
|
+
return path20.join(base, "dev.std.log");
|
|
6482
7006
|
}
|
|
6483
7007
|
if (type === "install-dep-std") {
|
|
6484
|
-
return
|
|
7008
|
+
return path20.join(base, "install-dep.std.log");
|
|
6485
7009
|
}
|
|
6486
7010
|
if (type === "browser") {
|
|
6487
|
-
return
|
|
7011
|
+
return path20.join(base, "browser.log");
|
|
6488
7012
|
}
|
|
6489
7013
|
throw new Error(`Unsupported log type: ${type}`);
|
|
6490
7014
|
}
|
|
6491
|
-
async function
|
|
7015
|
+
async function run6(options) {
|
|
6492
7016
|
const result = await readLogsJsonResult(options);
|
|
6493
7017
|
process.stdout.write(JSON.stringify(result) + "\n");
|
|
6494
7018
|
}
|
|
@@ -6530,7 +7054,7 @@ var readLogsCommand = {
|
|
|
6530
7054
|
const offset = parseNonNegativeInt(rawOptions.offset, "--offset");
|
|
6531
7055
|
const traceId = typeof rawOptions.traceId === "string" ? rawOptions.traceId : void 0;
|
|
6532
7056
|
const levels = parseCommaSeparatedList(rawOptions.level);
|
|
6533
|
-
await
|
|
7057
|
+
await run6({ logDir, type, maxLines, offset, traceId, levels });
|
|
6534
7058
|
} catch (error) {
|
|
6535
7059
|
const message = error instanceof Error ? error.message : String(error);
|
|
6536
7060
|
process.stderr.write(message + "\n");
|
|
@@ -6619,6 +7143,7 @@ var buildCommandGroup = {
|
|
|
6619
7143
|
var commands = [
|
|
6620
7144
|
genDbSchemaCommand,
|
|
6621
7145
|
syncCommand,
|
|
7146
|
+
upgradeCommand,
|
|
6622
7147
|
actionPluginCommandGroup,
|
|
6623
7148
|
capabilityCommandGroup,
|
|
6624
7149
|
componentCommandGroup,
|
|
@@ -6628,12 +7153,12 @@ var commands = [
|
|
|
6628
7153
|
];
|
|
6629
7154
|
|
|
6630
7155
|
// src/index.ts
|
|
6631
|
-
var envPath =
|
|
6632
|
-
if (
|
|
7156
|
+
var envPath = path21.join(process.cwd(), ".env");
|
|
7157
|
+
if (fs25.existsSync(envPath)) {
|
|
6633
7158
|
dotenvConfig({ path: envPath });
|
|
6634
7159
|
}
|
|
6635
|
-
var __dirname =
|
|
6636
|
-
var pkg = JSON.parse(
|
|
7160
|
+
var __dirname = path21.dirname(fileURLToPath5(import.meta.url));
|
|
7161
|
+
var pkg = JSON.parse(fs25.readFileSync(path21.join(__dirname, "../package.json"), "utf-8"));
|
|
6637
7162
|
var cli = new FullstackCLI(pkg.version);
|
|
6638
7163
|
cli.useAll(commands);
|
|
6639
7164
|
cli.run();
|