react-native-update-cli 1.46.1 → 2.0.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 (64) hide show
  1. package/README.md +578 -1
  2. package/README.zh-CN.md +576 -0
  3. package/cli.json +18 -0
  4. package/lib/api.js +5 -5
  5. package/lib/app.js +1 -1
  6. package/lib/bundle.js +43 -29
  7. package/lib/exports.js +65 -0
  8. package/lib/index.js +100 -9
  9. package/lib/module-manager.js +125 -0
  10. package/lib/modules/app-module.js +223 -0
  11. package/lib/modules/bundle-module.js +188 -0
  12. package/lib/modules/index.js +42 -0
  13. package/lib/modules/package-module.js +16 -0
  14. package/lib/modules/user-module.js +402 -0
  15. package/lib/modules/version-module.js +16 -0
  16. package/lib/package.js +16 -6
  17. package/lib/provider.js +340 -0
  18. package/lib/user.js +3 -3
  19. package/lib/utils/app-info-parser/apk.js +1 -1
  20. package/lib/utils/app-info-parser/ipa.js +2 -2
  21. package/lib/utils/app-info-parser/resource-finder.js +35 -35
  22. package/lib/utils/app-info-parser/xml-parser/manifest.js +2 -2
  23. package/lib/utils/app-info-parser/zip.js +3 -6
  24. package/lib/utils/check-plugin.js +1 -1
  25. package/lib/utils/git.js +1 -1
  26. package/lib/utils/i18n.js +3 -1
  27. package/lib/utils/index.js +4 -4
  28. package/lib/utils/latest-version/cli.js +3 -3
  29. package/lib/utils/latest-version/index.js +4 -4
  30. package/lib/versions.js +2 -2
  31. package/package.json +4 -4
  32. package/src/api.ts +7 -7
  33. package/src/app.ts +2 -2
  34. package/src/bundle.ts +57 -32
  35. package/src/exports.ts +30 -0
  36. package/src/index.ts +118 -16
  37. package/src/module-manager.ts +149 -0
  38. package/src/modules/app-module.ts +205 -0
  39. package/src/modules/bundle-module.ts +202 -0
  40. package/src/modules/index.ts +19 -0
  41. package/src/modules/package-module.ts +11 -0
  42. package/src/modules/user-module.ts +406 -0
  43. package/src/modules/version-module.ts +8 -0
  44. package/src/package.ts +29 -16
  45. package/src/provider.ts +341 -0
  46. package/src/types.ts +125 -0
  47. package/src/user.ts +4 -3
  48. package/src/utils/app-info-parser/apk.js +62 -52
  49. package/src/utils/app-info-parser/app.js +5 -5
  50. package/src/utils/app-info-parser/ipa.js +69 -57
  51. package/src/utils/app-info-parser/resource-finder.js +50 -54
  52. package/src/utils/app-info-parser/utils.js +59 -54
  53. package/src/utils/app-info-parser/xml-parser/binary.js +366 -354
  54. package/src/utils/app-info-parser/xml-parser/manifest.js +145 -137
  55. package/src/utils/app-info-parser/zip.js +1 -1
  56. package/src/utils/check-plugin.ts +4 -2
  57. package/src/utils/dep-versions.ts +13 -6
  58. package/src/utils/git.ts +1 -1
  59. package/src/utils/i18n.ts +3 -1
  60. package/src/utils/index.ts +8 -10
  61. package/src/utils/latest-version/cli.ts +4 -4
  62. package/src/utils/latest-version/index.ts +17 -17
  63. package/src/utils/plugin-config.ts +3 -3
  64. package/src/versions.ts +3 -3
package/lib/utils/git.js CHANGED
@@ -8,9 +8,9 @@ Object.defineProperty(exports, "getCommitInfo", {
8
8
  return getCommitInfo;
9
9
  }
10
10
  });
11
- const _isomorphicgit = /*#__PURE__*/ _interop_require_default(require("isomorphic-git"));
12
11
  const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
13
12
  const _path = /*#__PURE__*/ _interop_require_default(require("path"));
13
+ const _isomorphicgit = /*#__PURE__*/ _interop_require_default(require("isomorphic-git"));
14
14
  function _interop_require_default(obj) {
15
15
  return obj && obj.__esModule ? obj : {
16
16
  default: obj
package/lib/utils/i18n.js CHANGED
@@ -33,4 +33,6 @@ _i18next.default.init({
33
33
  escapeValue: false
34
34
  }
35
35
  });
36
- const t = _i18next.default.t;
36
+ function t(key, options) {
37
+ return _i18next.default.t(key, options);
38
+ }
@@ -34,14 +34,14 @@ _export(exports, {
34
34
  return translateOptions;
35
35
  }
36
36
  });
37
- const _fsextra = /*#__PURE__*/ _interop_require_default(require("fs-extra"));
38
37
  const _os = /*#__PURE__*/ _interop_require_default(require("os"));
39
38
  const _path = /*#__PURE__*/ _interop_require_default(require("path"));
40
- const _packagejson = /*#__PURE__*/ _interop_require_default(require("../../package.json"));
41
- const _appinfoparser = /*#__PURE__*/ _interop_require_default(require("./app-info-parser"));
42
- const _compareversions = require("compare-versions");
43
39
  const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
40
+ const _compareversions = require("compare-versions");
41
+ const _fsextra = /*#__PURE__*/ _interop_require_default(require("fs-extra"));
42
+ const _packagejson = /*#__PURE__*/ _interop_require_default(require("../../package.json"));
44
43
  const _latestversion = /*#__PURE__*/ _interop_require_default(require("../utils/latest-version"));
44
+ const _appinfoparser = /*#__PURE__*/ _interop_require_default(require("./app-info-parser"));
45
45
  const _checkplugin = require("./check-plugin");
46
46
  const _read = require("read");
47
47
  const _constants = require("./constants");
@@ -2,12 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- const _safe = require("@colors/colors/safe");
6
5
  const _fs = require("fs");
7
6
  const _path = require("path");
8
- const _ = /*#__PURE__*/ _interop_require_default(require("."));
9
- const _major = /*#__PURE__*/ _interop_require_default(require("semver/functions/major"));
7
+ const _safe = require("@colors/colors/safe");
10
8
  const _diff = /*#__PURE__*/ _interop_require_default(require("semver/functions/diff"));
9
+ const _major = /*#__PURE__*/ _interop_require_default(require("semver/functions/major"));
10
+ const _ = /*#__PURE__*/ _interop_require_default(require("."));
11
11
  function _interop_require_default(obj) {
12
12
  return obj && obj.__esModule ? obj : {
13
13
  default: obj
@@ -17,14 +17,14 @@ _export(exports, {
17
17
  }
18
18
  });
19
19
  const _fs = require("fs");
20
- const _path = require("path");
21
- const _globaldirs = require("global-dirs");
22
20
  const _os = require("os");
21
+ const _path = require("path");
23
22
  const _url = require("url");
24
- const _registryurl = /*#__PURE__*/ _interop_require_default(require("registry-auth-token/registry-url"));
23
+ const _globaldirs = require("global-dirs");
25
24
  const _registryauthtoken = /*#__PURE__*/ _interop_require_default(require("registry-auth-token"));
26
- const _maxsatisfying = /*#__PURE__*/ _interop_require_default(require("semver/ranges/max-satisfying"));
25
+ const _registryurl = /*#__PURE__*/ _interop_require_default(require("registry-auth-token/registry-url"));
27
26
  const _gt = /*#__PURE__*/ _interop_require_default(require("semver/functions/gt"));
27
+ const _maxsatisfying = /*#__PURE__*/ _interop_require_default(require("semver/ranges/max-satisfying"));
28
28
  function _interop_require_default(obj) {
29
29
  return obj && obj.__esModule ? obj : {
30
30
  default: obj
package/lib/versions.js CHANGED
@@ -19,12 +19,12 @@ _export(exports, {
19
19
  const _api = require("./api");
20
20
  const _utils = require("./utils");
21
21
  const _i18n = require("./utils/i18n");
22
+ const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
23
+ const _compareversions = require("compare-versions");
22
24
  const _app = require("./app");
23
25
  const _package = require("./package");
24
26
  const _depversions = require("./utils/dep-versions");
25
27
  const _git = require("./utils/git");
26
- const _compareversions = require("compare-versions");
27
- const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
28
28
  function _interop_require_default(obj) {
29
29
  return obj && obj.__esModule ? obj : {
30
30
  default: obj
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-update-cli",
3
- "version": "1.46.1",
3
+ "version": "2.0.0",
4
4
  "description": "command line tool for react-native-update (remote updates for react native)",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",
22
- "url": "git+https://github.com/reactnativecn/react-native-pushy-cli.git"
22
+ "url": "git+https://github.com/reactnativecn/react-native-update-cli.git"
23
23
  },
24
24
  "keywords": [
25
25
  "react-native",
@@ -31,9 +31,9 @@
31
31
  "author": "reactnativecn",
32
32
  "license": "BSD-3-Clause",
33
33
  "bugs": {
34
- "url": "https://github.com/reactnativecn/react-native-pushy/issues"
34
+ "url": "https://github.com/reactnativecn/react-native-update-cli/issues"
35
35
  },
36
- "homepage": "https://github.com/reactnativecn/react-native-pushy/tree/master/react-native-pushy-cli",
36
+ "homepage": "https://github.com/reactnativecn/react-native-update-cli",
37
37
  "dependencies": {
38
38
  "@colors/colors": "^1.6.0",
39
39
  "bplist-parser": "^0.3.2",
package/src/api.ts CHANGED
@@ -1,18 +1,18 @@
1
- import fetch from 'node-fetch';
2
1
  import fs from 'fs';
3
- import util from 'util';
4
2
  import path from 'path';
3
+ import util from 'util';
4
+ import filesizeParser from 'filesize-parser';
5
+ import FormData from 'form-data';
6
+ import fetch from 'node-fetch';
5
7
  import ProgressBar from 'progress';
6
- import packageJson from '../package.json';
7
8
  import tcpp from 'tcp-ping';
8
- import filesizeParser from 'filesize-parser';
9
+ import packageJson from '../package.json';
10
+ import type { Package, Session } from './types';
9
11
  import {
10
- pricingPageUrl,
11
12
  credentialFile,
12
13
  defaultEndpoint,
14
+ pricingPageUrl,
13
15
  } from './utils/constants';
14
- import type { Session, Package } from 'types';
15
- import FormData from 'form-data';
16
16
  import { t } from './utils/i18n';
17
17
 
18
18
  const tcpPing = util.promisify(tcpp.ping);
package/src/app.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { question } from './utils';
2
1
  import fs from 'fs';
3
2
  import Table from 'tty-table';
3
+ import { question } from './utils';
4
4
 
5
- import { post, get, doDelete } from './api';
5
+ import { doDelete, get, post } from './api';
6
6
  import type { Platform } from './types';
7
7
  import { t } from './utils/i18n';
8
8
 
package/src/bundle.ts CHANGED
@@ -1,24 +1,24 @@
1
+ import { spawn, spawnSync } from 'child_process';
1
2
  import path from 'path';
2
- import { translateOptions } from './utils';
3
+ import { satisfies } from 'compare-versions';
3
4
  import * as fs from 'fs-extra';
4
- import { ZipFile as YazlZipFile } from 'yazl';
5
5
  import {
6
6
  type Entry,
7
- open as openZipFile,
8
7
  type ZipFile as YauzlZipFile,
8
+ open as openZipFile,
9
9
  } from 'yauzl';
10
- import { question, checkPlugins } from './utils';
10
+ import { ZipFile as YazlZipFile } from 'yazl';
11
11
  import { getPlatform } from './app';
12
- import { spawn, spawnSync } from 'child_process';
13
- import { satisfies } from 'compare-versions';
12
+ import { translateOptions } from './utils';
13
+ import { checkPlugins, question } from './utils';
14
14
  const g2js = require('gradle-to-js/lib/parser');
15
15
  import os from 'os';
16
16
  const properties = require('properties');
17
+ import { addGitIgnore } from './utils/add-gitignore';
18
+ import { checkLockFiles } from './utils/check-lockfile';
19
+ import { tempDir } from './utils/constants';
17
20
  import { depVersions } from './utils/dep-versions';
18
21
  import { t } from './utils/i18n';
19
- import { tempDir } from './utils/constants';
20
- import { checkLockFiles } from './utils/check-lockfile';
21
- import { addGitIgnore } from './utils/add-gitignore';
22
22
  import { versionCommands } from './versions';
23
23
 
24
24
  type Diff = (oldSource?: Buffer, newSource?: Buffer) => Buffer;
@@ -288,9 +288,22 @@ async function copyHarmonyBundle(outputFolder: string) {
288
288
  }
289
289
  await fs.remove(path.join(harmonyRawPath, 'update.json'));
290
290
  await fs.copy('update.json', path.join(harmonyRawPath, 'update.json'));
291
-
292
291
  await fs.ensureDir(outputFolder);
293
- await fs.copy(harmonyRawPath, outputFolder);
292
+
293
+ const files = await fs.readdir(harmonyRawPath);
294
+ for (const file of files) {
295
+ if (file !== 'update.json' && file !== 'meta.json') {
296
+ const sourcePath = path.join(harmonyRawPath, file);
297
+ const destPath = path.join(outputFolder, file);
298
+ const stat = await fs.stat(sourcePath);
299
+
300
+ if (stat.isFile()) {
301
+ await fs.copy(sourcePath, destPath);
302
+ } else if (stat.isDirectory()) {
303
+ await fs.copy(sourcePath, destPath);
304
+ }
305
+ }
306
+ }
294
307
  } catch (error: any) {
295
308
  console.error(t('copyHarmonyBundleError', { error }));
296
309
  throw new Error(t('copyFileFailed', { error: error.message }));
@@ -521,7 +534,7 @@ async function pack(dir: string, output: string) {
521
534
 
522
535
  zipfile.outputStream.on('error', (err: any) => reject(err));
523
536
  zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
524
- resolve();
537
+ resolve(void 0);
525
538
  });
526
539
  zipfile.end();
527
540
  });
@@ -535,17 +548,14 @@ export function readEntry(
535
548
  const buffers: Buffer[] = [];
536
549
  return new Promise((resolve, reject) => {
537
550
  zipFile.openReadStream(entry, (err, stream) => {
538
- stream.pipe({
539
- write(chunk: Buffer) {
540
- buffers.push(chunk);
541
- },
542
- end() {
543
- resolve(Buffer.concat(buffers));
544
- },
545
- prependListener() {},
546
- on() {},
547
- once() {},
548
- emit() {},
551
+ stream.on('data', (chunk: Buffer) => {
552
+ buffers.push(chunk);
553
+ });
554
+ stream.on('end', () => {
555
+ resolve(Buffer.concat(buffers));
556
+ });
557
+ stream.on('error', (err) => {
558
+ reject(err);
549
559
  });
550
560
  });
551
561
  });
@@ -595,7 +605,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
595
605
  throw err;
596
606
  });
597
607
  zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
598
- resolve();
608
+ resolve(void 0);
599
609
  });
600
610
  });
601
611
 
@@ -672,7 +682,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
672
682
  zipfile.addReadStream(readStream, entry.fileName);
673
683
  readStream.on('end', () => {
674
684
  //console.log('add finished');
675
- resolve();
685
+ resolve(void 0);
676
686
  });
677
687
  });
678
688
  });
@@ -745,7 +755,7 @@ async function diffFromPackage(
745
755
  throw err;
746
756
  });
747
757
  zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
748
- resolve();
758
+ resolve(void 0);
749
759
  });
750
760
  });
751
761
 
@@ -793,7 +803,7 @@ async function diffFromPackage(
793
803
  zipfile.addReadStream(readStream, entry.fileName);
794
804
  readStream.on('end', () => {
795
805
  //console.log('add finished');
796
- resolve();
806
+ resolve(void 0);
797
807
  });
798
808
  });
799
809
  });
@@ -845,7 +855,7 @@ export async function enumZipEntries(
845
855
  if (err) return rej(err);
846
856
  const writeStream = fs.createWriteStream(tempZipPath);
847
857
  readStream.pipe(writeStream);
848
- writeStream.on('finish', res);
858
+ writeStream.on('finish', () => res(void 0));
849
859
  writeStream.on('error', rej);
850
860
  });
851
861
  });
@@ -963,11 +973,11 @@ export const bundleCommands = {
963
973
  outputFolder: intermediaDir,
964
974
  platform,
965
975
  sourcemapOutput: sourcemap || sourcemapPlugin ? sourcemapOutput : '',
966
- disableHermes,
976
+ disableHermes: !!disableHermes,
967
977
  cli: {
968
- taro,
969
- expo,
970
- rncli,
978
+ taro: !!taro,
979
+ expo: !!expo,
980
+ rncli: !!rncli,
971
981
  },
972
982
  });
973
983
 
@@ -1072,6 +1082,21 @@ export const bundleCommands = {
1072
1082
  console.log(`${realOutput} generated.`);
1073
1083
  },
1074
1084
 
1085
+ async diffFromApp({ args, options }) {
1086
+ const { origin, next, realOutput } = diffArgsCheck(
1087
+ args,
1088
+ options,
1089
+ 'diffFromApp',
1090
+ );
1091
+ await diffFromPackage(
1092
+ origin,
1093
+ next,
1094
+ realOutput,
1095
+ 'resources/rawfile/bundle.harmony.js',
1096
+ );
1097
+ console.log(`${realOutput} generated.`);
1098
+ },
1099
+
1075
1100
  async hdiffFromApp({ args, options }) {
1076
1101
  const { origin, next, realOutput } = diffArgsCheck(
1077
1102
  args,
package/src/exports.ts ADDED
@@ -0,0 +1,30 @@
1
+ export { moduleManager } from './module-manager';
2
+ export { CLIProviderImpl } from './provider';
3
+
4
+ export type {
5
+ CLIProvider,
6
+ CLIModule,
7
+ CommandDefinition,
8
+ CustomWorkflow,
9
+ WorkflowStep,
10
+ CommandContext,
11
+ CommandResult,
12
+ BundleOptions,
13
+ PublishOptions,
14
+ UploadOptions,
15
+ Platform,
16
+ Session,
17
+ Version,
18
+ Package,
19
+ } from './types';
20
+
21
+ export { builtinModules } from './modules';
22
+ export { bundleModule } from './modules/bundle-module';
23
+ export { versionModule } from './modules/version-module';
24
+ export { appModule } from './modules/app-module';
25
+ export { userModule } from './modules/user-module';
26
+ export { packageModule } from './modules/package-module';
27
+
28
+ export { loadSession, getSession } from './api';
29
+ export { getPlatform, getSelectedApp } from './app';
30
+ export { question, saveToLocal } from './utils';
package/src/index.ts CHANGED
@@ -1,25 +1,76 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { loadSession } from './api';
4
+ import { appCommands } from './app';
5
+ import { bundleCommands } from './bundle';
6
+ import { moduleManager } from './module-manager';
7
+ import { builtinModules } from './modules';
8
+ import { packageCommands } from './package';
9
+ import type { CommandContext } from './types';
10
+ import { userCommands } from './user';
4
11
  import { printVersionCommand } from './utils';
5
12
  import { t } from './utils/i18n';
6
- import { bundleCommands } from './bundle';
7
13
  import { versionCommands } from './versions';
8
- import { userCommands } from './user';
9
- import { appCommands } from './app';
10
- import { packageCommands } from './package';
14
+
15
+ function registerBuiltinModules() {
16
+ for (const module of builtinModules) {
17
+ try {
18
+ moduleManager.registerModule(module);
19
+ } catch (error) {
20
+ console.error(`Failed to register module ${module.name}:`, error);
21
+ }
22
+ }
23
+ }
11
24
 
12
25
  function printUsage() {
13
- // const commandName = args[0];
14
- // TODO: print usage of commandName, or print global usage.
26
+ console.log('React Native Update CLI');
27
+ console.log('');
28
+ console.log('Traditional commands:');
29
+
30
+ const legacyCommands = {
31
+ ...userCommands,
32
+ ...bundleCommands,
33
+ ...appCommands,
34
+ ...packageCommands,
35
+ ...versionCommands,
36
+ };
37
+
38
+ for (const [name, handler] of Object.entries(legacyCommands)) {
39
+ console.log(` ${name}: Legacy command`);
40
+ }
15
41
 
42
+ console.log('');
43
+ console.log('Modular commands:');
44
+ const commands = moduleManager.getRegisteredCommands();
45
+ for (const command of commands) {
46
+ console.log(
47
+ ` ${command.name}: ${command.description || 'No description'}`,
48
+ );
49
+ }
50
+
51
+ console.log('');
52
+ console.log('Available workflows:');
53
+ const workflows = moduleManager.getRegisteredWorkflows();
54
+ for (const workflow of workflows) {
55
+ console.log(
56
+ ` ${workflow.name}: ${workflow.description || 'No description'}`,
57
+ );
58
+ }
59
+
60
+ console.log('');
61
+ console.log('Special commands:');
62
+ console.log(' list: List all available commands and workflows');
63
+ console.log(' workflow <name>: Execute a specific workflow');
64
+ console.log(' help: Show this help message');
65
+
66
+ console.log('');
16
67
  console.log(
17
68
  'Visit `https://github.com/reactnativecn/react-native-update` for document.',
18
69
  );
19
70
  process.exit(1);
20
71
  }
21
72
 
22
- const commands = {
73
+ const legacyCommands = {
23
74
  ...userCommands,
24
75
  ...bundleCommands,
25
76
  ...appCommands,
@@ -34,20 +85,71 @@ async function run() {
34
85
  process.exit();
35
86
  }
36
87
 
88
+ // Register builtin modules for modular functionality
89
+ registerBuiltinModules();
90
+
37
91
  const argv = require('cli-arguments').parse(require('../cli.json'));
38
92
  global.NO_INTERACTIVE = argv.options['no-interactive'];
39
93
  global.USE_ACC_OSS = argv.options.acc;
40
94
 
41
- loadSession()
42
- .then(() => commands[argv.command](argv))
43
- .catch((err) => {
44
- if (err.status === 401) {
45
- console.log(t('loginFirst'));
46
- return;
95
+ const context: CommandContext = {
96
+ args: argv.args || [],
97
+ options: argv.options || {},
98
+ };
99
+
100
+ try {
101
+ await loadSession();
102
+ context.session = require('./api').getSession();
103
+
104
+ // Handle special modular commands first
105
+ if (argv.command === 'help') {
106
+ printUsage();
107
+ } else if (argv.command === 'list') {
108
+ moduleManager.listAll();
109
+ } else if (argv.command === 'workflow') {
110
+ const workflowName = argv.args[0];
111
+ if (!workflowName) {
112
+ console.error('Workflow name is required');
113
+ process.exit(1);
114
+ }
115
+ const result = await moduleManager.executeWorkflow(workflowName, context);
116
+ if (!result.success) {
117
+ console.error('Workflow execution failed:', result.error);
118
+ process.exit(1);
119
+ }
120
+ console.log('Workflow completed successfully:', result.data);
121
+ }
122
+ // Try legacy commands first for backward compatibility
123
+ else if (legacyCommands[argv.command]) {
124
+ await legacyCommands[argv.command](argv);
125
+ }
126
+ // Fall back to modular commands
127
+ else {
128
+ const result = await moduleManager.executeCommand(argv.command, context);
129
+ if (!result.success) {
130
+ console.error('Command execution failed:', result.error);
131
+ process.exit(1);
47
132
  }
48
- console.error(err.stack);
49
- process.exit(-1);
50
- });
133
+ console.log('Command completed successfully:', result.data);
134
+ }
135
+ } catch (err: any) {
136
+ if (err.status === 401) {
137
+ console.log(t('loginFirst'));
138
+ return;
139
+ }
140
+ console.error(err.stack);
141
+ process.exit(-1);
142
+ }
51
143
  }
52
144
 
145
+ export { moduleManager };
146
+ export { CLIProviderImpl } from './provider';
147
+ export type {
148
+ CLIProvider,
149
+ CLIModule,
150
+ CommandDefinition,
151
+ CustomWorkflow,
152
+ WorkflowStep,
153
+ } from './types';
154
+
53
155
  run();
@@ -0,0 +1,149 @@
1
+ import { CLIProviderImpl } from './provider';
2
+ import type {
3
+ CLIModule,
4
+ CLIProvider,
5
+ CommandDefinition,
6
+ CustomWorkflow,
7
+ } from './types';
8
+
9
+ export class ModuleManager {
10
+ private modules: Map<string, CLIModule> = new Map();
11
+ private provider: CLIProvider;
12
+ private commands: Map<string, CommandDefinition> = new Map();
13
+ private workflows: Map<string, CustomWorkflow> = new Map();
14
+
15
+ constructor() {
16
+ this.provider = new CLIProviderImpl();
17
+ }
18
+
19
+ registerModule(module: CLIModule): void {
20
+ if (this.modules.has(module.name)) {
21
+ throw new Error(`Module '${module.name}' is already registered`);
22
+ }
23
+
24
+ this.modules.set(module.name, module);
25
+
26
+ if (module.commands) {
27
+ for (const command of module.commands) {
28
+ this.registerCommand(command);
29
+ }
30
+ }
31
+
32
+ if (module.workflows) {
33
+ for (const workflow of module.workflows) {
34
+ this.registerWorkflow(workflow);
35
+ }
36
+ }
37
+
38
+ if (module.init) {
39
+ module.init(this.provider);
40
+ }
41
+
42
+ console.log(
43
+ `Module '${module.name}' (v${module.version}) registered successfully`,
44
+ );
45
+ }
46
+
47
+ unregisterModule(moduleName: string): void {
48
+ const module = this.modules.get(moduleName);
49
+ if (!module) {
50
+ throw new Error(`Module '${moduleName}' is not registered`);
51
+ }
52
+
53
+ if (module.commands) {
54
+ for (const command of module.commands) {
55
+ this.commands.delete(command.name);
56
+ }
57
+ }
58
+
59
+ if (module.workflows) {
60
+ for (const workflow of module.workflows) {
61
+ this.workflows.delete(workflow.name);
62
+ }
63
+ }
64
+
65
+ if (module.cleanup) {
66
+ module.cleanup();
67
+ }
68
+
69
+ this.modules.delete(moduleName);
70
+ console.log(`Module '${moduleName}' unregistered successfully`);
71
+ }
72
+
73
+ registerCommand(command: CommandDefinition): void {
74
+ if (this.commands.has(command.name)) {
75
+ throw new Error(`Command '${command.name}' is already registered`);
76
+ }
77
+ this.commands.set(command.name, command);
78
+ }
79
+
80
+ registerWorkflow(workflow: CustomWorkflow): void {
81
+ if (this.workflows.has(workflow.name)) {
82
+ throw new Error(`Workflow '${workflow.name}' is already registered`);
83
+ }
84
+ this.workflows.set(workflow.name, workflow);
85
+ this.provider.registerWorkflow(workflow);
86
+ }
87
+
88
+ getRegisteredCommands(): CommandDefinition[] {
89
+ return Array.from(this.commands.values());
90
+ }
91
+
92
+ getRegisteredWorkflows(): CustomWorkflow[] {
93
+ return Array.from(this.workflows.values());
94
+ }
95
+
96
+ getRegisteredModules(): CLIModule[] {
97
+ return Array.from(this.modules.values());
98
+ }
99
+
100
+ async executeCommand(commandName: string, context: any): Promise<any> {
101
+ const command = this.commands.get(commandName);
102
+ if (!command) {
103
+ throw new Error(`Command '${commandName}' not found`);
104
+ }
105
+
106
+ return await command.handler(context);
107
+ }
108
+
109
+ async executeWorkflow(workflowName: string, context: any): Promise<any> {
110
+ return await this.provider.executeWorkflow(workflowName, context);
111
+ }
112
+
113
+ getProvider(): CLIProvider {
114
+ return this.provider;
115
+ }
116
+
117
+ listCommands(): any[] {
118
+ return Array.from(this.commands.values());
119
+ }
120
+
121
+ listWorkflows(): CustomWorkflow[] {
122
+ return Array.from(this.workflows.values());
123
+ }
124
+
125
+ listAll(): void {
126
+ console.log('\n=== Registered Commands ===');
127
+ for (const command of this.commands.values()) {
128
+ console.log(
129
+ ` ${command.name}: ${command.description || 'No description'}`,
130
+ );
131
+ }
132
+
133
+ console.log('\n=== Registered Workflows ===');
134
+ for (const workflow of this.workflows.values()) {
135
+ console.log(
136
+ ` ${workflow.name}: ${workflow.description || 'No description'}`,
137
+ );
138
+ }
139
+
140
+ console.log('\n=== Registered Modules ===');
141
+ for (const module of this.modules.values()) {
142
+ console.log(
143
+ ` ${module.name} (v${module.version}): ${module.commands?.length || 0} commands, ${module.workflows?.length || 0} workflows`,
144
+ );
145
+ }
146
+ }
147
+ }
148
+
149
+ export const moduleManager = new ModuleManager();