@nasl/cli 0.3.3 → 0.3.4
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/bin/nasl.mjs +156 -110
- package/dist/bin/nasl.mjs.map +1 -1
- package/dist/bin/naslc.mjs +2 -1
- package/dist/bin/naslc.mjs.map +1 -1
- package/dist/index.mjs +143 -83
- package/dist/index.mjs.map +1 -1
- package/out/apis/appApi.d.ts +17 -0
- package/out/apis/appApi.d.ts.map +1 -0
- package/out/apis/appApi.js +36 -0
- package/out/apis/appApi.js.map +1 -0
- package/out/apis/index.d.ts +1 -1
- package/out/apis/index.d.ts.map +1 -1
- package/out/apis/index.js +1 -1
- package/out/apis/index.js.map +1 -1
- package/out/bin/nasl.js +14 -61
- package/out/bin/nasl.js.map +1 -1
- package/out/commands/createAppInIde.d.ts +0 -3
- package/out/commands/createAppInIde.d.ts.map +1 -1
- package/out/commands/createAppInIde.js +26 -93
- package/out/commands/createAppInIde.js.map +1 -1
- package/out/commands/index.d.ts +1 -0
- package/out/commands/index.d.ts.map +1 -1
- package/out/commands/index.js +1 -0
- package/out/commands/index.js.map +1 -1
- package/out/commands/updateAppInIde.d.ts +3 -0
- package/out/commands/updateAppInIde.d.ts.map +1 -0
- package/out/commands/updateAppInIde.js +59 -0
- package/out/commands/updateAppInIde.js.map +1 -0
- package/out/utils/appName.d.ts +8 -0
- package/out/utils/appName.d.ts.map +1 -0
- package/out/utils/appName.js +71 -0
- package/out/utils/appName.js.map +1 -0
- package/out/utils/prompt.d.ts +5 -0
- package/out/utils/prompt.d.ts.map +1 -0
- package/out/utils/prompt.js +54 -0
- package/out/utils/prompt.js.map +1 -0
- package/package.json +1 -1
package/dist/bin/nasl.mjs
CHANGED
|
@@ -29227,41 +29227,33 @@ async function checkApi(fullNaturalTS, options) {
|
|
|
29227
29227
|
}
|
|
29228
29228
|
|
|
29229
29229
|
/**
|
|
29230
|
-
*
|
|
29230
|
+
* 创建应用(POST /nasl/app/create)
|
|
29231
29231
|
*/
|
|
29232
|
-
async function
|
|
29233
|
-
const
|
|
29234
|
-
const
|
|
29235
|
-
|
|
29236
|
-
|
|
29237
|
-
|
|
29238
|
-
|
|
29239
|
-
|
|
29240
|
-
|
|
29241
|
-
|
|
29242
|
-
|
|
29243
|
-
|
|
29244
|
-
|
|
29245
|
-
|
|
29246
|
-
|
|
29247
|
-
|
|
29248
|
-
|
|
29249
|
-
|
|
29250
|
-
|
|
29251
|
-
|
|
29252
|
-
|
|
29253
|
-
|
|
29254
|
-
|
|
29255
|
-
|
|
29256
|
-
|
|
29257
|
-
error: res.data.message || '应用创建失败',
|
|
29258
|
-
};
|
|
29259
|
-
}
|
|
29260
|
-
}
|
|
29261
|
-
catch (error) {
|
|
29262
|
-
console.log(error);
|
|
29263
|
-
throw error;
|
|
29264
|
-
}
|
|
29232
|
+
async function createApp(fullNaturalTS, options, appName, packageName) {
|
|
29233
|
+
const axiosInstance = await createAxios(options);
|
|
29234
|
+
const res = await axiosInstance.post('/app/create', {
|
|
29235
|
+
fullNaturalTS,
|
|
29236
|
+
packageName,
|
|
29237
|
+
appName,
|
|
29238
|
+
ideVersion: options.ideVersion,
|
|
29239
|
+
}, {
|
|
29240
|
+
headers: { ...buildNaslHeaders(options), 'Content-Type': 'application/json' },
|
|
29241
|
+
});
|
|
29242
|
+
return res.data.result;
|
|
29243
|
+
}
|
|
29244
|
+
/**
|
|
29245
|
+
* 更新应用(POST /nasl/app/update)
|
|
29246
|
+
*/
|
|
29247
|
+
async function updateApp(fullNaturalTS, options, appId) {
|
|
29248
|
+
const axiosInstance = await createAxios(options);
|
|
29249
|
+
const res = await axiosInstance.post('/app/update', {
|
|
29250
|
+
fullNaturalTS,
|
|
29251
|
+
appId,
|
|
29252
|
+
ideVersion: options.ideVersion,
|
|
29253
|
+
}, {
|
|
29254
|
+
headers: { ...buildNaslHeaders(options), 'Content-Type': 'application/json' },
|
|
29255
|
+
});
|
|
29256
|
+
return res.data.result;
|
|
29265
29257
|
}
|
|
29266
29258
|
|
|
29267
29259
|
async function installDependenciesApi(dependenciesJSON, options) {
|
|
@@ -38935,78 +38927,94 @@ async function build(entry, options) {
|
|
|
38935
38927
|
}
|
|
38936
38928
|
|
|
38937
38929
|
/**
|
|
38938
|
-
*
|
|
38930
|
+
* 从 specs/ 目录取第一个子文件夹名;若无则退回项目根目录名
|
|
38939
38931
|
*/
|
|
38940
|
-
function
|
|
38941
|
-
const dirname = path$1.basename(projectRoot);
|
|
38932
|
+
function getSpecBaseName(projectRoot) {
|
|
38942
38933
|
const specsDir = path$1.join(projectRoot, 'specs');
|
|
38943
|
-
if (
|
|
38944
|
-
|
|
38945
|
-
|
|
38946
|
-
|
|
38947
|
-
.
|
|
38948
|
-
|
|
38949
|
-
|
|
38950
|
-
|
|
38951
|
-
return folders[0];
|
|
38934
|
+
if (libExports.existsSync(specsDir)) {
|
|
38935
|
+
const folders = libExports.readdirSync(specsDir, { withFileTypes: true })
|
|
38936
|
+
.filter(e => e.isDirectory())
|
|
38937
|
+
.map(e => e.name);
|
|
38938
|
+
if (folders.length > 0)
|
|
38939
|
+
return folders[0];
|
|
38940
|
+
}
|
|
38941
|
+
return path$1.basename(projectRoot);
|
|
38952
38942
|
}
|
|
38953
38943
|
/**
|
|
38954
|
-
*
|
|
38944
|
+
* 从项目目录推导出合法的应用名称和包名
|
|
38945
|
+
*/
|
|
38946
|
+
function deriveAppNames(projectRoot) {
|
|
38947
|
+
const baseName = getSpecBaseName(projectRoot);
|
|
38948
|
+
const suffix = dayjs().format('MMDDHHmmss');
|
|
38949
|
+
let cleaned = baseName.replace(/[^a-zA-Z0-9]/g, '').replace(/^\d+/, '').slice(0, 12);
|
|
38950
|
+
if (!cleaned)
|
|
38951
|
+
cleaned = 'app';
|
|
38952
|
+
return {
|
|
38953
|
+
appName: `${cleaned}_${suffix}`,
|
|
38954
|
+
packageName: `${cleaned}${suffix}`,
|
|
38955
|
+
};
|
|
38956
|
+
}
|
|
38957
|
+
|
|
38958
|
+
/**
|
|
38959
|
+
* 使用 readline 询问用户确认
|
|
38955
38960
|
*/
|
|
38961
|
+
function askForConfirmation(question) {
|
|
38962
|
+
const rl = readline.createInterface({
|
|
38963
|
+
input: process.stdin,
|
|
38964
|
+
output: process.stdout,
|
|
38965
|
+
});
|
|
38966
|
+
return new Promise((resolve) => {
|
|
38967
|
+
rl.question(question, (answer) => {
|
|
38968
|
+
rl.close();
|
|
38969
|
+
const a = answer.trim().toLowerCase();
|
|
38970
|
+
resolve(!a || a === 'y' || a === 'yes' || a === '是');
|
|
38971
|
+
});
|
|
38972
|
+
});
|
|
38973
|
+
}
|
|
38974
|
+
|
|
38956
38975
|
async function createAppInIde(entry, options) {
|
|
38957
38976
|
const logger = options?.logger || defaultLogger;
|
|
38958
|
-
|
|
38959
|
-
|
|
38960
|
-
|
|
38961
|
-
|
|
38962
|
-
|
|
38963
|
-
|
|
38977
|
+
// ── 扫描 ─────────────────────────────────────────────
|
|
38978
|
+
const { collectedFiles, config, mergedDependencies } = await resolveNASLFiles(entry, logger, false, options?.verbose);
|
|
38979
|
+
// ── 展示参数 ──────────────────────────────────────────
|
|
38980
|
+
const { appName, packageName } = deriveAppNames(getProjectRoot());
|
|
38981
|
+
logger.newLine();
|
|
38982
|
+
logger.info(`应用名称: ${appName}`);
|
|
38983
|
+
logger.info(`包名: ${packageName}`);
|
|
38984
|
+
logger.info(`IDE 版本: ${config.ideVersion}`);
|
|
38985
|
+
logger.info(`租户名称: ${config.tenantName || 'defaulttenant'}`);
|
|
38986
|
+
// ── 确认 ──────────────────────────────────────────────
|
|
38987
|
+
if (!options?.quiet) {
|
|
38988
|
+
logger.newLine();
|
|
38989
|
+
const confirmed = await askForConfirmation('即将在 IDE 中创建新的应用,请确认是否继续?(Y/n): ');
|
|
38990
|
+
if (!confirmed) {
|
|
38991
|
+
logger.info('已取消操作');
|
|
38992
|
+
process.exit(0);
|
|
38993
|
+
}
|
|
38964
38994
|
}
|
|
38965
|
-
//
|
|
38995
|
+
// ── 执行 ──────────────────────────────────────────────
|
|
38966
38996
|
logger.newLine();
|
|
38967
38997
|
logger.info('正在生成 NaturalTS 代码...');
|
|
38968
|
-
let fullNaturalTS
|
|
38998
|
+
let fullNaturalTS;
|
|
38969
38999
|
try {
|
|
38970
39000
|
fullNaturalTS = composeToString(collectedFiles);
|
|
39001
|
+
fullNaturalTS = prependDependencies(fullNaturalTS, mergedDependencies);
|
|
38971
39002
|
}
|
|
38972
39003
|
catch (error) {
|
|
38973
39004
|
logger.error(`生成 NaturalTS 代码失败: ${error.message}`);
|
|
38974
39005
|
throw error;
|
|
38975
39006
|
}
|
|
38976
|
-
// 获取 specs 下第1个文件夹
|
|
38977
|
-
const projectRoot = getProjectRoot();
|
|
38978
|
-
const firstSpecFolderName = getFirstSpecFolderName(projectRoot);
|
|
38979
|
-
const suffix = dayjs().format('MMDDHHmmss');
|
|
38980
|
-
let cleaned = firstSpecFolderName.replace(/[^a-zA-Z0-9]/g, '').replace(/^\d+/, '').slice(0, 12);
|
|
38981
|
-
if (!cleaned)
|
|
38982
|
-
cleaned = 'app';
|
|
38983
|
-
const appName = `${cleaned}_${suffix}`;
|
|
38984
|
-
const packageName = `${cleaned}${suffix}`;
|
|
38985
|
-
logger.info(`应用名称: ${appName}`);
|
|
38986
|
-
logger.info(`包名: ${packageName}`);
|
|
38987
|
-
logger.info(`IDE 版本: ${config.ideVersion}`);
|
|
38988
|
-
logger.info(`完整版本: ${config.ideVersion}.0`);
|
|
38989
|
-
// 调用创建应用 API
|
|
38990
|
-
logger.newLine();
|
|
38991
39007
|
logger.info('正在调用创建应用服务...');
|
|
38992
39008
|
try {
|
|
38993
|
-
const result = await
|
|
38994
|
-
packageName: packageName,
|
|
38995
|
-
appName: appName,
|
|
38996
|
-
serverBaseURL: config.serverBaseURL,
|
|
38997
|
-
ideVersion: config.ideVersion,
|
|
38998
|
-
});
|
|
39009
|
+
const result = await createApp(fullNaturalTS, config, appName, packageName);
|
|
38999
39010
|
if (result.success) {
|
|
39000
39011
|
logger.success('应用创建成功!');
|
|
39001
|
-
if (result.appURL)
|
|
39012
|
+
if (result.appURL)
|
|
39002
39013
|
logger.info(`应用 URL: ${result.appURL}`);
|
|
39003
|
-
|
|
39004
|
-
if (result.appId) {
|
|
39014
|
+
if (result.appId)
|
|
39005
39015
|
logger.info(`应用 ID: ${result.appId}`);
|
|
39006
|
-
|
|
39007
|
-
if (result.message) {
|
|
39016
|
+
if (result.message)
|
|
39008
39017
|
logger.info(result.message);
|
|
39009
|
-
}
|
|
39010
39018
|
}
|
|
39011
39019
|
else {
|
|
39012
39020
|
logger.error(`应用创建失败: ${result.error || '未知错误'}`);
|
|
@@ -39019,6 +39027,57 @@ async function createAppInIde(entry, options) {
|
|
|
39019
39027
|
}
|
|
39020
39028
|
}
|
|
39021
39029
|
|
|
39030
|
+
async function updateAppInIde(appId, entry, options) {
|
|
39031
|
+
const logger = options?.logger || defaultLogger;
|
|
39032
|
+
// ── 扫描 ─────────────────────────────────────────────
|
|
39033
|
+
const { collectedFiles, config, mergedDependencies } = await resolveNASLFiles(entry, logger, false, options?.verbose);
|
|
39034
|
+
// ── 展示参数 ──────────────────────────────────────────
|
|
39035
|
+
logger.newLine();
|
|
39036
|
+
logger.info(`应用 ID: ${appId}`);
|
|
39037
|
+
logger.info(`IDE 版本: ${config.ideVersion}`);
|
|
39038
|
+
logger.info(`租户名称: ${config.tenantName || 'defaulttenant'}`);
|
|
39039
|
+
// ── 确认 ──────────────────────────────────────────────
|
|
39040
|
+
if (!options?.quiet) {
|
|
39041
|
+
logger.newLine();
|
|
39042
|
+
const confirmed = await askForConfirmation(`即将更新应用 ${appId},请确认是否继续?(Y/n): `);
|
|
39043
|
+
if (!confirmed) {
|
|
39044
|
+
logger.info('已取消操作');
|
|
39045
|
+
process.exit(0);
|
|
39046
|
+
}
|
|
39047
|
+
}
|
|
39048
|
+
// ── 执行 ──────────────────────────────────────────────
|
|
39049
|
+
logger.newLine();
|
|
39050
|
+
logger.info('正在生成 NaturalTS 代码...');
|
|
39051
|
+
let fullNaturalTS;
|
|
39052
|
+
try {
|
|
39053
|
+
fullNaturalTS = composeToString(collectedFiles);
|
|
39054
|
+
fullNaturalTS = prependDependencies(fullNaturalTS, mergedDependencies);
|
|
39055
|
+
}
|
|
39056
|
+
catch (error) {
|
|
39057
|
+
logger.error(`生成 NaturalTS 代码失败: ${error.message}`);
|
|
39058
|
+
throw error;
|
|
39059
|
+
}
|
|
39060
|
+
logger.info('正在调用更新应用服务...');
|
|
39061
|
+
try {
|
|
39062
|
+
const result = await updateApp(fullNaturalTS, config, appId);
|
|
39063
|
+
if (result.success) {
|
|
39064
|
+
logger.success('应用更新成功!');
|
|
39065
|
+
if (result.appURL)
|
|
39066
|
+
logger.info(`应用 URL: ${result.appURL}`);
|
|
39067
|
+
if (result.message)
|
|
39068
|
+
logger.info(result.message);
|
|
39069
|
+
}
|
|
39070
|
+
else {
|
|
39071
|
+
logger.error(`应用更新失败: ${result.error || '未知错误'}`);
|
|
39072
|
+
throw new Error(result.error || '应用更新失败');
|
|
39073
|
+
}
|
|
39074
|
+
}
|
|
39075
|
+
catch (error) {
|
|
39076
|
+
logger.error(`调用更新应用服务失败: ${error.message}`);
|
|
39077
|
+
throw error;
|
|
39078
|
+
}
|
|
39079
|
+
}
|
|
39080
|
+
|
|
39022
39081
|
/**
|
|
39023
39082
|
* 编译 NASL 代码
|
|
39024
39083
|
* TODO: 实现具体的 API 调用逻辑
|
|
@@ -39384,27 +39443,11 @@ async function installByJSON(json, options) {
|
|
|
39384
39443
|
logger.success(`成功写入 ${writtenCount} 个依赖文件到 ${config.srcDir} 目录`);
|
|
39385
39444
|
}
|
|
39386
39445
|
|
|
39387
|
-
var version = "0.3.
|
|
39446
|
+
var version = "0.3.4";
|
|
39388
39447
|
var pkg = {
|
|
39389
39448
|
version: version};
|
|
39390
39449
|
|
|
39391
39450
|
const program = new Command();
|
|
39392
|
-
/**
|
|
39393
|
-
* 使用 readline 询问用户确认
|
|
39394
|
-
*/
|
|
39395
|
-
function askForConfirmation(question) {
|
|
39396
|
-
const rl = readline.createInterface({
|
|
39397
|
-
input: process.stdin,
|
|
39398
|
-
output: process.stdout,
|
|
39399
|
-
});
|
|
39400
|
-
return new Promise((resolve) => {
|
|
39401
|
-
rl.question(question, (answer) => {
|
|
39402
|
-
rl.close();
|
|
39403
|
-
const normalizedAnswer = answer.trim().toLowerCase();
|
|
39404
|
-
resolve(!normalizedAnswer || normalizedAnswer === 'y' || normalizedAnswer === 'yes' || normalizedAnswer === '是');
|
|
39405
|
-
});
|
|
39406
|
-
});
|
|
39407
|
-
}
|
|
39408
39451
|
const entryDescription = `是相对于项目根目录的路径,支持 glob 模式(注意要用引号包裹),例如:
|
|
39409
39452
|
- src/app.enums.Status.ts 支持具体文件
|
|
39410
39453
|
- "src/app.enums.*.ts" 表示所有枚举
|
|
@@ -39526,17 +39569,6 @@ program
|
|
|
39526
39569
|
.option('-q, --quiet', '不询问问题')
|
|
39527
39570
|
.action(async (entry, options) => {
|
|
39528
39571
|
try {
|
|
39529
|
-
// 如果不是 quiet 模式,询问用户确认
|
|
39530
|
-
if (!options?.quiet) {
|
|
39531
|
-
defaultLogger.newLine();
|
|
39532
|
-
defaultLogger.info('即将在 IDE 中创建新的应用,此操作将调用远程接口。');
|
|
39533
|
-
const confirmed = await askForConfirmation('请确认是否继续?(Y/n): ');
|
|
39534
|
-
if (!confirmed) {
|
|
39535
|
-
defaultLogger.info('已取消操作');
|
|
39536
|
-
process.exit(0);
|
|
39537
|
-
}
|
|
39538
|
-
defaultLogger.newLine();
|
|
39539
|
-
}
|
|
39540
39572
|
await createAppInIde(entry, options);
|
|
39541
39573
|
}
|
|
39542
39574
|
catch (error) {
|
|
@@ -39544,6 +39576,20 @@ program
|
|
|
39544
39576
|
process.exit(1);
|
|
39545
39577
|
}
|
|
39546
39578
|
});
|
|
39579
|
+
program
|
|
39580
|
+
.command('update-app-in-ide <appId> [entry]')
|
|
39581
|
+
.description('在 IDE 中更新已有应用')
|
|
39582
|
+
.option('-v, --verbose', '显示详细信息,如依赖分析树')
|
|
39583
|
+
.option('-q, --quiet', '不询问问题')
|
|
39584
|
+
.action(async (appId, entry, options) => {
|
|
39585
|
+
try {
|
|
39586
|
+
await updateAppInIde(appId, entry, options);
|
|
39587
|
+
}
|
|
39588
|
+
catch (error) {
|
|
39589
|
+
defaultLogger.error(`更新应用过程发生错误:${error.message}`);
|
|
39590
|
+
process.exit(1);
|
|
39591
|
+
}
|
|
39592
|
+
});
|
|
39547
39593
|
program
|
|
39548
39594
|
.command('transform <transformType> [entry]')
|
|
39549
39595
|
.description('转换文件格式\n transformType: files2full (将 src 文件组合成 fullNaturalTS), json2files (将 JSON 转换为文件), files2json (将 src 文件转换为 JSON), doc2full (将 plan markdown 文档组合成 fullNaturalTS)')
|