@nasl/cli 0.1.15 → 0.1.17
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/build/nasl.bundle.js +4970 -4941
- package/dist/bin/nasl.mjs +243 -51
- package/dist/bin/nasl.mjs.map +1 -1
- package/dist/bin/naslc.mjs +196 -16
- package/dist/bin/naslc.mjs.map +1 -1
- package/dist/index.mjs +212 -49
- package/dist/index.mjs.map +1 -1
- package/out/apis/compileApi.d.ts.map +1 -1
- package/out/apis/compileApi.js +2 -4
- package/out/apis/compileApi.js.map +1 -1
- package/out/apis/createAppApi.js +1 -1
- package/out/apis/createAppApi.js.map +1 -1
- package/out/apis/createAxios.d.ts +7 -1
- package/out/apis/createAxios.d.ts.map +1 -1
- package/out/apis/createAxios.js +34 -5
- package/out/apis/createAxios.js.map +1 -1
- package/out/apis/openapi.d.ts +34 -0
- package/out/apis/openapi.d.ts.map +1 -0
- package/out/apis/openapi.js +114 -0
- package/out/apis/openapi.js.map +1 -0
- package/out/apis/transformApi.d.ts +1 -1
- package/out/apis/transformApi.d.ts.map +1 -1
- package/out/apis/transformApi.js +4 -6
- package/out/apis/transformApi.js.map +1 -1
- package/out/bin/nasl.js +63 -1
- package/out/bin/nasl.js.map +1 -1
- package/out/commands/check.d.ts.map +1 -1
- package/out/commands/check.js +1 -4
- package/out/commands/check.js.map +1 -1
- package/out/commands/compile.d.ts.map +1 -1
- package/out/commands/compile.js +1 -4
- package/out/commands/compile.js.map +1 -1
- package/out/commands/transform.d.ts.map +1 -1
- package/out/commands/transform.js +7 -19
- package/out/commands/transform.js.map +1 -1
- package/out/types/api.d.ts +8 -0
- package/out/types/api.d.ts.map +1 -1
- package/out/types/command.d.ts +1 -0
- package/out/types/command.d.ts.map +1 -1
- package/out/types/config.d.ts +6 -0
- package/out/types/config.d.ts.map +1 -1
- package/out/types/config.js +2 -2
- package/out/types/config.js.map +1 -1
- package/package.json +3 -1
package/dist/bin/nasl.mjs
CHANGED
|
@@ -15,9 +15,10 @@ import require$$1$1 from 'tty';
|
|
|
15
15
|
import require$$3 from 'http';
|
|
16
16
|
import require$$4$1 from 'https';
|
|
17
17
|
import require$$0$6 from 'url';
|
|
18
|
-
import
|
|
18
|
+
import crypto$1 from 'crypto';
|
|
19
19
|
import http2 from 'http2';
|
|
20
20
|
import zlib from 'zlib';
|
|
21
|
+
import * as readline from 'readline';
|
|
21
22
|
import { realpath as realpath$1, stat as stat$2, lstat as lstat$1, open, readdir as readdir$1 } from 'fs/promises';
|
|
22
23
|
import { lstat, stat as stat$1, readdir, realpath } from 'node:fs/promises';
|
|
23
24
|
import { Readable as Readable$1 } from 'node:stream';
|
|
@@ -6191,10 +6192,10 @@ var libExports = /*@__PURE__*/ requireLib();
|
|
|
6191
6192
|
* 默认配置
|
|
6192
6193
|
*/
|
|
6193
6194
|
const DEFAULT_CONFIG = {
|
|
6194
|
-
serverBaseURL: 'https://nasl.lcap.163yun.com
|
|
6195
|
+
serverBaseURL: 'https://nasl.lcap.163yun.com',
|
|
6195
6196
|
representation: 'NaturalTS',
|
|
6196
6197
|
namespaceResolution: 'filename-as-namespace',
|
|
6197
|
-
ideVersion: '4.
|
|
6198
|
+
ideVersion: '4.4',
|
|
6198
6199
|
srcDir: 'src',
|
|
6199
6200
|
outDir: 'out',
|
|
6200
6201
|
};
|
|
@@ -22145,7 +22146,7 @@ function requireForm_data () {
|
|
|
22145
22146
|
var parseUrl = require$$0$6.parse;
|
|
22146
22147
|
var fs = require$$0$2;
|
|
22147
22148
|
var Stream = stream$4.Stream;
|
|
22148
|
-
var crypto =
|
|
22149
|
+
var crypto = crypto$1;
|
|
22149
22150
|
var mime = requireMimeTypes();
|
|
22150
22151
|
var asynckit = requireAsynckit();
|
|
22151
22152
|
var setToStringTag = /*@__PURE__*/ requireEsSetTostringtag();
|
|
@@ -23054,7 +23055,7 @@ const generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => {
|
|
|
23054
23055
|
let str = '';
|
|
23055
23056
|
const {length} = alphabet;
|
|
23056
23057
|
const randomValues = new Uint32Array(size);
|
|
23057
|
-
|
|
23058
|
+
crypto$1.randomFillSync(randomValues);
|
|
23058
23059
|
for (let i = 0; i < size; i++) {
|
|
23059
23060
|
str += alphabet[randomValues[i] % length];
|
|
23060
23061
|
}
|
|
@@ -28839,14 +28840,199 @@ const {
|
|
|
28839
28840
|
mergeConfig
|
|
28840
28841
|
} = axios;
|
|
28841
28842
|
|
|
28842
|
-
|
|
28843
|
-
|
|
28843
|
+
// Unique ID creation requires a high quality random # generator. In the browser we therefore
|
|
28844
|
+
// require the crypto API and do not support built-in fallback to lower quality random number
|
|
28845
|
+
// generators (like Math.random()).
|
|
28846
|
+
let getRandomValues;
|
|
28847
|
+
const rnds8 = new Uint8Array(16);
|
|
28848
|
+
function rng() {
|
|
28849
|
+
// lazy load so that environments that need to polyfill have a chance to do so
|
|
28850
|
+
if (!getRandomValues) {
|
|
28851
|
+
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
|
|
28852
|
+
getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
|
|
28853
|
+
|
|
28854
|
+
if (!getRandomValues) {
|
|
28855
|
+
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
|
|
28856
|
+
}
|
|
28857
|
+
}
|
|
28858
|
+
|
|
28859
|
+
return getRandomValues(rnds8);
|
|
28860
|
+
}
|
|
28861
|
+
|
|
28862
|
+
/**
|
|
28863
|
+
* Convert array of 16 byte values to UUID string format of the form:
|
|
28864
|
+
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
|
28865
|
+
*/
|
|
28866
|
+
|
|
28867
|
+
const byteToHex = [];
|
|
28868
|
+
|
|
28869
|
+
for (let i = 0; i < 256; ++i) {
|
|
28870
|
+
byteToHex.push((i + 0x100).toString(16).slice(1));
|
|
28871
|
+
}
|
|
28872
|
+
|
|
28873
|
+
function unsafeStringify(arr, offset = 0) {
|
|
28874
|
+
// Note: Be careful editing this code! It's been tuned for performance
|
|
28875
|
+
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
|
|
28876
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
28877
|
+
}
|
|
28878
|
+
|
|
28879
|
+
const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
|
|
28880
|
+
var native = {
|
|
28881
|
+
randomUUID
|
|
28882
|
+
};
|
|
28883
|
+
|
|
28884
|
+
function v4(options, buf, offset) {
|
|
28885
|
+
if (native.randomUUID && true && !options) {
|
|
28886
|
+
return native.randomUUID();
|
|
28887
|
+
}
|
|
28888
|
+
|
|
28889
|
+
options = options || {};
|
|
28890
|
+
const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
|
28891
|
+
|
|
28892
|
+
rnds[6] = rnds[6] & 0x0f | 0x40;
|
|
28893
|
+
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
|
|
28894
|
+
|
|
28895
|
+
return unsafeStringify(rnds);
|
|
28896
|
+
}
|
|
28897
|
+
|
|
28898
|
+
/**
|
|
28899
|
+
* 构建签名字符串
|
|
28900
|
+
*/
|
|
28901
|
+
function buildStringToSign(appKey, nonce, timestamp, secretKey) {
|
|
28902
|
+
return `${appKey}&${nonce}&${timestamp}&${secretKey}`;
|
|
28903
|
+
}
|
|
28904
|
+
/**
|
|
28905
|
+
* 生成 MD5 签名
|
|
28906
|
+
*/
|
|
28907
|
+
function generateSignature(plainText) {
|
|
28908
|
+
return crypto$1.createHash('md5').update(plainText).digest('hex');
|
|
28909
|
+
}
|
|
28910
|
+
/**
|
|
28911
|
+
* 生成客户端签名信息
|
|
28912
|
+
* @param appKey AppKey
|
|
28913
|
+
* @param secretKey SecretKey
|
|
28914
|
+
* @returns 签名信息
|
|
28915
|
+
*/
|
|
28916
|
+
function generateClientSignature(appKey, secretKey) {
|
|
28917
|
+
const timestamp = Math.floor(Date.now() / 1000).toString();
|
|
28918
|
+
const nonce = v4();
|
|
28919
|
+
const plainText = buildStringToSign(appKey, nonce, timestamp, secretKey);
|
|
28920
|
+
const signature = generateSignature(plainText);
|
|
28921
|
+
return {
|
|
28922
|
+
appKey,
|
|
28923
|
+
timestamp,
|
|
28924
|
+
nonce,
|
|
28925
|
+
signature,
|
|
28926
|
+
};
|
|
28927
|
+
}
|
|
28928
|
+
/**
|
|
28929
|
+
* 生成基础认证头
|
|
28930
|
+
* @param ak AppKey
|
|
28931
|
+
* @param sk SecretKey
|
|
28932
|
+
* @returns 基础认证头
|
|
28933
|
+
*/
|
|
28934
|
+
function generateBaseHeaders(ak, sk) {
|
|
28935
|
+
const { timestamp, signature, nonce } = generateClientSignature(ak, sk);
|
|
28936
|
+
return {
|
|
28937
|
+
'Content-Type': 'application/json',
|
|
28938
|
+
'x-appKey': ak,
|
|
28939
|
+
'x-timestamp': timestamp,
|
|
28940
|
+
'x-nonce': nonce,
|
|
28941
|
+
'x-signature': signature,
|
|
28942
|
+
};
|
|
28943
|
+
}
|
|
28944
|
+
/**
|
|
28945
|
+
* 获取租户的 signInfo
|
|
28946
|
+
* @param options 服务器选项
|
|
28947
|
+
* @param baseHeaders 基础认证头
|
|
28948
|
+
* @returns x-signInfo 值
|
|
28949
|
+
*/
|
|
28950
|
+
async function fetchSignInfo(options, baseHeaders) {
|
|
28951
|
+
const tenantName = options.tenantName || 'defaulttenant';
|
|
28952
|
+
const userName = tenantName === 'defaulttenant' ? 'admin' : `${tenantName}-admin`;
|
|
28953
|
+
const data = {
|
|
28954
|
+
tenantName,
|
|
28955
|
+
userName,
|
|
28956
|
+
source: 'Normal',
|
|
28957
|
+
};
|
|
28958
|
+
const url = `${options.serverBaseURL}/openapi/v3/auth/getSignInfo`;
|
|
28959
|
+
try {
|
|
28960
|
+
const tempAxios = axios.create({
|
|
28961
|
+
headers: baseHeaders,
|
|
28962
|
+
timeout: 120000,
|
|
28963
|
+
});
|
|
28964
|
+
const response = await tempAxios.post(url, data);
|
|
28965
|
+
return response?.data?.result || null;
|
|
28966
|
+
}
|
|
28967
|
+
catch (error) {
|
|
28968
|
+
console.error('Error fetching sign info:', error.response?.data);
|
|
28969
|
+
return null;
|
|
28970
|
+
}
|
|
28971
|
+
}
|
|
28972
|
+
/**
|
|
28973
|
+
* 生成完整的认证头(包含 x-signInfo)
|
|
28974
|
+
* @param options 服务器选项
|
|
28975
|
+
* @returns 完整的认证头
|
|
28976
|
+
*/
|
|
28977
|
+
async function generateCompleteHeaders(options) {
|
|
28978
|
+
const headers = {
|
|
28979
|
+
'Content-Type': 'application/json',
|
|
28980
|
+
};
|
|
28981
|
+
const OPENAPI_AK = options.OPENAPI_AK || process.env.LCAP_OPENAPI_AK;
|
|
28982
|
+
const OPENAPI_SK = options.OPENAPI_SK || process.env.LCAP_OPENAPI_SK;
|
|
28983
|
+
// 如果没有提供 ak 和 sk,返回基础 headers
|
|
28984
|
+
if (!OPENAPI_AK || !OPENAPI_SK) {
|
|
28985
|
+
throw new Error(`配置了 useOPENAPI,但没有提供 OPENAPI_AK 和 OPENAPI_SK:
|
|
28986
|
+
- 可取消配置 useOPENAPI
|
|
28987
|
+
- 在 nasl.config.json 中配置 OPENAPI_AK 和 OPENAPI_SK,或者在环境变量中配置 LCAP_OPENAPI_AK 和 LCAP_OPENAPI_SK`);
|
|
28988
|
+
}
|
|
28989
|
+
// 生成基础认证头
|
|
28990
|
+
const baseHeaders = generateBaseHeaders(OPENAPI_AK, OPENAPI_SK);
|
|
28991
|
+
Object.assign(headers, baseHeaders);
|
|
28992
|
+
// 获取 signInfo
|
|
28993
|
+
const signInfo = await fetchSignInfo(options, headers);
|
|
28994
|
+
if (signInfo) {
|
|
28995
|
+
headers['x-signInfo'] = signInfo;
|
|
28996
|
+
}
|
|
28997
|
+
return headers;
|
|
28998
|
+
}
|
|
28999
|
+
|
|
29000
|
+
/**
|
|
29001
|
+
* 创建 Axios 实例
|
|
29002
|
+
* @param options 服务器选项,包含认证信息
|
|
29003
|
+
* @returns Axios 实例
|
|
29004
|
+
*/
|
|
29005
|
+
async function createAxios(options) {
|
|
29006
|
+
// 如果需要鉴权,拼接 /openapi/v3/nasl;否则使用原始 URL
|
|
29007
|
+
const serverBaseURL = new URL(options.serverBaseURL).origin;
|
|
29008
|
+
const useOPENAPI = options.useOPENAPI || process.env.USE_LCAP_OPENAPI === 'true';
|
|
29009
|
+
const baseURL = useOPENAPI ? `${serverBaseURL}/openapi/v3/nasl` : `${serverBaseURL}/api/v1/nasl`;
|
|
29010
|
+
// 如果需要鉴权,生成完整的认证头;否则只使用基础 headers
|
|
29011
|
+
const headers = useOPENAPI ? await generateCompleteHeaders(options) : { 'Content-Type': 'application/json' };
|
|
29012
|
+
console.log('本次服务调用方为:', baseURL);
|
|
29013
|
+
const instance = axios.create({
|
|
28844
29014
|
baseURL,
|
|
28845
|
-
headers
|
|
28846
|
-
'Content-Type': 'application/json',
|
|
28847
|
-
},
|
|
29015
|
+
headers,
|
|
28848
29016
|
timeout: 120000,
|
|
28849
29017
|
});
|
|
29018
|
+
const oldPost = instance.post;
|
|
29019
|
+
instance.post = async (url, data, config) => {
|
|
29020
|
+
return oldPost(url, data, config).then((res) => {
|
|
29021
|
+
const data = res.data;
|
|
29022
|
+
if (data.code !== 200)
|
|
29023
|
+
throw new Error(JSON.stringify(data));
|
|
29024
|
+
return res;
|
|
29025
|
+
}).catch((err) => {
|
|
29026
|
+
// console.log(err.response ? err.response.data : err);
|
|
29027
|
+
if (err.response) {
|
|
29028
|
+
throw new Error(JSON.stringify(err.response.data));
|
|
29029
|
+
}
|
|
29030
|
+
else {
|
|
29031
|
+
throw err;
|
|
29032
|
+
}
|
|
29033
|
+
});
|
|
29034
|
+
};
|
|
29035
|
+
return instance;
|
|
28850
29036
|
}
|
|
28851
29037
|
|
|
28852
29038
|
function truncate(str, maxLength) {
|
|
@@ -28860,13 +29046,11 @@ function truncate(str, maxLength) {
|
|
|
28860
29046
|
async function compileApi(fullNaturalTS, options) {
|
|
28861
29047
|
// 这里需要调用实际的编译服务接口
|
|
28862
29048
|
// 示例实现:
|
|
28863
|
-
const axios = createAxios(options
|
|
29049
|
+
const axios = await createAxios(options);
|
|
28864
29050
|
const res = await axios.post(`/compile/tsx?ideVersion=${options.ideVersion}&needAnnotation=true`, fullNaturalTS, {
|
|
28865
29051
|
headers: { 'Content-Type': 'text/plain' },
|
|
28866
29052
|
});
|
|
28867
29053
|
const data = res.data;
|
|
28868
|
-
if (data.code !== 200)
|
|
28869
|
-
throw new Error(data.message);
|
|
28870
29054
|
const { bundle } = data.result;
|
|
28871
29055
|
const fileMap = bundle.frontendBundle.files;
|
|
28872
29056
|
const files = Object.keys(fileMap).map((key) => {
|
|
@@ -28894,7 +29078,7 @@ window.backendApp = app;
|
|
|
28894
29078
|
* TODO: 实现具体的 API 调用逻辑
|
|
28895
29079
|
*/
|
|
28896
29080
|
async function checkApi(fullNaturalTS, options) {
|
|
28897
|
-
const axios = createAxios(options
|
|
29081
|
+
const axios = await createAxios(options);
|
|
28898
29082
|
const res = await axios.post(`/check/tsx?ideVersion=${options.ideVersion}`, fullNaturalTS, {
|
|
28899
29083
|
headers: { 'Content-Type': 'text/plain' },
|
|
28900
29084
|
});
|
|
@@ -28912,7 +29096,7 @@ async function checkApi(fullNaturalTS, options) {
|
|
|
28912
29096
|
async function createAppSyncApi(fullNaturalTS, options) {
|
|
28913
29097
|
const url = new URL(options.serverBaseURL);
|
|
28914
29098
|
const origin = url.origin + '/app-ai-creator';
|
|
28915
|
-
const axios = createAxios(origin);
|
|
29099
|
+
const axios = await createAxios({ serverBaseURL: origin});
|
|
28916
29100
|
try {
|
|
28917
29101
|
const res = await axios.post('/api/createAppSync', {
|
|
28918
29102
|
fullNaturalTS,
|
|
@@ -37795,10 +37979,7 @@ async function compile(entry, options) {
|
|
|
37795
37979
|
logger.info('正在调用编译服务...');
|
|
37796
37980
|
try {
|
|
37797
37981
|
const fullNaturalTS = composeToString(collectedFiles);
|
|
37798
|
-
const outputFiles = await compileApi(fullNaturalTS,
|
|
37799
|
-
serverBaseURL: config.serverBaseURL,
|
|
37800
|
-
ideVersion: config.ideVersion,
|
|
37801
|
-
});
|
|
37982
|
+
const outputFiles = await compileApi(fullNaturalTS, config);
|
|
37802
37983
|
logger.success('编译成功!');
|
|
37803
37984
|
// 写入输出文件
|
|
37804
37985
|
for (const file of outputFiles) {
|
|
@@ -37845,10 +38026,7 @@ async function check(entry, options) {
|
|
|
37845
38026
|
result = error.message.trim();
|
|
37846
38027
|
}
|
|
37847
38028
|
if (!result && fullNaturalTS) {
|
|
37848
|
-
result = (await checkApi(fullNaturalTS,
|
|
37849
|
-
serverBaseURL: config.serverBaseURL,
|
|
37850
|
-
ideVersion: config.ideVersion,
|
|
37851
|
-
})).trim();
|
|
38029
|
+
result = (await checkApi(fullNaturalTS, config)).trim();
|
|
37852
38030
|
}
|
|
37853
38031
|
const checkResult = {
|
|
37854
38032
|
success: !result,
|
|
@@ -38188,15 +38366,13 @@ async function createAppInIde(entry, options) {
|
|
|
38188
38366
|
* 编译 NASL 代码
|
|
38189
38367
|
* TODO: 实现具体的 API 调用逻辑
|
|
38190
38368
|
*/
|
|
38191
|
-
async function transformJson2FilesApi(
|
|
38369
|
+
async function transformJson2FilesApi(json, options) {
|
|
38192
38370
|
// 示例实现:
|
|
38193
|
-
const axios = createAxios(options
|
|
38194
|
-
const res = await axios.post(`/transform/json2files?ideVersion=${options.ideVersion}`,
|
|
38195
|
-
headers: { 'Content-Type': '
|
|
38371
|
+
const axios = await createAxios(options);
|
|
38372
|
+
const res = await axios.post(`/transform/json2files?ideVersion=${options.ideVersion}`, json, {
|
|
38373
|
+
headers: { 'Content-Type': 'application/json' },
|
|
38196
38374
|
});
|
|
38197
38375
|
const data = res.data;
|
|
38198
|
-
if (data.code !== 200)
|
|
38199
|
-
throw new Error(data.message);
|
|
38200
38376
|
return data.result;
|
|
38201
38377
|
}
|
|
38202
38378
|
|
|
@@ -38236,14 +38412,19 @@ const transformFns = {
|
|
|
38236
38412
|
const projectRoot = getProjectRoot();
|
|
38237
38413
|
logger.info(`项目根目录: ${projectRoot}`);
|
|
38238
38414
|
logger.info(`源代码目录: ${config.srcDir}`);
|
|
38415
|
+
if (!libExports.existsSync(config.srcDir)) {
|
|
38416
|
+
logger.error(`当前目录下 ${config.srcDir} 目录不存在,请先创建`);
|
|
38417
|
+
logger.exit(1);
|
|
38418
|
+
}
|
|
38239
38419
|
let jsonContent = '';
|
|
38240
38420
|
if (!entry) {
|
|
38241
38421
|
logger.warn('没有指定 JSON 文件路径,按照默认 IDE 版本的基础模板转换');
|
|
38242
38422
|
}
|
|
38243
38423
|
else {
|
|
38244
38424
|
jsonContent = libExports.readFileSync(entry, 'utf-8');
|
|
38425
|
+
logger.info(`读取到 JSON 文件: ${entry}`);
|
|
38245
38426
|
}
|
|
38246
|
-
const files = await transformJson2FilesApi(jsonContent, {
|
|
38427
|
+
const files = await transformJson2FilesApi(jsonContent ? JSON.parse(jsonContent) : {}, {
|
|
38247
38428
|
serverBaseURL: config.serverBaseURL,
|
|
38248
38429
|
ideVersion: config.ideVersion,
|
|
38249
38430
|
});
|
|
@@ -38257,25 +38438,8 @@ const transformFns = {
|
|
|
38257
38438
|
* 将 src 中的文件转换成一个 JSON
|
|
38258
38439
|
*/
|
|
38259
38440
|
async files2json(entry, options) {
|
|
38260
|
-
|
|
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}`);
|
|
38441
|
+
options?.logger || defaultLogger;
|
|
38442
|
+
throw new Error('files2json 转换类型尚未实现');
|
|
38279
38443
|
},
|
|
38280
38444
|
};
|
|
38281
38445
|
/**
|
|
@@ -38292,11 +38456,27 @@ async function transform(transformType, entry, options) {
|
|
|
38292
38456
|
await transformFn(entry, options);
|
|
38293
38457
|
}
|
|
38294
38458
|
|
|
38295
|
-
var version = "0.1.
|
|
38459
|
+
var version = "0.1.17";
|
|
38296
38460
|
var pkg = {
|
|
38297
38461
|
version: version};
|
|
38298
38462
|
|
|
38299
38463
|
const program = new Command();
|
|
38464
|
+
/**
|
|
38465
|
+
* 使用 readline 询问用户确认
|
|
38466
|
+
*/
|
|
38467
|
+
function askForConfirmation(question) {
|
|
38468
|
+
const rl = readline.createInterface({
|
|
38469
|
+
input: process.stdin,
|
|
38470
|
+
output: process.stdout,
|
|
38471
|
+
});
|
|
38472
|
+
return new Promise((resolve) => {
|
|
38473
|
+
rl.question(question, (answer) => {
|
|
38474
|
+
rl.close();
|
|
38475
|
+
const normalizedAnswer = answer.trim().toLowerCase();
|
|
38476
|
+
resolve(normalizedAnswer === 'y' || normalizedAnswer === 'yes' || normalizedAnswer === '是');
|
|
38477
|
+
});
|
|
38478
|
+
});
|
|
38479
|
+
}
|
|
38300
38480
|
const entryDescription = `是相对于项目根目录的路径,支持 glob 模式(注意要用引号包裹),例如:
|
|
38301
38481
|
- src/app.enums.Status.ts 支持具体文件
|
|
38302
38482
|
- "src/app.enums.*.ts" 表示所有枚举
|
|
@@ -38379,8 +38559,20 @@ program
|
|
|
38379
38559
|
.command('create-app-in-ide [entry]')
|
|
38380
38560
|
.description('在 IDE 中创建应用')
|
|
38381
38561
|
.option('-v, --verbose', '显示详细信息,如依赖分析树')
|
|
38562
|
+
.option('-q, --quiet', '不询问问题')
|
|
38382
38563
|
.action(async (entry, options) => {
|
|
38383
38564
|
try {
|
|
38565
|
+
// 如果不是 quiet 模式,询问用户确认
|
|
38566
|
+
if (!options?.quiet) {
|
|
38567
|
+
defaultLogger.newLine();
|
|
38568
|
+
defaultLogger.info('即将在 IDE 中创建新的应用,此操作将调用远程接口。');
|
|
38569
|
+
const confirmed = await askForConfirmation('请确认是否继续?(y/N): ');
|
|
38570
|
+
if (!confirmed) {
|
|
38571
|
+
defaultLogger.info('已取消操作');
|
|
38572
|
+
process.exit(0);
|
|
38573
|
+
}
|
|
38574
|
+
defaultLogger.newLine();
|
|
38575
|
+
}
|
|
38384
38576
|
await createAppInIde(entry, options);
|
|
38385
38577
|
}
|
|
38386
38578
|
catch (error) {
|
|
@@ -38390,7 +38582,7 @@ program
|
|
|
38390
38582
|
});
|
|
38391
38583
|
program
|
|
38392
38584
|
.command('transform <transformType> [entry]')
|
|
38393
|
-
.description('转换文件格式\n transformType: files2full (将 src 文件组合成 fullNaturalTS), json2files (将 JSON
|
|
38585
|
+
.description('转换文件格式\n transformType: files2full (将 src 文件组合成 fullNaturalTS), json2files (将 JSON 转换为文件), files2json (将 src 文件转换为 JSON)')
|
|
38394
38586
|
.option('-o, --output <outputPath>', '指定输出路径')
|
|
38395
38587
|
.option('-v, --verbose', '显示详细信息,如依赖分析树')
|
|
38396
38588
|
.action(async (transformType, entry, options) => {
|