@lark-apaas/fullstack-cli 1.1.22-alpha.2 → 1.1.22-alpha.21
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 +883 -269
- package/package.json +1 -1
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,112 @@ 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
|
+
var DEFAULT_TIMEOUT_MS2 = 1e4;
|
|
1408
|
+
async function fetchSyncedTables(appId, workspace) {
|
|
1409
|
+
try {
|
|
1410
|
+
const client = getHttpClient();
|
|
1411
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
1412
|
+
setTimeout(
|
|
1413
|
+
() => reject(new Error(`Timeout after ${DEFAULT_TIMEOUT_MS2}ms`)),
|
|
1414
|
+
DEFAULT_TIMEOUT_MS2
|
|
1415
|
+
);
|
|
1416
|
+
});
|
|
1417
|
+
const start = Date.now();
|
|
1418
|
+
console.log(
|
|
1419
|
+
`[fetchSyncedTables] \u2192 GET listTableView (dbBranch=main) appId=${appId ? "set" : "unset"} workspace=${workspace ? "set" : "unset"}`
|
|
1420
|
+
);
|
|
1421
|
+
const response = await Promise.race([
|
|
1422
|
+
client.get(
|
|
1423
|
+
`/api/v1/dataloom/inner/app/${appId}/workspaces/${workspace}/listTableView`,
|
|
1424
|
+
{ params: { dbBranch: "main" }, headers: { "x-supaas-bizsource": "miaoda" } }
|
|
1425
|
+
),
|
|
1426
|
+
timeoutPromise
|
|
1427
|
+
]);
|
|
1428
|
+
console.log(
|
|
1429
|
+
`[fetchSyncedTables] \u2190 listTableView response: ${response.status} ${response.statusText} (${Date.now() - start}ms) with logId=${response.headers.get("x-tt-logid")}`
|
|
1430
|
+
);
|
|
1431
|
+
if (!response.ok) {
|
|
1432
|
+
throw new Error(
|
|
1433
|
+
`listTableView API failed: ${response.status} ${response.statusText}`
|
|
1434
|
+
);
|
|
1435
|
+
}
|
|
1436
|
+
let json;
|
|
1437
|
+
try {
|
|
1438
|
+
json = await response.json();
|
|
1439
|
+
} catch (error) {
|
|
1440
|
+
console.warn(
|
|
1441
|
+
"[fetchSyncedTables] \u26A0 Failed to parse listTableView response JSON, returning empty map:",
|
|
1442
|
+
error instanceof Error ? error.message : String(error)
|
|
1443
|
+
);
|
|
1444
|
+
return /* @__PURE__ */ new Map();
|
|
1445
|
+
}
|
|
1446
|
+
const tableView = json?.data?.data;
|
|
1447
|
+
if (!tableView) {
|
|
1448
|
+
console.warn(
|
|
1449
|
+
"[fetchSyncedTables] \u26A0 listTableView response missing data.data, returning empty map"
|
|
1450
|
+
);
|
|
1451
|
+
return /* @__PURE__ */ new Map();
|
|
1452
|
+
}
|
|
1453
|
+
const syncedMap = extractSyncedTableMap(tableView);
|
|
1454
|
+
const totalCount = (tableView.table?.data?.length ?? 0) + (tableView.view?.data?.length ?? 0) + (tableView.materializedView?.data?.length ?? 0);
|
|
1455
|
+
console.log(
|
|
1456
|
+
`[fetchSyncedTables] \u2713 Extracted synced tables: ${syncedMap.size}/${totalCount} (elapsed ${Date.now() - start}ms)`
|
|
1457
|
+
);
|
|
1458
|
+
return syncedMap;
|
|
1459
|
+
} catch (error) {
|
|
1460
|
+
console.error(
|
|
1461
|
+
"[fetchSyncedTables] \u274C Error fetching synced tables:",
|
|
1462
|
+
error
|
|
1463
|
+
);
|
|
1464
|
+
return /* @__PURE__ */ new Map();
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
function extractSyncedTableMap(tableView) {
|
|
1468
|
+
const syncedMap = /* @__PURE__ */ new Map();
|
|
1469
|
+
const allTables = [
|
|
1470
|
+
...tableView.table?.data ?? [],
|
|
1471
|
+
...tableView.view?.data ?? [],
|
|
1472
|
+
...tableView.materializedView?.data ?? []
|
|
1473
|
+
];
|
|
1474
|
+
for (const table of allTables) {
|
|
1475
|
+
if (table.bitableSyncTask && table.bitableSyncTask.fieldApiNameList?.length > 0) {
|
|
1476
|
+
syncedMap.set(
|
|
1477
|
+
table.tableName,
|
|
1478
|
+
new Set(table.bitableSyncTask.fieldApiNameList)
|
|
1479
|
+
);
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
return syncedMap;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1298
1485
|
// src/commands/db/gen-nest-resource/generator.ts
|
|
1299
1486
|
import { pluralize } from "inflection";
|
|
1300
1487
|
|
|
@@ -1973,7 +2160,9 @@ async function run(options = {}) {
|
|
|
1973
2160
|
}
|
|
1974
2161
|
const databaseUrl = process.env.SUDA_DATABASE_URL;
|
|
1975
2162
|
if (!databaseUrl) {
|
|
1976
|
-
console.error(
|
|
2163
|
+
console.error(
|
|
2164
|
+
"[gen-db-schema] Error: SUDA_DATABASE_URL environment variable is required"
|
|
2165
|
+
);
|
|
1977
2166
|
process.exit(1);
|
|
1978
2167
|
}
|
|
1979
2168
|
const outputPath = options.output || process.env.DB_SCHEMA_OUTPUT || "server/database/schema.ts";
|
|
@@ -1988,9 +2177,14 @@ async function run(options = {}) {
|
|
|
1988
2177
|
path2.resolve(__dirname2, "../../../dist/config/drizzle.config.js")
|
|
1989
2178
|
];
|
|
1990
2179
|
const configPath = configPathCandidates.find((p) => fs4.existsSync(p));
|
|
1991
|
-
console.log(
|
|
2180
|
+
console.log(
|
|
2181
|
+
"[gen-db-schema] Using drizzle config from:",
|
|
2182
|
+
configPath ?? "(not found)"
|
|
2183
|
+
);
|
|
1992
2184
|
if (!configPath) {
|
|
1993
|
-
console.error(
|
|
2185
|
+
console.error(
|
|
2186
|
+
"[gen-db-schema] Error: drizzle config not found in CLI package"
|
|
2187
|
+
);
|
|
1994
2188
|
process.exit(1);
|
|
1995
2189
|
}
|
|
1996
2190
|
const resolveDrizzleKitBin = () => {
|
|
@@ -2006,7 +2200,9 @@ async function run(options = {}) {
|
|
|
2006
2200
|
const binField = pkgJson.bin;
|
|
2007
2201
|
const binRelPath = typeof binField === "string" ? binField : binField?.["drizzle-kit"];
|
|
2008
2202
|
if (!binRelPath) {
|
|
2009
|
-
throw new Error(
|
|
2203
|
+
throw new Error(
|
|
2204
|
+
"Unable to resolve drizzle-kit binary from package.json"
|
|
2205
|
+
);
|
|
2010
2206
|
}
|
|
2011
2207
|
return path2.resolve(currentDir, binRelPath);
|
|
2012
2208
|
}
|
|
@@ -2017,15 +2213,66 @@ async function run(options = {}) {
|
|
|
2017
2213
|
throw new Error("Unable to locate drizzle-kit package root");
|
|
2018
2214
|
};
|
|
2019
2215
|
let columnComments;
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2216
|
+
let syncedTableMap;
|
|
2217
|
+
const appId = process.env.app_id;
|
|
2218
|
+
const workspace = process.env.suda_workspace_id;
|
|
2219
|
+
console.log(
|
|
2220
|
+
`[gen-db-schema] Pre-fetch info: columnComments=enabled, syncedTables=${appId && workspace ? "enabled" : "skipped"} (app_id=${appId ? "set" : "unset"}, suda_workspace_id=${workspace ? "set" : "unset"})`
|
|
2221
|
+
);
|
|
2222
|
+
const columnCommentsTask = (async () => {
|
|
2223
|
+
const start = Date.now();
|
|
2224
|
+
console.log("[gen-db-schema] \u2192 Fetching column comments...");
|
|
2225
|
+
const res = await fetchColumnComments(databaseUrl, { timeoutMs: 1e4 });
|
|
2226
|
+
console.log(
|
|
2227
|
+
`[gen-db-schema] \u2190 Fetched column comments: ${res.size} items (${Date.now() - start}ms)`
|
|
2228
|
+
);
|
|
2229
|
+
return res;
|
|
2230
|
+
})();
|
|
2231
|
+
const syncedTablesTask = appId && workspace ? (async () => {
|
|
2232
|
+
const start = Date.now();
|
|
2233
|
+
console.log(
|
|
2234
|
+
"[gen-db-schema] \u2192 Fetching synced tables from listTableView..."
|
|
2235
|
+
);
|
|
2236
|
+
const res = await fetchSyncedTables(appId, workspace);
|
|
2237
|
+
console.log(
|
|
2238
|
+
`[gen-db-schema] \u2190 Fetched synced tables: ${res.size} tables (${Date.now() - start}ms)`
|
|
2239
|
+
);
|
|
2240
|
+
return res;
|
|
2241
|
+
})() : void 0;
|
|
2242
|
+
const fetchTasks = await Promise.allSettled([
|
|
2243
|
+
columnCommentsTask,
|
|
2244
|
+
...syncedTablesTask ? [syncedTablesTask] : []
|
|
2245
|
+
]);
|
|
2246
|
+
if (fetchTasks[0].status === "fulfilled") {
|
|
2247
|
+
columnComments = fetchTasks[0].value;
|
|
2248
|
+
console.log(
|
|
2249
|
+
`[gen-db-schema] \u2713 Column comments ready: ${columnComments.size}`
|
|
2250
|
+
);
|
|
2251
|
+
} else {
|
|
2024
2252
|
console.warn(
|
|
2025
2253
|
"[gen-db-schema] \u26A0 Failed to fetch column comments (skipping):",
|
|
2026
|
-
|
|
2254
|
+
fetchTasks[0].reason instanceof Error ? fetchTasks[0].reason.message : String(fetchTasks[0].reason)
|
|
2027
2255
|
);
|
|
2028
2256
|
}
|
|
2257
|
+
if (appId && workspace) {
|
|
2258
|
+
if (fetchTasks[1]?.status === "fulfilled") {
|
|
2259
|
+
syncedTableMap = fetchTasks[1].value;
|
|
2260
|
+
console.log(
|
|
2261
|
+
`[gen-db-schema] \u2713 Synced tables ready: ${syncedTableMap.size}`
|
|
2262
|
+
);
|
|
2263
|
+
} else if (fetchTasks[1]?.status === "rejected") {
|
|
2264
|
+
console.warn(
|
|
2265
|
+
"[gen-db-schema] \u26A0 Failed to fetch synced tables (skipping):",
|
|
2266
|
+
fetchTasks[1].reason instanceof Error ? fetchTasks[1].reason.message : String(fetchTasks[1].reason)
|
|
2267
|
+
);
|
|
2268
|
+
syncedTableMap = /* @__PURE__ */ new Map();
|
|
2269
|
+
}
|
|
2270
|
+
} else {
|
|
2271
|
+
console.info(
|
|
2272
|
+
"[gen-db-schema] \u2139 Skipping synced table detection (app_id or suda_workspace_id not set)"
|
|
2273
|
+
);
|
|
2274
|
+
syncedTableMap = /* @__PURE__ */ new Map();
|
|
2275
|
+
}
|
|
2029
2276
|
try {
|
|
2030
2277
|
const env = {
|
|
2031
2278
|
...process.env,
|
|
@@ -2036,13 +2283,19 @@ async function run(options = {}) {
|
|
|
2036
2283
|
};
|
|
2037
2284
|
const drizzleKitBin = resolveDrizzleKitBin();
|
|
2038
2285
|
const spawnArgs = [drizzleKitBin, "introspect", "--config", configPath];
|
|
2039
|
-
const result = spawnSync(process.execPath, spawnArgs, {
|
|
2286
|
+
const result = spawnSync(process.execPath, spawnArgs, {
|
|
2287
|
+
stdio: "inherit",
|
|
2288
|
+
env,
|
|
2289
|
+
cwd: process.cwd()
|
|
2290
|
+
});
|
|
2040
2291
|
if (result.error) {
|
|
2041
2292
|
console.error("[gen-db-schema] Execution failed:", result.error);
|
|
2042
2293
|
throw result.error;
|
|
2043
2294
|
}
|
|
2044
2295
|
if ((result.status ?? 0) !== 0) {
|
|
2045
|
-
throw new Error(
|
|
2296
|
+
throw new Error(
|
|
2297
|
+
`drizzle-kit introspect failed with status ${result.status}`
|
|
2298
|
+
);
|
|
2046
2299
|
}
|
|
2047
2300
|
const generatedSchema = path2.join(OUT_DIR, "schema.ts");
|
|
2048
2301
|
if (!fs4.existsSync(generatedSchema)) {
|
|
@@ -2050,10 +2303,14 @@ async function run(options = {}) {
|
|
|
2050
2303
|
throw new Error("drizzle-kit introspect failed to generate schema.ts");
|
|
2051
2304
|
}
|
|
2052
2305
|
const stats = await postprocessDrizzleSchema(generatedSchema, {
|
|
2053
|
-
columnComments
|
|
2306
|
+
columnComments,
|
|
2307
|
+
syncedTableMap
|
|
2054
2308
|
});
|
|
2055
2309
|
if (stats?.unmatchedUnknown?.length) {
|
|
2056
|
-
console.warn(
|
|
2310
|
+
console.warn(
|
|
2311
|
+
"[gen-db-schema] Unmatched custom types detected:",
|
|
2312
|
+
stats.unmatchedUnknown
|
|
2313
|
+
);
|
|
2057
2314
|
}
|
|
2058
2315
|
console.log("[gen-db-schema] \u2713 Postprocessed schema");
|
|
2059
2316
|
fs4.mkdirSync(path2.dirname(SCHEMA_FILE), { recursive: true });
|
|
@@ -2068,14 +2325,22 @@ async function run(options = {}) {
|
|
|
2068
2325
|
schemaFilePath,
|
|
2069
2326
|
moduleOutputDir: path2.resolve(process.cwd(), "server/modules")
|
|
2070
2327
|
});
|
|
2071
|
-
console.log(
|
|
2328
|
+
console.log(
|
|
2329
|
+
"[gen-db-schema] \u2713 Generate NestJS Module Boilerplate Successfully"
|
|
2330
|
+
);
|
|
2072
2331
|
}
|
|
2073
2332
|
} catch (error) {
|
|
2074
|
-
console.warn(
|
|
2333
|
+
console.warn(
|
|
2334
|
+
"[gen-db-schema] Generate NestJS Module Boilerplate failed:",
|
|
2335
|
+
error instanceof Error ? error.message : String(error)
|
|
2336
|
+
);
|
|
2075
2337
|
}
|
|
2076
2338
|
console.log("[gen-db-schema] \u2713 Complete");
|
|
2077
2339
|
} catch (err) {
|
|
2078
|
-
console.error(
|
|
2340
|
+
console.error(
|
|
2341
|
+
"[gen-db-schema] Failed:",
|
|
2342
|
+
err instanceof Error ? err.message : String(err)
|
|
2343
|
+
);
|
|
2079
2344
|
exitCode = 1;
|
|
2080
2345
|
} finally {
|
|
2081
2346
|
if (fs4.existsSync(OUT_DIR)) {
|
|
@@ -2419,10 +2684,398 @@ var syncCommand = {
|
|
|
2419
2684
|
}
|
|
2420
2685
|
};
|
|
2421
2686
|
|
|
2422
|
-
// src/
|
|
2687
|
+
// src/utils/telemetry.ts
|
|
2688
|
+
async function reportEvents(events) {
|
|
2689
|
+
if (events.length === 0) {
|
|
2690
|
+
return true;
|
|
2691
|
+
}
|
|
2692
|
+
try {
|
|
2693
|
+
const client = getHttpClient();
|
|
2694
|
+
const response = await client.post("/api/v1/studio/innerapi/resource_events", { events });
|
|
2695
|
+
if (!response.ok) {
|
|
2696
|
+
console.warn(`[telemetry] Failed to report events: ${response.status} ${response.statusText}`);
|
|
2697
|
+
return false;
|
|
2698
|
+
}
|
|
2699
|
+
const result = await response.json();
|
|
2700
|
+
if (result.status_code !== "0") {
|
|
2701
|
+
console.warn(`[telemetry] API error: ${result.message}`);
|
|
2702
|
+
return false;
|
|
2703
|
+
}
|
|
2704
|
+
return true;
|
|
2705
|
+
} catch (error) {
|
|
2706
|
+
console.warn(`[telemetry] Failed to report events: ${error instanceof Error ? error.message : error}`);
|
|
2707
|
+
return false;
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
async function reportInstallEvent(pluginKey, version) {
|
|
2711
|
+
await reportEvents([
|
|
2712
|
+
{
|
|
2713
|
+
resourceType: "plugin",
|
|
2714
|
+
resourceKey: pluginKey,
|
|
2715
|
+
eventType: "install",
|
|
2716
|
+
details: { version }
|
|
2717
|
+
}
|
|
2718
|
+
]);
|
|
2719
|
+
}
|
|
2720
|
+
async function reportCreateInstanceEvent(pluginKey, version) {
|
|
2721
|
+
await reportEvents([
|
|
2722
|
+
{
|
|
2723
|
+
resourceType: "plugin",
|
|
2724
|
+
resourceKey: pluginKey,
|
|
2725
|
+
eventType: "create_instance",
|
|
2726
|
+
details: { version }
|
|
2727
|
+
}
|
|
2728
|
+
]);
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2731
|
+
// src/utils/git.ts
|
|
2732
|
+
import { execSync, spawnSync as spawnSync2 } from "child_process";
|
|
2423
2733
|
import fs7 from "fs";
|
|
2424
2734
|
import path5 from "path";
|
|
2425
|
-
|
|
2735
|
+
function isGitRepository(cwd = process.cwd()) {
|
|
2736
|
+
try {
|
|
2737
|
+
const gitDir = path5.join(cwd, ".git");
|
|
2738
|
+
if (fs7.existsSync(gitDir)) {
|
|
2739
|
+
return true;
|
|
2740
|
+
}
|
|
2741
|
+
const result = spawnSync2("git", ["rev-parse", "--git-dir"], {
|
|
2742
|
+
cwd,
|
|
2743
|
+
stdio: "pipe",
|
|
2744
|
+
encoding: "utf-8"
|
|
2745
|
+
});
|
|
2746
|
+
return result.status === 0;
|
|
2747
|
+
} catch {
|
|
2748
|
+
return false;
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
function getChangedFiles(cwd = process.cwd()) {
|
|
2752
|
+
try {
|
|
2753
|
+
const output = execSync("git status --porcelain", {
|
|
2754
|
+
cwd,
|
|
2755
|
+
stdio: "pipe",
|
|
2756
|
+
encoding: "utf-8"
|
|
2757
|
+
});
|
|
2758
|
+
return output.split("\n").filter((line) => line.trim()).map((line) => line.substring(3));
|
|
2759
|
+
} catch (error) {
|
|
2760
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2761
|
+
throw new Error(`Failed to get changed files: ${message}`);
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
function gitAddUpgradeFiles(cwd = process.cwd(), filesToStage) {
|
|
2765
|
+
const filteredFiles = [];
|
|
2766
|
+
for (const filePath of filesToStage) {
|
|
2767
|
+
if (fs7.existsSync(path5.join(cwd, filePath))) {
|
|
2768
|
+
filteredFiles.push(filePath);
|
|
2769
|
+
continue;
|
|
2770
|
+
}
|
|
2771
|
+
const tracked = spawnSync2("git", ["ls-files", "--error-unmatch", "--", filePath], {
|
|
2772
|
+
cwd,
|
|
2773
|
+
stdio: "pipe",
|
|
2774
|
+
encoding: "utf-8"
|
|
2775
|
+
});
|
|
2776
|
+
if (tracked.status === 0) {
|
|
2777
|
+
filteredFiles.push(filePath);
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
if (filteredFiles.length === 0) {
|
|
2781
|
+
return;
|
|
2782
|
+
}
|
|
2783
|
+
const result = spawnSync2("git", ["add", "--", ...filteredFiles], {
|
|
2784
|
+
cwd,
|
|
2785
|
+
stdio: "pipe",
|
|
2786
|
+
encoding: "utf-8"
|
|
2787
|
+
});
|
|
2788
|
+
if (result.error || result.status !== 0) {
|
|
2789
|
+
const errorMsg = result.stderr || result.error?.message || "Unknown error";
|
|
2790
|
+
throw new Error(`git add failed: ${errorMsg}`);
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
function hasStagedChanges(cwd = process.cwd()) {
|
|
2794
|
+
const result = spawnSync2("git", ["diff", "--cached", "--quiet"], {
|
|
2795
|
+
cwd,
|
|
2796
|
+
stdio: "pipe",
|
|
2797
|
+
encoding: "utf-8"
|
|
2798
|
+
});
|
|
2799
|
+
if (result.status === 0) {
|
|
2800
|
+
return false;
|
|
2801
|
+
}
|
|
2802
|
+
if (result.status === 1) {
|
|
2803
|
+
return true;
|
|
2804
|
+
}
|
|
2805
|
+
const errorMsg = result.stderr || result.error?.message || "Unknown error";
|
|
2806
|
+
throw new Error(`Failed to check staged changes: ${errorMsg}`);
|
|
2807
|
+
}
|
|
2808
|
+
function gitCommit(message, cwd = process.cwd()) {
|
|
2809
|
+
const result = spawnSync2("git", ["commit", "-m", message], {
|
|
2810
|
+
cwd,
|
|
2811
|
+
stdio: "pipe",
|
|
2812
|
+
encoding: "utf-8"
|
|
2813
|
+
});
|
|
2814
|
+
if (result.error || result.status !== 0) {
|
|
2815
|
+
const errorMsg = result.stderr || result.error?.message || "Unknown error";
|
|
2816
|
+
throw new Error(`git commit failed: ${errorMsg}`);
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
function autoCommitUpgradeChanges(version, cwd, filesToStage, commitMessage) {
|
|
2820
|
+
if (!isGitRepository(cwd)) {
|
|
2821
|
+
console.log("[fullstack-cli] \u26A0 Not a git repository, skipping auto-commit");
|
|
2822
|
+
return false;
|
|
2823
|
+
}
|
|
2824
|
+
const changedFiles = getChangedFiles(cwd);
|
|
2825
|
+
if (changedFiles.length === 0) {
|
|
2826
|
+
console.log("[fullstack-cli] No changes to commit");
|
|
2827
|
+
return false;
|
|
2828
|
+
}
|
|
2829
|
+
try {
|
|
2830
|
+
gitAddUpgradeFiles(cwd, filesToStage);
|
|
2831
|
+
if (!hasStagedChanges(cwd)) {
|
|
2832
|
+
console.log("[fullstack-cli] No upgrade changes to commit");
|
|
2833
|
+
return false;
|
|
2834
|
+
}
|
|
2835
|
+
const message = commitMessage || `chore(upgrade): auto-upgrade by fullstack-cli
|
|
2836
|
+
|
|
2837
|
+
- Sync template files
|
|
2838
|
+
- Cleanup package.json config
|
|
2839
|
+
- Upgrade @lark-apaas dependencies (if any)
|
|
2840
|
+
|
|
2841
|
+
Auto-committed by fullstack-cli`;
|
|
2842
|
+
gitCommit(message, cwd);
|
|
2843
|
+
console.log(`[fullstack-cli] \u2713 Auto-committed ${changedFiles.length} changed file(s)`);
|
|
2844
|
+
return true;
|
|
2845
|
+
} catch (error) {
|
|
2846
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2847
|
+
throw new Error(`Failed to auto-commit changes: ${message}`);
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2850
|
+
|
|
2851
|
+
// src/utils/package-json.ts
|
|
2852
|
+
import fs8 from "fs";
|
|
2853
|
+
import path6 from "path";
|
|
2854
|
+
function readPackageJson(cwd = process.cwd()) {
|
|
2855
|
+
const pkgPath = path6.join(cwd, "package.json");
|
|
2856
|
+
if (!fs8.existsSync(pkgPath)) {
|
|
2857
|
+
throw new Error(`package.json not found at ${pkgPath}`);
|
|
2858
|
+
}
|
|
2859
|
+
const content = fs8.readFileSync(pkgPath, "utf-8");
|
|
2860
|
+
return JSON.parse(content);
|
|
2861
|
+
}
|
|
2862
|
+
function writePackageJson(pkg2, cwd = process.cwd()) {
|
|
2863
|
+
const pkgPath = path6.join(cwd, "package.json");
|
|
2864
|
+
const content = JSON.stringify(pkg2, null, 2) + "\n";
|
|
2865
|
+
fs8.writeFileSync(pkgPath, content, "utf-8");
|
|
2866
|
+
}
|
|
2867
|
+
function removeUpgradeScript(pkg2) {
|
|
2868
|
+
if (!pkg2.scripts?.upgrade) {
|
|
2869
|
+
return false;
|
|
2870
|
+
}
|
|
2871
|
+
delete pkg2.scripts.upgrade;
|
|
2872
|
+
return true;
|
|
2873
|
+
}
|
|
2874
|
+
function cleanDevScript(pkg2) {
|
|
2875
|
+
if (!pkg2.scripts?.dev) {
|
|
2876
|
+
return false;
|
|
2877
|
+
}
|
|
2878
|
+
const originalDev = pkg2.scripts.dev;
|
|
2879
|
+
const cleanedDev = originalDev.replace(/npm\s+run\s+upgrade\s*&&\s*/g, "").replace(/npm\s+run\s+upgrade\s*$/g, "").trim();
|
|
2880
|
+
if (cleanedDev !== originalDev) {
|
|
2881
|
+
pkg2.scripts.dev = cleanedDev;
|
|
2882
|
+
return true;
|
|
2883
|
+
}
|
|
2884
|
+
return false;
|
|
2885
|
+
}
|
|
2886
|
+
function cleanupPackageJson(cwd = process.cwd()) {
|
|
2887
|
+
try {
|
|
2888
|
+
const pkg2 = readPackageJson(cwd);
|
|
2889
|
+
let changed = false;
|
|
2890
|
+
if (removeUpgradeScript(pkg2)) {
|
|
2891
|
+
console.log("[fullstack-cli] \u2713 Removed scripts.upgrade");
|
|
2892
|
+
changed = true;
|
|
2893
|
+
}
|
|
2894
|
+
if (cleanDevScript(pkg2)) {
|
|
2895
|
+
console.log("[fullstack-cli] \u2713 Cleaned scripts.dev (removed npm run upgrade)");
|
|
2896
|
+
changed = true;
|
|
2897
|
+
}
|
|
2898
|
+
if (changed) {
|
|
2899
|
+
writePackageJson(pkg2, cwd);
|
|
2900
|
+
}
|
|
2901
|
+
return changed;
|
|
2902
|
+
} catch (error) {
|
|
2903
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2904
|
+
console.log(`[fullstack-cli] \u26A0 Could not cleanup package.json: ${message}`);
|
|
2905
|
+
return false;
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2909
|
+
// src/commands/upgrade/shared/utils.ts
|
|
2910
|
+
import path7 from "path";
|
|
2911
|
+
import fs9 from "fs";
|
|
2912
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
2913
|
+
function getCliVersion() {
|
|
2914
|
+
try {
|
|
2915
|
+
const __filename = fileURLToPath4(import.meta.url);
|
|
2916
|
+
const __dirname2 = path7.dirname(__filename);
|
|
2917
|
+
const pkgPath = path7.resolve(__dirname2, "../../../package.json");
|
|
2918
|
+
const pkgContent = fs9.readFileSync(pkgPath, "utf-8");
|
|
2919
|
+
const pkg2 = JSON.parse(pkgContent);
|
|
2920
|
+
return pkg2.version || "unknown";
|
|
2921
|
+
} catch {
|
|
2922
|
+
return "unknown";
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
// src/commands/upgrade/get-upgrade-files.ts
|
|
2927
|
+
function getUpgradeFilesToStage(disableGenOpenapi = true) {
|
|
2928
|
+
const syncConfig2 = genSyncConfig({ disableGenOpenapi });
|
|
2929
|
+
const filesToStage = /* @__PURE__ */ new Set();
|
|
2930
|
+
syncConfig2.sync.forEach((rule) => {
|
|
2931
|
+
if (rule.type === "file" || rule.type === "directory") {
|
|
2932
|
+
filesToStage.add(rule.to);
|
|
2933
|
+
} else if (rule.type === "remove-line" || rule.type === "add-line") {
|
|
2934
|
+
filesToStage.add(rule.to);
|
|
2935
|
+
} else if (rule.type === "add-script") {
|
|
2936
|
+
filesToStage.add("package.json");
|
|
2937
|
+
} else if (rule.type === "delete-file" || rule.type === "delete-directory") {
|
|
2938
|
+
filesToStage.add(rule.to);
|
|
2939
|
+
}
|
|
2940
|
+
});
|
|
2941
|
+
filesToStage.add("package.json");
|
|
2942
|
+
filesToStage.add("package-lock.json");
|
|
2943
|
+
return Array.from(filesToStage);
|
|
2944
|
+
}
|
|
2945
|
+
|
|
2946
|
+
// src/commands/upgrade/run.handler.ts
|
|
2947
|
+
async function run3(options = {}) {
|
|
2948
|
+
const userProjectRoot = process.env.INIT_CWD || process.cwd();
|
|
2949
|
+
console.log("[fullstack-cli] Starting upgrade...");
|
|
2950
|
+
try {
|
|
2951
|
+
console.log("[fullstack-cli] Step 1/3: Syncing template files...");
|
|
2952
|
+
await run2({ disableGenOpenapi: options.disableGenOpenapi ?? true });
|
|
2953
|
+
console.log("[fullstack-cli] Step 2/3: Cleaning up package.json...");
|
|
2954
|
+
const cleaned = cleanupPackageJson(userProjectRoot);
|
|
2955
|
+
if (!cleaned) {
|
|
2956
|
+
console.log("[fullstack-cli] \u25CB No cleanup needed");
|
|
2957
|
+
}
|
|
2958
|
+
const shouldCommit = options.commit ?? true;
|
|
2959
|
+
if (shouldCommit) {
|
|
2960
|
+
console.log("[fullstack-cli] Step 3/3: Committing changes...");
|
|
2961
|
+
const version = getCliVersion();
|
|
2962
|
+
const filesToStage = getUpgradeFilesToStage(options.disableGenOpenapi ?? true);
|
|
2963
|
+
autoCommitUpgradeChanges(version, userProjectRoot, filesToStage);
|
|
2964
|
+
} else {
|
|
2965
|
+
console.log("[fullstack-cli] Step 3/3: Skipping commit (--no-commit flag)");
|
|
2966
|
+
}
|
|
2967
|
+
console.log("[fullstack-cli] Upgrade completed successfully \u2705");
|
|
2968
|
+
} catch (error) {
|
|
2969
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2970
|
+
console.error("[fullstack-cli] Failed to upgrade:", message);
|
|
2971
|
+
process.exit(1);
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2975
|
+
// src/commands/upgrade/deps/run.handler.ts
|
|
2976
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
2977
|
+
function findLarkAapaasPackages(cwd, filterPackages) {
|
|
2978
|
+
const pkg2 = readPackageJson(cwd);
|
|
2979
|
+
const allPackages = /* @__PURE__ */ new Set();
|
|
2980
|
+
if (pkg2.dependencies) {
|
|
2981
|
+
Object.keys(pkg2.dependencies).forEach((name) => {
|
|
2982
|
+
if (name.startsWith("@lark-apaas/")) {
|
|
2983
|
+
allPackages.add(name);
|
|
2984
|
+
}
|
|
2985
|
+
});
|
|
2986
|
+
}
|
|
2987
|
+
if (pkg2.devDependencies) {
|
|
2988
|
+
Object.keys(pkg2.devDependencies).forEach((name) => {
|
|
2989
|
+
if (name.startsWith("@lark-apaas/")) {
|
|
2990
|
+
allPackages.add(name);
|
|
2991
|
+
}
|
|
2992
|
+
});
|
|
2993
|
+
}
|
|
2994
|
+
const packages = Array.from(allPackages);
|
|
2995
|
+
if (filterPackages) {
|
|
2996
|
+
const filter = new Set(filterPackages.split(",").map((p) => p.trim()));
|
|
2997
|
+
return packages.filter((p) => filter.has(p));
|
|
2998
|
+
}
|
|
2999
|
+
return packages;
|
|
3000
|
+
}
|
|
3001
|
+
function upgradePackages(packages, version, cwd) {
|
|
3002
|
+
if (version) {
|
|
3003
|
+
console.log(`[fullstack-cli] Upgrading to version ${version}...`);
|
|
3004
|
+
packages.forEach((pkg2) => {
|
|
3005
|
+
const target = `${pkg2}@${version}`;
|
|
3006
|
+
console.log(`[fullstack-cli] Installing ${target}...`);
|
|
3007
|
+
const result = spawnSync3("npm", ["install", target], {
|
|
3008
|
+
cwd,
|
|
3009
|
+
stdio: "inherit"
|
|
3010
|
+
});
|
|
3011
|
+
if (result.error || result.status !== 0) {
|
|
3012
|
+
throw new Error(`Failed to install ${target}`);
|
|
3013
|
+
}
|
|
3014
|
+
});
|
|
3015
|
+
} else {
|
|
3016
|
+
console.log("[fullstack-cli] Upgrading to latest compatible versions...");
|
|
3017
|
+
packages.forEach((pkg2) => {
|
|
3018
|
+
console.log(`[fullstack-cli] Updating ${pkg2}...`);
|
|
3019
|
+
const result = spawnSync3("npm", ["update", pkg2], {
|
|
3020
|
+
cwd,
|
|
3021
|
+
stdio: "inherit"
|
|
3022
|
+
});
|
|
3023
|
+
if (result.error || result.status !== 0) {
|
|
3024
|
+
throw new Error(`Failed to update ${pkg2}`);
|
|
3025
|
+
}
|
|
3026
|
+
});
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
async function run4(options = {}) {
|
|
3030
|
+
const cwd = process.env.INIT_CWD || process.cwd();
|
|
3031
|
+
console.log("[fullstack-cli] Starting dependencies upgrade...");
|
|
3032
|
+
try {
|
|
3033
|
+
console.log("[fullstack-cli] Step 1/2: Scanning @lark-apaas dependencies...");
|
|
3034
|
+
const packages = findLarkAapaasPackages(cwd, options.packages);
|
|
3035
|
+
if (packages.length === 0) {
|
|
3036
|
+
console.log("[fullstack-cli] No @lark-apaas packages found");
|
|
3037
|
+
return;
|
|
3038
|
+
}
|
|
3039
|
+
console.log(`[fullstack-cli] Found ${packages.length} @lark-apaas package(s):`);
|
|
3040
|
+
packages.forEach((p) => console.log(` - ${p}`));
|
|
3041
|
+
console.log("[fullstack-cli] Step 2/2: Upgrading packages...");
|
|
3042
|
+
upgradePackages(packages, options.version, cwd);
|
|
3043
|
+
console.log(`[fullstack-cli] \u2713 Successfully upgraded ${packages.length} package(s)`);
|
|
3044
|
+
console.log("[fullstack-cli] Dependencies upgrade completed successfully \u2705");
|
|
3045
|
+
} catch (error) {
|
|
3046
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3047
|
+
console.error("[fullstack-cli] Failed to upgrade dependencies:", message);
|
|
3048
|
+
process.exit(1);
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
|
|
3052
|
+
// src/commands/upgrade/deps/index.ts
|
|
3053
|
+
var depsCommand = {
|
|
3054
|
+
name: "deps",
|
|
3055
|
+
description: "Upgrade @lark-apaas dependencies",
|
|
3056
|
+
register(parentCommand) {
|
|
3057
|
+
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) => {
|
|
3058
|
+
await run4(options);
|
|
3059
|
+
});
|
|
3060
|
+
}
|
|
3061
|
+
};
|
|
3062
|
+
|
|
3063
|
+
// src/commands/upgrade/index.ts
|
|
3064
|
+
var upgradeCommand = {
|
|
3065
|
+
name: "upgrade",
|
|
3066
|
+
description: "Upgrade template files and auto-commit changes",
|
|
3067
|
+
register(program) {
|
|
3068
|
+
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) => {
|
|
3069
|
+
await run3(options);
|
|
3070
|
+
});
|
|
3071
|
+
depsCommand.register(upgradeCmd);
|
|
3072
|
+
}
|
|
3073
|
+
};
|
|
3074
|
+
|
|
3075
|
+
// src/commands/action-plugin/utils.ts
|
|
3076
|
+
import fs10 from "fs";
|
|
3077
|
+
import path8 from "path";
|
|
3078
|
+
import { spawnSync as spawnSync4, execSync as execSync2 } from "child_process";
|
|
2426
3079
|
function parsePluginName(input) {
|
|
2427
3080
|
const match = input.match(/^(@[^/]+\/[^@]+)(?:@(.+))?$/);
|
|
2428
3081
|
if (!match) {
|
|
@@ -2439,35 +3092,35 @@ function getProjectRoot() {
|
|
|
2439
3092
|
return process.cwd();
|
|
2440
3093
|
}
|
|
2441
3094
|
function getPackageJsonPath() {
|
|
2442
|
-
return
|
|
3095
|
+
return path8.join(getProjectRoot(), "package.json");
|
|
2443
3096
|
}
|
|
2444
3097
|
function getPluginPath(pluginName) {
|
|
2445
|
-
return
|
|
3098
|
+
return path8.join(getProjectRoot(), "node_modules", pluginName);
|
|
2446
3099
|
}
|
|
2447
|
-
function
|
|
3100
|
+
function readPackageJson2() {
|
|
2448
3101
|
const pkgPath = getPackageJsonPath();
|
|
2449
|
-
if (!
|
|
3102
|
+
if (!fs10.existsSync(pkgPath)) {
|
|
2450
3103
|
throw new Error("package.json not found in current directory");
|
|
2451
3104
|
}
|
|
2452
3105
|
try {
|
|
2453
|
-
const content =
|
|
3106
|
+
const content = fs10.readFileSync(pkgPath, "utf-8");
|
|
2454
3107
|
return JSON.parse(content);
|
|
2455
3108
|
} catch {
|
|
2456
3109
|
throw new Error("Failed to parse package.json");
|
|
2457
3110
|
}
|
|
2458
3111
|
}
|
|
2459
|
-
function
|
|
3112
|
+
function writePackageJson2(pkg2) {
|
|
2460
3113
|
const pkgPath = getPackageJsonPath();
|
|
2461
|
-
|
|
3114
|
+
fs10.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
|
|
2462
3115
|
}
|
|
2463
3116
|
function readActionPlugins() {
|
|
2464
|
-
const pkg2 =
|
|
3117
|
+
const pkg2 = readPackageJson2();
|
|
2465
3118
|
return pkg2.actionPlugins || {};
|
|
2466
3119
|
}
|
|
2467
3120
|
function writeActionPlugins(plugins) {
|
|
2468
|
-
const pkg2 =
|
|
3121
|
+
const pkg2 = readPackageJson2();
|
|
2469
3122
|
pkg2.actionPlugins = plugins;
|
|
2470
|
-
|
|
3123
|
+
writePackageJson2(pkg2);
|
|
2471
3124
|
}
|
|
2472
3125
|
function isPluginInstalled(pluginName) {
|
|
2473
3126
|
const plugins = readActionPlugins();
|
|
@@ -2479,7 +3132,7 @@ function getInstalledPluginVersion(pluginName) {
|
|
|
2479
3132
|
}
|
|
2480
3133
|
function npmInstall(tgzPath) {
|
|
2481
3134
|
console.log(`[action-plugin] Running npm install ${tgzPath}...`);
|
|
2482
|
-
const result =
|
|
3135
|
+
const result = spawnSync4("npm", ["install", tgzPath, "--no-save", "--no-package-lock", "--ignore-scripts"], {
|
|
2483
3136
|
cwd: getProjectRoot(),
|
|
2484
3137
|
stdio: "inherit"
|
|
2485
3138
|
});
|
|
@@ -2491,12 +3144,12 @@ function npmInstall(tgzPath) {
|
|
|
2491
3144
|
}
|
|
2492
3145
|
}
|
|
2493
3146
|
function getPackageVersion(pluginName) {
|
|
2494
|
-
const pkgJsonPath =
|
|
2495
|
-
if (!
|
|
3147
|
+
const pkgJsonPath = path8.join(getPluginPath(pluginName), "package.json");
|
|
3148
|
+
if (!fs10.existsSync(pkgJsonPath)) {
|
|
2496
3149
|
return null;
|
|
2497
3150
|
}
|
|
2498
3151
|
try {
|
|
2499
|
-
const content =
|
|
3152
|
+
const content = fs10.readFileSync(pkgJsonPath, "utf-8");
|
|
2500
3153
|
const pkg2 = JSON.parse(content);
|
|
2501
3154
|
return pkg2.version || null;
|
|
2502
3155
|
} catch {
|
|
@@ -2504,49 +3157,49 @@ function getPackageVersion(pluginName) {
|
|
|
2504
3157
|
}
|
|
2505
3158
|
}
|
|
2506
3159
|
function readPluginPackageJson(pluginPath) {
|
|
2507
|
-
const pkgJsonPath =
|
|
2508
|
-
if (!
|
|
3160
|
+
const pkgJsonPath = path8.join(pluginPath, "package.json");
|
|
3161
|
+
if (!fs10.existsSync(pkgJsonPath)) {
|
|
2509
3162
|
return null;
|
|
2510
3163
|
}
|
|
2511
3164
|
try {
|
|
2512
|
-
const content =
|
|
3165
|
+
const content = fs10.readFileSync(pkgJsonPath, "utf-8");
|
|
2513
3166
|
return JSON.parse(content);
|
|
2514
3167
|
} catch {
|
|
2515
3168
|
return null;
|
|
2516
3169
|
}
|
|
2517
3170
|
}
|
|
2518
3171
|
function extractTgzToNodeModules(tgzPath, pluginName) {
|
|
2519
|
-
const nodeModulesPath =
|
|
2520
|
-
const targetDir =
|
|
2521
|
-
const scopeDir =
|
|
2522
|
-
if (!
|
|
2523
|
-
|
|
3172
|
+
const nodeModulesPath = path8.join(getProjectRoot(), "node_modules");
|
|
3173
|
+
const targetDir = path8.join(nodeModulesPath, pluginName);
|
|
3174
|
+
const scopeDir = path8.dirname(targetDir);
|
|
3175
|
+
if (!fs10.existsSync(scopeDir)) {
|
|
3176
|
+
fs10.mkdirSync(scopeDir, { recursive: true });
|
|
2524
3177
|
}
|
|
2525
|
-
if (
|
|
2526
|
-
|
|
3178
|
+
if (fs10.existsSync(targetDir)) {
|
|
3179
|
+
fs10.rmSync(targetDir, { recursive: true });
|
|
2527
3180
|
}
|
|
2528
|
-
const tempDir =
|
|
2529
|
-
if (
|
|
2530
|
-
|
|
3181
|
+
const tempDir = path8.join(nodeModulesPath, ".cache", "fullstack-cli", "extract-temp");
|
|
3182
|
+
if (fs10.existsSync(tempDir)) {
|
|
3183
|
+
fs10.rmSync(tempDir, { recursive: true });
|
|
2531
3184
|
}
|
|
2532
|
-
|
|
3185
|
+
fs10.mkdirSync(tempDir, { recursive: true });
|
|
2533
3186
|
try {
|
|
2534
|
-
|
|
2535
|
-
const extractedDir =
|
|
2536
|
-
if (
|
|
2537
|
-
|
|
3187
|
+
execSync2(`tar -xzf "${tgzPath}" -C "${tempDir}"`, { stdio: "pipe" });
|
|
3188
|
+
const extractedDir = path8.join(tempDir, "package");
|
|
3189
|
+
if (fs10.existsSync(extractedDir)) {
|
|
3190
|
+
fs10.renameSync(extractedDir, targetDir);
|
|
2538
3191
|
} else {
|
|
2539
|
-
const files =
|
|
3192
|
+
const files = fs10.readdirSync(tempDir);
|
|
2540
3193
|
if (files.length === 1) {
|
|
2541
|
-
|
|
3194
|
+
fs10.renameSync(path8.join(tempDir, files[0]), targetDir);
|
|
2542
3195
|
} else {
|
|
2543
3196
|
throw new Error("Unexpected tgz structure");
|
|
2544
3197
|
}
|
|
2545
3198
|
}
|
|
2546
3199
|
return targetDir;
|
|
2547
3200
|
} finally {
|
|
2548
|
-
if (
|
|
2549
|
-
|
|
3201
|
+
if (fs10.existsSync(tempDir)) {
|
|
3202
|
+
fs10.rmSync(tempDir, { recursive: true });
|
|
2550
3203
|
}
|
|
2551
3204
|
}
|
|
2552
3205
|
}
|
|
@@ -2555,10 +3208,10 @@ function checkMissingPeerDeps(peerDeps) {
|
|
|
2555
3208
|
return [];
|
|
2556
3209
|
}
|
|
2557
3210
|
const missing = [];
|
|
2558
|
-
const nodeModulesPath =
|
|
3211
|
+
const nodeModulesPath = path8.join(getProjectRoot(), "node_modules");
|
|
2559
3212
|
for (const [depName, _version] of Object.entries(peerDeps)) {
|
|
2560
|
-
const depPath =
|
|
2561
|
-
if (!
|
|
3213
|
+
const depPath = path8.join(nodeModulesPath, depName);
|
|
3214
|
+
if (!fs10.existsSync(depPath)) {
|
|
2562
3215
|
missing.push(depName);
|
|
2563
3216
|
}
|
|
2564
3217
|
}
|
|
@@ -2569,7 +3222,7 @@ function installMissingDeps(deps) {
|
|
|
2569
3222
|
return;
|
|
2570
3223
|
}
|
|
2571
3224
|
console.log(`[action-plugin] Installing missing dependencies: ${deps.join(", ")}`);
|
|
2572
|
-
const result =
|
|
3225
|
+
const result = spawnSync4("npm", ["install", ...deps, "--no-save", "--no-package-lock"], {
|
|
2573
3226
|
cwd: getProjectRoot(),
|
|
2574
3227
|
stdio: "inherit"
|
|
2575
3228
|
});
|
|
@@ -2582,76 +3235,16 @@ function installMissingDeps(deps) {
|
|
|
2582
3235
|
}
|
|
2583
3236
|
function removePluginDirectory(pluginName) {
|
|
2584
3237
|
const pluginPath = getPluginPath(pluginName);
|
|
2585
|
-
if (
|
|
2586
|
-
|
|
3238
|
+
if (fs10.existsSync(pluginPath)) {
|
|
3239
|
+
fs10.rmSync(pluginPath, { recursive: true });
|
|
2587
3240
|
console.log(`[action-plugin] Removed ${pluginName}`);
|
|
2588
3241
|
}
|
|
2589
3242
|
}
|
|
2590
3243
|
|
|
2591
3244
|
// src/commands/action-plugin/api-client.ts
|
|
2592
3245
|
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
|
|
3246
|
+
import fs11 from "fs";
|
|
3247
|
+
import path9 from "path";
|
|
2655
3248
|
var PLUGIN_CACHE_DIR = "node_modules/.cache/fullstack-cli/plugins";
|
|
2656
3249
|
async function getPluginVersions(keys, latestOnly = true) {
|
|
2657
3250
|
const client = getHttpClient();
|
|
@@ -2715,19 +3308,19 @@ async function downloadFromPublic(downloadURL) {
|
|
|
2715
3308
|
return Buffer.from(arrayBuffer);
|
|
2716
3309
|
}
|
|
2717
3310
|
function getPluginCacheDir() {
|
|
2718
|
-
return
|
|
3311
|
+
return path9.join(process.cwd(), PLUGIN_CACHE_DIR);
|
|
2719
3312
|
}
|
|
2720
3313
|
function ensureCacheDir() {
|
|
2721
3314
|
const cacheDir = getPluginCacheDir();
|
|
2722
|
-
if (!
|
|
2723
|
-
|
|
3315
|
+
if (!fs11.existsSync(cacheDir)) {
|
|
3316
|
+
fs11.mkdirSync(cacheDir, { recursive: true });
|
|
2724
3317
|
}
|
|
2725
3318
|
}
|
|
2726
3319
|
function getTempFilePath(pluginKey, version) {
|
|
2727
3320
|
ensureCacheDir();
|
|
2728
3321
|
const safeKey = pluginKey.replace(/[/@]/g, "_");
|
|
2729
3322
|
const filename = `${safeKey}@${version}.tgz`;
|
|
2730
|
-
return
|
|
3323
|
+
return path9.join(getPluginCacheDir(), filename);
|
|
2731
3324
|
}
|
|
2732
3325
|
var MAX_RETRIES = 2;
|
|
2733
3326
|
async function withRetry(operation, description, maxRetries = MAX_RETRIES) {
|
|
@@ -2764,7 +3357,7 @@ async function downloadPlugin(pluginKey, requestedVersion) {
|
|
|
2764
3357
|
);
|
|
2765
3358
|
}
|
|
2766
3359
|
const tgzPath = getTempFilePath(pluginKey, pluginInfo.version);
|
|
2767
|
-
|
|
3360
|
+
fs11.writeFileSync(tgzPath, tgzBuffer);
|
|
2768
3361
|
console.log(`[action-plugin] Downloaded to ${tgzPath} (${(tgzBuffer.length / 1024).toFixed(2)} KB)`);
|
|
2769
3362
|
return {
|
|
2770
3363
|
tgzPath,
|
|
@@ -2778,18 +3371,18 @@ function getCachePath(pluginKey, version) {
|
|
|
2778
3371
|
ensureCacheDir();
|
|
2779
3372
|
const safeKey = pluginKey.replace(/[/@]/g, "_");
|
|
2780
3373
|
const filename = `${safeKey}@${version}.tgz`;
|
|
2781
|
-
return
|
|
3374
|
+
return path9.join(getPluginCacheDir(), filename);
|
|
2782
3375
|
}
|
|
2783
3376
|
function hasCachedPlugin(pluginKey, version) {
|
|
2784
3377
|
const cachePath = getCachePath(pluginKey, version);
|
|
2785
|
-
return
|
|
3378
|
+
return fs11.existsSync(cachePath);
|
|
2786
3379
|
}
|
|
2787
3380
|
function listCachedPlugins() {
|
|
2788
3381
|
const cacheDir = getPluginCacheDir();
|
|
2789
|
-
if (!
|
|
3382
|
+
if (!fs11.existsSync(cacheDir)) {
|
|
2790
3383
|
return [];
|
|
2791
3384
|
}
|
|
2792
|
-
const files =
|
|
3385
|
+
const files = fs11.readdirSync(cacheDir);
|
|
2793
3386
|
const result = [];
|
|
2794
3387
|
for (const file of files) {
|
|
2795
3388
|
if (!file.endsWith(".tgz")) continue;
|
|
@@ -2797,8 +3390,8 @@ function listCachedPlugins() {
|
|
|
2797
3390
|
if (!match) continue;
|
|
2798
3391
|
const [, rawName, version] = match;
|
|
2799
3392
|
const name = rawName.replace(/^_/, "@").replace(/_/, "/");
|
|
2800
|
-
const filePath =
|
|
2801
|
-
const stat =
|
|
3393
|
+
const filePath = path9.join(cacheDir, file);
|
|
3394
|
+
const stat = fs11.statSync(filePath);
|
|
2802
3395
|
result.push({
|
|
2803
3396
|
name,
|
|
2804
3397
|
version,
|
|
@@ -2811,14 +3404,14 @@ function listCachedPlugins() {
|
|
|
2811
3404
|
}
|
|
2812
3405
|
function cleanAllCache() {
|
|
2813
3406
|
const cacheDir = getPluginCacheDir();
|
|
2814
|
-
if (!
|
|
3407
|
+
if (!fs11.existsSync(cacheDir)) {
|
|
2815
3408
|
return 0;
|
|
2816
3409
|
}
|
|
2817
|
-
const files =
|
|
3410
|
+
const files = fs11.readdirSync(cacheDir);
|
|
2818
3411
|
let count = 0;
|
|
2819
3412
|
for (const file of files) {
|
|
2820
3413
|
if (file.endsWith(".tgz")) {
|
|
2821
|
-
|
|
3414
|
+
fs11.unlinkSync(path9.join(cacheDir, file));
|
|
2822
3415
|
count++;
|
|
2823
3416
|
}
|
|
2824
3417
|
}
|
|
@@ -2826,21 +3419,21 @@ function cleanAllCache() {
|
|
|
2826
3419
|
}
|
|
2827
3420
|
function cleanPluginCache(pluginKey, version) {
|
|
2828
3421
|
const cacheDir = getPluginCacheDir();
|
|
2829
|
-
if (!
|
|
3422
|
+
if (!fs11.existsSync(cacheDir)) {
|
|
2830
3423
|
return 0;
|
|
2831
3424
|
}
|
|
2832
3425
|
const safeKey = pluginKey.replace(/[/@]/g, "_");
|
|
2833
|
-
const files =
|
|
3426
|
+
const files = fs11.readdirSync(cacheDir);
|
|
2834
3427
|
let count = 0;
|
|
2835
3428
|
for (const file of files) {
|
|
2836
3429
|
if (version) {
|
|
2837
3430
|
if (file === `${safeKey}@${version}.tgz`) {
|
|
2838
|
-
|
|
3431
|
+
fs11.unlinkSync(path9.join(cacheDir, file));
|
|
2839
3432
|
count++;
|
|
2840
3433
|
}
|
|
2841
3434
|
} else {
|
|
2842
3435
|
if (file.startsWith(`${safeKey}@`) && file.endsWith(".tgz")) {
|
|
2843
|
-
|
|
3436
|
+
fs11.unlinkSync(path9.join(cacheDir, file));
|
|
2844
3437
|
count++;
|
|
2845
3438
|
}
|
|
2846
3439
|
}
|
|
@@ -2934,6 +3527,8 @@ async function installOne(nameWithVersion) {
|
|
|
2934
3527
|
if (actualVersion === requestedVersion) {
|
|
2935
3528
|
console.log(`[action-plugin] Plugin ${name}@${requestedVersion} is already installed`);
|
|
2936
3529
|
syncActionPluginsRecord(name, actualVersion);
|
|
3530
|
+
reportCreateInstanceEvent(name, actualVersion).catch(() => {
|
|
3531
|
+
});
|
|
2937
3532
|
return { name, version: actualVersion, success: true, skipped: true };
|
|
2938
3533
|
}
|
|
2939
3534
|
}
|
|
@@ -2944,6 +3539,8 @@ async function installOne(nameWithVersion) {
|
|
|
2944
3539
|
if (actualVersion === targetVersion) {
|
|
2945
3540
|
console.log(`[action-plugin] Plugin ${name} is already up to date (version: ${actualVersion})`);
|
|
2946
3541
|
syncActionPluginsRecord(name, actualVersion);
|
|
3542
|
+
reportCreateInstanceEvent(name, actualVersion).catch(() => {
|
|
3543
|
+
});
|
|
2947
3544
|
return { name, version: actualVersion, success: true, skipped: true };
|
|
2948
3545
|
}
|
|
2949
3546
|
console.log(`[action-plugin] Found newer version: ${targetVersion} (installed: ${actualVersion || "none"})`);
|
|
@@ -2976,6 +3573,8 @@ async function installOne(nameWithVersion) {
|
|
|
2976
3573
|
console.log(`[action-plugin] Successfully installed ${name}@${installedVersion} (${source})`);
|
|
2977
3574
|
reportInstallEvent(name, installedVersion).catch(() => {
|
|
2978
3575
|
});
|
|
3576
|
+
reportCreateInstanceEvent(name, installedVersion).catch(() => {
|
|
3577
|
+
});
|
|
2979
3578
|
return { name, version: installedVersion, success: true };
|
|
2980
3579
|
} catch (error) {
|
|
2981
3580
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -3261,40 +3860,40 @@ var actionPluginCommandGroup = {
|
|
|
3261
3860
|
};
|
|
3262
3861
|
|
|
3263
3862
|
// src/commands/capability/utils.ts
|
|
3264
|
-
import
|
|
3863
|
+
import fs12 from "fs";
|
|
3265
3864
|
import { createRequire as createRequire2 } from "module";
|
|
3266
|
-
import
|
|
3865
|
+
import path10 from "path";
|
|
3267
3866
|
var CAPABILITIES_DIR = "server/capabilities";
|
|
3268
3867
|
function getProjectRoot2() {
|
|
3269
3868
|
return process.cwd();
|
|
3270
3869
|
}
|
|
3271
3870
|
function getCapabilitiesDir() {
|
|
3272
|
-
return
|
|
3871
|
+
return path10.join(getProjectRoot2(), CAPABILITIES_DIR);
|
|
3273
3872
|
}
|
|
3274
3873
|
function getCapabilityPath(id) {
|
|
3275
|
-
return
|
|
3874
|
+
return path10.join(getCapabilitiesDir(), `${id}.json`);
|
|
3276
3875
|
}
|
|
3277
3876
|
function getPluginManifestPath(pluginKey) {
|
|
3278
|
-
return
|
|
3877
|
+
return path10.join(getProjectRoot2(), "node_modules", pluginKey, "manifest.json");
|
|
3279
3878
|
}
|
|
3280
3879
|
function capabilitiesDirExists() {
|
|
3281
|
-
return
|
|
3880
|
+
return fs12.existsSync(getCapabilitiesDir());
|
|
3282
3881
|
}
|
|
3283
3882
|
function listCapabilityIds() {
|
|
3284
3883
|
const dir = getCapabilitiesDir();
|
|
3285
|
-
if (!
|
|
3884
|
+
if (!fs12.existsSync(dir)) {
|
|
3286
3885
|
return [];
|
|
3287
3886
|
}
|
|
3288
|
-
const files =
|
|
3887
|
+
const files = fs12.readdirSync(dir);
|
|
3289
3888
|
return files.filter((f) => f.endsWith(".json") && f !== "capabilities.json").map((f) => f.replace(/\.json$/, ""));
|
|
3290
3889
|
}
|
|
3291
3890
|
function readCapability(id) {
|
|
3292
3891
|
const filePath = getCapabilityPath(id);
|
|
3293
|
-
if (!
|
|
3892
|
+
if (!fs12.existsSync(filePath)) {
|
|
3294
3893
|
throw new Error(`Capability not found: ${id}`);
|
|
3295
3894
|
}
|
|
3296
3895
|
try {
|
|
3297
|
-
const content =
|
|
3896
|
+
const content = fs12.readFileSync(filePath, "utf-8");
|
|
3298
3897
|
return JSON.parse(content);
|
|
3299
3898
|
} catch (error) {
|
|
3300
3899
|
if (error instanceof SyntaxError) {
|
|
@@ -3321,11 +3920,11 @@ function readAllCapabilities() {
|
|
|
3321
3920
|
}
|
|
3322
3921
|
function readPluginManifest(pluginKey) {
|
|
3323
3922
|
const manifestPath = getPluginManifestPath(pluginKey);
|
|
3324
|
-
if (!
|
|
3923
|
+
if (!fs12.existsSync(manifestPath)) {
|
|
3325
3924
|
throw new Error(`Plugin not installed: ${pluginKey} (manifest.json not found)`);
|
|
3326
3925
|
}
|
|
3327
3926
|
try {
|
|
3328
|
-
const content =
|
|
3927
|
+
const content = fs12.readFileSync(manifestPath, "utf-8");
|
|
3329
3928
|
return JSON.parse(content);
|
|
3330
3929
|
} catch (error) {
|
|
3331
3930
|
if (error instanceof SyntaxError) {
|
|
@@ -3342,7 +3941,7 @@ function hasValidParamsSchema(paramsSchema) {
|
|
|
3342
3941
|
}
|
|
3343
3942
|
async function loadPlugin(pluginKey) {
|
|
3344
3943
|
try {
|
|
3345
|
-
const userRequire = createRequire2(
|
|
3944
|
+
const userRequire = createRequire2(path10.join(getProjectRoot2(), "package.json"));
|
|
3346
3945
|
const resolvedPath = userRequire.resolve(pluginKey);
|
|
3347
3946
|
const pluginModule = await import(resolvedPath);
|
|
3348
3947
|
const pluginPackage = pluginModule.default ?? pluginModule;
|
|
@@ -3501,9 +4100,12 @@ var capabilityCommandGroup = {
|
|
|
3501
4100
|
commands: [listCommand2]
|
|
3502
4101
|
};
|
|
3503
4102
|
|
|
4103
|
+
// src/commands/component/add.handler.ts
|
|
4104
|
+
import { execFile } from "child_process";
|
|
4105
|
+
|
|
3504
4106
|
// src/commands/component/registry-preparer.ts
|
|
3505
|
-
import
|
|
3506
|
-
import
|
|
4107
|
+
import fs13 from "fs";
|
|
4108
|
+
import path11 from "path";
|
|
3507
4109
|
import os from "os";
|
|
3508
4110
|
|
|
3509
4111
|
// src/commands/component/service.ts
|
|
@@ -3559,7 +4161,7 @@ async function sendInstallEvent(key) {
|
|
|
3559
4161
|
}
|
|
3560
4162
|
|
|
3561
4163
|
// src/commands/component/registry-preparer.ts
|
|
3562
|
-
var REGISTRY_TEMP_DIR =
|
|
4164
|
+
var REGISTRY_TEMP_DIR = path11.join(os.tmpdir(), "miaoda-registry");
|
|
3563
4165
|
function parseComponentKey(key) {
|
|
3564
4166
|
const match = key.match(/^@([^/]+)\/(.+)$/);
|
|
3565
4167
|
if (!match) {
|
|
@@ -3571,11 +4173,11 @@ function parseComponentKey(key) {
|
|
|
3571
4173
|
}
|
|
3572
4174
|
function getLocalRegistryPath(key) {
|
|
3573
4175
|
const { scope, name } = parseComponentKey(key);
|
|
3574
|
-
return
|
|
4176
|
+
return path11.join(REGISTRY_TEMP_DIR, scope, `${name}.json`);
|
|
3575
4177
|
}
|
|
3576
4178
|
function ensureDir(dirPath) {
|
|
3577
|
-
if (!
|
|
3578
|
-
|
|
4179
|
+
if (!fs13.existsSync(dirPath)) {
|
|
4180
|
+
fs13.mkdirSync(dirPath, { recursive: true });
|
|
3579
4181
|
}
|
|
3580
4182
|
}
|
|
3581
4183
|
async function prepareRecursive(key, visited) {
|
|
@@ -3608,8 +4210,8 @@ async function prepareRecursive(key, visited) {
|
|
|
3608
4210
|
registryDependencies: deps.map((dep) => getLocalRegistryPath(dep))
|
|
3609
4211
|
};
|
|
3610
4212
|
const localPath = getLocalRegistryPath(key);
|
|
3611
|
-
ensureDir(
|
|
3612
|
-
|
|
4213
|
+
ensureDir(path11.dirname(localPath));
|
|
4214
|
+
fs13.writeFileSync(localPath, JSON.stringify(rewrittenItem, null, 2), "utf-8");
|
|
3613
4215
|
debug("\u4FDD\u5B58\u5230: %s", localPath);
|
|
3614
4216
|
}
|
|
3615
4217
|
async function prepareComponentRegistryItems(id) {
|
|
@@ -3619,18 +4221,18 @@ async function prepareComponentRegistryItems(id) {
|
|
|
3619
4221
|
}
|
|
3620
4222
|
function cleanupTempDir() {
|
|
3621
4223
|
try {
|
|
3622
|
-
if (
|
|
3623
|
-
|
|
4224
|
+
if (fs13.existsSync(REGISTRY_TEMP_DIR)) {
|
|
4225
|
+
fs13.rmSync(REGISTRY_TEMP_DIR, { recursive: true, force: true });
|
|
3624
4226
|
}
|
|
3625
4227
|
} catch {
|
|
3626
4228
|
}
|
|
3627
4229
|
}
|
|
3628
4230
|
function getDownloadedRegistryItem(itemId) {
|
|
3629
4231
|
const localPath = getLocalRegistryPath(itemId);
|
|
3630
|
-
if (!
|
|
4232
|
+
if (!fs13.existsSync(localPath)) {
|
|
3631
4233
|
return null;
|
|
3632
4234
|
}
|
|
3633
|
-
const content =
|
|
4235
|
+
const content = fs13.readFileSync(localPath, "utf-8");
|
|
3634
4236
|
return JSON.parse(content);
|
|
3635
4237
|
}
|
|
3636
4238
|
|
|
@@ -3730,6 +4332,16 @@ async function executeShadcnAdd(registryItemPath) {
|
|
|
3730
4332
|
}
|
|
3731
4333
|
|
|
3732
4334
|
// src/commands/component/add.handler.ts
|
|
4335
|
+
function runActionPluginInit() {
|
|
4336
|
+
return new Promise((resolve) => {
|
|
4337
|
+
execFile("fullstack-cli", ["action-plugin", "init"], { cwd: process.cwd(), stdio: "ignore" }, (error) => {
|
|
4338
|
+
if (error) {
|
|
4339
|
+
debug("action-plugin init \u5931\u8D25: %s", error.message);
|
|
4340
|
+
}
|
|
4341
|
+
resolve();
|
|
4342
|
+
});
|
|
4343
|
+
});
|
|
4344
|
+
}
|
|
3733
4345
|
function printResult(result) {
|
|
3734
4346
|
console.log(JSON.stringify(result, null, 2));
|
|
3735
4347
|
}
|
|
@@ -3766,6 +4378,7 @@ async function add(key) {
|
|
|
3766
4378
|
errors: [{ message: errorMessage }]
|
|
3767
4379
|
});
|
|
3768
4380
|
} finally {
|
|
4381
|
+
await runActionPluginInit();
|
|
3769
4382
|
cleanupTempDir();
|
|
3770
4383
|
}
|
|
3771
4384
|
}
|
|
@@ -3787,58 +4400,58 @@ var componentCommandGroup = {
|
|
|
3787
4400
|
};
|
|
3788
4401
|
|
|
3789
4402
|
// src/commands/migration/version-manager.ts
|
|
3790
|
-
import
|
|
3791
|
-
import
|
|
4403
|
+
import fs14 from "fs";
|
|
4404
|
+
import path12 from "path";
|
|
3792
4405
|
var PACKAGE_JSON = "package.json";
|
|
3793
4406
|
var VERSION_FIELD = "migrationVersion";
|
|
3794
4407
|
function getPackageJsonPath2() {
|
|
3795
|
-
return
|
|
4408
|
+
return path12.join(process.cwd(), PACKAGE_JSON);
|
|
3796
4409
|
}
|
|
3797
4410
|
function getCurrentVersion() {
|
|
3798
4411
|
const pkgPath = getPackageJsonPath2();
|
|
3799
|
-
if (!
|
|
4412
|
+
if (!fs14.existsSync(pkgPath)) {
|
|
3800
4413
|
throw new Error("package.json not found");
|
|
3801
4414
|
}
|
|
3802
|
-
const pkg2 = JSON.parse(
|
|
4415
|
+
const pkg2 = JSON.parse(fs14.readFileSync(pkgPath, "utf-8"));
|
|
3803
4416
|
return pkg2[VERSION_FIELD] ?? 0;
|
|
3804
4417
|
}
|
|
3805
4418
|
function setCurrentVersion(version) {
|
|
3806
4419
|
const pkgPath = getPackageJsonPath2();
|
|
3807
|
-
const pkg2 = JSON.parse(
|
|
4420
|
+
const pkg2 = JSON.parse(fs14.readFileSync(pkgPath, "utf-8"));
|
|
3808
4421
|
pkg2[VERSION_FIELD] = version;
|
|
3809
|
-
|
|
4422
|
+
fs14.writeFileSync(pkgPath, JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
|
|
3810
4423
|
}
|
|
3811
4424
|
|
|
3812
4425
|
// src/commands/migration/versions/v001_capability/json-migrator/detector.ts
|
|
3813
|
-
import
|
|
3814
|
-
import
|
|
4426
|
+
import fs16 from "fs";
|
|
4427
|
+
import path14 from "path";
|
|
3815
4428
|
|
|
3816
4429
|
// src/commands/migration/versions/v001_capability/utils.ts
|
|
3817
|
-
import
|
|
3818
|
-
import
|
|
4430
|
+
import fs15 from "fs";
|
|
4431
|
+
import path13 from "path";
|
|
3819
4432
|
var CAPABILITIES_DIR2 = "server/capabilities";
|
|
3820
4433
|
function getProjectRoot3() {
|
|
3821
4434
|
return process.cwd();
|
|
3822
4435
|
}
|
|
3823
4436
|
function getCapabilitiesDir2() {
|
|
3824
|
-
return
|
|
4437
|
+
return path13.join(getProjectRoot3(), CAPABILITIES_DIR2);
|
|
3825
4438
|
}
|
|
3826
4439
|
function getPluginManifestPath2(pluginKey) {
|
|
3827
|
-
return
|
|
4440
|
+
return path13.join(getProjectRoot3(), "node_modules", pluginKey, "manifest.json");
|
|
3828
4441
|
}
|
|
3829
4442
|
|
|
3830
4443
|
// src/commands/migration/versions/v001_capability/json-migrator/detector.ts
|
|
3831
4444
|
function detectJsonMigration() {
|
|
3832
4445
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
3833
|
-
const oldFilePath =
|
|
3834
|
-
if (!
|
|
4446
|
+
const oldFilePath = path14.join(capabilitiesDir, "capabilities.json");
|
|
4447
|
+
if (!fs16.existsSync(oldFilePath)) {
|
|
3835
4448
|
return {
|
|
3836
4449
|
needsMigration: false,
|
|
3837
4450
|
reason: "capabilities.json not found"
|
|
3838
4451
|
};
|
|
3839
4452
|
}
|
|
3840
4453
|
try {
|
|
3841
|
-
const content =
|
|
4454
|
+
const content = fs16.readFileSync(oldFilePath, "utf-8");
|
|
3842
4455
|
const parsed = JSON.parse(content);
|
|
3843
4456
|
if (!Array.isArray(parsed)) {
|
|
3844
4457
|
return {
|
|
@@ -3889,8 +4502,8 @@ async function check(options) {
|
|
|
3889
4502
|
}
|
|
3890
4503
|
|
|
3891
4504
|
// src/commands/migration/versions/v001_capability/json-migrator/index.ts
|
|
3892
|
-
import
|
|
3893
|
-
import
|
|
4505
|
+
import fs17 from "fs";
|
|
4506
|
+
import path15 from "path";
|
|
3894
4507
|
|
|
3895
4508
|
// src/commands/migration/versions/v001_capability/mapping.ts
|
|
3896
4509
|
var DEFAULT_PLUGIN_VERSION = "1.0.0";
|
|
@@ -4120,18 +4733,18 @@ function transformCapabilities(oldCapabilities) {
|
|
|
4120
4733
|
// src/commands/migration/versions/v001_capability/json-migrator/index.ts
|
|
4121
4734
|
function loadExistingCapabilities() {
|
|
4122
4735
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
4123
|
-
if (!
|
|
4736
|
+
if (!fs17.existsSync(capabilitiesDir)) {
|
|
4124
4737
|
return [];
|
|
4125
4738
|
}
|
|
4126
|
-
const files =
|
|
4739
|
+
const files = fs17.readdirSync(capabilitiesDir);
|
|
4127
4740
|
const capabilities = [];
|
|
4128
4741
|
for (const file of files) {
|
|
4129
4742
|
if (file === "capabilities.json" || !file.endsWith(".json")) {
|
|
4130
4743
|
continue;
|
|
4131
4744
|
}
|
|
4132
4745
|
try {
|
|
4133
|
-
const filePath =
|
|
4134
|
-
const content =
|
|
4746
|
+
const filePath = path15.join(capabilitiesDir, file);
|
|
4747
|
+
const content = fs17.readFileSync(filePath, "utf-8");
|
|
4135
4748
|
const capability = JSON.parse(content);
|
|
4136
4749
|
if (capability.id && capability.pluginKey) {
|
|
4137
4750
|
capabilities.push(capability);
|
|
@@ -4189,9 +4802,9 @@ async function migrateJsonFiles(options) {
|
|
|
4189
4802
|
}
|
|
4190
4803
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
4191
4804
|
for (const cap of newCapabilities) {
|
|
4192
|
-
const filePath =
|
|
4805
|
+
const filePath = path15.join(capabilitiesDir, `${cap.id}.json`);
|
|
4193
4806
|
const content = JSON.stringify(cap, null, 2);
|
|
4194
|
-
|
|
4807
|
+
fs17.writeFileSync(filePath, content, "utf-8");
|
|
4195
4808
|
console.log(` \u2713 Created: ${cap.id}.json`);
|
|
4196
4809
|
}
|
|
4197
4810
|
return {
|
|
@@ -4203,11 +4816,11 @@ async function migrateJsonFiles(options) {
|
|
|
4203
4816
|
}
|
|
4204
4817
|
|
|
4205
4818
|
// src/commands/migration/versions/v001_capability/plugin-installer/detector.ts
|
|
4206
|
-
import
|
|
4819
|
+
import fs18 from "fs";
|
|
4207
4820
|
function isPluginInstalled2(pluginKey) {
|
|
4208
4821
|
const actionPlugins = readActionPlugins();
|
|
4209
4822
|
const manifestPath = getPluginManifestPath2(pluginKey);
|
|
4210
|
-
return
|
|
4823
|
+
return fs18.existsSync(manifestPath) && !!actionPlugins[pluginKey];
|
|
4211
4824
|
}
|
|
4212
4825
|
function detectPluginsToInstall(capabilities) {
|
|
4213
4826
|
const pluginKeys = /* @__PURE__ */ new Set();
|
|
@@ -4283,12 +4896,12 @@ async function installPlugins(capabilities, options) {
|
|
|
4283
4896
|
}
|
|
4284
4897
|
|
|
4285
4898
|
// src/commands/migration/versions/v001_capability/code-migrator/index.ts
|
|
4286
|
-
import
|
|
4899
|
+
import path17 from "path";
|
|
4287
4900
|
import { Project as Project3 } from "ts-morph";
|
|
4288
4901
|
|
|
4289
4902
|
// src/commands/migration/versions/v001_capability/code-migrator/scanner.ts
|
|
4290
|
-
import
|
|
4291
|
-
import
|
|
4903
|
+
import fs19 from "fs";
|
|
4904
|
+
import path16 from "path";
|
|
4292
4905
|
var EXCLUDED_DIRS = [
|
|
4293
4906
|
"node_modules",
|
|
4294
4907
|
"dist",
|
|
@@ -4303,9 +4916,9 @@ var EXCLUDED_PATTERNS = [
|
|
|
4303
4916
|
/\.d\.ts$/
|
|
4304
4917
|
];
|
|
4305
4918
|
function scanDirectory(dir, files = []) {
|
|
4306
|
-
const entries =
|
|
4919
|
+
const entries = fs19.readdirSync(dir, { withFileTypes: true });
|
|
4307
4920
|
for (const entry of entries) {
|
|
4308
|
-
const fullPath =
|
|
4921
|
+
const fullPath = path16.join(dir, entry.name);
|
|
4309
4922
|
if (entry.isDirectory()) {
|
|
4310
4923
|
if (EXCLUDED_DIRS.includes(entry.name)) {
|
|
4311
4924
|
continue;
|
|
@@ -4321,14 +4934,14 @@ function scanDirectory(dir, files = []) {
|
|
|
4321
4934
|
return files;
|
|
4322
4935
|
}
|
|
4323
4936
|
function scanServerFiles() {
|
|
4324
|
-
const serverDir =
|
|
4325
|
-
if (!
|
|
4937
|
+
const serverDir = path16.join(getProjectRoot3(), "server");
|
|
4938
|
+
if (!fs19.existsSync(serverDir)) {
|
|
4326
4939
|
return [];
|
|
4327
4940
|
}
|
|
4328
4941
|
return scanDirectory(serverDir);
|
|
4329
4942
|
}
|
|
4330
4943
|
function hasCapabilityImport(filePath) {
|
|
4331
|
-
const content =
|
|
4944
|
+
const content = fs19.readFileSync(filePath, "utf-8");
|
|
4332
4945
|
return /import\s+.*from\s+['"][^'"]*capabilities[^'"]*['"]/.test(content);
|
|
4333
4946
|
}
|
|
4334
4947
|
function scanFilesToMigrate() {
|
|
@@ -4705,7 +5318,7 @@ function analyzeFile(project, filePath, actionNameMap) {
|
|
|
4705
5318
|
const callSites = analyzeCallSites(sourceFile, imports);
|
|
4706
5319
|
const classInfo = analyzeClass(sourceFile);
|
|
4707
5320
|
const { canMigrate, reason } = canAutoMigrate(classInfo);
|
|
4708
|
-
const relativePath =
|
|
5321
|
+
const relativePath = path17.relative(getProjectRoot3(), filePath);
|
|
4709
5322
|
return {
|
|
4710
5323
|
filePath: relativePath,
|
|
4711
5324
|
imports,
|
|
@@ -4716,7 +5329,7 @@ function analyzeFile(project, filePath, actionNameMap) {
|
|
|
4716
5329
|
};
|
|
4717
5330
|
}
|
|
4718
5331
|
function migrateFile(project, analysis, dryRun) {
|
|
4719
|
-
const absolutePath =
|
|
5332
|
+
const absolutePath = path17.join(getProjectRoot3(), analysis.filePath);
|
|
4720
5333
|
if (!analysis.canAutoMigrate) {
|
|
4721
5334
|
return {
|
|
4722
5335
|
filePath: analysis.filePath,
|
|
@@ -4819,17 +5432,17 @@ function getSuggestion(analysis) {
|
|
|
4819
5432
|
}
|
|
4820
5433
|
|
|
4821
5434
|
// src/commands/migration/versions/v001_capability/cleanup.ts
|
|
4822
|
-
import
|
|
4823
|
-
import
|
|
5435
|
+
import fs20 from "fs";
|
|
5436
|
+
import path18 from "path";
|
|
4824
5437
|
function cleanupOldFiles(capabilities, dryRun) {
|
|
4825
5438
|
const deletedFiles = [];
|
|
4826
5439
|
const errors = [];
|
|
4827
5440
|
const capabilitiesDir = getCapabilitiesDir2();
|
|
4828
|
-
const oldJsonPath =
|
|
4829
|
-
if (
|
|
5441
|
+
const oldJsonPath = path18.join(capabilitiesDir, "capabilities.json");
|
|
5442
|
+
if (fs20.existsSync(oldJsonPath)) {
|
|
4830
5443
|
try {
|
|
4831
5444
|
if (!dryRun) {
|
|
4832
|
-
|
|
5445
|
+
fs20.unlinkSync(oldJsonPath);
|
|
4833
5446
|
}
|
|
4834
5447
|
deletedFiles.push("capabilities.json");
|
|
4835
5448
|
} catch (error) {
|
|
@@ -4837,11 +5450,11 @@ function cleanupOldFiles(capabilities, dryRun) {
|
|
|
4837
5450
|
}
|
|
4838
5451
|
}
|
|
4839
5452
|
for (const cap of capabilities) {
|
|
4840
|
-
const tsFilePath =
|
|
4841
|
-
if (
|
|
5453
|
+
const tsFilePath = path18.join(capabilitiesDir, `${cap.id}.ts`);
|
|
5454
|
+
if (fs20.existsSync(tsFilePath)) {
|
|
4842
5455
|
try {
|
|
4843
5456
|
if (!dryRun) {
|
|
4844
|
-
|
|
5457
|
+
fs20.unlinkSync(tsFilePath);
|
|
4845
5458
|
}
|
|
4846
5459
|
deletedFiles.push(`${cap.id}.ts`);
|
|
4847
5460
|
} catch (error) {
|
|
@@ -4857,8 +5470,8 @@ function cleanupOldFiles(capabilities, dryRun) {
|
|
|
4857
5470
|
}
|
|
4858
5471
|
|
|
4859
5472
|
// src/commands/migration/versions/v001_capability/report-generator.ts
|
|
4860
|
-
import
|
|
4861
|
-
import
|
|
5473
|
+
import fs21 from "fs";
|
|
5474
|
+
import path19 from "path";
|
|
4862
5475
|
var REPORT_FILE = "capability-migration-report.md";
|
|
4863
5476
|
function printSummary(result) {
|
|
4864
5477
|
const { jsonMigration, pluginInstallation, codeMigration, cleanup } = result;
|
|
@@ -5021,15 +5634,15 @@ async function generateReport(result) {
|
|
|
5021
5634
|
}
|
|
5022
5635
|
lines.push("");
|
|
5023
5636
|
const logDir = process.env.LOG_DIR || "logs";
|
|
5024
|
-
if (!
|
|
5637
|
+
if (!fs21.existsSync(logDir)) {
|
|
5025
5638
|
return;
|
|
5026
5639
|
}
|
|
5027
|
-
const reportDir =
|
|
5028
|
-
if (!
|
|
5029
|
-
|
|
5640
|
+
const reportDir = path19.join(logDir, "migration");
|
|
5641
|
+
if (!fs21.existsSync(reportDir)) {
|
|
5642
|
+
fs21.mkdirSync(reportDir, { recursive: true });
|
|
5030
5643
|
}
|
|
5031
|
-
const reportPath =
|
|
5032
|
-
|
|
5644
|
+
const reportPath = path19.join(reportDir, REPORT_FILE);
|
|
5645
|
+
fs21.writeFileSync(reportPath, lines.join("\n"), "utf-8");
|
|
5033
5646
|
console.log(`\u{1F4C4} Report generated: ${reportPath}`);
|
|
5034
5647
|
}
|
|
5035
5648
|
|
|
@@ -5206,7 +5819,7 @@ function buildResult(jsonMigration, pluginInstallation, codeMigration, cleanup)
|
|
|
5206
5819
|
}
|
|
5207
5820
|
|
|
5208
5821
|
// src/commands/migration/versions/v001_capability/run.ts
|
|
5209
|
-
async function
|
|
5822
|
+
async function run5(options) {
|
|
5210
5823
|
try {
|
|
5211
5824
|
const migrationOptions = {
|
|
5212
5825
|
dryRun: options.dryRun ?? false
|
|
@@ -5271,7 +5884,7 @@ var v001CapabilityMigration = {
|
|
|
5271
5884
|
name: "capability",
|
|
5272
5885
|
description: "Migrate capability configurations from old format (capabilities.json array) to new format (individual JSON files)",
|
|
5273
5886
|
check,
|
|
5274
|
-
run:
|
|
5887
|
+
run: run5
|
|
5275
5888
|
};
|
|
5276
5889
|
|
|
5277
5890
|
// src/commands/migration/versions/index.ts
|
|
@@ -5561,10 +6174,10 @@ var migrationCommand = {
|
|
|
5561
6174
|
};
|
|
5562
6175
|
|
|
5563
6176
|
// src/commands/read-logs/index.ts
|
|
5564
|
-
import
|
|
6177
|
+
import path20 from "path";
|
|
5565
6178
|
|
|
5566
6179
|
// src/commands/read-logs/std-utils.ts
|
|
5567
|
-
import
|
|
6180
|
+
import fs22 from "fs";
|
|
5568
6181
|
function formatStdPrefixTime(localTime) {
|
|
5569
6182
|
const match = localTime.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
|
|
5570
6183
|
if (!match) return localTime;
|
|
@@ -5594,11 +6207,11 @@ function stripPrefixFromStdLine(line) {
|
|
|
5594
6207
|
return `[${time}] ${content}`;
|
|
5595
6208
|
}
|
|
5596
6209
|
function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarker) {
|
|
5597
|
-
const stat =
|
|
6210
|
+
const stat = fs22.statSync(filePath);
|
|
5598
6211
|
if (stat.size === 0) {
|
|
5599
6212
|
return { lines: [], markerFound: false, totalLinesCount: 0 };
|
|
5600
6213
|
}
|
|
5601
|
-
const fd =
|
|
6214
|
+
const fd = fs22.openSync(filePath, "r");
|
|
5602
6215
|
const chunkSize = 64 * 1024;
|
|
5603
6216
|
let position = stat.size;
|
|
5604
6217
|
let remainder = "";
|
|
@@ -5612,7 +6225,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
|
|
|
5612
6225
|
const length = Math.min(chunkSize, position);
|
|
5613
6226
|
position -= length;
|
|
5614
6227
|
const buffer = Buffer.alloc(length);
|
|
5615
|
-
|
|
6228
|
+
fs22.readSync(fd, buffer, 0, length, position);
|
|
5616
6229
|
let chunk = buffer.toString("utf8");
|
|
5617
6230
|
if (remainder) {
|
|
5618
6231
|
chunk += remainder;
|
|
@@ -5654,7 +6267,7 @@ function readStdLinesTailFromLastMarkerPaged(filePath, maxLines, offset, isMarke
|
|
|
5654
6267
|
}
|
|
5655
6268
|
}
|
|
5656
6269
|
} finally {
|
|
5657
|
-
|
|
6270
|
+
fs22.closeSync(fd);
|
|
5658
6271
|
}
|
|
5659
6272
|
return { lines: collected.reverse(), markerFound, totalLinesCount };
|
|
5660
6273
|
}
|
|
@@ -5675,21 +6288,21 @@ function readServerStdSegment(filePath, maxLines, offset) {
|
|
|
5675
6288
|
}
|
|
5676
6289
|
|
|
5677
6290
|
// src/commands/read-logs/tail.ts
|
|
5678
|
-
import
|
|
6291
|
+
import fs23 from "fs";
|
|
5679
6292
|
function fileExists(filePath) {
|
|
5680
6293
|
try {
|
|
5681
|
-
|
|
6294
|
+
fs23.accessSync(filePath, fs23.constants.F_OK | fs23.constants.R_OK);
|
|
5682
6295
|
return true;
|
|
5683
6296
|
} catch {
|
|
5684
6297
|
return false;
|
|
5685
6298
|
}
|
|
5686
6299
|
}
|
|
5687
6300
|
function readFileTailLines(filePath, maxLines) {
|
|
5688
|
-
const stat =
|
|
6301
|
+
const stat = fs23.statSync(filePath);
|
|
5689
6302
|
if (stat.size === 0) {
|
|
5690
6303
|
return [];
|
|
5691
6304
|
}
|
|
5692
|
-
const fd =
|
|
6305
|
+
const fd = fs23.openSync(filePath, "r");
|
|
5693
6306
|
const chunkSize = 64 * 1024;
|
|
5694
6307
|
const chunks = [];
|
|
5695
6308
|
let position = stat.size;
|
|
@@ -5699,13 +6312,13 @@ function readFileTailLines(filePath, maxLines) {
|
|
|
5699
6312
|
const length = Math.min(chunkSize, position);
|
|
5700
6313
|
position -= length;
|
|
5701
6314
|
const buffer = Buffer.alloc(length);
|
|
5702
|
-
|
|
6315
|
+
fs23.readSync(fd, buffer, 0, length, position);
|
|
5703
6316
|
chunks.unshift(buffer.toString("utf8"));
|
|
5704
6317
|
const chunkLines = buffer.toString("utf8").split("\n").length - 1;
|
|
5705
6318
|
collectedLines += chunkLines;
|
|
5706
6319
|
}
|
|
5707
6320
|
} finally {
|
|
5708
|
-
|
|
6321
|
+
fs23.closeSync(fd);
|
|
5709
6322
|
}
|
|
5710
6323
|
const content = chunks.join("");
|
|
5711
6324
|
const allLines = content.split("\n");
|
|
@@ -5721,11 +6334,11 @@ function readFileTailLines(filePath, maxLines) {
|
|
|
5721
6334
|
return allLines.slice(allLines.length - maxLines);
|
|
5722
6335
|
}
|
|
5723
6336
|
function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
5724
|
-
const stat =
|
|
6337
|
+
const stat = fs23.statSync(filePath);
|
|
5725
6338
|
if (stat.size === 0) {
|
|
5726
6339
|
return { lines: [], totalLinesCount: 0 };
|
|
5727
6340
|
}
|
|
5728
|
-
const fd =
|
|
6341
|
+
const fd = fs23.openSync(filePath, "r");
|
|
5729
6342
|
const chunkSize = 64 * 1024;
|
|
5730
6343
|
let position = stat.size;
|
|
5731
6344
|
let remainder = "";
|
|
@@ -5737,7 +6350,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
|
5737
6350
|
const length = Math.min(chunkSize, position);
|
|
5738
6351
|
position -= length;
|
|
5739
6352
|
const buffer = Buffer.alloc(length);
|
|
5740
|
-
|
|
6353
|
+
fs23.readSync(fd, buffer, 0, length, position);
|
|
5741
6354
|
let chunk = buffer.toString("utf8");
|
|
5742
6355
|
if (remainder) {
|
|
5743
6356
|
chunk += remainder;
|
|
@@ -5768,7 +6381,7 @@ function readFileTailNonEmptyLinesWithOffset(filePath, maxLines, offset) {
|
|
|
5768
6381
|
}
|
|
5769
6382
|
}
|
|
5770
6383
|
} finally {
|
|
5771
|
-
|
|
6384
|
+
fs23.closeSync(fd);
|
|
5772
6385
|
}
|
|
5773
6386
|
return { lines: collected.reverse(), totalLinesCount };
|
|
5774
6387
|
}
|
|
@@ -5910,7 +6523,7 @@ function readDevStdSegment(filePath, maxLines, offset) {
|
|
|
5910
6523
|
}
|
|
5911
6524
|
|
|
5912
6525
|
// src/commands/read-logs/json-lines.ts
|
|
5913
|
-
import
|
|
6526
|
+
import fs24 from "fs";
|
|
5914
6527
|
function normalizePid(value) {
|
|
5915
6528
|
if (typeof value === "number") {
|
|
5916
6529
|
return String(value);
|
|
@@ -5961,11 +6574,11 @@ function buildWantedLevelSet(levels) {
|
|
|
5961
6574
|
return set.size > 0 ? set : null;
|
|
5962
6575
|
}
|
|
5963
6576
|
function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
5964
|
-
const stat =
|
|
6577
|
+
const stat = fs24.statSync(filePath);
|
|
5965
6578
|
if (stat.size === 0) {
|
|
5966
6579
|
return { lines: [], totalLinesCount: 0 };
|
|
5967
6580
|
}
|
|
5968
|
-
const fd =
|
|
6581
|
+
const fd = fs24.openSync(filePath, "r");
|
|
5969
6582
|
const chunkSize = 64 * 1024;
|
|
5970
6583
|
let position = stat.size;
|
|
5971
6584
|
let remainder = "";
|
|
@@ -5980,7 +6593,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
|
5980
6593
|
const length = Math.min(chunkSize, position);
|
|
5981
6594
|
position -= length;
|
|
5982
6595
|
const buffer = Buffer.alloc(length);
|
|
5983
|
-
|
|
6596
|
+
fs24.readSync(fd, buffer, 0, length, position);
|
|
5984
6597
|
let chunk = buffer.toString("utf8");
|
|
5985
6598
|
if (remainder) {
|
|
5986
6599
|
chunk += remainder;
|
|
@@ -6042,7 +6655,7 @@ function readJsonLinesLastPid(filePath, maxLines, offset, levels) {
|
|
|
6042
6655
|
}
|
|
6043
6656
|
}
|
|
6044
6657
|
} finally {
|
|
6045
|
-
|
|
6658
|
+
fs24.closeSync(fd);
|
|
6046
6659
|
}
|
|
6047
6660
|
return { lines: collected.reverse(), totalLinesCount };
|
|
6048
6661
|
}
|
|
@@ -6085,11 +6698,11 @@ function extractTraceId(obj) {
|
|
|
6085
6698
|
function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
6086
6699
|
const wanted = traceId.trim();
|
|
6087
6700
|
if (!wanted) return { lines: [], totalLinesCount: 0 };
|
|
6088
|
-
const stat =
|
|
6701
|
+
const stat = fs24.statSync(filePath);
|
|
6089
6702
|
if (stat.size === 0) {
|
|
6090
6703
|
return { lines: [], totalLinesCount: 0 };
|
|
6091
6704
|
}
|
|
6092
|
-
const fd =
|
|
6705
|
+
const fd = fs24.openSync(filePath, "r");
|
|
6093
6706
|
const chunkSize = 64 * 1024;
|
|
6094
6707
|
let position = stat.size;
|
|
6095
6708
|
let remainder = "";
|
|
@@ -6102,7 +6715,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
|
6102
6715
|
const length = Math.min(chunkSize, position);
|
|
6103
6716
|
position -= length;
|
|
6104
6717
|
const buffer = Buffer.alloc(length);
|
|
6105
|
-
|
|
6718
|
+
fs24.readSync(fd, buffer, 0, length, position);
|
|
6106
6719
|
let chunk = buffer.toString("utf8");
|
|
6107
6720
|
if (remainder) {
|
|
6108
6721
|
chunk += remainder;
|
|
@@ -6155,7 +6768,7 @@ function readJsonLinesByTraceId(filePath, traceId, maxLines, offset, levels) {
|
|
|
6155
6768
|
}
|
|
6156
6769
|
}
|
|
6157
6770
|
} finally {
|
|
6158
|
-
|
|
6771
|
+
fs24.closeSync(fd);
|
|
6159
6772
|
}
|
|
6160
6773
|
return { lines: collected.reverse(), totalLinesCount };
|
|
6161
6774
|
}
|
|
@@ -6164,11 +6777,11 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
6164
6777
|
if (!wantedLevelSet) {
|
|
6165
6778
|
return { lines: [], totalLinesCount: 0 };
|
|
6166
6779
|
}
|
|
6167
|
-
const stat =
|
|
6780
|
+
const stat = fs24.statSync(filePath);
|
|
6168
6781
|
if (stat.size === 0) {
|
|
6169
6782
|
return { lines: [], totalLinesCount: 0 };
|
|
6170
6783
|
}
|
|
6171
|
-
const fd =
|
|
6784
|
+
const fd = fs24.openSync(filePath, "r");
|
|
6172
6785
|
const chunkSize = 64 * 1024;
|
|
6173
6786
|
let position = stat.size;
|
|
6174
6787
|
let remainder = "";
|
|
@@ -6180,7 +6793,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
6180
6793
|
const length = Math.min(chunkSize, position);
|
|
6181
6794
|
position -= length;
|
|
6182
6795
|
const buffer = Buffer.alloc(length);
|
|
6183
|
-
|
|
6796
|
+
fs24.readSync(fd, buffer, 0, length, position);
|
|
6184
6797
|
let chunk = buffer.toString("utf8");
|
|
6185
6798
|
if (remainder) {
|
|
6186
6799
|
chunk += remainder;
|
|
@@ -6227,7 +6840,7 @@ function readJsonLinesTailByLevel(filePath, maxLines, offset, levels) {
|
|
|
6227
6840
|
}
|
|
6228
6841
|
}
|
|
6229
6842
|
} finally {
|
|
6230
|
-
|
|
6843
|
+
fs24.closeSync(fd);
|
|
6231
6844
|
}
|
|
6232
6845
|
return { lines: collected.reverse(), totalLinesCount };
|
|
6233
6846
|
}
|
|
@@ -6461,34 +7074,34 @@ async function readLogsJsonResult(options) {
|
|
|
6461
7074
|
};
|
|
6462
7075
|
}
|
|
6463
7076
|
function resolveLogFilePath(logDir, type) {
|
|
6464
|
-
const base =
|
|
7077
|
+
const base = path20.isAbsolute(logDir) ? logDir : path20.join(process.cwd(), logDir);
|
|
6465
7078
|
if (type === "server") {
|
|
6466
|
-
return
|
|
7079
|
+
return path20.join(base, "server.log");
|
|
6467
7080
|
}
|
|
6468
7081
|
if (type === "trace") {
|
|
6469
|
-
return
|
|
7082
|
+
return path20.join(base, "trace.log");
|
|
6470
7083
|
}
|
|
6471
7084
|
if (type === "server-std") {
|
|
6472
|
-
return
|
|
7085
|
+
return path20.join(base, "server.std.log");
|
|
6473
7086
|
}
|
|
6474
7087
|
if (type === "client-std") {
|
|
6475
|
-
return
|
|
7088
|
+
return path20.join(base, "client.std.log");
|
|
6476
7089
|
}
|
|
6477
7090
|
if (type === "dev") {
|
|
6478
|
-
return
|
|
7091
|
+
return path20.join(base, "dev.log");
|
|
6479
7092
|
}
|
|
6480
7093
|
if (type === "dev-std") {
|
|
6481
|
-
return
|
|
7094
|
+
return path20.join(base, "dev.std.log");
|
|
6482
7095
|
}
|
|
6483
7096
|
if (type === "install-dep-std") {
|
|
6484
|
-
return
|
|
7097
|
+
return path20.join(base, "install-dep.std.log");
|
|
6485
7098
|
}
|
|
6486
7099
|
if (type === "browser") {
|
|
6487
|
-
return
|
|
7100
|
+
return path20.join(base, "browser.log");
|
|
6488
7101
|
}
|
|
6489
7102
|
throw new Error(`Unsupported log type: ${type}`);
|
|
6490
7103
|
}
|
|
6491
|
-
async function
|
|
7104
|
+
async function run6(options) {
|
|
6492
7105
|
const result = await readLogsJsonResult(options);
|
|
6493
7106
|
process.stdout.write(JSON.stringify(result) + "\n");
|
|
6494
7107
|
}
|
|
@@ -6530,7 +7143,7 @@ var readLogsCommand = {
|
|
|
6530
7143
|
const offset = parseNonNegativeInt(rawOptions.offset, "--offset");
|
|
6531
7144
|
const traceId = typeof rawOptions.traceId === "string" ? rawOptions.traceId : void 0;
|
|
6532
7145
|
const levels = parseCommaSeparatedList(rawOptions.level);
|
|
6533
|
-
await
|
|
7146
|
+
await run6({ logDir, type, maxLines, offset, traceId, levels });
|
|
6534
7147
|
} catch (error) {
|
|
6535
7148
|
const message = error instanceof Error ? error.message : String(error);
|
|
6536
7149
|
process.stderr.write(message + "\n");
|
|
@@ -6619,6 +7232,7 @@ var buildCommandGroup = {
|
|
|
6619
7232
|
var commands = [
|
|
6620
7233
|
genDbSchemaCommand,
|
|
6621
7234
|
syncCommand,
|
|
7235
|
+
upgradeCommand,
|
|
6622
7236
|
actionPluginCommandGroup,
|
|
6623
7237
|
capabilityCommandGroup,
|
|
6624
7238
|
componentCommandGroup,
|
|
@@ -6628,12 +7242,12 @@ var commands = [
|
|
|
6628
7242
|
];
|
|
6629
7243
|
|
|
6630
7244
|
// src/index.ts
|
|
6631
|
-
var envPath =
|
|
6632
|
-
if (
|
|
7245
|
+
var envPath = path21.join(process.cwd(), ".env");
|
|
7246
|
+
if (fs25.existsSync(envPath)) {
|
|
6633
7247
|
dotenvConfig({ path: envPath });
|
|
6634
7248
|
}
|
|
6635
|
-
var __dirname =
|
|
6636
|
-
var pkg = JSON.parse(
|
|
7249
|
+
var __dirname = path21.dirname(fileURLToPath5(import.meta.url));
|
|
7250
|
+
var pkg = JSON.parse(fs25.readFileSync(path21.join(__dirname, "../package.json"), "utf-8"));
|
|
6637
7251
|
var cli = new FullstackCLI(pkg.version);
|
|
6638
7252
|
cli.useAll(commands);
|
|
6639
7253
|
cli.run();
|