@share-crm/sharedev-cli 0.0.4-rc.47-test.0 → 0.0.4-rc.48

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 (2) hide show
  1. package/dist/sharedev.js +194 -43
  2. package/package.json +4 -2
package/dist/sharedev.js CHANGED
@@ -13630,10 +13630,11 @@ Examples:
13630
13630
  await (0, pwc_command_ts_1.pwcPlaceholderCommand)(commandName);
13631
13631
  }));
13632
13632
  });
13633
- pwc.command('dev <filePath>')
13633
+ pwc.command('dev [filePath]')
13634
13634
  .description('Start the local Beefly development server (output name defaults to the PWC apiName)')
13635
13635
  .option('--name <name>', 'Override the output bundle name (default: PWC resource apiName)')
13636
13636
  .option('--port <port>', 'Dev server port (default: Beefly default, usually 8080)')
13637
+ .option('--all', 'Debug all local PWC resources (components + plugins) in one dev server')
13637
13638
  .action((0, command_ts_1.createCommandAction)('pwc', 'dev', runtimeContext, async ({ args, options, context }) => {
13638
13639
  await (0, pwc_command_ts_1.pwcDevCommand)(args[0], context, options);
13639
13640
  }));
@@ -17687,7 +17688,7 @@ exports.aplDebugCommand = aplDebugCommand;
17687
17688
  exports.aplPlaceholderCommand = aplPlaceholderCommand;
17688
17689
  const prompts_1 = __webpack_require__(29848);
17689
17690
  const logger_ts_1 = __webpack_require__(63333);
17690
- const diff2_ts_1 = __webpack_require__(54444);
17691
+ const diff_ts_1 = __webpack_require__(27804);
17691
17692
  const apl_service_ts_1 = __webpack_require__(76869);
17692
17693
  const apl_workspace_ts_1 = __webpack_require__(20527);
17693
17694
  async function aplListCommand(_context, options = {}) {
@@ -17919,7 +17920,7 @@ async function aplDiffCommand(apiName, context, options = {}) {
17919
17920
  : `remote@v${remoteVersion.actualVersion}`;
17920
17921
  }
17921
17922
  }
17922
- const diffResult = (0, diff2_ts_1.createLineDiff)(baseBody, target.localBody, {
17923
+ const diffResult = (0, diff_ts_1.createLineDiff)(baseBody, target.localBody, {
17923
17924
  oldFileName: `${target.apiName}.groovy`,
17924
17925
  newFileName: `${target.apiName}.groovy`,
17925
17926
  oldHeader: baseLabel,
@@ -17927,7 +17928,7 @@ async function aplDiffCommand(apiName, context, options = {}) {
17927
17928
  oldGitPath: `${target.apiName}.groovy`,
17928
17929
  newGitPath: `${target.apiName}.groovy`
17929
17930
  });
17930
- const summary = (0, diff2_ts_1.summarizeDiff)(diffResult);
17931
+ const summary = (0, diff_ts_1.summarizeDiff)(diffResult);
17931
17932
  if (!summary.changed) {
17932
17933
  logger_ts_1.loggerService.stopLoading();
17933
17934
  logger_ts_1.loggerService.success(`No changes for APL function ${target.apiName} (baseline: ${baseLabel}).`);
@@ -17935,7 +17936,7 @@ async function aplDiffCommand(apiName, context, options = {}) {
17935
17936
  }
17936
17937
  logger_ts_1.loggerService.stopLoading();
17937
17938
  logger_ts_1.loggerService.info(`APL diff ${target.apiName}: baseline=${baseLabel}, localVersion=${snapshot.version}, compareVersion=${actualVersion}, +${summary.additions} -${summary.deletions}`);
17938
- logger_ts_1.loggerService.printRaw((0, diff2_ts_1.renderUnifiedDiff)(diffResult));
17939
+ logger_ts_1.loggerService.printRaw((0, diff_ts_1.renderUnifiedDiff)(diffResult));
17939
17940
  }
17940
17941
  async function aplPushCommand(apiName, context, options = {}) {
17941
17942
  const pushComment = options.remark?.trim();
@@ -20702,7 +20703,7 @@ async function aplDiffNewService(target, options = {}) {
20702
20703
  }
20703
20704
  }
20704
20705
  // 输出对比结果
20705
- const { createLineDiff, renderUnifiedDiff, summarizeDiff } = await Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 54444, 23));
20706
+ const { createLineDiff, renderUnifiedDiff, summarizeDiff } = await Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 27804, 23));
20706
20707
  const diffResult = createLineDiff(baseBody, target.localBody, {
20707
20708
  oldFileName: `${target.apiName}.groovy`,
20708
20709
  newFileName: `${target.apiName}.groovy`,
@@ -40248,12 +40249,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
40248
40249
  return (mod && mod.__esModule) ? mod : { "default": mod };
40249
40250
  };
40250
40251
  Object.defineProperty(exports, "__esModule", ({ value: true }));
40252
+ exports.isPublicObject = isPublicObject;
40251
40253
  exports.objectListService = objectListService;
40252
40254
  const logger_ts_1 = __webpack_require__(63333);
40253
40255
  const request_execute_command_paths_ts_1 = __webpack_require__(32351);
40254
40256
  const normalize_ts_1 = __importDefault(__webpack_require__(39268));
40255
40257
  const request_ts_1 = __webpack_require__(43176);
40256
40258
  const types_ts_1 = __webpack_require__(77480);
40259
+ const PUBLIC_OBJECT_VISIBLE_SCOPES = new Set(['public', 'public_big']);
40260
+ function isPublicObject(item) {
40261
+ return PUBLIC_OBJECT_VISIBLE_SCOPES.has(item.visibleScope) && item.upstreamTenantId.length > 0;
40262
+ }
40257
40263
  const getObjectListFromExecute = async (queryType) => {
40258
40264
  if (queryType === null) {
40259
40265
  throw new Error('queryType is required');
@@ -40282,6 +40288,8 @@ const getObjectsFromPullResponse = async (response) => {
40282
40288
  apiName: normalize_ts_1.default.normalizeText(item.api_name),
40283
40289
  description: normalize_ts_1.default.normalizeText(item.description),
40284
40290
  defineType: normalize_ts_1.default.normalizeText(item.define_type),
40291
+ visibleScope: normalize_ts_1.default.normalizeText(item.visible_scope),
40292
+ upstreamTenantId: normalize_ts_1.default.normalizeText(item.upstream_tenant_id),
40285
40293
  createTime: normalize_ts_1.default.normalizeDateTime(item.create_time),
40286
40294
  lastModifiedTime: normalize_ts_1.default.normalizeDateTime(item.last_modified_time)
40287
40295
  })).filter(item => item.apiName);
@@ -40363,13 +40371,19 @@ async function objectPullService(shouldQueryAll, queryType = null, apiName, skip
40363
40371
  }
40364
40372
  else if (shouldQueryAll) {
40365
40373
  logger_ts_1.loggerService.startLoading('Fetching object apiName list...');
40374
+ const skippedPublicApiNames = objectListResult.objects
40375
+ .filter(obj => (0, object_list_ts_1.isPublicObject)(obj))
40376
+ .map(obj => obj.apiName);
40366
40377
  try {
40367
- apiNamesList.push(...remoteApiNamesList);
40378
+ apiNamesList.push(...remoteApiNamesList.filter(name => !skippedPublicApiNames.includes(name)));
40368
40379
  }
40369
40380
  finally {
40370
40381
  logger_ts_1.loggerService.stopLoading();
40371
40382
  }
40372
40383
  logger_ts_1.loggerService.info(`Fetched object apiName count: ${apiNamesList.length}`);
40384
+ if (skippedPublicApiNames.length) {
40385
+ logger_ts_1.loggerService.info(`Skipped public object count: ${skippedPublicApiNames.length}`);
40386
+ }
40373
40387
  }
40374
40388
  // 50个分批拉取
40375
40389
  const apiNamesListGroups = apiNamesList.reduce((acc, item, index) => {
@@ -44897,57 +44911,111 @@ async function pwcInfoCommand(apiName, type) {
44897
44911
  throw error;
44898
44912
  }
44899
44913
  }
44914
+ /** 批量调试时扫描的资源类型:组件与插件都扫,宿主对两者都从同一端口取资源 */
44915
+ const PWC_DEV_ALL_TYPES = [pwc_types_ts_1.PWCType.Component, pwc_types_ts_1.PWCType.Plugin];
44900
44916
  /**
44901
44917
  * 启动 PWC 本地 Beefly 开发服务。
44902
- * filePath 支持相对当前目录的路径和绝对路径,未提供时抛出参数错误。
44903
- * 产物名默认取 PWC 资源 apiName(宿主按 <apiName>.js 取资源),可用 --name 覆盖。
44904
- * 服务入口从 Beefly npm 依赖加载,并通过 configureWebpack 注入入口文件。
44918
+ *
44919
+ * 两种模式:
44920
+ * - 单资源:sharedev pwc dev <filePath> [--name <name>] [--port <port>]
44921
+ * - 批量: sharedev pwc dev --all [--port <port>]
44922
+ *
44923
+ * 批量模式会同时扫描 pwc/components 与 pwc/plugins,合并为同一个 dev server 的多入口。
44924
+ * 宿主对组件和插件都从固定端口(8080)取 <apiName>.js,因此两类资源必须挂在同一端口上,
44925
+ * 分端口启动会导致宿主导不到另一类资源。
44926
+ * 产物名默认取 PWC 资源 apiName,单资源模式可用 --name 覆盖。
44927
+ * 服务入口从 Beefly npm 依赖加载。
44905
44928
  */
44906
44929
  async function pwcDevCommand(filePath, context, options = {}) {
44907
44930
  const normalizedFilePath = filePath?.trim();
44908
- if (!normalizedFilePath) {
44909
- throw new Error('Invalid arguments: use sharedev pwc dev <filePath>.');
44910
- }
44911
- const projectRoot = context.cwd;
44912
- const entryPath = node_path_1.default.isAbsolute(normalizedFilePath)
44913
- ? normalizedFilePath
44914
- : node_path_1.default.resolve(projectRoot, normalizedFilePath);
44915
- // 校验显式传入的 Beefly 入口文件,避免开发服务启动后才报告路径错误。
44916
- try {
44917
- const entryStat = await (0, file_ts_1.statPath)(entryPath);
44918
- if (!entryStat.isFile()) {
44919
- throw new Error(`PWC dev entry is not a file: ${entryPath}`);
44931
+ const shouldQueryAll = options.all === true;
44932
+ // 参数校验:--all 与 filePath 互斥;单资源模式 filePath 必填。
44933
+ if (shouldQueryAll && normalizedFilePath) {
44934
+ throw new Error('Invalid arguments: do not pass filePath when using --all.');
44935
+ }
44936
+ if (!shouldQueryAll && !normalizedFilePath) {
44937
+ throw new Error('Invalid arguments: use sharedev pwc dev <filePath> or sharedev pwc dev --all.');
44938
+ }
44939
+ // 构建 webpack 多入口:key 为产物名(= apiName),value 为入口文件绝对路径。
44940
+ const entry = {};
44941
+ if (shouldQueryAll) {
44942
+ // 批量模式:同时扫描 components 与 plugins,逐个解析入口文件后合并为多入口。
44943
+ // 宿主对两类资源都从同一端口取 <apiName>.js,必须放进同一个 dev server。
44944
+ const { entries, skipped } = await (0, pwc_workspace_ts_1.collectLocalPwcDevEntries)(context, PWC_DEV_ALL_TYPES);
44945
+ if (!entries.length) {
44946
+ throw new Error('No local PWC resource with a resolvable entry file found under pwc/components or pwc/plugins.');
44947
+ }
44948
+ for (const item of entries) {
44949
+ entry[item.apiName] = item.entryPath;
44950
+ }
44951
+ // 按类型分组统计,便于确认组件与插件是否都已被纳入同一个 server
44952
+ const summary = PWC_DEV_ALL_TYPES
44953
+ .map((type) => {
44954
+ const names = entries.filter((item) => item.type === type).map((item) => item.apiName);
44955
+ return `${type}=${names.length}${names.length ? ` (${names.join(', ')})` : ''}`;
44956
+ })
44957
+ .join('; ');
44958
+ logger_ts_1.loggerService.info(`PWC dev --all resolved ${entries.length} resource(s): ${summary}`);
44959
+ if (skipped.length) {
44960
+ logger_ts_1.loggerService.warn(`Skipped ${skipped.length} resource(s) without a resolvable entry file: ${skipped
44961
+ .map((item) => `${item.type}/${item.apiName}`)
44962
+ .join(', ')}`);
44920
44963
  }
44921
44964
  }
44922
- catch (error) {
44923
- if (error instanceof Error && error.message.startsWith('PWC dev entry is not a file:')) {
44924
- throw error;
44965
+ else {
44966
+ // 单资源模式:解析并校验显式传入的入口文件。
44967
+ const projectRoot = context.cwd;
44968
+ const entryPath = node_path_1.default.isAbsolute(normalizedFilePath)
44969
+ ? normalizedFilePath
44970
+ : node_path_1.default.resolve(projectRoot, normalizedFilePath);
44971
+ try {
44972
+ const entryStat = await (0, file_ts_1.statPath)(entryPath);
44973
+ if (!entryStat.isFile()) {
44974
+ throw new Error(`PWC dev entry is not a file: ${entryPath}`);
44975
+ }
44925
44976
  }
44926
- throw new Error(`PWC dev entry file not found: ${entryPath}`);
44927
- }
44928
- // 产物名默认取 PWC 资源 apiName:宿主插件引擎按 <apiName>.js 到 dev server 取资源,
44929
- // 取入口文件名(通常 index.js)会产出 index.js,导致宿主请求 <apiName>.js 时 404。
44930
- const entryName = await (0, pwc_workspace_ts_1.resolvePwcDevEntryName)(entryPath, options.name);
44931
- const fallbackName = node_path_1.default.parse(entryPath).name;
44932
- if (entryName !== fallbackName) {
44933
- logger_ts_1.loggerService.info(`PWC dev entry name resolved to "${entryName}" (host loads <apiName>.js). Entry file: ${normalizedFilePath}`);
44977
+ catch (error) {
44978
+ if (error instanceof Error && error.message.startsWith('PWC dev entry is not a file:')) {
44979
+ throw error;
44980
+ }
44981
+ throw new Error(`PWC dev entry file not found: ${entryPath}`);
44982
+ }
44983
+ // 产物名默认取 PWC 资源 apiName:宿主插件引擎按 <apiName>.js 到 dev server 取资源,
44984
+ // 取入口文件名(通常 index.js)会产出 index.js,导致宿主请求 <apiName>.js 时 404。
44985
+ const entryName = await (0, pwc_workspace_ts_1.resolvePwcDevEntryName)(entryPath, options.name);
44986
+ const fallbackName = node_path_1.default.parse(entryPath).name;
44987
+ if (entryName !== fallbackName) {
44988
+ logger_ts_1.loggerService.info(`PWC dev entry name resolved to "${entryName}" (host loads <apiName>.js). Entry file: ${normalizedFilePath}`);
44989
+ }
44990
+ entry[entryName] = entryPath;
44934
44991
  }
44935
- logger_ts_1.loggerService.info(`Starting Beefly dev server with ${normalizedFilePath}`);
44992
+ const outputNames = Object.keys(entry);
44993
+ logger_ts_1.loggerService.info(shouldQueryAll
44994
+ ? `Starting Beefly dev server for ${outputNames.length} entr${outputNames.length === 1 ? 'y' : 'ies'}`
44995
+ : `Starting Beefly dev server with ${normalizedFilePath}`);
44936
44996
  const require = (0, node_module_1.createRequire)("file:///Users/dlxpq/work/fx/web-ide/packages/share-dev-cli/src/modules/pwc/pwc.command.ts");
44937
- const beefly = require('beefly');
44997
+ let beefly;
44998
+ try {
44999
+ beefly = require('beefly');
45000
+ }
45001
+ catch {
45002
+ logger_ts_1.loggerService.error('beefly@1.0.10 is required by "pwc dev" but is not installed on this machine, ' +
45003
+ 'and beefly has been unpublished from public npm registries. ' +
45004
+ 'Obtain the beefly tarball from the team (or an internal mirror) and install it globally to use "pwc dev".');
45005
+ return;
45006
+ }
44938
45007
  // 复用 Beefly 官方 API 启动 webpack dev server,入口名称决定预览产物名称。
44939
45008
  const server = await beefly.cli.dev({
44940
45009
  port: options.port,
44941
45010
  configureWebpack: {
44942
- entry: {
44943
- [entryName]: entryPath
44944
- }
45011
+ entry
44945
45012
  }
44946
45013
  });
44947
45014
  const port = server.options?.port;
44948
- logger_ts_1.loggerService.success(`Beefly dev server started${port ? ` at http://localhost:${port}/${entryName}.js` : ''}.`);
45015
+ const bundleList = outputNames.map((name) => `${name}.js`).join(', ');
45016
+ logger_ts_1.loggerService.success(`Beefly dev server started${port ? ` at http://localhost:${port}/` : ''} serving: ${port ? bundleList : outputNames.join(', ')}.`);
44949
45017
  if (port) {
44950
- logger_ts_1.loggerService.info(`Open the host page with ?debug=1 to load this resource; add --name <name> to override the output name.`);
45018
+ logger_ts_1.loggerService.info(`Open the host page with ?debug=1 to load these resources; add --name <name> to override the output name.`);
44951
45019
  }
44952
45020
  }
44953
45021
  async function pwcPlaceholderCommand(commandName) {
@@ -46072,6 +46140,7 @@ exports.readLocalPwcUploadBundle = readLocalPwcUploadBundle;
46072
46140
  exports.resolveFileTreeRelativePath = resolveFileTreeRelativePath;
46073
46141
  exports.resolvePwcDevEntryName = resolvePwcDevEntryName;
46074
46142
  exports.writePwcComponent = writePwcComponent;
46143
+ exports.collectLocalPwcDevEntries = collectLocalPwcDevEntries;
46075
46144
  const node_path_1 = __importDefault(__webpack_require__(76760));
46076
46145
  const fast_xml_parser_1 = __webpack_require__(94603);
46077
46146
  const file_ts_1 = __webpack_require__(85409);
@@ -46297,6 +46366,88 @@ async function writePwcComponent(context, component) {
46297
46366
  });
46298
46367
  return componentRoot;
46299
46368
  }
46369
+ /**
46370
+ * 将单个本地 PWC 资源的 mateXml.xml 解析为调试入口。
46371
+ * 入口文件取 source/<entryFileName>(entryFileName 来自 mateXml,通常 index.js / index.vue);
46372
+ * 若 mateXml 未声明或文件缺失,则回退到 source/index.js、source/index.vue、source/index.ts 探测。
46373
+ */
46374
+ async function resolveLocalPwcDevEntry(type, componentRoot) {
46375
+ const sourceDir = node_path_1.default.join(componentRoot, 'source');
46376
+ if (!(await (0, file_ts_1.pathExists)(sourceDir))) {
46377
+ return undefined;
46378
+ }
46379
+ const apiName = node_path_1.default.basename(componentRoot);
46380
+ let entryFileName = '';
46381
+ const mateXmlPath = node_path_1.default.join(componentRoot, 'mateXml.xml');
46382
+ if (await (0, file_ts_1.pathExists)(mateXmlPath)) {
46383
+ try {
46384
+ entryFileName = resolveMateXmlInfo(type, await (0, file_ts_1.readTextFile)(mateXmlPath)).entryFileName.trim();
46385
+ }
46386
+ catch {
46387
+ // mateXml 解析失败时走文件名探测兜底
46388
+ entryFileName = '';
46389
+ }
46390
+ }
46391
+ const candidates = [
46392
+ ...(entryFileName ? [entryFileName] : []),
46393
+ 'index.js',
46394
+ 'index.vue',
46395
+ 'index.ts',
46396
+ 'index.jsx',
46397
+ 'index.tsx'
46398
+ ];
46399
+ for (const candidate of candidates) {
46400
+ const entryPath = node_path_1.default.join(sourceDir, candidate);
46401
+ try {
46402
+ const entryStat = await (0, file_ts_1.statPath)(entryPath);
46403
+ if (entryStat.isFile()) {
46404
+ return {
46405
+ apiName,
46406
+ type,
46407
+ entryPath,
46408
+ entryRelativePath: node_path_1.default.relative(componentRoot, entryPath).split(node_path_1.default.sep).join('/')
46409
+ };
46410
+ }
46411
+ }
46412
+ catch {
46413
+ // 该候选不存在,继续尝试下一个
46414
+ }
46415
+ }
46416
+ return undefined;
46417
+ }
46418
+ /**
46419
+ * 扫描本地工作区下指定类型(component/plugin)的全部 PWC 资源并解析调试入口。
46420
+ * 传入多个类型时会一并扫描并合并结果——宿主对组件与插件都从同一个端口取资源,
46421
+ * 因此 sharedev pwc dev --all 必须能把两类资源放进同一个 dev server。
46422
+ * 无入口文件的资源会被跳过并在 skipped 中返回,由调用方提示用户。
46423
+ */
46424
+ async function collectLocalPwcDevEntries(context, types) {
46425
+ const targetTypes = Array.isArray(types) ? types : [types];
46426
+ const entries = [];
46427
+ const skipped = [];
46428
+ const { readdir } = await Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, 59031));
46429
+ for (const type of targetTypes) {
46430
+ const rootDir = node_path_1.default.join(resolveProjectRoot(context), getPwcWorkspaceRootDir(type));
46431
+ if (!(await (0, file_ts_1.pathExists)(rootDir))) {
46432
+ continue;
46433
+ }
46434
+ const dirEntries = await readdir(rootDir, { withFileTypes: true });
46435
+ const apiNames = dirEntries
46436
+ .filter((entry) => entry.isDirectory())
46437
+ .map((entry) => entry.name)
46438
+ .sort((a, b) => a.localeCompare(b));
46439
+ for (const apiName of apiNames) {
46440
+ const resolved = await resolveLocalPwcDevEntry(type, node_path_1.default.join(rootDir, apiName));
46441
+ if (resolved) {
46442
+ entries.push(resolved);
46443
+ }
46444
+ else {
46445
+ skipped.push({ apiName, type });
46446
+ }
46447
+ }
46448
+ }
46449
+ return { entries, skipped };
46450
+ }
46300
46451
 
46301
46452
 
46302
46453
  /***/ },
@@ -48998,7 +49149,7 @@ async function executeWorkflowDefShareCli(commandPath, data, others) {
48998
49149
 
48999
49150
  /***/ },
49000
49151
 
49001
- /***/ 54444
49152
+ /***/ 27804
49002
49153
  (__unused_webpack_module, exports, __webpack_require__) {
49003
49154
 
49004
49155
 
@@ -49510,8 +49661,8 @@ async function readCliPackageMeta() {
49510
49661
  ? "@share-crm/sharedev-cli".trim()
49511
49662
  : '@share-crm/sharedev-cli';
49512
49663
  const debugEnabled = true && Boolean(false);
49513
- const rawVersion = ( true && "0.0.4-rc.47-test.0".trim())
49514
- ? "0.0.4-rc.47-test.0".trim()
49664
+ const rawVersion = ( true && "0.0.4-rc.48".trim())
49665
+ ? "0.0.4-rc.48".trim()
49515
49666
  : '0.0.0';
49516
49667
  const version = rawVersion + (debugEnabled ? '-debug' : '');
49517
49668
  return { name, version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@share-crm/sharedev-cli",
3
- "version": "0.0.4-rc.47-test.0",
3
+ "version": "0.0.4-rc.48",
4
4
  "private": false,
5
5
  "description": "sharedev command line tool",
6
6
  "type": "module",
@@ -33,7 +33,6 @@
33
33
  "@clack/prompts": "^1.1.0",
34
34
  "@mariozechner/pi-coding-agent": "^0.62.0",
35
35
  "axios": "~1.13.0",
36
- "beefly": "1.0.10",
37
36
  "chalk": "^5.6.2",
38
37
  "commander": "^14.0.1",
39
38
  "extract-zip": "^2.0.1",
@@ -43,6 +42,9 @@
43
42
  "ora": "^9.3.0",
44
43
  "terser-webpack-plugin": "^5.6.1"
45
44
  },
45
+ "optionalDependencies": {
46
+ "beefly": "1.0.10"
47
+ },
46
48
  "devDependencies": {
47
49
  "@types/extract-zip": "^2.0.3",
48
50
  "@types/fs-extra": "^11.0.4",