@nasl/cli 0.1.13 → 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.
Files changed (40) hide show
  1. package/dist/bin/nasl.mjs +265 -2
  2. package/dist/bin/nasl.mjs.map +1 -1
  3. package/dist/bin/naslc.mjs +6 -2
  4. package/dist/bin/naslc.mjs.map +1 -1
  5. package/dist/index.mjs +233 -2
  6. package/dist/index.mjs.map +1 -1
  7. package/out/apis/compileApi.d.ts +17 -0
  8. package/out/apis/compileApi.d.ts.map +1 -0
  9. package/out/apis/compileApi.js +83 -0
  10. package/out/apis/compileApi.js.map +1 -0
  11. package/out/apis/createAppApi.d.ts +31 -0
  12. package/out/apis/createAppApi.d.ts.map +1 -0
  13. package/out/apis/createAppApi.js +42 -0
  14. package/out/apis/createAppApi.js.map +1 -0
  15. package/out/apis/index.d.ts +2 -16
  16. package/out/apis/index.d.ts.map +1 -1
  17. package/out/apis/index.js +16 -80
  18. package/out/apis/index.js.map +1 -1
  19. package/out/apis/transformApi.d.ts +7 -0
  20. package/out/apis/transformApi.d.ts.map +1 -0
  21. package/out/apis/transformApi.js +20 -0
  22. package/out/apis/transformApi.js.map +1 -0
  23. package/out/bin/nasl.js +32 -0
  24. package/out/bin/nasl.js.map +1 -1
  25. package/out/commands/createAppInIde.d.ts +6 -0
  26. package/out/commands/createAppInIde.d.ts.map +1 -0
  27. package/out/commands/createAppInIde.js +128 -0
  28. package/out/commands/createAppInIde.js.map +1 -0
  29. package/out/commands/index.d.ts +2 -0
  30. package/out/commands/index.d.ts.map +1 -1
  31. package/out/commands/index.js +2 -0
  32. package/out/commands/index.js.map +1 -1
  33. package/out/commands/transform.d.ts +10 -0
  34. package/out/commands/transform.d.ts.map +1 -0
  35. package/out/commands/transform.js +134 -0
  36. package/out/commands/transform.js.map +1 -0
  37. package/out/services/resolve.d.ts.map +1 -1
  38. package/out/services/resolve.js +5 -1
  39. package/out/services/resolve.js.map +1 -1
  40. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -13672,7 +13672,11 @@ async function scanEntryFiles(projectRoot, patterns, logger) {
13672
13672
  */
13673
13673
  function extractDeps(content) {
13674
13674
  const deps = new Set();
13675
- const allMatches = content.matchAll(/app\.\w+\.[\w.]+/g); // 起码要2个点
13675
+ // 预处理:移除注释,避免注释影响依赖分析
13676
+ let processedContent = content
13677
+ .replace(/\/\/.*$/gm, '') // 移除单行注释 // ...
13678
+ .replace(/\/\*[\s\S]*?\*\//g, ''); // 移除多行注释 /* ... */
13679
+ const allMatches = processedContent.matchAll(/app\.\w+\.[\w.]+/g); // 起码要2个点
13676
13680
  for (const match of allMatches) {
13677
13681
  let dep = match[0];
13678
13682
  if (/Entity$|Entity\./.test(dep)) {
@@ -34409,6 +34413,44 @@ async function checkApi(fullNaturalTS, options) {
34409
34413
  return '';
34410
34414
  }
34411
34415
 
34416
+ /**
34417
+ * 创建应用同步
34418
+ */
34419
+ async function createAppSyncApi(fullNaturalTS, options) {
34420
+ const url = new URL(options.serverBaseURL);
34421
+ const origin = url.origin + '/app-ai-creator';
34422
+ const axios = createAxios(origin);
34423
+ try {
34424
+ const res = await axios.post('/api/createAppSync', {
34425
+ fullNaturalTS,
34426
+ packageName: options.packageName,
34427
+ appName: options.appName,
34428
+ hostname: url.hostname,
34429
+ enableAuthTemplate: false,
34430
+ ideVersion: options.ideVersion,
34431
+ fullVersion: `${options.ideVersion}.0`,
34432
+ });
34433
+ if (res.data.success) {
34434
+ return {
34435
+ success: true,
34436
+ appId: res.data.data?.appId,
34437
+ appURL: res.data.data?.appURL,
34438
+ message: res.data.data?.message,
34439
+ };
34440
+ }
34441
+ else {
34442
+ return {
34443
+ success: false,
34444
+ error: res.data.message || '应用创建失败',
34445
+ };
34446
+ }
34447
+ }
34448
+ catch (error) {
34449
+ console.log(error);
34450
+ throw error;
34451
+ }
34452
+ }
34453
+
34412
34454
  /**
34413
34455
  * 编译命令 - 将 NASL 编译为 Vue 和 JS
34414
34456
  */
@@ -34732,6 +34774,195 @@ async function build(entry, options) {
34732
34774
  await justExecCommandSync(webpackArgs, outDir);
34733
34775
  }
34734
34776
 
34777
+ /**
34778
+ * 获取 specs 下第1个文件夹的名字
34779
+ */
34780
+ function getFirstSpecFolderName(projectRoot) {
34781
+ const dirname = sysPath.basename(projectRoot);
34782
+ const specsDir = sysPath.join(projectRoot, 'specs');
34783
+ if (!libExports.existsSync(specsDir))
34784
+ return dirname;
34785
+ const entries = libExports.readdirSync(specsDir, { withFileTypes: true });
34786
+ const folders = entries
34787
+ .filter(entry => entry.isDirectory())
34788
+ .map(entry => entry.name);
34789
+ if (folders.length === 0)
34790
+ return dirname;
34791
+ return folders[0];
34792
+ }
34793
+ /**
34794
+ * 创建应用在 IDE 中
34795
+ */
34796
+ async function createAppInIde(entry, options) {
34797
+ const logger = options?.logger || defaultLogger;
34798
+ logger.info('开始创建应用在 IDE 中...');
34799
+ // 收集需要处理的文件
34800
+ const { collectedFiles, config } = await resolveNASLFiles(entry, logger, false, options?.verbose);
34801
+ // 生成 fullNaturalTS
34802
+ logger.newLine();
34803
+ logger.info('正在生成 NaturalTS 代码...');
34804
+ let fullNaturalTS = '';
34805
+ try {
34806
+ fullNaturalTS = composeToString(collectedFiles);
34807
+ }
34808
+ catch (error) {
34809
+ logger.error(`生成 NaturalTS 代码失败: ${error.message}`);
34810
+ throw error;
34811
+ }
34812
+ // 获取 specs 下第1个文件夹
34813
+ const projectRoot = getProjectRoot();
34814
+ const firstSpecFolderName = getFirstSpecFolderName(projectRoot);
34815
+ const suffix = dayjs().format('MMDDHHmmss');
34816
+ const appName = `${firstSpecFolderName}_${suffix}`;
34817
+ let cleaned = firstSpecFolderName.replace(/[^a-zA-Z0-9]/g, '').replace(/^\d+/, '');
34818
+ if (!cleaned)
34819
+ cleaned = 'app';
34820
+ const packageName = `${cleaned}${suffix}`;
34821
+ logger.info(`应用名称: ${appName}`);
34822
+ logger.info(`包名: ${packageName}`);
34823
+ logger.info(`IDE 版本: ${config.ideVersion}`);
34824
+ logger.info(`完整版本: ${config.ideVersion}.0`);
34825
+ // 调用创建应用 API
34826
+ logger.newLine();
34827
+ logger.info('正在调用创建应用服务...');
34828
+ try {
34829
+ const result = await createAppSyncApi(fullNaturalTS, {
34830
+ packageName: packageName,
34831
+ appName: appName,
34832
+ serverBaseURL: config.serverBaseURL,
34833
+ ideVersion: config.ideVersion,
34834
+ });
34835
+ if (result.success) {
34836
+ logger.success('应用创建成功!');
34837
+ if (result.appURL) {
34838
+ logger.info(`应用 URL: ${result.appURL}`);
34839
+ }
34840
+ if (result.appId) {
34841
+ logger.info(`应用 ID: ${result.appId}`);
34842
+ }
34843
+ if (result.message) {
34844
+ logger.info(result.message);
34845
+ }
34846
+ }
34847
+ else {
34848
+ logger.error(`应用创建失败: ${result.error || '未知错误'}`);
34849
+ throw new Error(result.error || '应用创建失败');
34850
+ }
34851
+ }
34852
+ catch (error) {
34853
+ logger.error(`调用创建应用服务失败: ${error.message}`);
34854
+ throw error;
34855
+ }
34856
+ }
34857
+
34858
+ /**
34859
+ * 编译 NASL 代码
34860
+ * TODO: 实现具体的 API 调用逻辑
34861
+ */
34862
+ async function transformJson2FilesApi(jsonContent, options) {
34863
+ // 示例实现:
34864
+ const axios = createAxios(options.serverBaseURL);
34865
+ const res = await axios.post(`/transform/json2files?ideVersion=${options.ideVersion}`, jsonContent, {
34866
+ headers: { 'Content-Type': 'text/plain' },
34867
+ });
34868
+ const data = res.data;
34869
+ if (data.code !== 200)
34870
+ throw new Error(data.message);
34871
+ return data.result;
34872
+ }
34873
+
34874
+ const transformFns = {
34875
+ /**
34876
+ * 将 src 中的文件组合成 fullNaturalTS
34877
+ */
34878
+ async files2full(entry, options) {
34879
+ const logger = options?.logger || defaultLogger;
34880
+ // 收集需要处理的文件
34881
+ const { collectedFiles, projectRoot } = await resolveNASLFiles(entry, logger, false, options?.verbose);
34882
+ if (collectedFiles.length === 0) {
34883
+ logger.error('未找到需要转换的文件');
34884
+ logger.exit(1);
34885
+ }
34886
+ logger.info(`找到 ${collectedFiles.length} 个文件`);
34887
+ // 组合成 fullNaturalTS
34888
+ logger.newLine();
34889
+ logger.info('正在组合文件...');
34890
+ const fullNaturalTS = composeToString(collectedFiles);
34891
+ // 确定输出路径
34892
+ const outputPath = options?.output
34893
+ ? sysPath.resolve(projectRoot, options.output)
34894
+ : sysPath.join(projectRoot, './full-natural.ts');
34895
+ // 写入文件
34896
+ writeFileWithLog(outputPath, fullNaturalTS, logger);
34897
+ logger.success(`文件已输出到: ${outputPath}`);
34898
+ },
34899
+ /**
34900
+ * 将 JSON 文件转换成 src 的 files
34901
+ * TODO: 待实现
34902
+ */
34903
+ async json2files(entry, options) {
34904
+ const logger = options?.logger || defaultLogger;
34905
+ // 加载配置
34906
+ const config = loadConfig();
34907
+ const projectRoot = getProjectRoot();
34908
+ logger.info(`项目根目录: ${projectRoot}`);
34909
+ logger.info(`源代码目录: ${config.srcDir}`);
34910
+ let jsonContent = '';
34911
+ if (!entry) {
34912
+ logger.warn('没有指定 JSON 文件路径,按照默认 IDE 版本的基础模板转换');
34913
+ }
34914
+ else {
34915
+ jsonContent = libExports.readFileSync(entry, 'utf-8');
34916
+ }
34917
+ const files = await transformJson2FilesApi(jsonContent, {
34918
+ serverBaseURL: config.serverBaseURL,
34919
+ ideVersion: config.ideVersion,
34920
+ });
34921
+ await Promise.all(files.map(async (file) => {
34922
+ const outputPath = sysPath.join(projectRoot, config.srcDir, file.path);
34923
+ await libExports.writeFile(outputPath, file.content);
34924
+ }));
34925
+ logger.success(`JSON 文件已转换为 ${files.length} 个文件,输出到 ${config.srcDir}`);
34926
+ },
34927
+ /**
34928
+ * 将 src 中的文件转换成一个 JSON
34929
+ */
34930
+ async files2json(entry, options) {
34931
+ const logger = options?.logger || defaultLogger;
34932
+ // 收集需要处理的文件
34933
+ const { collectedFiles, projectRoot } = await resolveNASLFiles(entry, logger, false, options?.verbose);
34934
+ if (collectedFiles.length === 0) {
34935
+ logger.error('未找到需要转换的文件');
34936
+ logger.exit(1);
34937
+ }
34938
+ logger.info(`找到 ${collectedFiles.length} 个文件`);
34939
+ // 转换为 JSON
34940
+ logger.newLine();
34941
+ logger.info('正在转换为 JSON...');
34942
+ const jsonContent = JSON.stringify(collectedFiles, null, 2);
34943
+ // 确定输出路径
34944
+ const outputPath = options?.output
34945
+ ? sysPath.resolve(projectRoot, options.output)
34946
+ : sysPath.join(projectRoot, './files.json');
34947
+ // 写入文件
34948
+ writeFileWithLog(outputPath, jsonContent, logger);
34949
+ logger.success(`JSON 文件已输出到: ${outputPath}`);
34950
+ },
34951
+ };
34952
+ /**
34953
+ * 转换命令 - 支持多种文件转换格式
34954
+ */
34955
+ async function transform(transformType, entry, options) {
34956
+ const logger = options?.logger || defaultLogger;
34957
+ logger.info(`开始执行转换: ${transformType}`);
34958
+ const transformFn = transformFns[transformType];
34959
+ if (!transformFn) {
34960
+ logger.error(`不支持的转换类型: ${transformType}`);
34961
+ logger.exit(1);
34962
+ }
34963
+ await transformFn(entry, options);
34964
+ }
34965
+
34735
34966
  const EntryTypes = {
34736
34967
  FILE_TYPE: 'files',
34737
34968
  DIR_TYPE: 'directories',
@@ -36397,5 +36628,5 @@ var index$1 = /*#__PURE__*/Object.freeze({
36397
36628
  watch: watch
36398
36629
  });
36399
36630
 
36400
- export { BaseLogger, CONFIG_FILE_NAME, ConsoleLogger, ConsoleLoggerWithoutExit, DEFAULT_CONFIG, MemoryLogger, build, check, compile, composeToString, createSorter, defaultLogger, dep, dev, fastAppendLogToFile, fastLogToFile, init, resolveNASLFiles, scanEntryFiles, scanNASLFiles, sorter, tryCompile };
36631
+ export { BaseLogger, CONFIG_FILE_NAME, ConsoleLogger, ConsoleLoggerWithoutExit, DEFAULT_CONFIG, MemoryLogger, build, check, compile, composeToString, createAppInIde, createSorter, defaultLogger, dep, dev, fastAppendLogToFile, fastLogToFile, init, resolveNASLFiles, scanEntryFiles, scanNASLFiles, sorter, transform, tryCompile };
36401
36632
  //# sourceMappingURL=index.mjs.map