@nasl/cli 0.2.3 → 0.3.0

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 (66) hide show
  1. package/dist/bin/nasl.mjs +516 -126
  2. package/dist/bin/nasl.mjs.map +1 -1
  3. package/dist/bin/naslc.mjs +311 -58
  4. package/dist/bin/naslc.mjs.map +1 -1
  5. package/dist/index.mjs +11610 -11255
  6. package/dist/index.mjs.map +1 -1
  7. package/out/apis/compileApi.d.ts.map +1 -1
  8. package/out/apis/compileApi.js +3 -2
  9. package/out/apis/compileApi.js.map +1 -1
  10. package/out/apis/dependencyApi.d.ts +29 -0
  11. package/out/apis/dependencyApi.d.ts.map +1 -0
  12. package/out/apis/dependencyApi.js +17 -0
  13. package/out/apis/dependencyApi.js.map +1 -0
  14. package/out/apis/index.d.ts +1 -0
  15. package/out/apis/index.d.ts.map +1 -1
  16. package/out/apis/index.js +1 -0
  17. package/out/apis/index.js.map +1 -1
  18. package/out/apis/openapi.d.ts +12 -0
  19. package/out/apis/openapi.d.ts.map +1 -1
  20. package/out/apis/openapi.js +15 -0
  21. package/out/apis/openapi.js.map +1 -1
  22. package/out/apis/transformApi.d.ts.map +1 -1
  23. package/out/apis/transformApi.js +2 -0
  24. package/out/apis/transformApi.js.map +1 -1
  25. package/out/bin/nasl.js +38 -2
  26. package/out/bin/nasl.js.map +1 -1
  27. package/out/commands/check.d.ts.map +1 -1
  28. package/out/commands/check.js +2 -1
  29. package/out/commands/check.js.map +1 -1
  30. package/out/commands/compile.d.ts.map +1 -1
  31. package/out/commands/compile.js +3 -2
  32. package/out/commands/compile.js.map +1 -1
  33. package/out/commands/dep.d.ts +4 -2
  34. package/out/commands/dep.d.ts.map +1 -1
  35. package/out/commands/dep.js +44 -2
  36. package/out/commands/dep.js.map +1 -1
  37. package/out/commands/index.d.ts +1 -0
  38. package/out/commands/index.d.ts.map +1 -1
  39. package/out/commands/index.js +1 -0
  40. package/out/commands/index.js.map +1 -1
  41. package/out/commands/install.d.ts +9 -0
  42. package/out/commands/install.d.ts.map +1 -0
  43. package/out/commands/install.js +123 -0
  44. package/out/commands/install.js.map +1 -0
  45. package/out/commands/transform.d.ts.map +1 -1
  46. package/out/commands/transform.js +3 -2
  47. package/out/commands/transform.js.map +1 -1
  48. package/out/constants/nasl-file-types.d.ts.map +1 -1
  49. package/out/constants/nasl-file-types.js +21 -0
  50. package/out/constants/nasl-file-types.js.map +1 -1
  51. package/out/services/compose.d.ts +8 -0
  52. package/out/services/compose.d.ts.map +1 -1
  53. package/out/services/compose.js +20 -0
  54. package/out/services/compose.js.map +1 -1
  55. package/out/services/resolve.d.ts +18 -0
  56. package/out/services/resolve.d.ts.map +1 -1
  57. package/out/services/resolve.js +208 -9
  58. package/out/services/resolve.js.map +1 -1
  59. package/out/types/config.d.ts +2 -0
  60. package/out/types/config.d.ts.map +1 -1
  61. package/out/types/config.js +1 -0
  62. package/out/types/config.js.map +1 -1
  63. package/out/utils/config.d.ts.map +1 -1
  64. package/out/utils/config.js +2 -0
  65. package/out/utils/config.js.map +1 -1
  66. package/package.json +1 -1
@@ -1,9 +1,8 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
3
2
  import require$$0$1, { EventEmitter } from 'events';
4
3
  import require$$1 from 'child_process';
5
- import * as sysPath from 'path';
6
- import sysPath__default, { join } from 'path';
4
+ import * as path$1 from 'path';
5
+ import path__default, { join } from 'path';
7
6
  import require$$0$2, { promises } from 'fs';
8
7
  import require$$4 from 'process';
9
8
  import require$$0$5 from 'os';
@@ -1166,7 +1165,7 @@ function requireCommand () {
1166
1165
  hasRequiredCommand = 1;
1167
1166
  const EventEmitter = require$$0$1.EventEmitter;
1168
1167
  const childProcess = require$$1;
1169
- const path = sysPath__default;
1168
+ const path = path__default;
1170
1169
  const fs = require$$0$2;
1171
1170
  const process = require$$4;
1172
1171
 
@@ -4576,7 +4575,7 @@ var hasRequiredUtils$5;
4576
4575
  function requireUtils$5 () {
4577
4576
  if (hasRequiredUtils$5) return utils$7;
4578
4577
  hasRequiredUtils$5 = 1;
4579
- const path = sysPath__default;
4578
+ const path = path__default;
4580
4579
 
4581
4580
  // https://github.com/nodejs/node/issues/8987
4582
4581
  // https://github.com/libuv/libuv/pull/1088
@@ -4722,7 +4721,7 @@ function requireStat () {
4722
4721
  hasRequiredStat = 1;
4723
4722
 
4724
4723
  const fs = /*@__PURE__*/ requireFs$4();
4725
- const path = sysPath__default;
4724
+ const path = path__default;
4726
4725
  const u = requireUniversalify().fromPromise;
4727
4726
 
4728
4727
  function getStats (src, dest, opts) {
@@ -4926,7 +4925,7 @@ function requireCopy$1 () {
4926
4925
  hasRequiredCopy$1 = 1;
4927
4926
 
4928
4927
  const fs = /*@__PURE__*/ requireFs$4();
4929
- const path = sysPath__default;
4928
+ const path = path__default;
4930
4929
  const { mkdirs } = /*@__PURE__*/ requireMkdirs();
4931
4930
  const { pathExists } = /*@__PURE__*/ requirePathExists();
4932
4931
  const { utimesMillis } = /*@__PURE__*/ requireUtimes();
@@ -5109,7 +5108,7 @@ function requireCopySync () {
5109
5108
  hasRequiredCopySync = 1;
5110
5109
 
5111
5110
  const fs = requireGracefulFs();
5112
- const path = sysPath__default;
5111
+ const path = path__default;
5113
5112
  const mkdirsSync = /*@__PURE__*/ requireMkdirs().mkdirsSync;
5114
5113
  const utimesMillisSync = /*@__PURE__*/ requireUtimes().utimesMillisSync;
5115
5114
  const stat = /*@__PURE__*/ requireStat();
@@ -5329,7 +5328,7 @@ function requireEmpty () {
5329
5328
 
5330
5329
  const u = requireUniversalify().fromPromise;
5331
5330
  const fs = /*@__PURE__*/ requireFs$4();
5332
- const path = sysPath__default;
5331
+ const path = path__default;
5333
5332
  const mkdir = /*@__PURE__*/ requireMkdirs();
5334
5333
  const remove = /*@__PURE__*/ requireRemove();
5335
5334
 
@@ -5375,7 +5374,7 @@ function requireFile () {
5375
5374
  hasRequiredFile = 1;
5376
5375
 
5377
5376
  const u = requireUniversalify().fromPromise;
5378
- const path = sysPath__default;
5377
+ const path = path__default;
5379
5378
  const fs = /*@__PURE__*/ requireFs$4();
5380
5379
  const mkdir = /*@__PURE__*/ requireMkdirs();
5381
5380
 
@@ -5449,7 +5448,7 @@ function requireLink () {
5449
5448
  hasRequiredLink = 1;
5450
5449
 
5451
5450
  const u = requireUniversalify().fromPromise;
5452
- const path = sysPath__default;
5451
+ const path = path__default;
5453
5452
  const fs = /*@__PURE__*/ requireFs$4();
5454
5453
  const mkdir = /*@__PURE__*/ requireMkdirs();
5455
5454
  const { pathExists } = /*@__PURE__*/ requirePathExists();
@@ -5520,7 +5519,7 @@ function requireSymlinkPaths () {
5520
5519
  if (hasRequiredSymlinkPaths) return symlinkPaths_1;
5521
5520
  hasRequiredSymlinkPaths = 1;
5522
5521
 
5523
- const path = sysPath__default;
5522
+ const path = path__default;
5524
5523
  const fs = /*@__PURE__*/ requireFs$4();
5525
5524
  const { pathExists } = /*@__PURE__*/ requirePathExists();
5526
5525
 
@@ -5672,7 +5671,7 @@ function requireSymlink () {
5672
5671
  hasRequiredSymlink = 1;
5673
5672
 
5674
5673
  const u = requireUniversalify().fromPromise;
5675
- const path = sysPath__default;
5674
+ const path = path__default;
5676
5675
  const fs = /*@__PURE__*/ requireFs$4();
5677
5676
 
5678
5677
  const { mkdirs, mkdirsSync } = /*@__PURE__*/ requireMkdirs();
@@ -5918,7 +5917,7 @@ function requireOutputFile () {
5918
5917
 
5919
5918
  const u = requireUniversalify().fromPromise;
5920
5919
  const fs = /*@__PURE__*/ requireFs$4();
5921
- const path = sysPath__default;
5920
+ const path = path__default;
5922
5921
  const mkdir = /*@__PURE__*/ requireMkdirs();
5923
5922
  const pathExists = /*@__PURE__*/ requirePathExists().pathExists;
5924
5923
 
@@ -6020,7 +6019,7 @@ function requireMove$1 () {
6020
6019
  hasRequiredMove$1 = 1;
6021
6020
 
6022
6021
  const fs = /*@__PURE__*/ requireFs$4();
6023
- const path = sysPath__default;
6022
+ const path = path__default;
6024
6023
  const { copy } = /*@__PURE__*/ requireCopy();
6025
6024
  const { remove } = /*@__PURE__*/ requireRemove();
6026
6025
  const { mkdirp } = /*@__PURE__*/ requireMkdirs();
@@ -6087,7 +6086,7 @@ function requireMoveSync () {
6087
6086
  hasRequiredMoveSync = 1;
6088
6087
 
6089
6088
  const fs = requireGracefulFs();
6090
- const path = sysPath__default;
6089
+ const path = path__default;
6091
6090
  const copySync = /*@__PURE__*/ requireCopy().copySync;
6092
6091
  const removeSync = /*@__PURE__*/ requireRemove().removeSync;
6093
6092
  const mkdirpSync = /*@__PURE__*/ requireMkdirs().mkdirpSync;
@@ -8204,16 +8203,16 @@ class BaseLogger {
8204
8203
  }
8205
8204
  debugToFile(topic, ...args) {
8206
8205
  if (process.env.DEBUG_TO_FILE) {
8207
- const baseDir = sysPath.join(process.cwd(), '.nasl');
8206
+ const baseDir = path$1.join(process.cwd(), '.nasl');
8208
8207
  const currentHour = dayjs().format('YYYYMMDD_HH');
8209
8208
  const prevHour = dayjs().subtract(1, 'hour').format('YYYYMMDD_HH');
8210
8209
  let subdir = `${topic}_${currentHour}`;
8211
8210
  const prevSubdir = `${topic}_${prevHour}`;
8212
8211
  // 判断如果有上一个小时的 subdir,则自己汇聚到上一个小时的 subdir 中
8213
- if (libExports.existsSync(sysPath.join(baseDir, prevSubdir)))
8212
+ if (libExports.existsSync(path$1.join(baseDir, prevSubdir)))
8214
8213
  subdir = prevSubdir;
8215
8214
  const fileName = `${topic}_${dayjs().format('YYYYMMDD_HHmmss')}.log`;
8216
- const filePath = sysPath.join(baseDir, subdir, fileName);
8215
+ const filePath = path$1.join(baseDir, subdir, fileName);
8217
8216
  libExports.outputFileSync(filePath, args.join(' '));
8218
8217
  }
8219
8218
  }
@@ -8278,11 +8277,11 @@ function findConfigDir(startDir = process.cwd()) {
8278
8277
  let currentDir = startDir;
8279
8278
  // eslint-disable-next-line no-constant-condition
8280
8279
  while (true) {
8281
- const configPath = sysPath.join(currentDir, CONFIG_FILE_NAME);
8280
+ const configPath = path$1.join(currentDir, CONFIG_FILE_NAME);
8282
8281
  if (libExports.existsSync(configPath)) {
8283
8282
  return currentDir;
8284
8283
  }
8285
- const parentDir = sysPath.dirname(currentDir);
8284
+ const parentDir = path$1.dirname(currentDir);
8286
8285
  // 已经到达根目录
8287
8286
  if (parentDir === currentDir) {
8288
8287
  return null;
@@ -8299,7 +8298,7 @@ function loadConfig(configDir) {
8299
8298
  defaultLogger.error(`未找到配置文件 ${CONFIG_FILE_NAME},请先运行 nasl-init 初始化配置`);
8300
8299
  return defaultLogger.exit(1);
8301
8300
  }
8302
- const configPath = sysPath.join(dir, CONFIG_FILE_NAME);
8301
+ const configPath = path$1.join(dir, CONFIG_FILE_NAME);
8303
8302
  try {
8304
8303
  const content = libExports.readFileSync(configPath, 'utf-8');
8305
8304
  const config = JSON.parse(content);
@@ -8330,6 +8329,8 @@ function loadConfig(configDir) {
8330
8329
  config.OPENAPI_AK = process.env.LCAP_OPENAPI_AK;
8331
8330
  if (process.env.LCAP_OPENAPI_SK)
8332
8331
  config.OPENAPI_SK = process.env.LCAP_OPENAPI_SK;
8332
+ if (process.env.LCAP_TENANT_NAME)
8333
+ config.tenantName = process.env.LCAP_TENANT_NAME;
8333
8334
  // 如果启用了 OpenAPI,验证必需的 AK 和 SK
8334
8335
  if (config.useOPENAPI) {
8335
8336
  if (!config.OPENAPI_AK || !config.OPENAPI_SK) {
@@ -8376,7 +8377,7 @@ function readFileWithLog(filePath, logger) {
8376
8377
  */
8377
8378
  function writeFileWithLog(filePath, content, logger) {
8378
8379
  try {
8379
- const dir = sysPath.dirname(filePath);
8380
+ const dir = path$1.dirname(filePath);
8380
8381
  libExports.ensureDirSync(dir);
8381
8382
  libExports.writeFileSync(filePath, content, 'utf-8');
8382
8383
  }
@@ -20362,7 +20363,7 @@ function requireMimeTypes () {
20362
20363
  */
20363
20364
 
20364
20365
  var db = requireMimeDb();
20365
- var extname = sysPath__default.extname;
20366
+ var extname = path__default.extname;
20366
20367
 
20367
20368
  /**
20368
20369
  * Module variables.
@@ -22103,7 +22104,7 @@ function requireForm_data () {
22103
22104
 
22104
22105
  var CombinedStream = requireCombined_stream();
22105
22106
  var util = require$$0$4;
22106
- var path = sysPath__default;
22107
+ var path = path__default;
22107
22108
  var http = require$$3;
22108
22109
  var https = require$$4$1;
22109
22110
  var parseUrl = require$$0$6.parse;
@@ -29047,6 +29048,20 @@ async function generateCompleteHeaders(options) {
29047
29048
  }
29048
29049
  return headers;
29049
29050
  }
29051
+ /**
29052
+ * 构建请求 headers
29053
+ * 如果 ServerOptions.useOPENAPI 为 true, 意味着接口内部是走的集群,反之则需要走 openapi 调用(本地或者server的场景,透传options相关配置)
29054
+ */
29055
+ function buildNaslHeaders(options) {
29056
+ return {
29057
+ 'Content-Type': 'text/plain',
29058
+ 'X-Server-Base-URL': options.serverBaseURL,
29059
+ ...(options.OPENAPI_AK && { 'X-OPENAPI-AK': options.OPENAPI_AK }),
29060
+ ...(options.OPENAPI_SK && { 'X-OPENAPI-SK': options.OPENAPI_SK }),
29061
+ ...(options.tenantName && { 'X-Tenant-Name': options.tenantName }),
29062
+ ...(options.useOPENAPI !== undefined && { 'X-Use-OPENAPI': String(!options.useOPENAPI) }),
29063
+ };
29064
+ }
29050
29065
 
29051
29066
  /**
29052
29067
  * 创建 Axios 实例
@@ -29094,7 +29109,7 @@ async function compileApi(fullNaturalTS, options) {
29094
29109
  // 示例实现:
29095
29110
  const axios = await createAxios(options);
29096
29111
  const res = await axios.post(`/compile/tsx?ideVersion=${options.ideVersion}&needAnnotation=true`, fullNaturalTS, {
29097
- headers: { 'Content-Type': 'text/plain' },
29112
+ headers: buildNaslHeaders(options),
29098
29113
  });
29099
29114
  const data = res.data;
29100
29115
  const { bundle } = data.result;
@@ -29242,6 +29257,25 @@ function composeToString(files) {
29242
29257
  }
29243
29258
  return result;
29244
29259
  }
29260
+ /**
29261
+ * 将依赖信息拼接到 fullNaturalTS 顶部
29262
+ * @param fullNaturalTS 组合后的 NASL 代码
29263
+ * @param dependencies mergedDependencies 对象或 JSON 字符串
29264
+ * @returns 拼接后的完整内容
29265
+ */
29266
+ function prependDependencies(fullNaturalTS, dependencies) {
29267
+ if (!dependencies)
29268
+ return fullNaturalTS;
29269
+ const jsonStr = JSON.stringify(dependencies, null, 2);
29270
+ const header = `/*
29271
+ -----------app.dependencies.json7xdhjutehm.start
29272
+ ${jsonStr}
29273
+ -----------app.dependencies.json7xdhjutehm.end
29274
+ */
29275
+
29276
+ `;
29277
+ return header + fullNaturalTS;
29278
+ }
29245
29279
 
29246
29280
  var globby$1 = {exports: {}};
29247
29281
 
@@ -29499,7 +29533,7 @@ function requirePath () {
29499
29533
  Object.defineProperty(path, "__esModule", { value: true });
29500
29534
  path.convertPosixPathToPattern = path.convertWindowsPathToPattern = path.convertPathToPattern = path.escapePosixPath = path.escapeWindowsPath = path.escape = path.removeLeadingDotSegment = path.makeAbsolute = path.unixify = void 0;
29501
29535
  const os = require$$0$5;
29502
- const path$1 = sysPath__default;
29536
+ const path$1 = path__default;
29503
29537
  const IS_WINDOWS_PLATFORM = os.platform() === 'win32';
29504
29538
  const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\
29505
29539
  /**
@@ -29764,7 +29798,7 @@ function requireGlobParent () {
29764
29798
  hasRequiredGlobParent = 1;
29765
29799
 
29766
29800
  var isGlob = requireIsGlob();
29767
- var pathPosixDirname = sysPath__default.posix.dirname;
29801
+ var pathPosixDirname = path__default.posix.dirname;
29768
29802
  var isWin32 = require$$0$5.platform() === 'win32';
29769
29803
 
29770
29804
  var slash = '/';
@@ -31336,7 +31370,7 @@ function requireConstants$1 () {
31336
31370
  if (hasRequiredConstants$1) return constants$1;
31337
31371
  hasRequiredConstants$1 = 1;
31338
31372
 
31339
- const path = sysPath__default;
31373
+ const path = path__default;
31340
31374
  const WIN_SLASH = '\\\\/';
31341
31375
  const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
31342
31376
 
@@ -31523,7 +31557,7 @@ function requireUtils$2 () {
31523
31557
  hasRequiredUtils$2 = 1;
31524
31558
  (function (exports$1) {
31525
31559
 
31526
- const path = sysPath__default;
31560
+ const path = path__default;
31527
31561
  const win32 = process.platform === 'win32';
31528
31562
  const {
31529
31563
  REGEX_BACKSLASH,
@@ -33094,7 +33128,7 @@ function requirePicomatch$1 () {
33094
33128
  if (hasRequiredPicomatch$1) return picomatch_1;
33095
33129
  hasRequiredPicomatch$1 = 1;
33096
33130
 
33097
- const path = sysPath__default;
33131
+ const path = path__default;
33098
33132
  const scan = requireScan();
33099
33133
  const parse = requireParse();
33100
33134
  const utils = requireUtils$2();
@@ -33937,7 +33971,7 @@ function requirePattern () {
33937
33971
  hasRequiredPattern = 1;
33938
33972
  Object.defineProperty(pattern, "__esModule", { value: true });
33939
33973
  pattern.isAbsolute = pattern.partitionAbsoluteAndRelative = pattern.removeDuplicateSlashes = pattern.matchAny = pattern.convertPatternsToRe = pattern.makeRe = pattern.getPatternParts = pattern.expandBraceExpansion = pattern.expandPatternsWithBraceExpansion = pattern.isAffectDepthOfReadingPattern = pattern.endsWithSlashGlobStar = pattern.hasGlobStar = pattern.getBaseDirectory = pattern.isPatternRelatedToParentDirectory = pattern.getPatternsOutsideCurrentDirectory = pattern.getPatternsInsideCurrentDirectory = pattern.getPositivePatterns = pattern.getNegativePatterns = pattern.isPositivePattern = pattern.isNegativePattern = pattern.convertToNegativePattern = pattern.convertToPositivePattern = pattern.isDynamicPattern = pattern.isStaticPattern = void 0;
33940
- const path = sysPath__default;
33974
+ const path = path__default;
33941
33975
  const globParent = requireGlobParent();
33942
33976
  const micromatch = requireMicromatch();
33943
33977
  const GLOBSTAR = '**';
@@ -34891,7 +34925,7 @@ function requireSettings$2 () {
34891
34925
  if (hasRequiredSettings$2) return settings$2;
34892
34926
  hasRequiredSettings$2 = 1;
34893
34927
  Object.defineProperty(settings$2, "__esModule", { value: true });
34894
- const path = sysPath__default;
34928
+ const path = path__default;
34895
34929
  const fsStat = requireOut$3();
34896
34930
  const fs = requireFs();
34897
34931
  class Settings {
@@ -35653,7 +35687,7 @@ function requireSettings$1 () {
35653
35687
  if (hasRequiredSettings$1) return settings$1;
35654
35688
  hasRequiredSettings$1 = 1;
35655
35689
  Object.defineProperty(settings$1, "__esModule", { value: true });
35656
- const path = sysPath__default;
35690
+ const path = path__default;
35657
35691
  const fsScandir = requireOut$2();
35658
35692
  class Settings {
35659
35693
  constructor(_options = {}) {
@@ -35729,7 +35763,7 @@ function requireReader () {
35729
35763
  if (hasRequiredReader) return reader;
35730
35764
  hasRequiredReader = 1;
35731
35765
  Object.defineProperty(reader, "__esModule", { value: true });
35732
- const path = sysPath__default;
35766
+ const path = path__default;
35733
35767
  const fsStat = requireOut$3();
35734
35768
  const utils = requireUtils$1();
35735
35769
  class Reader {
@@ -36202,7 +36236,7 @@ function requireProvider () {
36202
36236
  if (hasRequiredProvider) return provider;
36203
36237
  hasRequiredProvider = 1;
36204
36238
  Object.defineProperty(provider, "__esModule", { value: true });
36205
- const path = sysPath__default;
36239
+ const path = path__default;
36206
36240
  const deep_1 = requireDeep();
36207
36241
  const entry_1 = requireEntry$1();
36208
36242
  const error_1 = requireError();
@@ -36642,7 +36676,7 @@ var hasRequiredDirGlob;
36642
36676
  function requireDirGlob () {
36643
36677
  if (hasRequiredDirGlob) return dirGlob.exports;
36644
36678
  hasRequiredDirGlob = 1;
36645
- const path = sysPath__default;
36679
+ const path = path__default;
36646
36680
  const pathType = requirePathType();
36647
36681
 
36648
36682
  const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0];
@@ -37392,7 +37426,7 @@ function requireGitignore () {
37392
37426
  hasRequiredGitignore = 1;
37393
37427
  const {promisify} = require$$0$4;
37394
37428
  const fs = require$$0$2;
37395
- const path = sysPath__default;
37429
+ const path = path__default;
37396
37430
  const fastGlob = requireOut();
37397
37431
  const gitIgnore = requireIgnore();
37398
37432
  const slash = requireSlash();
@@ -37824,6 +37858,27 @@ const NASL_FILE_TYPES = [
37824
37858
  codeRefPattern: 'extensions\\.\\w+(?:\\.\\w+)*',
37825
37859
  extension: 'ts',
37826
37860
  },
37861
+ {
37862
+ name: 'apis',
37863
+ description: 'API',
37864
+ fileNamePattern: 'apis\\.\\w+\\.ts',
37865
+ codeRefPattern: 'apis\\.\\w+(?:\\.\\w+)*',
37866
+ extension: 'ts',
37867
+ },
37868
+ {
37869
+ name: 'connectors',
37870
+ description: '连接器',
37871
+ fileNamePattern: 'connectors\\.\\w+\\.ts',
37872
+ codeRefPattern: 'connectors\\.\\w+(?:\\.\\w+)*',
37873
+ extension: 'ts',
37874
+ },
37875
+ {
37876
+ name: 'uilibs',
37877
+ description: 'UI 库',
37878
+ fileNamePattern: 'uilibs\\.\\w+\\.ts',
37879
+ codeRefPattern: 'uilibs\\.\\w+(?:\\.\\w+)*',
37880
+ extension: 'ts',
37881
+ },
37827
37882
  ];
37828
37883
  /**
37829
37884
  * 获取用于验证文件名的正则表达式数组
@@ -37856,10 +37911,15 @@ const codeRefPatterns = getCodeRefPatterns();
37856
37911
  */
37857
37912
  function isKnownFileType(filePath) {
37858
37913
  // 提取文件名
37859
- const fileName = sysPath.basename(filePath);
37914
+ const fileName = path$1.basename(filePath);
37860
37915
  return fileNamePatterns.some((pattern) => pattern.test(fileName));
37861
37916
  }
37862
37917
 
37918
+ /** 这些前缀的依赖不再向下递归查找 */
37919
+ const EXTERNAL_DEP_PREFIXES = ['extensions.', 'connectors.', 'apis.', 'uilibs.'];
37920
+ function shouldSkipDependencyTraversal(depPath) {
37921
+ return EXTERNAL_DEP_PREFIXES.some((prefix) => depPath.startsWith(prefix));
37922
+ }
37863
37923
  /**
37864
37924
  * 扫描目录下的所有 NASL 文件
37865
37925
  */
@@ -37925,6 +37985,15 @@ function extractDeps(content) {
37925
37985
  if (/^extensions\.\w+\./.test(dep)) {
37926
37986
  dep = dep.replace(/^(extensions\.\w+)\..+$/, '$1');
37927
37987
  }
37988
+ if (/^apis\.\w+\./.test(dep)) {
37989
+ dep = dep.replace(/^(apis\.\w+)\..+$/, '$1');
37990
+ }
37991
+ if (/^connectors\.\w+\./.test(dep)) {
37992
+ dep = dep.replace(/^(connectors\.\w+)\..+$/, '$1');
37993
+ }
37994
+ if (/^uilibs\.\w+\./.test(dep)) {
37995
+ dep = dep.replace(/^(uilibs\.\w+)\..+$/, '$1');
37996
+ }
37928
37997
  // 跳过不合法的实体引用(实体后还有字段的情况)
37929
37998
  if (/app\.dataSources\.\w+\.entities\.\w+\.\w+$/.test(dep)) {
37930
37999
  continue;
@@ -37936,6 +38005,152 @@ function extractDeps(content) {
37936
38005
  }
37937
38006
  return Array.from(deps);
37938
38007
  }
38008
+ /**
38009
+ * 从文件内容中提取外部依赖引用(extensions/connectors/apis/uilibs)
38010
+ * 用于构建 externalDependencies
38011
+ */
38012
+ function extractExternalRefs(content) {
38013
+ const refs = {
38014
+ extensions: new Set(),
38015
+ connectors: new Set(),
38016
+ uilibs: new Set(),
38017
+ apis: new Map(),
38018
+ };
38019
+ const processedContent = content
38020
+ .replace(/\/\/.*$/gm, '')
38021
+ .replace(/\/\*[\s\S]*?\*\//g, '')
38022
+ .replace(/'(?:[^'\\]|\\.)*'/g, '')
38023
+ .replace(/"(?:[^"\\]|\\.)*"/g, '');
38024
+ // extensions.xxx, connectors.xxx, uilibs.xxx
38025
+ for (const m of processedContent.matchAll(/\b(extensions|connectors|uilibs)\.(\w+)/g)) {
38026
+ const [, kind, name] = m;
38027
+ if (kind === 'extensions')
38028
+ refs.extensions.add(name);
38029
+ else if (kind === 'connectors')
38030
+ refs.connectors.add(name);
38031
+ else
38032
+ refs.uilibs.add(name);
38033
+ }
38034
+ // apis.xxx.interfaces.yyy
38035
+ for (const m of processedContent.matchAll(/\bapis\.(\w+)\.interfaces\.(\w+)/g)) {
38036
+ const [, apiName, ifaceName] = m;
38037
+ if (!refs.apis.has(apiName))
38038
+ refs.apis.set(apiName, new Set());
38039
+ refs.apis.get(apiName).add(ifaceName);
38040
+ }
38041
+ return refs;
38042
+ }
38043
+ function mergeExternalRefs(into, from) {
38044
+ from.extensions.forEach((x) => into.extensions.add(x));
38045
+ from.connectors.forEach((x) => into.connectors.add(x));
38046
+ from.uilibs.forEach((x) => into.uilibs.add(x));
38047
+ from.apis.forEach((interfaces, apiName) => {
38048
+ if (!into.apis.has(apiName))
38049
+ into.apis.set(apiName, new Set());
38050
+ interfaces.forEach((i) => into.apis.get(apiName).add(i));
38051
+ });
38052
+ }
38053
+ /**
38054
+ * 加载 app.dependencies.json(不存在则返回空对象)
38055
+ */
38056
+ function loadAppDependencies(srcDir) {
38057
+ const p = path$1.join(srcDir, 'app.dependencies.json');
38058
+ if (!libExports.existsSync(p))
38059
+ return {};
38060
+ try {
38061
+ return libExports.readJsonSync(p);
38062
+ }
38063
+ catch {
38064
+ return {};
38065
+ }
38066
+ }
38067
+ /**
38068
+ * 加载并合并 app.dependencies.json 与 potential.dependencies.json
38069
+ * 用于版本号查找:先查 app,再查 potential
38070
+ */
38071
+ function loadMergedDependencies(srcDir) {
38072
+ const load = (file) => {
38073
+ const p = path$1.join(srcDir, file);
38074
+ if (!libExports.existsSync(p))
38075
+ return null;
38076
+ try {
38077
+ return libExports.readJsonSync(p);
38078
+ }
38079
+ catch {
38080
+ return null;
38081
+ }
38082
+ };
38083
+ const app = load('app.dependencies.json') ?? {};
38084
+ const potential = load('potential.dependencies.json') ?? {};
38085
+ const merged = {};
38086
+ for (const key of ['extensions', 'uilibs', 'connectors', 'apis']) {
38087
+ merged[key] = { ...(potential[key] ?? {}), ...(app[key] ?? {}) };
38088
+ }
38089
+ return merged;
38090
+ }
38091
+ /**
38092
+ * 将 externalDependencies 补充到 app.dependencies.json(只增不减)
38093
+ */
38094
+ function mergeDependenciesIntoApp(existing, incoming) {
38095
+ const result = {};
38096
+ for (const key of ['extensions', 'uilibs', 'connectors']) {
38097
+ const existingRecord = existing[key] ?? {};
38098
+ const incomingRecord = incoming[key] ?? {};
38099
+ result[key] = { ...incomingRecord, ...existingRecord };
38100
+ }
38101
+ result.apis = {};
38102
+ if (existing.apis || incoming.apis) {
38103
+ const allApiNames = new Set([...Object.keys(existing.apis ?? {}), ...Object.keys(incoming.apis ?? {})]);
38104
+ for (const apiName of allApiNames) {
38105
+ const existingInterfaces = existing.apis?.[apiName] ?? [];
38106
+ const incomingInterfaces = incoming.apis?.[apiName] ?? [];
38107
+ result.apis[apiName] = [...new Set([...existingInterfaces, ...incomingInterfaces])].sort();
38108
+ }
38109
+ }
38110
+ return result;
38111
+ }
38112
+ /**
38113
+ * 根据收集的外部引用和版本配置,构建 DependenciesJSON
38114
+ * extensions/connectors/uilibs 需要版本号,apis 只需 interfaces 数组
38115
+ */
38116
+ function buildExternalDependencies(refs, mergedDeps, logger) {
38117
+ const result = {};
38118
+ const errors = [];
38119
+ for (const name of refs.extensions) {
38120
+ const ver = mergedDeps.extensions?.[name];
38121
+ if (!ver) {
38122
+ errors.push(`extensions.${name} 未在 app.dependencies.json 或 potential.dependencies.json 中找到版本号`);
38123
+ }
38124
+ else {
38125
+ (result.extensions ?? (result.extensions = {}))[name] = ver;
38126
+ }
38127
+ }
38128
+ for (const name of refs.connectors) {
38129
+ const ver = mergedDeps.connectors?.[name];
38130
+ if (!ver) {
38131
+ errors.push(`connectors.${name} 未在 app.dependencies.json 或 potential.dependencies.json 中找到版本号`);
38132
+ }
38133
+ else {
38134
+ (result.connectors ?? (result.connectors = {}))[name] = ver;
38135
+ }
38136
+ }
38137
+ for (const name of refs.uilibs) {
38138
+ const ver = mergedDeps.uilibs?.[name];
38139
+ if (!ver) {
38140
+ errors.push(`uilibs.${name} 未在 app.dependencies.json 或 potential.dependencies.json 中找到版本号`);
38141
+ }
38142
+ else {
38143
+ (result.uilibs ?? (result.uilibs = {}))[name] = ver;
38144
+ }
38145
+ }
38146
+ // result.uilibs = mergedDeps.uilibs; // 临时先都加上去
38147
+ refs.apis.forEach((interfaces, apiName) => {
38148
+ (result.apis ?? (result.apis = {}))[apiName] = Array.from(interfaces).sort();
38149
+ });
38150
+ if (errors.length > 0)
38151
+ throw new Error(errors.join('\n'));
38152
+ return result;
38153
+ }
37939
38154
  /**
37940
38155
  * 提取页面文件的签名,移除函数体
37941
38156
  * @param content 页面文件内容
@@ -37958,7 +38173,7 @@ function replaceViewAsSignature(content, hasSubViews = false) {
37958
38173
  * @returns 文件信息和新发现的依赖文件列表
37959
38174
  */
37960
38175
  function processFileDeps(pathRelativeToSrc, srcDir, matchedFileSet, processedFileMap, depNotFoundList, logger, verbose) {
37961
- const absoluteFilePath = sysPath.join(srcDir, pathRelativeToSrc);
38176
+ const absoluteFilePath = path$1.join(srcDir, pathRelativeToSrc);
37962
38177
  const fileInfo = { path: pathRelativeToSrc, content: '' };
37963
38178
  try {
37964
38179
  fileInfo.content = readFileWithLog(absoluteFilePath, logger);
@@ -37988,7 +38203,9 @@ function processFileDeps(pathRelativeToSrc, srcDir, matchedFileSet, processedFil
37988
38203
  }
37989
38204
  processedFileMap.set(pathRelativeToSrc, fileInfo);
37990
38205
  // 提取依赖
37991
- const deps = extractDeps(fileInfo.content);
38206
+ // extensions/connectors/apis/uilibs 作为叶子节点,不再向下递归查找依赖
38207
+ const isExternalDep = shouldSkipDependencyTraversal(pathRelativeToSrc);
38208
+ const deps = isExternalDep ? [] : extractDeps(fileInfo.content);
37992
38209
  // 查找依赖文件
37993
38210
  if (isView) {
37994
38211
  const pathArr = pathRelativeToSrc.split('.');
@@ -38003,24 +38220,30 @@ function processFileDeps(pathRelativeToSrc, srcDir, matchedFileSet, processedFil
38003
38220
  } while (true);
38004
38221
  }
38005
38222
  if (verbose || process.env.DEBUG) {
38006
- console.log(`${isEntryFile ? chalk.magenta('[Entry]') : chalk.green('[ Dep ]')} ${pathRelativeToSrc}${deps.map((dep) => `\n├── ${dep}`).join('')}`);
38223
+ console.log(`${isEntryFile ? chalk.magenta('[Entry]') : isExternalDep ? chalk.blue('[ External Dep ]') : chalk.green('[ Dep ]')} ${pathRelativeToSrc}${deps.map((dep) => `\n├── ${dep}`).join('')}`);
38007
38224
  }
38008
38225
  return {
38009
38226
  fileInfo,
38010
38227
  newDeps: deps.filter((dep) => !processedFileMap.has(dep)),
38228
+ isExternalDep,
38011
38229
  };
38012
38230
  }
38013
38231
  /**
38014
38232
  * 收集入口文件及其依赖
38015
38233
  * @param patterns 入口文件的 glob 模式数组
38016
38234
  * @param srcDir 源代码目录绝对路径
38017
- * @param representation NASL 表示形式
38018
- * @returns 文件信息列表
38235
+ * @returns 文件信息列表和外部依赖引用
38019
38236
  */
38020
38237
  async function collectDeps(patterns, projectRoot, srcDir, logger, verbose) {
38021
38238
  const processedFileMap = new Map(); // 已处理的文件(相对路径)
38022
38239
  const filesToProcess = []; // 待处理的文件队列
38023
38240
  const result = [];
38241
+ const externalRefs = {
38242
+ extensions: new Set(),
38243
+ connectors: new Set(),
38244
+ uilibs: new Set(),
38245
+ apis: new Map(),
38246
+ };
38024
38247
  // 1. 使用 glob 匹配入口文件
38025
38248
  logger.newLine();
38026
38249
  logger.info(`匹配入口文件: ${patterns.join(', ')}`);
@@ -38030,15 +38253,15 @@ async function collectDeps(patterns, projectRoot, srcDir, logger, verbose) {
38030
38253
  throw new Error('未找到匹配的入口文件');
38031
38254
  }
38032
38255
  logger.info(`找到 ${matchedFiles.length} 个入口文件`);
38033
- const absoluteSrcDir = sysPath.resolve(srcDir);
38256
+ const absoluteSrcDir = path$1.resolve(srcDir);
38034
38257
  const matchedFileSet = new Set();
38035
38258
  matchedFiles.forEach((pathRelativeToRoot) => {
38036
38259
  // 统一使用相对于 src 的路径
38037
- const absoluteFilePath = sysPath.resolve(projectRoot, pathRelativeToRoot);
38260
+ const absoluteFilePath = path$1.resolve(projectRoot, pathRelativeToRoot);
38038
38261
  // 判断 file 是否超出 srcDir 目录(支持相对路径和绝对路径)
38039
38262
  if (!absoluteFilePath.startsWith(absoluteSrcDir))
38040
38263
  throw new Error(`入口文件 ${absoluteFilePath} 超出了源代码目录 ${srcDir}`);
38041
- const pathRelativeToSrc = sysPath.relative(srcDir, absoluteFilePath);
38264
+ const pathRelativeToSrc = path$1.relative(srcDir, absoluteFilePath);
38042
38265
  filesToProcess.push(pathRelativeToSrc);
38043
38266
  matchedFileSet.add(pathRelativeToSrc);
38044
38267
  });
@@ -38056,8 +38279,9 @@ async function collectDeps(patterns, projectRoot, srcDir, logger, verbose) {
38056
38279
  continue;
38057
38280
  }
38058
38281
  try {
38059
- const { fileInfo, newDeps } = processFileDeps(pathRelativeToSrc, srcDir, matchedFileSet, processedFileMap, depNotFoundList, logger, verbose);
38060
- result.push(fileInfo);
38282
+ const { fileInfo, newDeps, isExternalDep } = processFileDeps(pathRelativeToSrc, srcDir, matchedFileSet, processedFileMap, depNotFoundList, logger, verbose);
38283
+ !isExternalDep && result.push(fileInfo);
38284
+ mergeExternalRefs(externalRefs, extractExternalRefs(fileInfo.content));
38061
38285
  filesToProcess.push(...newDeps);
38062
38286
  }
38063
38287
  catch (error) {
@@ -38079,7 +38303,7 @@ ${depNotFoundList.map((dep) => `- ${dep}\n`).join('')}
38079
38303
  }
38080
38304
  if (errorMessage)
38081
38305
  throw new Error(errorMessage);
38082
- return result;
38306
+ return { files: result, externalRefs };
38083
38307
  }
38084
38308
  /**
38085
38309
  * 解析需要处理的文件(包含配置加载和目录设置)
@@ -38087,12 +38311,13 @@ ${depNotFoundList.map((dep) => `- ${dep}\n`).join('')}
38087
38311
  * @returns 文件信息、配置和目录信息
38088
38312
  */
38089
38313
  async function resolveNASLFiles(entry, logger, depMode, verbose) {
38314
+ depMode = true; // !!ensure depMode is true
38090
38315
  // 加载配置
38091
38316
  const config = loadConfig();
38092
38317
  const projectRoot = getProjectRoot();
38093
38318
  logger.info(`项目根目录: ${projectRoot}`);
38094
38319
  logger.info(`源代码目录: ${config.srcDir}`);
38095
- const srcDir = sysPath.join(projectRoot, config.srcDir);
38320
+ const srcDir = path$1.join(projectRoot, config.srcDir);
38096
38321
  // 收集需要处理的文件
38097
38322
  let collectedFiles = [];
38098
38323
  if (Array.isArray(entry) && !entry.length) {
@@ -38101,8 +38326,12 @@ async function resolveNASLFiles(entry, logger, depMode, verbose) {
38101
38326
  config,
38102
38327
  projectRoot,
38103
38328
  srcDir,
38329
+ externalDependencies: undefined,
38104
38330
  };
38105
38331
  }
38332
+ let externalRefs = null;
38333
+ if (!entry && depMode)
38334
+ entry = 'src/**/app.*.{ts,tsx,css}';
38106
38335
  if (entry) {
38107
38336
  // 检查入口路径是否在源代码目录外面
38108
38337
  // if (entry.startsWith('..')) throw new Error('入口路径不能在源代码目录外面');
@@ -38110,7 +38339,9 @@ async function resolveNASLFiles(entry, logger, depMode, verbose) {
38110
38339
  // 具体路径也转换为 glob 模式统一处理
38111
38340
  // 使用依赖分析收集文件
38112
38341
  try {
38113
- collectedFiles = await collectDeps(Array.isArray(entry) ? entry : [entry], projectRoot, srcDir, logger, depMode || verbose);
38342
+ const { files, externalRefs: refs } = await collectDeps(Array.isArray(entry) ? entry : [entry], projectRoot, srcDir, logger, depMode || verbose);
38343
+ collectedFiles = files;
38344
+ externalRefs = refs;
38114
38345
  }
38115
38346
  catch (error) {
38116
38347
  logger.error(`依赖分析失败:\n${error.message}`);
@@ -38124,13 +38355,21 @@ async function resolveNASLFiles(entry, logger, depMode, verbose) {
38124
38355
  filePaths.sort(sorter);
38125
38356
  collectedFiles = filePaths.map((filePath) => ({
38126
38357
  path: filePath,
38127
- content: readFileWithLog(sysPath.join(srcDir, filePath), logger),
38358
+ content: readFileWithLog(path$1.join(srcDir, filePath), logger),
38128
38359
  }));
38129
38360
  if (collectedFiles.length === 0) {
38130
38361
  logger.warn('未找到 NASL 文件');
38131
38362
  logger.exit(1);
38132
38363
  }
38133
38364
  logger.info(`找到 ${collectedFiles.length} 个 NASL 文件`);
38365
+ // 全量扫描时也从文件中提取外部依赖引用
38366
+ externalRefs = {
38367
+ extensions: new Set(),
38368
+ connectors: new Set(),
38369
+ uilibs: new Set(),
38370
+ apis: new Map(),
38371
+ };
38372
+ collectedFiles.forEach((f) => mergeExternalRefs(externalRefs, extractExternalRefs(f.content)));
38134
38373
  }
38135
38374
  // 统一过滤掉不支持的文件类型
38136
38375
  const filteredFiles = [];
@@ -38142,11 +38381,24 @@ async function resolveNASLFiles(entry, logger, depMode, verbose) {
38142
38381
  logger.warn(`跳过不支持的文件类型: ${file.path}`);
38143
38382
  }
38144
38383
  });
38384
+ // 从分析中构建 externalDependencies(版本号从 app.dependencies.json / potential.dependencies.json 获取)
38385
+ let externalDependencies;
38386
+ let mergedDependencies;
38387
+ if (externalRefs && (externalRefs.extensions.size > 0 || externalRefs.connectors.size > 0 || externalRefs.uilibs.size > 0 || externalRefs.apis.size > 0)) {
38388
+ const mergedDeps = loadMergedDependencies(srcDir);
38389
+ externalDependencies = buildExternalDependencies(externalRefs, mergedDeps);
38390
+ const appDeps = loadAppDependencies(srcDir);
38391
+ mergedDependencies = mergeDependenciesIntoApp(appDeps, externalDependencies);
38392
+ logger.debug('已从分析构建 externalDependencies', externalDependencies);
38393
+ logger.debug('已从分析构建 mergedDependencies', mergedDependencies);
38394
+ }
38145
38395
  return {
38146
38396
  collectedFiles: filteredFiles,
38147
38397
  config,
38148
38398
  projectRoot,
38149
38399
  srcDir,
38400
+ externalDependencies,
38401
+ mergedDependencies,
38150
38402
  };
38151
38403
  }
38152
38404
 
@@ -38157,19 +38409,20 @@ async function compile(entry, options) {
38157
38409
  const logger = options?.logger || defaultLogger;
38158
38410
  logger.info('开始编译 NASL 代码...');
38159
38411
  // 收集需要编译的文件
38160
- const { collectedFiles, config, projectRoot } = await resolveNASLFiles(entry, logger, false, options?.verbose);
38412
+ const { collectedFiles, config, projectRoot, mergedDependencies } = await resolveNASLFiles(entry, logger, false, options?.verbose);
38161
38413
  logger.info(`输出目录: ${config.outDir}`);
38162
- const outDir = sysPath.join(projectRoot, config.outDir);
38414
+ const outDir = path$1.join(projectRoot, config.outDir);
38163
38415
  // 调用编译 API
38164
38416
  logger.newLine();
38165
38417
  logger.info('正在调用编译服务...');
38166
38418
  try {
38167
- const fullNaturalTS = composeToString(collectedFiles);
38419
+ let fullNaturalTS = composeToString(collectedFiles);
38420
+ fullNaturalTS = prependDependencies(fullNaturalTS, mergedDependencies);
38168
38421
  const outputFiles = await compileApi(fullNaturalTS, config);
38169
38422
  logger.success('编译成功!');
38170
38423
  // 写入输出文件
38171
38424
  for (const file of outputFiles) {
38172
- const outputPath = sysPath.join(outDir, file.path);
38425
+ const outputPath = path$1.join(outDir, file.path);
38173
38426
  writeFileWithLog(outputPath, file.content, logger);
38174
38427
  }
38175
38428
  logger.info(`输出 ${outputFiles.length} 个文件`);
@@ -38192,7 +38445,7 @@ async function tryCompile(entry, options) {
38192
38445
  }
38193
38446
  }
38194
38447
 
38195
- var version = "0.2.3";
38448
+ var version = "0.3.0";
38196
38449
  var pkg = {
38197
38450
  version: version};
38198
38451