@memberjunction/cli 4.4.0 → 5.1.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 (78) hide show
  1. package/README.md +130 -0
  2. package/dist/commands/app/check-updates.d.ts +13 -0
  3. package/dist/commands/app/check-updates.d.ts.map +1 -0
  4. package/dist/commands/app/check-updates.js +54 -0
  5. package/dist/commands/app/check-updates.js.map +1 -0
  6. package/dist/commands/app/disable.d.ts +16 -0
  7. package/dist/commands/app/disable.d.ts.map +1 -0
  8. package/dist/commands/app/disable.js +47 -0
  9. package/dist/commands/app/disable.js.map +1 -0
  10. package/dist/commands/app/enable.d.ts +16 -0
  11. package/dist/commands/app/enable.d.ts.map +1 -0
  12. package/dist/commands/app/enable.js +47 -0
  13. package/dist/commands/app/enable.js.map +1 -0
  14. package/dist/commands/app/info.d.ts +16 -0
  15. package/dist/commands/app/info.d.ts.map +1 -0
  16. package/dist/commands/app/info.js +64 -0
  17. package/dist/commands/app/info.js.map +1 -0
  18. package/dist/commands/app/install.d.ts +21 -0
  19. package/dist/commands/app/install.d.ts.map +1 -0
  20. package/dist/commands/app/install.js +54 -0
  21. package/dist/commands/app/install.js.map +1 -0
  22. package/dist/commands/app/list.d.ts +16 -0
  23. package/dist/commands/app/list.d.ts.map +1 -0
  24. package/dist/commands/app/list.js +60 -0
  25. package/dist/commands/app/list.js.map +1 -0
  26. package/dist/commands/app/remove.d.ts +22 -0
  27. package/dist/commands/app/remove.d.ts.map +1 -0
  28. package/dist/commands/app/remove.js +66 -0
  29. package/dist/commands/app/remove.js.map +1 -0
  30. package/dist/commands/app/upgrade.d.ts +20 -0
  31. package/dist/commands/app/upgrade.d.ts.map +1 -0
  32. package/dist/commands/app/upgrade.js +52 -0
  33. package/dist/commands/app/upgrade.js.map +1 -0
  34. package/dist/commands/clean/index.d.ts +0 -2
  35. package/dist/commands/clean/index.d.ts.map +1 -1
  36. package/dist/commands/clean/index.js +31 -19
  37. package/dist/commands/clean/index.js.map +1 -1
  38. package/dist/commands/codegen/5-0-fix-entity-names.d.ts +17 -0
  39. package/dist/commands/codegen/5-0-fix-entity-names.d.ts.map +1 -0
  40. package/dist/commands/codegen/5-0-fix-entity-names.js +104 -0
  41. package/dist/commands/codegen/5-0-fix-entity-names.js.map +1 -0
  42. package/dist/commands/codegen/5-0-fix-html-entity-names.d.ts +17 -0
  43. package/dist/commands/codegen/5-0-fix-html-entity-names.d.ts.map +1 -0
  44. package/dist/commands/codegen/5-0-fix-html-entity-names.js +92 -0
  45. package/dist/commands/codegen/5-0-fix-html-entity-names.js.map +1 -0
  46. package/dist/commands/codegen/5-0-fix-metadata-names.d.ts +17 -0
  47. package/dist/commands/codegen/5-0-fix-metadata-names.d.ts.map +1 -0
  48. package/dist/commands/codegen/5-0-fix-metadata-names.js +93 -0
  49. package/dist/commands/codegen/5-0-fix-metadata-names.js.map +1 -0
  50. package/dist/commands/codegen/index.d.ts +4 -1
  51. package/dist/commands/codegen/index.d.ts.map +1 -1
  52. package/dist/commands/codegen/index.js +30 -5
  53. package/dist/commands/codegen/index.js.map +1 -1
  54. package/dist/commands/codegen/manifest.d.ts +4 -1
  55. package/dist/commands/codegen/manifest.d.ts.map +1 -1
  56. package/dist/commands/codegen/manifest.js +34 -11
  57. package/dist/commands/codegen/manifest.js.map +1 -1
  58. package/dist/commands/migrate/index.d.ts +5 -1
  59. package/dist/commands/migrate/index.d.ts.map +1 -1
  60. package/dist/commands/migrate/index.js +102 -229
  61. package/dist/commands/migrate/index.js.map +1 -1
  62. package/dist/commands/sync/init.js +1 -1
  63. package/dist/commands/sync/init.js.map +1 -1
  64. package/dist/commands/sync/pull.js +4 -4
  65. package/dist/commands/sync/pull.js.map +1 -1
  66. package/dist/config.d.ts +154 -4
  67. package/dist/config.d.ts.map +1 -1
  68. package/dist/config.js +81 -48
  69. package/dist/config.js.map +1 -1
  70. package/dist/light-commands.d.ts +1 -1
  71. package/dist/light-commands.js +2 -2
  72. package/dist/light-commands.js.map +1 -1
  73. package/dist/utils/open-app-context.d.ts +48 -0
  74. package/dist/utils/open-app-context.d.ts.map +1 -0
  75. package/dist/utils/open-app-context.js +143 -0
  76. package/dist/utils/open-app-context.js.map +1 -0
  77. package/oclif.manifest.json +789 -247
  78. package/package.json +12 -12
package/README.md CHANGED
@@ -135,6 +135,136 @@ mj codegen manifest
135
135
  mj codegen manifest --exclude-packages @memberjunction --output ./src/generated/manifest.ts
136
136
  ```
137
137
 
138
+ #### v5.0 Entity Name Migration Commands
139
+
140
+ Starting in MemberJunction v5.0, all 272 core entity names are being normalized with the `"MJ: "` prefix to prevent naming collisions on client systems (e.g., `"Actions"` becomes `"MJ: Actions"`). The database migration handles the rename automatically, but hardcoded entity name strings in your TypeScript source, Angular HTML templates, and metadata JSON files also need updating. These three commands automate that process.
141
+
142
+ All three commands share the same workflow:
143
+ 1. **Dry-run first** (default) -- scans and reports what would change, without modifying any files.
144
+ 2. **Fix mode** (`--fix`) -- applies the changes in place.
145
+ 3. **Rename map** -- built dynamically by parsing `@RegisterClass(BaseEntity, 'MJ: XYZ')` decorators from `entity_subclasses.ts`. No hardcoded list to maintain.
146
+
147
+ > These commands will be kept for 1-2 years to support the v5.0 upgrade window, then removed.
148
+
149
+ ##### mj codegen 5-0-fix-entity-names
150
+
151
+ Scans **TypeScript source files** (`.ts`) using the TypeScript compiler AST to find hardcoded entity names that need the `"MJ: "` prefix. This is the most comprehensive scanner -- it understands code context, not just string matching.
152
+
153
+ **Detected patterns:**
154
+
155
+ | Pattern | Example |
156
+ |---------|---------|
157
+ | `GetEntityObject` calls | `md.GetEntityObject<T>('Actions')` |
158
+ | `OpenEntityRecord` calls | `this.OpenEntityRecord('Entities', id)` |
159
+ | `navigateToEntity` calls | `navigateToEntity('Templates')` |
160
+ | `BuildRelationshipViewParamsByEntityName` calls | `BuildRelationshipViewParamsByEntityName('Roles')` |
161
+ | `NewRecordValues` calls | `NewRecordValues('Users')` |
162
+ | `IsCurrentTab` calls | `IsCurrentTab('Queries')` |
163
+ | `EntityName:` property assignments | `EntityName: 'AI Agent Examples'` |
164
+ | `.Name ===` / `.Entity ===` comparisons | `entity.Name === 'Actions'` |
165
+ | `@RegisterClass` decorator (BaseEntity) | `@RegisterClass(BaseEntity, 'Actions')` |
166
+
167
+ **Default exclusions:** `node_modules`, `dist`, `build`, `.git`, `__tests__`, `*.d.ts`, `*.spec.ts`, `*.test.ts`, `generated/`, `Demos/`
168
+
169
+ ```bash
170
+ # Dry-run: scan entire packages/ directory
171
+ mj codegen 5-0-fix-entity-names --path packages/
172
+
173
+ # Dry-run: scan a single file
174
+ mj codegen 5-0-fix-entity-names --path packages/Angular/Explorer/dashboards/src/Actions/components/actions-overview.component.ts
175
+
176
+ # Apply fixes
177
+ mj codegen 5-0-fix-entity-names --path packages/ --fix
178
+
179
+ # Custom entity_subclasses.ts location
180
+ mj codegen 5-0-fix-entity-names --path packages/ --entity-subclasses ./path/to/entity_subclasses.ts
181
+
182
+ # Quiet mode (summary only)
183
+ mj codegen 5-0-fix-entity-names --path packages/ -q
184
+ ```
185
+
186
+ ##### mj codegen 5-0-fix-html-entity-names
187
+
188
+ Scans **Angular HTML template files** (`.html`) using targeted regex patterns for entity name references in template expressions and attribute values.
189
+
190
+ **Detected patterns:**
191
+
192
+ | Pattern | Example |
193
+ |---------|---------|
194
+ | Method calls in event/property bindings | `(click)="navigateToEntity('Actions')"` |
195
+ | `OpenEntityRecord` / `openEntityRecord` | `(click)="OpenEntityRecord('Entities', id)"` |
196
+ | `BuildRelationshipViewParamsByEntityName` | `[Params]="BuildRelationshipViewParamsByEntityName('Roles')"` |
197
+ | `RowsEntityName` attribute | `RowsEntityName="Users"` |
198
+ | `JoinEntityName` attribute | `JoinEntityName="Roles"` |
199
+
200
+ **Default exclusions:** `node_modules`, `dist`, `build`, `.git`, `generated/`, `Demos/`
201
+
202
+ ```bash
203
+ # Dry-run: scan Angular templates
204
+ mj codegen 5-0-fix-html-entity-names --path packages/Angular/
205
+
206
+ # Apply fixes
207
+ mj codegen 5-0-fix-html-entity-names --path packages/Angular/ --fix
208
+
209
+ # Verbose output showing individual file progress
210
+ mj codegen 5-0-fix-html-entity-names --path packages/ -v
211
+ ```
212
+
213
+ ##### mj codegen 5-0-fix-metadata-names
214
+
215
+ Scans **metadata JSON files** (including dotfiles like `.mj-sync.json`) for entity name references that need the `"MJ: "` prefix. Targets the `metadata/` directory used by `mj sync`.
216
+
217
+ **Detected patterns:**
218
+
219
+ | Pattern | Example |
220
+ |---------|---------|
221
+ | `@lookup:` entity name | `@lookup:Entities.Name=Dashboards` |
222
+ | `@lookup:` value (in Entities lookups) | `@lookup:MJ: Entities.Name=Actions` |
223
+ | Folder config `entity`/`entityName` | `.mj-sync.json` with `"entity": "Dashboards"` |
224
+ | `relatedEntities` object keys | `"relatedEntities": { "Actions": [...] }` |
225
+ | `fields.Name` in Entities folders | Entity record data files where Name is the entity name |
226
+
227
+ ```bash
228
+ # Dry-run: scan metadata directory
229
+ mj codegen 5-0-fix-metadata-names --path metadata/
230
+
231
+ # Apply fixes
232
+ mj codegen 5-0-fix-metadata-names --path metadata/ --fix
233
+
234
+ # Scan a specific subdirectory
235
+ mj codegen 5-0-fix-metadata-names --path metadata/resource-types
236
+
237
+ # Scan and fix a single file
238
+ mj codegen 5-0-fix-metadata-names --path metadata/entities/.audit-related-entities.json --fix
239
+ ```
240
+
241
+ ##### Common flags (all three commands)
242
+
243
+ | Flag | Short | Description |
244
+ |------|-------|-------------|
245
+ | `--path <dir\|file>` | `-p` | File or directory to scan. Defaults to current directory. |
246
+ | `--fix` | | Apply fixes in place. Without this flag, runs in dry-run mode. |
247
+ | `--entity-subclasses <path>` | | Path to `entity_subclasses.ts`. Auto-detected if omitted. |
248
+ | `--quiet` | `-q` | Suppress detailed output, show summary only. |
249
+ | `--verbose` | `-v` | Show detailed progress for each file scanned. |
250
+
251
+ ##### Recommended migration workflow
252
+
253
+ ```bash
254
+ # 1. Scan everything first (dry-run)
255
+ mj codegen 5-0-fix-entity-names --path packages/
256
+ mj codegen 5-0-fix-html-entity-names --path packages/
257
+ mj codegen 5-0-fix-metadata-names --path metadata/
258
+
259
+ # 2. Review the output, then apply
260
+ mj codegen 5-0-fix-entity-names --path packages/ --fix
261
+ mj codegen 5-0-fix-html-entity-names --path packages/ --fix
262
+ mj codegen 5-0-fix-metadata-names --path metadata/ --fix
263
+
264
+ # 3. Build and test
265
+ npm run build
266
+ ```
267
+
138
268
  ### mj sync
139
269
 
140
270
  Metadata synchronization between JSON files and the database.
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ /**
3
+ * CLI command: `mj app check-updates`.
4
+ *
5
+ * Queries GitHub for the latest version tag of each installed Open App
6
+ * and reports which apps have newer versions available.
7
+ */
8
+ export default class AppCheckUpdates extends Command {
9
+ static description: string;
10
+ static examples: string[];
11
+ run(): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=check-updates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-updates.d.ts","sourceRoot":"","sources":["../../../src/commands/app/check-updates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAMtC;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,OAAO;IAClD,MAAM,CAAC,WAAW,SAA6D;IAE/E,MAAM,CAAC,QAAQ,WAEb;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA2C3B"}
@@ -0,0 +1,54 @@
1
+ import { Command } from '@oclif/core';
2
+ import ora from 'ora-classic';
3
+ import chalk from 'chalk';
4
+ import { buildContextUser } from '../../utils/open-app-context.js';
5
+ import { getValidatedConfig } from '../../config.js';
6
+ /**
7
+ * CLI command: `mj app check-updates`.
8
+ *
9
+ * Queries GitHub for the latest version tag of each installed Open App
10
+ * and reports which apps have newer versions available.
11
+ */
12
+ export default class AppCheckUpdates extends Command {
13
+ static { this.description = 'Check for available upgrades for installed MJ Open Apps'; }
14
+ static { this.examples = [
15
+ '<%= config.bin %> app check-updates',
16
+ ]; }
17
+ async run() {
18
+ const spinner = ora('Checking for updates...').start();
19
+ try {
20
+ const { ListInstalledApps, GetLatestVersion } = await import('@memberjunction/open-app-engine');
21
+ const config = getValidatedConfig();
22
+ const contextUser = await buildContextUser();
23
+ const apps = await ListInstalledApps(contextUser);
24
+ if (apps.length === 0) {
25
+ spinner.info('No Open Apps installed.');
26
+ return;
27
+ }
28
+ const githubOptions = { Token: config.openApps?.github?.token ?? process.env.GITHUB_TOKEN };
29
+ const updates = [];
30
+ for (const app of apps) {
31
+ const latest = await GetLatestVersion(app.RepositoryURL, githubOptions);
32
+ if (latest && latest !== app.Version) {
33
+ updates.push({ Name: app.Name, Current: app.Version, Latest: latest });
34
+ }
35
+ }
36
+ spinner.stop();
37
+ if (updates.length === 0) {
38
+ this.log(chalk.green('\nAll apps are up to date.'));
39
+ return;
40
+ }
41
+ this.log(chalk.bold('\nUpdates available:\n'));
42
+ for (const update of updates) {
43
+ this.log(` ${update.Name}: ${chalk.yellow(update.Current)} -> ${chalk.green(update.Latest)}`);
44
+ }
45
+ this.log(`\nRun ${chalk.cyan('mj app upgrade <name>')} to upgrade.`);
46
+ }
47
+ catch (error) {
48
+ spinner.fail('Failed to check for updates');
49
+ const message = error instanceof Error ? error.message : String(error);
50
+ this.error(message);
51
+ }
52
+ }
53
+ }
54
+ //# sourceMappingURL=check-updates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-updates.js","sourceRoot":"","sources":["../../../src/commands/app/check-updates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,GAAG,MAAM,aAAa,CAAC;AAC9B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,OAAO;aAC3C,gBAAW,GAAG,yDAAyD,CAAC;aAExE,aAAQ,GAAG;QAChB,qCAAqC;KACtC,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,OAAO,GAAG,GAAG,CAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE,CAAC;QAEvD,IAAI,CAAC;YACH,MAAM,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC;YAChG,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;YAEpC,MAAM,WAAW,GAAG,MAAM,gBAAgB,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAElD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;gBACxC,OAAO;YACT,CAAC;YAED,MAAM,aAAa,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC5F,MAAM,OAAO,GAA6D,EAAE,CAAC;YAE7E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;gBACxE,IAAI,MAAM,IAAI,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC;oBACrC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;YAED,OAAO,CAAC,IAAI,EAAE,CAAC;YAEf,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;gBACpD,OAAO;YACT,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;YAC/C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACjG,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,cAAc,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;IACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Command } from '@oclif/core';
2
+ /**
3
+ * CLI command: `mj app disable <name>`.
4
+ *
5
+ * Disables an installed Open App by commenting out its config entries and
6
+ * client imports. The app data and packages remain in place.
7
+ */
8
+ export default class AppDisable extends Command {
9
+ static description: string;
10
+ static examples: string[];
11
+ static args: {
12
+ name: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=disable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disable.d.ts","sourceRoot":"","sources":["../../../src/commands/app/disable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAE,MAAM,aAAa,CAAC;AAK5C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,SAA0D;IAE5E,MAAM,CAAC,QAAQ,WAEb;IAEF,MAAM,CAAC,IAAI;;MAKT;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAyB3B"}
@@ -0,0 +1,47 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import ora from 'ora-classic';
3
+ import chalk from 'chalk';
4
+ import { buildOrchestratorContext } from '../../utils/open-app-context.js';
5
+ /**
6
+ * CLI command: `mj app disable <name>`.
7
+ *
8
+ * Disables an installed Open App by commenting out its config entries and
9
+ * client imports. The app data and packages remain in place.
10
+ */
11
+ export default class AppDisable extends Command {
12
+ static { this.description = 'Disable an installed MJ Open App without removing it'; }
13
+ static { this.examples = [
14
+ '<%= config.bin %> app disable acme-crm',
15
+ ]; }
16
+ static { this.args = {
17
+ name: Args.string({
18
+ description: 'Name of the installed app to disable',
19
+ required: true,
20
+ }),
21
+ }; }
22
+ async run() {
23
+ const { args } = await this.parse(AppDisable);
24
+ const spinner = ora(`Disabling ${args.name}...`).start();
25
+ try {
26
+ const { DisableApp } = await import('@memberjunction/open-app-engine');
27
+ const context = await buildOrchestratorContext(this);
28
+ const result = await DisableApp(args.name, context);
29
+ if (result.Success) {
30
+ spinner.succeed(chalk.green(`Disabled ${args.name}`));
31
+ if (result.Summary) {
32
+ this.log(`\n${result.Summary}`);
33
+ }
34
+ }
35
+ else {
36
+ spinner.fail(chalk.red(`Failed to disable: ${result.ErrorMessage}`));
37
+ this.exit(1);
38
+ }
39
+ }
40
+ catch (error) {
41
+ spinner.fail('Disable failed');
42
+ const message = error instanceof Error ? error.message : String(error);
43
+ this.error(message);
44
+ }
45
+ }
46
+ }
47
+ //# sourceMappingURL=disable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disable.js","sourceRoot":"","sources":["../../../src/commands/app/disable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,GAAG,MAAM,aAAa,CAAC;AAC9B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;aACtC,gBAAW,GAAG,sDAAsD,CAAC;aAErE,aAAQ,GAAG;QAChB,wCAAwC;KACzC,CAAC;aAEK,SAAI,GAAG;QACZ,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAChB,WAAW,EAAE,sCAAsC;YACnD,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;QAEzD,IAAI,CAAC;YACH,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC;YACvE,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,IAAI,CAAC,CAAC;YAErD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAEpD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBACtD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,IAAI,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;gBACrE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACf,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC/B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;IACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Command } from '@oclif/core';
2
+ /**
3
+ * CLI command: `mj app enable <name>`.
4
+ *
5
+ * Re-enables a previously disabled Open App by restoring its config
6
+ * entries and client imports.
7
+ */
8
+ export default class AppEnable extends Command {
9
+ static description: string;
10
+ static examples: string[];
11
+ static args: {
12
+ name: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=enable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enable.d.ts","sourceRoot":"","sources":["../../../src/commands/app/enable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAE,MAAM,aAAa,CAAC;AAK5C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,OAAO;IAC5C,MAAM,CAAC,WAAW,SAAsC;IAExD,MAAM,CAAC,QAAQ,WAEb;IAEF,MAAM,CAAC,IAAI;;MAKT;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAyB3B"}
@@ -0,0 +1,47 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import ora from 'ora-classic';
3
+ import chalk from 'chalk';
4
+ import { buildOrchestratorContext } from '../../utils/open-app-context.js';
5
+ /**
6
+ * CLI command: `mj app enable <name>`.
7
+ *
8
+ * Re-enables a previously disabled Open App by restoring its config
9
+ * entries and client imports.
10
+ */
11
+ export default class AppEnable extends Command {
12
+ static { this.description = 'Re-enable a disabled MJ Open App'; }
13
+ static { this.examples = [
14
+ '<%= config.bin %> app enable acme-crm',
15
+ ]; }
16
+ static { this.args = {
17
+ name: Args.string({
18
+ description: 'Name of the installed app to enable',
19
+ required: true,
20
+ }),
21
+ }; }
22
+ async run() {
23
+ const { args } = await this.parse(AppEnable);
24
+ const spinner = ora(`Enabling ${args.name}...`).start();
25
+ try {
26
+ const { EnableApp } = await import('@memberjunction/open-app-engine');
27
+ const context = await buildOrchestratorContext(this);
28
+ const result = await EnableApp(args.name, context);
29
+ if (result.Success) {
30
+ spinner.succeed(chalk.green(`Enabled ${args.name}`));
31
+ if (result.Summary) {
32
+ this.log(`\n${result.Summary}`);
33
+ }
34
+ }
35
+ else {
36
+ spinner.fail(chalk.red(`Failed to enable: ${result.ErrorMessage}`));
37
+ this.exit(1);
38
+ }
39
+ }
40
+ catch (error) {
41
+ spinner.fail('Enable failed');
42
+ const message = error instanceof Error ? error.message : String(error);
43
+ this.error(message);
44
+ }
45
+ }
46
+ }
47
+ //# sourceMappingURL=enable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enable.js","sourceRoot":"","sources":["../../../src/commands/app/enable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,GAAG,MAAM,aAAa,CAAC;AAC9B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,OAAO;aACrC,gBAAW,GAAG,kCAAkC,CAAC;aAEjD,aAAQ,GAAG;QAChB,uCAAuC;KACxC,CAAC;aAEK,SAAI,GAAG;QACZ,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAChB,WAAW,EAAE,qCAAqC;YAClD,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC;YACtE,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,IAAI,CAAC,CAAC;YAErD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAEnD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBACrD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,IAAI,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;gBACpE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACf,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC9B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;IACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Command } from '@oclif/core';
2
+ /**
3
+ * CLI command: `mj app info <name>`.
4
+ *
5
+ * Displays detailed metadata about an installed Open App including
6
+ * publisher, version, schema, license, and description.
7
+ */
8
+ export default class AppInfo extends Command {
9
+ static description: string;
10
+ static examples: string[];
11
+ static args: {
12
+ name: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../../src/commands/app/info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAE,MAAM,aAAa,CAAC;AAI5C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,OAAO;IAC1C,MAAM,CAAC,WAAW,SAA8D;IAEhF,MAAM,CAAC,QAAQ,WAEb;IAEF,MAAM,CAAC,IAAI;;MAKT;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA+B3B"}
@@ -0,0 +1,64 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { buildContextUser } from '../../utils/open-app-context.js';
4
+ /**
5
+ * CLI command: `mj app info <name>`.
6
+ *
7
+ * Displays detailed metadata about an installed Open App including
8
+ * publisher, version, schema, license, and description.
9
+ */
10
+ export default class AppInfo extends Command {
11
+ static { this.description = 'Show detailed information about an installed MJ Open App'; }
12
+ static { this.examples = [
13
+ '<%= config.bin %> app info acme-crm',
14
+ ]; }
15
+ static { this.args = {
16
+ name: Args.string({
17
+ description: 'Name of the installed app',
18
+ required: true,
19
+ }),
20
+ }; }
21
+ async run() {
22
+ const { args } = await this.parse(AppInfo);
23
+ try {
24
+ const { FindInstalledApp } = await import('@memberjunction/open-app-engine');
25
+ const contextUser = await buildContextUser();
26
+ const app = await FindInstalledApp(contextUser, args.name);
27
+ if (!app) {
28
+ this.error(`App '${args.name}' is not installed.`);
29
+ }
30
+ this.log(chalk.bold(`\n${app.DisplayName}\n`));
31
+ this.log(` Name: ${app.Name}`);
32
+ this.log(` Version: ${app.Version}`);
33
+ this.log(` Status: ${FormatStatus(app.Status)}`);
34
+ this.log(` Publisher: ${app.Publisher}`);
35
+ if (app.PublisherEmail)
36
+ this.log(` Email: ${app.PublisherEmail}`);
37
+ if (app.PublisherURL)
38
+ this.log(` URL: ${app.PublisherURL}`);
39
+ this.log(` Repository: ${app.RepositoryURL}`);
40
+ if (app.SchemaName)
41
+ this.log(` Schema: ${app.SchemaName}`);
42
+ this.log(` MJ Range: ${app.MJVersionRange}`);
43
+ if (app.License)
44
+ this.log(` License: ${app.License}`);
45
+ if (app.Description)
46
+ this.log(`\n ${app.Description}`);
47
+ this.log('');
48
+ }
49
+ catch (error) {
50
+ const message = error instanceof Error ? error.message : String(error);
51
+ this.error(message);
52
+ }
53
+ }
54
+ }
55
+ /** Returns the status string with color-coding based on app state. */
56
+ function FormatStatus(status) {
57
+ switch (status) {
58
+ case 'Active': return chalk.green(status);
59
+ case 'Error': return chalk.red(status);
60
+ case 'Disabled': return chalk.yellow(status);
61
+ default: return chalk.blue(status);
62
+ }
63
+ }
64
+ //# sourceMappingURL=info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.js","sourceRoot":"","sources":["../../../src/commands/app/info.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { Command } from '@oclif/core';
2
+ /**
3
+ * CLI command: `mj app install <source>`.
4
+ *
5
+ * Installs an Open App from a GitHub repository URL, executing the full
6
+ * install flow (manifest validation, dependency resolution, schema creation,
7
+ * migration execution, npm package management, and config updates).
8
+ */
9
+ export default class AppInstall extends Command {
10
+ static description: string;
11
+ static examples: string[];
12
+ static args: {
13
+ source: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
14
+ };
15
+ static flags: {
16
+ version: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
17
+ verbose: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
18
+ };
19
+ run(): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/commands/app/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAS,MAAM,aAAa,CAAC;AAKnD;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,SAAqD;IAEvE,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,IAAI;;MAKT;IAEF,MAAM,CAAC,KAAK;;;MAGV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA4B3B"}
@@ -0,0 +1,54 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import ora from 'ora-classic';
3
+ import chalk from 'chalk';
4
+ import { buildOrchestratorContext } from '../../utils/open-app-context.js';
5
+ /**
6
+ * CLI command: `mj app install <source>`.
7
+ *
8
+ * Installs an Open App from a GitHub repository URL, executing the full
9
+ * install flow (manifest validation, dependency resolution, schema creation,
10
+ * migration execution, npm package management, and config updates).
11
+ */
12
+ export default class AppInstall extends Command {
13
+ static { this.description = 'Install an MJ Open App from a GitHub repository'; }
14
+ static { this.examples = [
15
+ '<%= config.bin %> app install https://github.com/acme/mj-crm',
16
+ '<%= config.bin %> app install https://github.com/acme/mj-crm --version 1.2.0',
17
+ '<%= config.bin %> app install https://github.com/acme/mj-crm --verbose',
18
+ ]; }
19
+ static { this.args = {
20
+ source: Args.string({
21
+ description: 'GitHub repository URL of the Open App',
22
+ required: true,
23
+ }),
24
+ }; }
25
+ static { this.flags = {
26
+ version: Flags.string({ description: 'Specific version to install (default: latest)' }),
27
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed output' }),
28
+ }; }
29
+ async run() {
30
+ const { args, flags } = await this.parse(AppInstall);
31
+ const spinner = ora();
32
+ try {
33
+ const { InstallApp } = await import('@memberjunction/open-app-engine');
34
+ const context = await buildOrchestratorContext(this, flags.verbose);
35
+ const result = await InstallApp({ Source: args.source, Version: flags.version, Verbose: flags.verbose }, context);
36
+ if (result.Success) {
37
+ spinner.succeed(chalk.green(`Installed ${result.AppName} v${result.Version}`));
38
+ if (result.Summary) {
39
+ this.log(`\n${result.Summary}`);
40
+ }
41
+ }
42
+ else {
43
+ spinner.fail(chalk.red(`Install failed: ${result.ErrorMessage}`));
44
+ this.exit(1);
45
+ }
46
+ }
47
+ catch (error) {
48
+ spinner.fail('Install failed');
49
+ const message = error instanceof Error ? error.message : String(error);
50
+ this.error(message);
51
+ }
52
+ }
53
+ }
54
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/commands/app/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,GAAG,MAAM,aAAa,CAAC;AAC9B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;aACtC,gBAAW,GAAG,iDAAiD,CAAC;aAEhE,aAAQ,GAAG;QAChB,8DAA8D;QAC9D,8EAA8E;QAC9E,wEAAwE;KACzE,CAAC;aAEK,SAAI,GAAG;QACZ,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;YAClB,WAAW,EAAE,uCAAuC;YACpD,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAC;aAEK,UAAK,GAAG;QACb,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,+CAA+C,EAAE,CAAC;QACvF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;KAC3E,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC;QAEtB,IAAI,CAAC;YACH,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC;YACvE,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAEpE,MAAM,MAAM,GAAG,MAAM,UAAU,CAC7B,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EACvE,OAAO,CACR,CAAC;YAEF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC/E,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,IAAI,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;gBAClE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACf,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC/B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;IACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Command } from '@oclif/core';
2
+ /**
3
+ * CLI command: `mj app list`.
4
+ *
5
+ * Displays a table of all installed Open Apps with name, version, and status.
6
+ * Use `--verbose` to include schema and publisher columns.
7
+ */
8
+ export default class AppList extends Command {
9
+ static description: string;
10
+ static examples: string[];
11
+ static flags: {
12
+ verbose: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/app/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAa7C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,OAAO;IAC1C,MAAM,CAAC,WAAW,SAAqC;IAEvD,MAAM,CAAC,QAAQ,WAEb;IAEF,MAAM,CAAC,KAAK;;MAEV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAoB3B"}
@@ -0,0 +1,60 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { buildContextUser } from '../../utils/open-app-context.js';
4
+ /**
5
+ * CLI command: `mj app list`.
6
+ *
7
+ * Displays a table of all installed Open Apps with name, version, and status.
8
+ * Use `--verbose` to include schema and publisher columns.
9
+ */
10
+ export default class AppList extends Command {
11
+ static { this.description = 'List all installed MJ Open Apps'; }
12
+ static { this.examples = [
13
+ '<%= config.bin %> app list',
14
+ ]; }
15
+ static { this.flags = {
16
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed output' }),
17
+ }; }
18
+ async run() {
19
+ const { flags } = await this.parse(AppList);
20
+ try {
21
+ const { ListInstalledApps } = await import('@memberjunction/open-app-engine');
22
+ const contextUser = await buildContextUser();
23
+ const apps = await ListInstalledApps(contextUser);
24
+ if (apps.length === 0) {
25
+ this.log('No Open Apps installed.');
26
+ return;
27
+ }
28
+ this.log(chalk.bold('\nInstalled Open Apps:\n'));
29
+ this.log(FormatAppTable(apps, flags.verbose));
30
+ }
31
+ catch (error) {
32
+ const message = error instanceof Error ? error.message : String(error);
33
+ this.error(message);
34
+ }
35
+ }
36
+ }
37
+ /** Formats installed apps into a fixed-width table string with color-coded status. */
38
+ function FormatAppTable(apps, verbose) {
39
+ const lines = [];
40
+ const header = verbose
41
+ ? PadColumns(['Name', 'Version', 'Status', 'Schema', 'Publisher'])
42
+ : PadColumns(['Name', 'Version', 'Status']);
43
+ const separator = '-'.repeat(header.length);
44
+ lines.push(header);
45
+ lines.push(separator);
46
+ for (const app of apps) {
47
+ const statusColor = app.Status === 'Active' ? chalk.green : app.Status === 'Error' ? chalk.red : chalk.yellow;
48
+ const row = verbose
49
+ ? PadColumns([app.Name, app.Version, statusColor(app.Status), app.SchemaName ?? '-', app.Publisher])
50
+ : PadColumns([app.Name, app.Version, statusColor(app.Status)]);
51
+ lines.push(row);
52
+ }
53
+ return lines.join('\n');
54
+ }
55
+ /** Pads an array of column values to fixed widths for table alignment. */
56
+ function PadColumns(values) {
57
+ const widths = [30, 12, 12, 20, 30];
58
+ return values.map((v, i) => v.padEnd(widths[i] ?? 20)).join(' ');
59
+ }
60
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/app/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAWnE;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,OAAO;aACnC,gBAAW,GAAG,iCAAiC,CAAC;aAEhD,aAAQ,GAAG;QAChB,4BAA4B;KAC7B,CAAC;aAEK,UAAK,GAAG;QACb,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;KAC3E,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE5C,IAAI,CAAC;YACH,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC,CAAC;YAC9E,MAAM,WAAW,GAAG,MAAM,gBAAgB,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;YAElD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;gBACpC,OAAO;YACT,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;;AAGH,sFAAsF;AACtF,SAAS,cAAc,CACrB,IAAuB,EACvB,OAAiB;IAEjB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,OAAO;QACpB,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAClE,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAE5C,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEtB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;QAC9G,MAAM,GAAG,GAAG,OAAO;YACjB,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,UAAU,IAAI,GAAG,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;YACpG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACjE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,0EAA0E;AAC1E,SAAS,UAAU,CAAC,MAAgB;IAClC,MAAM,MAAM,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpE,CAAC"}