@nasl/cli 0.1.14 → 0.1.15
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 +260 -1
- package/dist/bin/nasl.mjs.map +1 -1
- package/dist/bin/naslc.mjs +1 -1
- package/dist/bin/naslc.mjs.map +1 -1
- package/dist/index.mjs +228 -1
- package/dist/index.mjs.map +1 -1
- package/out/apis/compileApi.d.ts +17 -0
- package/out/apis/compileApi.d.ts.map +1 -0
- package/out/apis/compileApi.js +83 -0
- package/out/apis/compileApi.js.map +1 -0
- package/out/apis/createAppApi.d.ts +31 -0
- package/out/apis/createAppApi.d.ts.map +1 -0
- package/out/apis/createAppApi.js +42 -0
- package/out/apis/createAppApi.js.map +1 -0
- package/out/apis/index.d.ts +2 -16
- package/out/apis/index.d.ts.map +1 -1
- package/out/apis/index.js +16 -80
- package/out/apis/index.js.map +1 -1
- package/out/apis/transformApi.d.ts +7 -0
- package/out/apis/transformApi.d.ts.map +1 -0
- package/out/apis/transformApi.js +20 -0
- package/out/apis/transformApi.js.map +1 -0
- package/out/bin/nasl.js +32 -0
- package/out/bin/nasl.js.map +1 -1
- package/out/commands/createAppInIde.d.ts +6 -0
- package/out/commands/createAppInIde.d.ts.map +1 -0
- package/out/commands/createAppInIde.js +128 -0
- package/out/commands/createAppInIde.js.map +1 -0
- package/out/commands/index.d.ts +2 -0
- package/out/commands/index.d.ts.map +1 -1
- package/out/commands/index.js +2 -0
- package/out/commands/index.js.map +1 -1
- package/out/commands/transform.d.ts +10 -0
- package/out/commands/transform.d.ts.map +1 -0
- package/out/commands/transform.js +134 -0
- package/out/commands/transform.js.map +1 -0
- package/package.json +1 -1
package/dist/bin/nasl.mjs
CHANGED
|
@@ -28906,6 +28906,44 @@ async function checkApi(fullNaturalTS, options) {
|
|
|
28906
28906
|
return '';
|
|
28907
28907
|
}
|
|
28908
28908
|
|
|
28909
|
+
/**
|
|
28910
|
+
* 创建应用同步
|
|
28911
|
+
*/
|
|
28912
|
+
async function createAppSyncApi(fullNaturalTS, options) {
|
|
28913
|
+
const url = new URL(options.serverBaseURL);
|
|
28914
|
+
const origin = url.origin + '/app-ai-creator';
|
|
28915
|
+
const axios = createAxios(origin);
|
|
28916
|
+
try {
|
|
28917
|
+
const res = await axios.post('/api/createAppSync', {
|
|
28918
|
+
fullNaturalTS,
|
|
28919
|
+
packageName: options.packageName,
|
|
28920
|
+
appName: options.appName,
|
|
28921
|
+
hostname: url.hostname,
|
|
28922
|
+
enableAuthTemplate: false,
|
|
28923
|
+
ideVersion: options.ideVersion,
|
|
28924
|
+
fullVersion: `${options.ideVersion}.0`,
|
|
28925
|
+
});
|
|
28926
|
+
if (res.data.success) {
|
|
28927
|
+
return {
|
|
28928
|
+
success: true,
|
|
28929
|
+
appId: res.data.data?.appId,
|
|
28930
|
+
appURL: res.data.data?.appURL,
|
|
28931
|
+
message: res.data.data?.message,
|
|
28932
|
+
};
|
|
28933
|
+
}
|
|
28934
|
+
else {
|
|
28935
|
+
return {
|
|
28936
|
+
success: false,
|
|
28937
|
+
error: res.data.message || '应用创建失败',
|
|
28938
|
+
};
|
|
28939
|
+
}
|
|
28940
|
+
}
|
|
28941
|
+
catch (error) {
|
|
28942
|
+
console.log(error);
|
|
28943
|
+
throw error;
|
|
28944
|
+
}
|
|
28945
|
+
}
|
|
28946
|
+
|
|
28909
28947
|
function createSorter() {
|
|
28910
28948
|
const priorityOrder = ['app.dataSources', 'app.enums', 'app.structures', 'app.logics', 'app.frontendTypes'];
|
|
28911
28949
|
// 获取优先级索引
|
|
@@ -38065,7 +38103,196 @@ async function build(entry, options) {
|
|
|
38065
38103
|
await justExecCommandSync(webpackArgs, outDir);
|
|
38066
38104
|
}
|
|
38067
38105
|
|
|
38068
|
-
|
|
38106
|
+
/**
|
|
38107
|
+
* 获取 specs 下第1个文件夹的名字
|
|
38108
|
+
*/
|
|
38109
|
+
function getFirstSpecFolderName(projectRoot) {
|
|
38110
|
+
const dirname = sysPath.basename(projectRoot);
|
|
38111
|
+
const specsDir = sysPath.join(projectRoot, 'specs');
|
|
38112
|
+
if (!libExports.existsSync(specsDir))
|
|
38113
|
+
return dirname;
|
|
38114
|
+
const entries = libExports.readdirSync(specsDir, { withFileTypes: true });
|
|
38115
|
+
const folders = entries
|
|
38116
|
+
.filter(entry => entry.isDirectory())
|
|
38117
|
+
.map(entry => entry.name);
|
|
38118
|
+
if (folders.length === 0)
|
|
38119
|
+
return dirname;
|
|
38120
|
+
return folders[0];
|
|
38121
|
+
}
|
|
38122
|
+
/**
|
|
38123
|
+
* 创建应用在 IDE 中
|
|
38124
|
+
*/
|
|
38125
|
+
async function createAppInIde(entry, options) {
|
|
38126
|
+
const logger = options?.logger || defaultLogger;
|
|
38127
|
+
logger.info('开始创建应用在 IDE 中...');
|
|
38128
|
+
// 收集需要处理的文件
|
|
38129
|
+
const { collectedFiles, config } = await resolveNASLFiles(entry, logger, false, options?.verbose);
|
|
38130
|
+
// 生成 fullNaturalTS
|
|
38131
|
+
logger.newLine();
|
|
38132
|
+
logger.info('正在生成 NaturalTS 代码...');
|
|
38133
|
+
let fullNaturalTS = '';
|
|
38134
|
+
try {
|
|
38135
|
+
fullNaturalTS = composeToString(collectedFiles);
|
|
38136
|
+
}
|
|
38137
|
+
catch (error) {
|
|
38138
|
+
logger.error(`生成 NaturalTS 代码失败: ${error.message}`);
|
|
38139
|
+
throw error;
|
|
38140
|
+
}
|
|
38141
|
+
// 获取 specs 下第1个文件夹
|
|
38142
|
+
const projectRoot = getProjectRoot();
|
|
38143
|
+
const firstSpecFolderName = getFirstSpecFolderName(projectRoot);
|
|
38144
|
+
const suffix = dayjs().format('MMDDHHmmss');
|
|
38145
|
+
const appName = `${firstSpecFolderName}_${suffix}`;
|
|
38146
|
+
let cleaned = firstSpecFolderName.replace(/[^a-zA-Z0-9]/g, '').replace(/^\d+/, '');
|
|
38147
|
+
if (!cleaned)
|
|
38148
|
+
cleaned = 'app';
|
|
38149
|
+
const packageName = `${cleaned}${suffix}`;
|
|
38150
|
+
logger.info(`应用名称: ${appName}`);
|
|
38151
|
+
logger.info(`包名: ${packageName}`);
|
|
38152
|
+
logger.info(`IDE 版本: ${config.ideVersion}`);
|
|
38153
|
+
logger.info(`完整版本: ${config.ideVersion}.0`);
|
|
38154
|
+
// 调用创建应用 API
|
|
38155
|
+
logger.newLine();
|
|
38156
|
+
logger.info('正在调用创建应用服务...');
|
|
38157
|
+
try {
|
|
38158
|
+
const result = await createAppSyncApi(fullNaturalTS, {
|
|
38159
|
+
packageName: packageName,
|
|
38160
|
+
appName: appName,
|
|
38161
|
+
serverBaseURL: config.serverBaseURL,
|
|
38162
|
+
ideVersion: config.ideVersion,
|
|
38163
|
+
});
|
|
38164
|
+
if (result.success) {
|
|
38165
|
+
logger.success('应用创建成功!');
|
|
38166
|
+
if (result.appURL) {
|
|
38167
|
+
logger.info(`应用 URL: ${result.appURL}`);
|
|
38168
|
+
}
|
|
38169
|
+
if (result.appId) {
|
|
38170
|
+
logger.info(`应用 ID: ${result.appId}`);
|
|
38171
|
+
}
|
|
38172
|
+
if (result.message) {
|
|
38173
|
+
logger.info(result.message);
|
|
38174
|
+
}
|
|
38175
|
+
}
|
|
38176
|
+
else {
|
|
38177
|
+
logger.error(`应用创建失败: ${result.error || '未知错误'}`);
|
|
38178
|
+
throw new Error(result.error || '应用创建失败');
|
|
38179
|
+
}
|
|
38180
|
+
}
|
|
38181
|
+
catch (error) {
|
|
38182
|
+
logger.error(`调用创建应用服务失败: ${error.message}`);
|
|
38183
|
+
throw error;
|
|
38184
|
+
}
|
|
38185
|
+
}
|
|
38186
|
+
|
|
38187
|
+
/**
|
|
38188
|
+
* 编译 NASL 代码
|
|
38189
|
+
* TODO: 实现具体的 API 调用逻辑
|
|
38190
|
+
*/
|
|
38191
|
+
async function transformJson2FilesApi(jsonContent, options) {
|
|
38192
|
+
// 示例实现:
|
|
38193
|
+
const axios = createAxios(options.serverBaseURL);
|
|
38194
|
+
const res = await axios.post(`/transform/json2files?ideVersion=${options.ideVersion}`, jsonContent, {
|
|
38195
|
+
headers: { 'Content-Type': 'text/plain' },
|
|
38196
|
+
});
|
|
38197
|
+
const data = res.data;
|
|
38198
|
+
if (data.code !== 200)
|
|
38199
|
+
throw new Error(data.message);
|
|
38200
|
+
return data.result;
|
|
38201
|
+
}
|
|
38202
|
+
|
|
38203
|
+
const transformFns = {
|
|
38204
|
+
/**
|
|
38205
|
+
* 将 src 中的文件组合成 fullNaturalTS
|
|
38206
|
+
*/
|
|
38207
|
+
async files2full(entry, options) {
|
|
38208
|
+
const logger = options?.logger || defaultLogger;
|
|
38209
|
+
// 收集需要处理的文件
|
|
38210
|
+
const { collectedFiles, projectRoot } = await resolveNASLFiles(entry, logger, false, options?.verbose);
|
|
38211
|
+
if (collectedFiles.length === 0) {
|
|
38212
|
+
logger.error('未找到需要转换的文件');
|
|
38213
|
+
logger.exit(1);
|
|
38214
|
+
}
|
|
38215
|
+
logger.info(`找到 ${collectedFiles.length} 个文件`);
|
|
38216
|
+
// 组合成 fullNaturalTS
|
|
38217
|
+
logger.newLine();
|
|
38218
|
+
logger.info('正在组合文件...');
|
|
38219
|
+
const fullNaturalTS = composeToString(collectedFiles);
|
|
38220
|
+
// 确定输出路径
|
|
38221
|
+
const outputPath = options?.output
|
|
38222
|
+
? sysPath.resolve(projectRoot, options.output)
|
|
38223
|
+
: sysPath.join(projectRoot, './full-natural.ts');
|
|
38224
|
+
// 写入文件
|
|
38225
|
+
writeFileWithLog(outputPath, fullNaturalTS, logger);
|
|
38226
|
+
logger.success(`文件已输出到: ${outputPath}`);
|
|
38227
|
+
},
|
|
38228
|
+
/**
|
|
38229
|
+
* 将 JSON 文件转换成 src 的 files
|
|
38230
|
+
* TODO: 待实现
|
|
38231
|
+
*/
|
|
38232
|
+
async json2files(entry, options) {
|
|
38233
|
+
const logger = options?.logger || defaultLogger;
|
|
38234
|
+
// 加载配置
|
|
38235
|
+
const config = loadConfig();
|
|
38236
|
+
const projectRoot = getProjectRoot();
|
|
38237
|
+
logger.info(`项目根目录: ${projectRoot}`);
|
|
38238
|
+
logger.info(`源代码目录: ${config.srcDir}`);
|
|
38239
|
+
let jsonContent = '';
|
|
38240
|
+
if (!entry) {
|
|
38241
|
+
logger.warn('没有指定 JSON 文件路径,按照默认 IDE 版本的基础模板转换');
|
|
38242
|
+
}
|
|
38243
|
+
else {
|
|
38244
|
+
jsonContent = libExports.readFileSync(entry, 'utf-8');
|
|
38245
|
+
}
|
|
38246
|
+
const files = await transformJson2FilesApi(jsonContent, {
|
|
38247
|
+
serverBaseURL: config.serverBaseURL,
|
|
38248
|
+
ideVersion: config.ideVersion,
|
|
38249
|
+
});
|
|
38250
|
+
await Promise.all(files.map(async (file) => {
|
|
38251
|
+
const outputPath = sysPath.join(projectRoot, config.srcDir, file.path);
|
|
38252
|
+
await libExports.writeFile(outputPath, file.content);
|
|
38253
|
+
}));
|
|
38254
|
+
logger.success(`JSON 文件已转换为 ${files.length} 个文件,输出到 ${config.srcDir}`);
|
|
38255
|
+
},
|
|
38256
|
+
/**
|
|
38257
|
+
* 将 src 中的文件转换成一个 JSON
|
|
38258
|
+
*/
|
|
38259
|
+
async files2json(entry, options) {
|
|
38260
|
+
const logger = options?.logger || defaultLogger;
|
|
38261
|
+
// 收集需要处理的文件
|
|
38262
|
+
const { collectedFiles, projectRoot } = await resolveNASLFiles(entry, logger, false, options?.verbose);
|
|
38263
|
+
if (collectedFiles.length === 0) {
|
|
38264
|
+
logger.error('未找到需要转换的文件');
|
|
38265
|
+
logger.exit(1);
|
|
38266
|
+
}
|
|
38267
|
+
logger.info(`找到 ${collectedFiles.length} 个文件`);
|
|
38268
|
+
// 转换为 JSON
|
|
38269
|
+
logger.newLine();
|
|
38270
|
+
logger.info('正在转换为 JSON...');
|
|
38271
|
+
const jsonContent = JSON.stringify(collectedFiles, null, 2);
|
|
38272
|
+
// 确定输出路径
|
|
38273
|
+
const outputPath = options?.output
|
|
38274
|
+
? sysPath.resolve(projectRoot, options.output)
|
|
38275
|
+
: sysPath.join(projectRoot, './files.json');
|
|
38276
|
+
// 写入文件
|
|
38277
|
+
writeFileWithLog(outputPath, jsonContent, logger);
|
|
38278
|
+
logger.success(`JSON 文件已输出到: ${outputPath}`);
|
|
38279
|
+
},
|
|
38280
|
+
};
|
|
38281
|
+
/**
|
|
38282
|
+
* 转换命令 - 支持多种文件转换格式
|
|
38283
|
+
*/
|
|
38284
|
+
async function transform(transformType, entry, options) {
|
|
38285
|
+
const logger = options?.logger || defaultLogger;
|
|
38286
|
+
logger.info(`开始执行转换: ${transformType}`);
|
|
38287
|
+
const transformFn = transformFns[transformType];
|
|
38288
|
+
if (!transformFn) {
|
|
38289
|
+
logger.error(`不支持的转换类型: ${transformType}`);
|
|
38290
|
+
logger.exit(1);
|
|
38291
|
+
}
|
|
38292
|
+
await transformFn(entry, options);
|
|
38293
|
+
}
|
|
38294
|
+
|
|
38295
|
+
var version = "0.1.15";
|
|
38069
38296
|
var pkg = {
|
|
38070
38297
|
version: version};
|
|
38071
38298
|
|
|
@@ -38148,6 +38375,38 @@ program
|
|
|
38148
38375
|
process.exit(1);
|
|
38149
38376
|
}
|
|
38150
38377
|
});
|
|
38378
|
+
program
|
|
38379
|
+
.command('create-app-in-ide [entry]')
|
|
38380
|
+
.description('在 IDE 中创建应用')
|
|
38381
|
+
.option('-v, --verbose', '显示详细信息,如依赖分析树')
|
|
38382
|
+
.action(async (entry, options) => {
|
|
38383
|
+
try {
|
|
38384
|
+
await createAppInIde(entry, options);
|
|
38385
|
+
}
|
|
38386
|
+
catch (error) {
|
|
38387
|
+
defaultLogger.error(`创建应用过程发生错误:${error.message}`);
|
|
38388
|
+
process.exit(1);
|
|
38389
|
+
}
|
|
38390
|
+
});
|
|
38391
|
+
program
|
|
38392
|
+
.command('transform <transformType> [entry]')
|
|
38393
|
+
.description('转换文件格式\n transformType: files2full (将 src 文件组合成 fullNaturalTS), json2files (将 JSON 转换为文件, 待实现), files2json (将 src 文件转换为 JSON)')
|
|
38394
|
+
.option('-o, --output <outputPath>', '指定输出路径')
|
|
38395
|
+
.option('-v, --verbose', '显示详细信息,如依赖分析树')
|
|
38396
|
+
.action(async (transformType, entry, options) => {
|
|
38397
|
+
try {
|
|
38398
|
+
const validTypes = ['files2full', 'json2files', 'files2json'];
|
|
38399
|
+
if (!validTypes.includes(transformType)) {
|
|
38400
|
+
defaultLogger.error(`无效的转换类型: ${transformType}。支持的类型: ${validTypes.join(', ')}`);
|
|
38401
|
+
process.exit(1);
|
|
38402
|
+
}
|
|
38403
|
+
await transform(transformType, entry, options);
|
|
38404
|
+
}
|
|
38405
|
+
catch (error) {
|
|
38406
|
+
defaultLogger.error(`转换过程发生错误:${error.message}`);
|
|
38407
|
+
process.exit(1);
|
|
38408
|
+
}
|
|
38409
|
+
});
|
|
38151
38410
|
program.parse(process.argv);
|
|
38152
38411
|
// 如果没有提供任何命令,显示帮助信息
|
|
38153
38412
|
if (!process.argv.slice(2).length) {
|