@nasl/cli 0.1.17 → 0.1.18

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/README.md CHANGED
@@ -7,12 +7,12 @@ NASL 语言的命令行工具,提供编译、检查、开发服务等功能。
7
7
  ## 安装
8
8
 
9
9
  ```bash
10
- pnpm install -g @nasl/cli
10
+ npm install -g @nasl/cli
11
11
  ```
12
12
 
13
13
  ## 使用
14
14
 
15
- ### 初始化配置
15
+ ### 初始化配置(nasl init)
16
16
 
17
17
  ```bash
18
18
  nasl init
@@ -22,16 +22,15 @@ nasl init
22
22
 
23
23
  ```json
24
24
  {
25
- "serverBaseURL": "https://nasl.lcap.163yun.com/api/v1/nasl", // NASL 编译服务的基础 URL
25
+ "serverBaseURL": "https://nasl.lcap.163yun.com", // NASL 编译服务的基础 URL
26
26
  "representation": "NaturalTS", // NASL 语言的表示
27
27
  "namespaceResolution": "filename-as-namespace", // 命名空间解析策略
28
- "ideVersion": "4.1", // IDE 版本
28
+ "ideVersion": "4.4", // IDE 版本
29
29
  "srcDir": "src", // 源代码目录
30
30
  "outDir": "out" // 输出目录
31
31
  }
32
32
  ```
33
33
 
34
-
35
34
  ### 入口文件说明
36
35
 
37
36
  下面的命令中均支持 [entry] 参数,表示入口文件:
@@ -47,7 +46,7 @@ nasl init
47
46
  - 会自动进行依赖分析,收集所有依赖的文件
48
47
  - 依赖的页面文件(.tsx)不会继续进行依赖分析,而是直接提取签名,以提高性能
49
48
 
50
- ### 编译 NASL 代码
49
+ ### 编译 NASL 代码(nasl compile 或 naslc)
51
50
 
52
51
  ```bash
53
52
  # 编译整个 src 目录
@@ -63,7 +62,7 @@ naslc "src/app.logics.*.ts"
63
62
  naslc "src/*.tsx"
64
63
  ```
65
64
 
66
- ### 检查 NASL 代码
65
+ ### 检查 NASL 代码(nasl check)
67
66
 
68
67
  ```bash
69
68
  # 检查整个 src 目录
@@ -77,7 +76,7 @@ nasl check "src/app.logics.*.ts"
77
76
  nasl check "src/*.tsx"
78
77
  ```
79
78
 
80
- ### 依赖分析
79
+ ### 依赖分析(nasl dep)
81
80
 
82
81
  建议指定入口文件,否则会扫描整个 src 目录,输出量较大。
83
82
 
@@ -89,13 +88,19 @@ nasl dep "src/*.tsx"
89
88
  nasl dep
90
89
  ```
91
90
 
92
- ### 启动开发服务
91
+ ### 启动开发服务(nasl dev)
93
92
 
94
93
  ```bash
95
94
  nasl dev
96
95
  ```
97
96
 
98
- 启动开发服务后,默认可以访问 http://localhost:3100 查看预览效果。
97
+ 启动开发服务后,默认访问 http://localhost:3100 查看预览效果。
98
+
99
+ 可以用 --port 和 --host 更换端口号和主机名。
100
+
101
+ ```bash
102
+ nasl dev --port 4900 --host 0.0.0.0
103
+ ```
99
104
 
100
105
  dev 进程始终保持运行,规则如下:
101
106
 
@@ -109,7 +114,104 @@ dev 进程始终保持运行,规则如下:
109
114
  2. src 被创建:自动编译生成 out 目录
110
115
  3. src 被删除: 使用缓存的 out 目录
111
116
 
112
- ## 开发 CLI 工具
117
+ ### 构建项目(nasl build)
118
+
119
+ 与 nasl dev 对应,构建成最终用于浏览器的 dist 产物。
120
+
121
+ ```bash
122
+ # 使用生产模式构建(默认)
123
+ nasl build
124
+
125
+ # 使用开发模式构建
126
+ nasl build --mode development
127
+
128
+ # 构建指定入口文件及其依赖
129
+ nasl build src/app.frontendTypes.pc.frontends.pc.views.dashboard.tsx
130
+ ```
131
+
132
+ ### 转换文件格式(nasl transform)
133
+
134
+ ```bash
135
+ # files2full: 将 src 中的文件组合成 fullNaturalTS
136
+ nasl transform files2full [entry] --output [outputPath]
137
+ # 默认输出到 ./full-natural.ts
138
+
139
+ # json2files: 将 JSON 文件转换成 src 的 files
140
+ nasl transform json2files [jsonFile] --output [outputPath]
141
+ # 如果不指定 jsonFile,将按照默认 IDE 版本的基础模板转换
142
+
143
+ # files2json: 将 src 中的文件转换成一个 JSON(待实现)
144
+ nasl transform files2json [entry] --output [outputPath]
145
+ # 默认输出到 ./files.json
146
+ ```
147
+
148
+ ### 在 IDE 中直接创建应用(nasl create-app-in-ide)
149
+
150
+ **注意**:目前该命令不支持 useOPENAPI 模式,只在测试环境使用。
151
+
152
+ ```bash
153
+ # 会询问确认(默认)
154
+ nasl create-app-in-ide [entry]
155
+
156
+ # 跳过确认,直接执行
157
+ nasl create-app-in-ide [entry] --quiet
158
+
159
+ # 显示详细信息
160
+ nasl create-app-in-ide [entry] --verbose
161
+ ```
162
+
163
+ 此命令会将当前项目的 NASL 代码上传到远程服务,在 IDE 中创建新的应用。默认会询问用户确认,使用 `--quiet` 选项可以跳过确认。
164
+
165
+ ## 环境变量配置
166
+
167
+ 除了在 `nasl.config.json` 中配置外,也可以通过环境变量来配置部分选项。环境变量的优先级低于配置文件。
168
+
169
+ ### 支持的环境变量
170
+
171
+ - `NASL_IDE_VERSION`: IDE 版本号,对应配置`ideVersion`字段
172
+ ```bash
173
+ export NASL_IDE_VERSION=4.4
174
+ ```
175
+
176
+ - `NASL_SERVER_BASE_URL`: NASL 编译服务的基础 URL,对应配置`serverBaseURL`字段
177
+ ```bash
178
+ export NASL_SERVER_BASE_URL=https://nasl.lcap.163yun.com
179
+ ```
180
+
181
+ - `USE_LCAP_OPENAPI`: 是否使用 OpenAPI 方式调用(值为 `'true'` 时启用),对应配置`useOPENAPI`字段
182
+ ```bash
183
+ export USE_LCAP_OPENAPI=true
184
+ ```
185
+
186
+ - `LCAP_OPENAPI_AK`: LCAP OpenAPI Access Key(使用 OpenAPI 时必需),对应配置`OPENAPI_AK`字段
187
+ ```bash
188
+ export LCAP_OPENAPI_AK=your_access_key
189
+ ```
190
+
191
+ - `LCAP_OPENAPI_SK`: LCAP OpenAPI Secret Key(使用 OpenAPI 时必需),对应配置`OPENAPI_SK`字段
192
+ ```bash
193
+ export LCAP_OPENAPI_SK=your_secret_key
194
+ ```
195
+
196
+ ### 配置文件示例(包含 OpenAPI 配置)
197
+
198
+ ```json
199
+ {
200
+ "serverBaseURL": "https://sometenant.codewave.163.com",
201
+ "representation": "NaturalTS",
202
+ "namespaceResolution": "filename-as-namespace",
203
+ "ideVersion": "4.4",
204
+ "srcDir": "src",
205
+ "outDir": "out",
206
+ "useOPENAPI": true,
207
+ "OPENAPI_AK": "your_access_key",
208
+ "OPENAPI_SK": "your_secret_key"
209
+ }
210
+ ```
211
+
212
+ 注意:如果配置了 `useOPENAPI: true`,则必须同时配置 `OPENAPI_AK` 和 `OPENAPI_SK`(可在配置文件中配置,或通过环境变量 `LCAP_OPENAPI_AK` 和 `LCAP_OPENAPI_SK` 配置)。
213
+
214
+ ## DEVELOPMENT
113
215
 
114
216
  ```bash
115
217
  # 安装依赖
package/dist/bin/nasl.mjs CHANGED
@@ -3,8 +3,8 @@
3
3
  import require$$0$1, { EventEmitter } from 'events';
4
4
  import require$$1, { spawn, spawnSync } from 'child_process';
5
5
  import * as sysPath from 'path';
6
- import sysPath__default from 'path';
7
- import require$$0$2, { unwatchFile, watchFile, watch as watch$1, stat as stat$3 } from 'fs';
6
+ import sysPath__default, { join } from 'path';
7
+ import require$$0$2, { promises, unwatchFile, watchFile, watch as watch$1, stat as stat$3 } from 'fs';
8
8
  import require$$4 from 'process';
9
9
  import require$$0$3 from 'constants';
10
10
  import stream$4, { Readable } from 'stream';
@@ -15,14 +15,14 @@ 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 crypto$1 from 'crypto';
18
+ import crypto$1, { createHash } from 'crypto';
19
19
  import http2 from 'http2';
20
20
  import zlib from 'zlib';
21
21
  import * as readline from 'readline';
22
22
  import { realpath as realpath$1, stat as stat$2, lstat as lstat$1, open, readdir as readdir$1 } from 'fs/promises';
23
23
  import { lstat, stat as stat$1, readdir, realpath } from 'node:fs/promises';
24
24
  import { Readable as Readable$1 } from 'node:stream';
25
- import { resolve, join, relative, sep } from 'node:path';
25
+ import { resolve, join as join$1, relative, sep } from 'node:path';
26
26
 
27
27
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
28
28
 
@@ -8338,10 +8338,39 @@ function loadConfig(configDir) {
8338
8338
  const content = libExports.readFileSync(configPath, 'utf-8');
8339
8339
  const config = JSON.parse(content);
8340
8340
  // 验证必需字段
8341
- if (!config.serverBaseURL || !config.ideVersion || !config.srcDir || !config.outDir) {
8342
- defaultLogger.error('配置文件格式不正确,缺少必需字段');
8341
+ if (!config.srcDir || !config.outDir) {
8342
+ defaultLogger.error('配置文件格式不正确,缺少必需的 srcDir 或 outDir 字段');
8343
8343
  return defaultLogger.exit(1);
8344
8344
  }
8345
+ if (!config.ideVersion) {
8346
+ config.ideVersion = process.env.NASL_IDE_VERSION || '';
8347
+ if (!config.ideVersion) {
8348
+ defaultLogger.error('缺少配置 ideVersion,请在配置文件中添加,或在环境变量中配置 NASL_IDE_VERSION');
8349
+ return defaultLogger.exit(1);
8350
+ }
8351
+ }
8352
+ if (!config.serverBaseURL) {
8353
+ config.serverBaseURL = process.env.NASL_SERVER_BASE_URL || '';
8354
+ if (!config.serverBaseURL) {
8355
+ defaultLogger.error('缺少配置 serverBaseURL,请在配置文件中添加,或在环境变量中配置 NASL_SERVER_BASE_URL');
8356
+ return defaultLogger.exit(1);
8357
+ }
8358
+ }
8359
+ if (!config.useOPENAPI)
8360
+ config.useOPENAPI = process.env.USE_LCAP_OPENAPI === 'true';
8361
+ if (!config.OPENAPI_AK)
8362
+ config.OPENAPI_AK = process.env.LCAP_OPENAPI_AK;
8363
+ if (!config.OPENAPI_SK)
8364
+ config.OPENAPI_SK = process.env.LCAP_OPENAPI_SK;
8365
+ if (config.useOPENAPI) {
8366
+ if (!config.OPENAPI_AK || !config.OPENAPI_SK) {
8367
+ defaultLogger.error(`配置了 useOPENAPI,但缺少配置 OPENAPI_AK 和 OPENAPI_SK:
8368
+ - 在 nasl.config.json 中配置 OPENAPI_AK 和 OPENAPI_SK,或者在环境变量中配置 LCAP_OPENAPI_AK 和 LCAP_OPENAPI_SK
8369
+ - 或将 useOPENAPI 配置为 false
8370
+ `);
8371
+ return defaultLogger.exit(1);
8372
+ }
8373
+ }
8345
8374
  return config;
8346
8375
  }
8347
8376
  catch (error) {
@@ -28895,18 +28924,99 @@ function v4(options, buf, offset) {
28895
28924
  return unsafeStringify(rnds);
28896
28925
  }
28897
28926
 
28927
+ function generateHash(params) {
28928
+ const hash = createHash('sha256');
28929
+ hash.update(JSON.stringify(params));
28930
+ return hash.digest('hex');
28931
+ }
28932
+ async function getCachePathWithTimestamp(hash) {
28933
+ const cacheDir = join(process.cwd(), '.cache');
28934
+ await promises.mkdir(cacheDir, { recursive: true });
28935
+ return join(cacheDir, `${hash}_${Date.now()}.json`);
28936
+ }
28898
28937
  /**
28899
- * 构建签名字符串
28938
+ * 查找指定 hash 的有效缓存文件
28939
+ * @param hash 缓存标识
28940
+ * @param ttl 缓存有效期(毫秒)
28941
+ * @returns 缓存文件路径和缓存内容,如果没有有效缓存则返回 null
28900
28942
  */
28901
- function buildStringToSign(appKey, nonce, timestamp, secretKey) {
28902
- return `${appKey}&${nonce}&${timestamp}&${secretKey}`;
28943
+ async function findValidCache(hash, ttl) {
28944
+ const cacheDir = join(process.cwd(), '.cache');
28945
+ try {
28946
+ await promises.mkdir(cacheDir, { recursive: true });
28947
+ const files = await promises.readdir(cacheDir);
28948
+ const now = Date.now();
28949
+ // 查找所有匹配的缓存文件
28950
+ const matchingFiles = files
28951
+ .filter((file) => file.startsWith(`${hash}_`) && file.endsWith('.json'))
28952
+ .map((file) => {
28953
+ const match = file.match(/_(\d+)\.json$/);
28954
+ if (!match)
28955
+ return null;
28956
+ const timestamp = parseInt(match[1], 10);
28957
+ return {
28958
+ path: join(cacheDir, file),
28959
+ timestamp,
28960
+ isExpired: now - timestamp > ttl,
28961
+ };
28962
+ })
28963
+ .filter((item) => item !== null);
28964
+ // 删除过期的缓存文件
28965
+ const expiredFiles = matchingFiles.filter((item) => item.isExpired);
28966
+ await Promise.all(expiredFiles.map((item) => promises.unlink(item.path).catch(() => { })));
28967
+ // 查找有效的缓存文件(按时间戳降序排序,获取最新的)
28968
+ const validFiles = matchingFiles.filter((item) => !item.isExpired).sort((a, b) => b.timestamp - a.timestamp);
28969
+ if (validFiles.length > 0) {
28970
+ const cacheFile = validFiles[0];
28971
+ const cacheContent = await promises.readFile(cacheFile.path, 'utf-8');
28972
+ const cachedResult = JSON.parse(cacheContent);
28973
+ return { path: cacheFile.path, data: cachedResult };
28974
+ }
28975
+ return null;
28976
+ }
28977
+ catch (error) {
28978
+ return null;
28979
+ }
28903
28980
  }
28904
28981
  /**
28905
- * 生成 MD5 签名
28982
+ * 高阶函数,为异步函数添加带时间戳的缓存功能
28983
+ * @param fn 需要添加缓存的函数
28984
+ * @param ttl 缓存有效期(毫秒),默认 1 小时
28985
+ * @param getCacheKey 可选的自定义缓存 key 生成函数,如果不提供则使用整个 params
28986
+ * @returns 带缓存的函数版本
28906
28987
  */
28907
- function generateSignature(plainText) {
28908
- return crypto$1.createHash('md5').update(plainText).digest('hex');
28988
+ function cachableWithTTL(fn, ttl = 3600 * 1000, // 默认 1 小时
28989
+ getCacheKey) {
28990
+ return async (params, extraParams) => {
28991
+ const functionName = fn.name;
28992
+ const logPrefix = functionName ? `[${functionName}]` : '[cachableWithTTL]';
28993
+ // 检查是否启用缓存
28994
+ if (process.env.NO_AI_CACHE) {
28995
+ return fn(params, extraParams);
28996
+ }
28997
+ // 使用自定义的 getCacheKey 或默认使用整个 params
28998
+ const cacheKey = getCacheKey ? getCacheKey(params) : params;
28999
+ const hash = generateHash(cacheKey);
29000
+ // 查找有效的缓存
29001
+ const validCache = await findValidCache(hash, ttl);
29002
+ if (validCache) {
29003
+ console.log(`${logPrefix} ✓ 使用缓存`);
29004
+ return validCache.data;
29005
+ }
29006
+ // 调用原函数
29007
+ const result = await fn(params, extraParams);
29008
+ // 保存结果到缓存(带时间戳)
29009
+ try {
29010
+ const cachePath = await getCachePathWithTimestamp(hash);
29011
+ await promises.writeFile(cachePath, JSON.stringify(result, null, 2), 'utf-8');
29012
+ }
29013
+ catch (error) {
29014
+ // 缓存写入失败,但不影响返回结果
29015
+ }
29016
+ return result;
29017
+ };
28909
29018
  }
29019
+
28910
29020
  /**
28911
29021
  * 生成客户端签名信息
28912
29022
  * @param appKey AppKey
@@ -28916,8 +29026,8 @@ function generateSignature(plainText) {
28916
29026
  function generateClientSignature(appKey, secretKey) {
28917
29027
  const timestamp = Math.floor(Date.now() / 1000).toString();
28918
29028
  const nonce = v4();
28919
- const plainText = buildStringToSign(appKey, nonce, timestamp, secretKey);
28920
- const signature = generateSignature(plainText);
29029
+ const plainText = `${appKey}&${nonce}&${timestamp}&${secretKey}`;
29030
+ const signature = crypto$1.createHash('md5').update(plainText).digest('hex');
28921
29031
  return {
28922
29032
  appKey,
28923
29033
  timestamp,
@@ -28942,12 +29052,12 @@ function generateBaseHeaders(ak, sk) {
28942
29052
  };
28943
29053
  }
28944
29054
  /**
28945
- * 获取租户的 signInfo
29055
+ * 获取租户的 signInfo(内部实现)
28946
29056
  * @param options 服务器选项
28947
29057
  * @param baseHeaders 基础认证头
28948
29058
  * @returns x-signInfo 值
28949
29059
  */
28950
- async function fetchSignInfo(options, baseHeaders) {
29060
+ async function _fetchSignInfo({ options, baseHeaders }) {
28951
29061
  const tenantName = options.tenantName || 'defaulttenant';
28952
29062
  const userName = tenantName === 'defaulttenant' ? 'admin' : `${tenantName}-admin`;
28953
29063
  const data = {
@@ -28969,6 +29079,14 @@ async function fetchSignInfo(options, baseHeaders) {
28969
29079
  return null;
28970
29080
  }
28971
29081
  }
29082
+ /**
29083
+ * 获取租户的 signInfo(带缓存,1 小时过期)
29084
+ * @param options 服务器选项
29085
+ * @param baseHeaders 基础认证头
29086
+ * @returns x-signInfo 值
29087
+ */
29088
+ const fetchSignInfo = cachableWithTTL(_fetchSignInfo, 3600 * 1000, // 1 小时
29089
+ (params) => params.options);
28972
29090
  /**
28973
29091
  * 生成完整的认证头(包含 x-signInfo)
28974
29092
  * @param options 服务器选项
@@ -28978,19 +29096,18 @@ async function generateCompleteHeaders(options) {
28978
29096
  const headers = {
28979
29097
  'Content-Type': 'application/json',
28980
29098
  };
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
29099
  // 如果没有提供 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`);
29100
+ if (!options.OPENAPI_AK || !options.OPENAPI_SK) {
29101
+ throw new Error(`配置了 useOPENAPI,但缺少配置 OPENAPI_AK 和 OPENAPI_SK:
29102
+ - nasl.config.json 中配置 OPENAPI_AK 和 OPENAPI_SK,或者在环境变量中配置 LCAP_OPENAPI_AK 和 LCAP_OPENAPI_SK
29103
+ - 或将 useOPENAPI 配置为 false
29104
+ `);
28988
29105
  }
28989
29106
  // 生成基础认证头
28990
- const baseHeaders = generateBaseHeaders(OPENAPI_AK, OPENAPI_SK);
29107
+ const baseHeaders = generateBaseHeaders(options.OPENAPI_AK, options.OPENAPI_SK);
28991
29108
  Object.assign(headers, baseHeaders);
28992
29109
  // 获取 signInfo
28993
- const signInfo = await fetchSignInfo(options, headers);
29110
+ const signInfo = await fetchSignInfo({ options, baseHeaders: headers });
28994
29111
  if (signInfo) {
28995
29112
  headers['x-signInfo'] = signInfo;
28996
29113
  }
@@ -29005,10 +29122,9 @@ async function generateCompleteHeaders(options) {
29005
29122
  async function createAxios(options) {
29006
29123
  // 如果需要鉴权,拼接 /openapi/v3/nasl;否则使用原始 URL
29007
29124
  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`;
29125
+ const baseURL = options.useOPENAPI ? `${serverBaseURL}/openapi/v3/nasl` : `${serverBaseURL}/api/v1/nasl`;
29010
29126
  // 如果需要鉴权,生成完整的认证头;否则只使用基础 headers
29011
- const headers = useOPENAPI ? await generateCompleteHeaders(options) : { 'Content-Type': 'application/json' };
29127
+ const headers = options.useOPENAPI ? await generateCompleteHeaders(options) : { 'Content-Type': 'application/json' };
29012
29128
  console.log('本次服务调用方为:', baseURL);
29013
29129
  const instance = axios.create({
29014
29130
  baseURL,
@@ -29096,7 +29212,7 @@ async function checkApi(fullNaturalTS, options) {
29096
29212
  async function createAppSyncApi(fullNaturalTS, options) {
29097
29213
  const url = new URL(options.serverBaseURL);
29098
29214
  const origin = url.origin + '/app-ai-creator';
29099
- const axios = await createAxios({ serverBaseURL: origin});
29215
+ const axios = await createAxios({ serverBaseURL: origin, ideVersion: options.ideVersion });
29100
29216
  try {
29101
29217
  const res = await axios.post('/api/createAppSync', {
29102
29218
  fullNaturalTS,
@@ -38305,6 +38421,10 @@ async function createAppInIde(entry, options) {
38305
38421
  logger.info('开始创建应用在 IDE 中...');
38306
38422
  // 收集需要处理的文件
38307
38423
  const { collectedFiles, config } = await resolveNASLFiles(entry, logger, false, options?.verbose);
38424
+ if (config.useOPENAPI) {
38425
+ logger.error('create-app-in-ide 暂不支持 useOPENAPI 模式');
38426
+ logger.exit(1);
38427
+ }
38308
38428
  // 生成 fullNaturalTS
38309
38429
  logger.newLine();
38310
38430
  logger.info('正在生成 NaturalTS 代码...');
@@ -38424,10 +38544,7 @@ const transformFns = {
38424
38544
  jsonContent = libExports.readFileSync(entry, 'utf-8');
38425
38545
  logger.info(`读取到 JSON 文件: ${entry}`);
38426
38546
  }
38427
- const files = await transformJson2FilesApi(jsonContent ? JSON.parse(jsonContent) : {}, {
38428
- serverBaseURL: config.serverBaseURL,
38429
- ideVersion: config.ideVersion,
38430
- });
38547
+ const files = await transformJson2FilesApi(jsonContent ? JSON.parse(jsonContent) : {}, config);
38431
38548
  await Promise.all(files.map(async (file) => {
38432
38549
  const outputPath = sysPath.join(projectRoot, config.srcDir, file.path);
38433
38550
  await libExports.writeFile(outputPath, file.content);
@@ -38456,7 +38573,7 @@ async function transform(transformType, entry, options) {
38456
38573
  await transformFn(entry, options);
38457
38574
  }
38458
38575
 
38459
- var version = "0.1.17";
38576
+ var version = "0.1.18";
38460
38577
  var pkg = {
38461
38578
  version: version};
38462
38579
 
@@ -38760,7 +38877,7 @@ class ReaddirpStream extends Readable$1 {
38760
38877
  let entry;
38761
38878
  const basename = this._isDirent ? dirent.name : dirent;
38762
38879
  try {
38763
- const fullPath = resolve(join(path, basename));
38880
+ const fullPath = resolve(join$1(path, basename));
38764
38881
  entry = { path: relative(this._root, fullPath), fullPath, basename };
38765
38882
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
38766
38883
  }