@memberjunction/cli 2.13.1 → 2.13.3
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 +65 -6
- package/bin/dev.js +1 -0
- package/bin/run.js +1 -1
- package/dist/commands/bump/index.d.ts +16 -0
- package/dist/commands/bump/index.js +122 -0
- package/dist/commands/clean/index.js +1 -1
- package/dist/commands/codegen/index.d.ts +11 -0
- package/dist/commands/codegen/index.js +29 -0
- package/dist/commands/install/index.d.ts +10 -11
- package/dist/commands/install/index.js +71 -70
- package/dist/commands/migrate/index.d.ts +2 -3
- package/dist/commands/migrate/index.js +10 -8
- package/dist/config.d.ts +23 -7
- package/dist/config.js +35 -13
- package/dist/hooks/prerun.js +17 -0
- package/oclif.manifest.json +120 -9
- package/package.json +5 -1
- package/dist/hooks/init.d.ts +0 -3
- package/dist/hooks/init.js +0 -18
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ $ npm install -g @memberjunction/cli
|
|
|
12
12
|
$ mj COMMAND
|
|
13
13
|
running command...
|
|
14
14
|
$ mj (--version)
|
|
15
|
-
@memberjunction/cli/2.13.
|
|
15
|
+
@memberjunction/cli/2.13.3 linux-x64 node-v20.18.1
|
|
16
16
|
$ mj --help [COMMAND]
|
|
17
17
|
USAGE
|
|
18
18
|
$ mj COMMAND
|
|
@@ -21,12 +21,50 @@ USAGE
|
|
|
21
21
|
<!-- usagestop -->
|
|
22
22
|
# Commands
|
|
23
23
|
<!-- commands -->
|
|
24
|
+
* [`mj bump`](#mj-bump)
|
|
24
25
|
* [`mj clean`](#mj-clean)
|
|
26
|
+
* [`mj codegen`](#mj-codegen)
|
|
25
27
|
* [`mj help [COMMAND]`](#mj-help-command)
|
|
26
28
|
* [`mj install`](#mj-install)
|
|
27
29
|
* [`mj migrate`](#mj-migrate)
|
|
28
30
|
* [`mj version`](#mj-version)
|
|
29
31
|
|
|
32
|
+
## `mj bump`
|
|
33
|
+
|
|
34
|
+
Bumps MemberJunction dependency versions
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
USAGE
|
|
38
|
+
$ mj bump [-v] [-r] [-t <value>] [-q] [-d]
|
|
39
|
+
|
|
40
|
+
FLAGS
|
|
41
|
+
-d, --dry Dry run, do not write changes to package.json files
|
|
42
|
+
-q, --quiet Only output paths for updated packages
|
|
43
|
+
-r, --recursive Bump version in current directory and all subdirectories
|
|
44
|
+
-t, --tag=<value> Version tag to bump target for bump (e.g. v2.10.0), defaults to the CLI version
|
|
45
|
+
-v, --verbose Enable additional logging
|
|
46
|
+
|
|
47
|
+
DESCRIPTION
|
|
48
|
+
Bumps MemberJunction dependency versions
|
|
49
|
+
|
|
50
|
+
EXAMPLES
|
|
51
|
+
Bump all @memberjunction/* dependencies in the current directory's package.json to the CLI version
|
|
52
|
+
|
|
53
|
+
$ mj bump
|
|
54
|
+
|
|
55
|
+
Preview all recursive packages bumps without writing any changes.
|
|
56
|
+
|
|
57
|
+
$ mj bump -rdv
|
|
58
|
+
|
|
59
|
+
Recursively bump all @memberjunction/* dependencies in all packages to version v2.10.0 and output only the paths
|
|
60
|
+
containing the updated package.json files. Pipe the output to xargs to run npm install in each directory and update
|
|
61
|
+
the package-lock.json files as well.
|
|
62
|
+
|
|
63
|
+
$ mj bump -rqt v2.10.0 | xargs -n1 -I{} npm install --prefix {}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
_See code: [src/commands/bump/index.ts](https://github.com/MemberJunction/MJ/blob/v2.13.3/src/commands/bump/index.ts)_
|
|
67
|
+
|
|
30
68
|
## `mj clean`
|
|
31
69
|
|
|
32
70
|
Resets the MemberJunction database to a pre-installation state
|
|
@@ -45,7 +83,27 @@ EXAMPLES
|
|
|
45
83
|
$ mj clean
|
|
46
84
|
```
|
|
47
85
|
|
|
48
|
-
_See code: [src/commands/clean/index.ts](https://github.com/MemberJunction/MJ/blob/v2.13.
|
|
86
|
+
_See code: [src/commands/clean/index.ts](https://github.com/MemberJunction/MJ/blob/v2.13.3/src/commands/clean/index.ts)_
|
|
87
|
+
|
|
88
|
+
## `mj codegen`
|
|
89
|
+
|
|
90
|
+
Run CodeGen to generate code and update metadata for MemberJunction
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
USAGE
|
|
94
|
+
$ mj codegen [--skipdb]
|
|
95
|
+
|
|
96
|
+
FLAGS
|
|
97
|
+
--skipdb Skip database migration
|
|
98
|
+
|
|
99
|
+
DESCRIPTION
|
|
100
|
+
Run CodeGen to generate code and update metadata for MemberJunction
|
|
101
|
+
|
|
102
|
+
EXAMPLES
|
|
103
|
+
$ mj codegen
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
_See code: [src/commands/codegen/index.ts](https://github.com/MemberJunction/MJ/blob/v2.13.3/src/commands/codegen/index.ts)_
|
|
49
107
|
|
|
50
108
|
## `mj help [COMMAND]`
|
|
51
109
|
|
|
@@ -85,7 +143,7 @@ EXAMPLES
|
|
|
85
143
|
$ mj install
|
|
86
144
|
```
|
|
87
145
|
|
|
88
|
-
_See code: [src/commands/install/index.ts](https://github.com/MemberJunction/MJ/blob/v2.13.
|
|
146
|
+
_See code: [src/commands/install/index.ts](https://github.com/MemberJunction/MJ/blob/v2.13.3/src/commands/install/index.ts)_
|
|
89
147
|
|
|
90
148
|
## `mj migrate`
|
|
91
149
|
|
|
@@ -93,10 +151,11 @@ Migrate MemberJunction database to latest version
|
|
|
93
151
|
|
|
94
152
|
```
|
|
95
153
|
USAGE
|
|
96
|
-
$ mj migrate [-v]
|
|
154
|
+
$ mj migrate [-v] [-t <value>]
|
|
97
155
|
|
|
98
156
|
FLAGS
|
|
99
|
-
-
|
|
157
|
+
-t, --tag=<value> Version tag to use for running remote migrations
|
|
158
|
+
-v, --verbose Enable additional logging
|
|
100
159
|
|
|
101
160
|
DESCRIPTION
|
|
102
161
|
Migrate MemberJunction database to latest version
|
|
@@ -105,7 +164,7 @@ EXAMPLES
|
|
|
105
164
|
$ mj migrate
|
|
106
165
|
```
|
|
107
166
|
|
|
108
|
-
_See code: [src/commands/migrate/index.ts](https://github.com/MemberJunction/MJ/blob/v2.13.
|
|
167
|
+
_See code: [src/commands/migrate/index.ts](https://github.com/MemberJunction/MJ/blob/v2.13.3/src/commands/migrate/index.ts)_
|
|
109
168
|
|
|
110
169
|
## `mj version`
|
|
111
170
|
|
package/bin/dev.js
CHANGED
package/bin/run.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class Bump extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: {
|
|
5
|
+
command: string;
|
|
6
|
+
description: string;
|
|
7
|
+
}[];
|
|
8
|
+
static flags: {
|
|
9
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
recursive: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
tag: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
quiet: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
dry: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
};
|
|
15
|
+
run(): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const core_1 = require("@oclif/core");
|
|
30
|
+
const node_fs_1 = require("node:fs");
|
|
31
|
+
const zod_1 = require("zod");
|
|
32
|
+
const fg = __importStar(require("fast-glob"));
|
|
33
|
+
const ora_classic_1 = __importDefault(require("ora-classic"));
|
|
34
|
+
const node_path_1 = require("node:path");
|
|
35
|
+
// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
|
|
36
|
+
const semverRegex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
37
|
+
const tagSchema = zod_1.z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.transform((tag) => tag?.replace(/^v/, ''))
|
|
41
|
+
.refine((tag) => !tag || semverRegex.test(tag));
|
|
42
|
+
/**
|
|
43
|
+
* No-op used to suppress logging output
|
|
44
|
+
* @returns No return value
|
|
45
|
+
*/
|
|
46
|
+
const suppressLogging = () => null;
|
|
47
|
+
class Bump extends core_1.Command {
|
|
48
|
+
static description = 'Bumps MemberJunction dependency versions';
|
|
49
|
+
static examples = [
|
|
50
|
+
{
|
|
51
|
+
command: '<%= config.bin %> <%= command.id %>',
|
|
52
|
+
description: "Bump all @memberjunction/* dependencies in the current directory's package.json to the CLI version",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
command: '<%= config.bin %> <%= command.id %> -rdv',
|
|
56
|
+
description: 'Preview all recursive packages bumps without writing any changes.',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
command: '<%= config.bin %> <%= command.id %> -rqt v2.10.0 | xargs -n1 -I{} npm install --prefix {}',
|
|
60
|
+
description: 'Recursively bump all @memberjunction/* dependencies in all packages to version v2.10.0 and output only the paths containing the updated package.json files. Pipe the output to xargs to run npm install in each directory and update the package-lock.json files as well.',
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
static flags = {
|
|
64
|
+
verbose: core_1.Flags.boolean({ char: 'v', description: 'Enable additional logging' }),
|
|
65
|
+
recursive: core_1.Flags.boolean({ char: 'r', description: 'Bump version in current directory and all subdirectories' }),
|
|
66
|
+
tag: core_1.Flags.string({ char: 't', description: 'Version tag to bump target for bump (e.g. v2.10.0), defaults to the CLI version' }),
|
|
67
|
+
quiet: core_1.Flags.boolean({ char: 'q', description: 'Only output paths for updated packages' }),
|
|
68
|
+
dry: core_1.Flags.boolean({ char: 'd', description: 'Dry run, do not write changes to package.json files' }),
|
|
69
|
+
};
|
|
70
|
+
async run() {
|
|
71
|
+
const { flags } = await this.parse(Bump);
|
|
72
|
+
const verboseLogger = flags.verbose && !flags.quiet ? this.log.bind(this) : suppressLogging;
|
|
73
|
+
const normalLogger = flags.quiet ? suppressLogging : this.log.bind(this);
|
|
74
|
+
const quietLogger = flags.quiet ? this.log.bind(this) : suppressLogging;
|
|
75
|
+
// Get the target version from the tag flag or the CLI version
|
|
76
|
+
const tagArgument = tagSchema.safeParse(flags.tag);
|
|
77
|
+
if (flags.tag && tagArgument.success === false) {
|
|
78
|
+
this.error(`Invalid tag argument: '${flags.tag}'; must be a valid semver version string (e.g. v2.10.0)`);
|
|
79
|
+
}
|
|
80
|
+
const targetVersion = flags.tag && tagArgument.success ? tagArgument.data : this.config.pjson.version;
|
|
81
|
+
normalLogger(`Bumping all @memberjunction/* dependencies to version ${targetVersion}`);
|
|
82
|
+
flags.recursive && normalLogger('Recursively updating all package.json files');
|
|
83
|
+
// get list of package.json files to edit
|
|
84
|
+
const packageJsonFiles = fg.sync(`${flags.recursive ? '**/' : ''}package.json`, { ignore: ['node_modules/**'] });
|
|
85
|
+
if (packageJsonFiles.length === 0) {
|
|
86
|
+
this.error('No package.json files found');
|
|
87
|
+
}
|
|
88
|
+
if (flags.dry) {
|
|
89
|
+
normalLogger('Dry run, no changes will be made to package.json files');
|
|
90
|
+
}
|
|
91
|
+
const skipped = [];
|
|
92
|
+
const mjRegx = /"@memberjunction\/([^"]+)":(\s*)("[^"]+")/g;
|
|
93
|
+
const banner = 'Bumping packages... ';
|
|
94
|
+
const spinner = (0, ora_classic_1.default)(banner);
|
|
95
|
+
spinner.start();
|
|
96
|
+
normalLogger('');
|
|
97
|
+
try {
|
|
98
|
+
for (let i = 0; i < packageJsonFiles.length; i++) {
|
|
99
|
+
const packageJson = `./${packageJsonFiles[i]}`;
|
|
100
|
+
const packageJsonContents = (0, node_fs_1.readFileSync)(packageJson).toString();
|
|
101
|
+
if (!mjRegx.test(packageJsonContents)) {
|
|
102
|
+
skipped.push(packageJson);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
verboseLogger(`\tBumping ${(0, node_path_1.dirname)(packageJson)}`);
|
|
106
|
+
spinner.text = `${banner} ${i + 1 - skipped.length}/${packageJsonFiles.length - skipped.length}`;
|
|
107
|
+
const bumpedPackageJson = packageJsonContents.replaceAll(mjRegx, `"@memberjunction/$1":$2"${targetVersion}"`);
|
|
108
|
+
if (!flags.dry) {
|
|
109
|
+
(0, node_fs_1.writeFileSync)(packageJson, bumpedPackageJson);
|
|
110
|
+
}
|
|
111
|
+
// In quiet mode, we only output the paths of the updated package.json files so they can be piped to another command
|
|
112
|
+
quietLogger((0, node_path_1.dirname)(packageJson));
|
|
113
|
+
}
|
|
114
|
+
spinner.succeed(`Bumped ${packageJsonFiles.length - skipped.length}/${packageJsonFiles.length} packages`);
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
spinner.fail();
|
|
118
|
+
this.error(error instanceof Error ? error : 'Command failed');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.default = Bump;
|
|
@@ -23,7 +23,7 @@ class Clean extends core_1.Command {
|
|
|
23
23
|
if (!config_1.config) {
|
|
24
24
|
this.error('No configuration found');
|
|
25
25
|
}
|
|
26
|
-
const flywayConfig = (0, config_1.getFlywayConfig)(config_1.config);
|
|
26
|
+
const flywayConfig = await (0, config_1.getFlywayConfig)(config_1.config);
|
|
27
27
|
const flyway = new node_flyway_1.Flyway(flywayConfig);
|
|
28
28
|
this.log('Resetting MJ database to pre-installation state');
|
|
29
29
|
this.log('Note that users and roles have not been dropped');
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { ParserOutput } from '@oclif/core/lib/interfaces/parser';
|
|
3
|
+
export default class CodeGen extends Command {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
skipdb: import("@oclif/core/lib/interfaces/parser").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
flags: ParserOutput<CodeGen>['flags'];
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const config_1 = require("../../config");
|
|
5
|
+
const codegen_lib_1 = require("@memberjunction/codegen-lib");
|
|
6
|
+
class CodeGen extends core_1.Command {
|
|
7
|
+
static description = 'Run CodeGen to generate code and update metadata for MemberJunction';
|
|
8
|
+
static examples = [
|
|
9
|
+
`<%= config.bin %> <%= command.id %>
|
|
10
|
+
`,
|
|
11
|
+
];
|
|
12
|
+
static flags = {
|
|
13
|
+
skipdb: core_1.Flags.boolean({ description: 'Skip database migration' }),
|
|
14
|
+
};
|
|
15
|
+
flags;
|
|
16
|
+
async run() {
|
|
17
|
+
const parsed = await this.parse(CodeGen);
|
|
18
|
+
this.flags = parsed.flags;
|
|
19
|
+
const config = (0, config_1.updatedConfig)();
|
|
20
|
+
if (!config) {
|
|
21
|
+
this.error('No configuration found');
|
|
22
|
+
}
|
|
23
|
+
// Initialize configuration
|
|
24
|
+
(0, codegen_lib_1.initializeConfig)(process.cwd());
|
|
25
|
+
// Call the function with the determined argument
|
|
26
|
+
(0, codegen_lib_1.runMemberJunctionCodeGeneration)(this.flags.skipDb);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.default = CodeGen;
|
|
@@ -5,7 +5,7 @@ type Config = z.infer<typeof configSchema>;
|
|
|
5
5
|
declare const configSchema: z.ZodObject<{
|
|
6
6
|
dbUrl: z.ZodString;
|
|
7
7
|
dbInstance: z.ZodString;
|
|
8
|
-
dbTrustServerCertificate: z.
|
|
8
|
+
dbTrustServerCertificate: z.ZodEffects<z.ZodDefault<z.ZodBoolean>, "N" | "Y", boolean | undefined>;
|
|
9
9
|
dbDatabase: z.ZodString;
|
|
10
10
|
dbPort: z.ZodNumber;
|
|
11
11
|
codeGenLogin: z.ZodString;
|
|
@@ -19,7 +19,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
19
19
|
auth0ClientId: z.ZodOptional<z.ZodString>;
|
|
20
20
|
auth0ClientSecret: z.ZodOptional<z.ZodString>;
|
|
21
21
|
auth0Domain: z.ZodOptional<z.ZodString>;
|
|
22
|
-
createNewUser: z.ZodOptional<z.
|
|
22
|
+
createNewUser: z.ZodOptional<z.ZodBoolean>;
|
|
23
23
|
userEmail: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>>>;
|
|
24
24
|
userFirstName: z.ZodOptional<z.ZodString>;
|
|
25
25
|
userLastName: z.ZodOptional<z.ZodString>;
|
|
@@ -31,7 +31,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
31
31
|
dbDatabase: string;
|
|
32
32
|
dbPort: number;
|
|
33
33
|
codeGenLogin: string;
|
|
34
|
-
dbTrustServerCertificate: "
|
|
34
|
+
dbTrustServerCertificate: "N" | "Y";
|
|
35
35
|
dbUrl: string;
|
|
36
36
|
dbInstance: string;
|
|
37
37
|
codeGenPwD: string;
|
|
@@ -45,7 +45,7 @@ declare const configSchema: z.ZodObject<{
|
|
|
45
45
|
auth0ClientId?: string | undefined;
|
|
46
46
|
auth0ClientSecret?: string | undefined;
|
|
47
47
|
auth0Domain?: string | undefined;
|
|
48
|
-
createNewUser?:
|
|
48
|
+
createNewUser?: boolean | undefined;
|
|
49
49
|
userFirstName?: string | undefined;
|
|
50
50
|
userLastName?: string | undefined;
|
|
51
51
|
userName?: string | undefined;
|
|
@@ -56,20 +56,20 @@ declare const configSchema: z.ZodObject<{
|
|
|
56
56
|
dbDatabase: string;
|
|
57
57
|
dbPort: number;
|
|
58
58
|
codeGenLogin: string;
|
|
59
|
-
dbTrustServerCertificate: "Y" | "N";
|
|
60
59
|
dbUrl: string;
|
|
61
60
|
dbInstance: string;
|
|
62
61
|
codeGenPwD: string;
|
|
63
62
|
mjAPILogin: string;
|
|
64
63
|
mjAPIPwD: string;
|
|
65
64
|
authType: "MSAL" | "AUTH0" | "BOTH";
|
|
65
|
+
dbTrustServerCertificate?: boolean | undefined;
|
|
66
66
|
graphQLPort?: number | undefined;
|
|
67
67
|
msalWebClientId?: string | undefined;
|
|
68
68
|
msalTenantId?: string | undefined;
|
|
69
69
|
auth0ClientId?: string | undefined;
|
|
70
70
|
auth0ClientSecret?: string | undefined;
|
|
71
71
|
auth0Domain?: string | undefined;
|
|
72
|
-
createNewUser?:
|
|
72
|
+
createNewUser?: boolean | undefined;
|
|
73
73
|
userEmail?: string | undefined;
|
|
74
74
|
userFirstName?: string | undefined;
|
|
75
75
|
userLastName?: string | undefined;
|
|
@@ -91,7 +91,7 @@ export default class Install extends Command {
|
|
|
91
91
|
dbDatabase: string;
|
|
92
92
|
dbPort: number;
|
|
93
93
|
codeGenLogin: string;
|
|
94
|
-
dbTrustServerCertificate: "
|
|
94
|
+
dbTrustServerCertificate: "N" | "Y";
|
|
95
95
|
dbUrl: string;
|
|
96
96
|
dbInstance: string;
|
|
97
97
|
codeGenPwD: string;
|
|
@@ -105,7 +105,7 @@ export default class Install extends Command {
|
|
|
105
105
|
auth0ClientId?: string | undefined;
|
|
106
106
|
auth0ClientSecret?: string | undefined;
|
|
107
107
|
auth0Domain?: string | undefined;
|
|
108
|
-
createNewUser?:
|
|
108
|
+
createNewUser?: boolean | undefined;
|
|
109
109
|
userFirstName?: string | undefined;
|
|
110
110
|
userLastName?: string | undefined;
|
|
111
111
|
userName?: string | undefined;
|
|
@@ -133,13 +133,12 @@ export default class Install extends Command {
|
|
|
133
133
|
updateEnvironmentFiles(dirPath: string, config: Record<string, string | undefined>): Promise<void>;
|
|
134
134
|
renameFolderToMJ_BASE(dbDatabase: string): void;
|
|
135
135
|
/**
|
|
136
|
-
* Updates newUserSetup in the config.
|
|
137
|
-
* @param {string} dirPath - The path to the directory containing the config.json file.
|
|
136
|
+
* Updates newUserSetup in the mj.config.cjs file.
|
|
138
137
|
* @param {string} userName - The new UserName to set.
|
|
139
138
|
* @param {string} firstName - The new FirstName to set.
|
|
140
139
|
* @param {string} lastName - The new LastName to set.
|
|
141
140
|
* @param {string} email - The new Email to set.
|
|
142
141
|
*/
|
|
143
|
-
updateConfigNewUserSetup(
|
|
142
|
+
updateConfigNewUserSetup(userName?: string, firstName?: string, lastName?: string, email?: string): Promise<void>;
|
|
144
143
|
}
|
|
145
144
|
export {};
|
|
@@ -27,6 +27,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
const prompts_1 = require("@inquirer/prompts");
|
|
30
|
+
const dotenv = __importStar(require("dotenv"));
|
|
31
|
+
const recast = __importStar(require("recast"));
|
|
30
32
|
const core_1 = require("@oclif/core");
|
|
31
33
|
const fs = __importStar(require("fs-extra"));
|
|
32
34
|
const node_child_process_1 = require("node:child_process");
|
|
@@ -44,7 +46,10 @@ const MJEXPLORER_DIR = 'MJExplorer';
|
|
|
44
46
|
const configSchema = zod_1.z.object({
|
|
45
47
|
dbUrl: zod_1.z.string().min(1),
|
|
46
48
|
dbInstance: zod_1.z.string(),
|
|
47
|
-
dbTrustServerCertificate: zod_1.z.
|
|
49
|
+
dbTrustServerCertificate: zod_1.z.coerce
|
|
50
|
+
.boolean()
|
|
51
|
+
.default(false)
|
|
52
|
+
.transform((v) => (v ? 'Y' : 'N')),
|
|
48
53
|
dbDatabase: zod_1.z.string().min(1),
|
|
49
54
|
dbPort: zod_1.z.number({ coerce: true }).int().positive(),
|
|
50
55
|
codeGenLogin: zod_1.z.string(),
|
|
@@ -58,7 +63,7 @@ const configSchema = zod_1.z.object({
|
|
|
58
63
|
auth0ClientId: zod_1.z.string().optional(),
|
|
59
64
|
auth0ClientSecret: zod_1.z.string().optional(),
|
|
60
65
|
auth0Domain: zod_1.z.string().optional(),
|
|
61
|
-
createNewUser: zod_1.z.
|
|
66
|
+
createNewUser: zod_1.z.coerce.boolean().optional(),
|
|
62
67
|
userEmail: zod_1.z.string().email().or(zod_1.z.literal('')).optional().default(''),
|
|
63
68
|
userFirstName: zod_1.z.string().optional(),
|
|
64
69
|
userLastName: zod_1.z.string().optional(),
|
|
@@ -83,17 +88,12 @@ class Install extends core_1.Command {
|
|
|
83
88
|
this.flags = parsed.flags;
|
|
84
89
|
this.checkNodeVersion();
|
|
85
90
|
this.checkAvailableDiskSpace(2);
|
|
86
|
-
this.verifyDirs(
|
|
91
|
+
this.verifyDirs(GENERATED_ENTITIES_DIR, SQL_SCRIPTS_DIR, MJAPI_DIR, MJEXPLORER_DIR);
|
|
87
92
|
this.userConfig = await this.getUserConfiguration();
|
|
88
93
|
this.log('Setting up MemberJunction Distribution...');
|
|
89
94
|
if (this.flags.verbose) {
|
|
90
95
|
this.logJson({ userConfig: this.userConfig, flags: this.flags });
|
|
91
96
|
}
|
|
92
|
-
// if the user asked for a new user via our config file, need to push that info down to the CodeGen config.json file
|
|
93
|
-
if (this.userConfig.createNewUser === 'Y') {
|
|
94
|
-
this.log(' Setting up config.json...');
|
|
95
|
-
await this.updateConfigNewUserSetup(CODEGEN_DIR, this.userConfig.userName, this.userConfig.userFirstName, this.userConfig.userLastName, this.userConfig.userEmail);
|
|
96
|
-
}
|
|
97
97
|
//*******************************************************************
|
|
98
98
|
// Process GeneratedEntities
|
|
99
99
|
//*******************************************************************
|
|
@@ -101,16 +101,18 @@ class Install extends core_1.Command {
|
|
|
101
101
|
this.log('Running npm install...');
|
|
102
102
|
(0, node_child_process_1.execSync)('npm install', { stdio: 'inherit', cwd: GENERATED_ENTITIES_DIR });
|
|
103
103
|
//*******************************************************************
|
|
104
|
-
// Process
|
|
104
|
+
// Process Config
|
|
105
105
|
//*******************************************************************
|
|
106
|
-
this.log('\nProcessing
|
|
106
|
+
this.log('\nProcessing Config...');
|
|
107
107
|
this.log(' Updating ');
|
|
108
|
-
this.log(' Setting up .env and config.
|
|
109
|
-
const
|
|
108
|
+
this.log(' Setting up .env and mj.config.cjs...');
|
|
109
|
+
const dotenvContent = `#Database Setup
|
|
110
110
|
DB_HOST='${this.userConfig.dbUrl}'
|
|
111
111
|
DB_PORT=${this.userConfig.dbPort}
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
CODEGEN_DB_USERNAME='${this.userConfig.codeGenLogin}'
|
|
113
|
+
CODEGEN_DB_PASSWORD='${this.userConfig.codeGenPwD}'
|
|
114
|
+
DB_USERNAME='${this.userConfig.mjAPILogin}'
|
|
115
|
+
DB_PASSWORD='${this.userConfig.mjAPIPwD}'
|
|
114
116
|
DB_DATABASE='${this.userConfig.dbDatabase}'
|
|
115
117
|
${this.userConfig.dbInstance ? "DB_INSTANCE_NAME='" + this.userConfig.dbInstance + "'" : ''}
|
|
116
118
|
${this.userConfig.dbTrustServerCertificate === 'Y' ? 'DB_TRUST_SERVER_CERTIFICATE=1' : ''}
|
|
@@ -121,34 +123,12 @@ OUTPUT_CODE='${this.userConfig.dbDatabase}'
|
|
|
121
123
|
# Name of the schema that MJ has been setup in. This defaults to __mj
|
|
122
124
|
MJ_CORE_SCHEMA='__mj'
|
|
123
125
|
|
|
124
|
-
# If using Advanced Generation, populate this with the API key for the AI vendor you are using
|
|
125
|
-
# Also, you need to configure the settings under advancedGeneration in the config.
|
|
126
|
+
# If using Advanced Generation or the MJAI library, populate this with the API key for the AI vendor you are using
|
|
127
|
+
# Also, you need to configure the settings under advancedGeneration in the mj.config.cjs file, including choosing the vendor.
|
|
126
128
|
AI_VENDOR_API_KEY__OpenAILLM='${this.userConfig.openAIAPIKey}'
|
|
127
129
|
AI_VENDOR_API_KEY__MistralLLM='${this.userConfig.mistralAPIKey}'
|
|
128
130
|
AI_VENDOR_API_KEY__AnthropicLLM='${this.userConfig.anthropicAPIKey}'
|
|
129
131
|
|
|
130
|
-
#CONFIG_FILE is the name of the file that has the configuration parameters for CodeGen
|
|
131
|
-
CONFIG_FILE='config.json'
|
|
132
|
-
`;
|
|
133
|
-
fs.writeFileSync(node_path_1.default.join(CODEGEN_DIR, '.env'), codeGenENV);
|
|
134
|
-
this.log(' Running npm link for GeneratedEntities...');
|
|
135
|
-
(0, node_child_process_1.execSync)('npm link ../GeneratedEntities', { stdio: 'inherit', cwd: CODEGEN_DIR });
|
|
136
|
-
//*******************************************************************
|
|
137
|
-
// Process MJAPI
|
|
138
|
-
//*******************************************************************
|
|
139
|
-
this.log('\n\nBootstrapping MJAPI...');
|
|
140
|
-
this.log(' Running npm link for generated code...');
|
|
141
|
-
(0, node_child_process_1.execSync)('npm link ../GeneratedEntities ../GeneratedActions', { stdio: 'inherit', cwd: MJAPI_DIR });
|
|
142
|
-
this.log(' Setting up MJAPI .env file...');
|
|
143
|
-
const mjAPIENV = `#Database Setup
|
|
144
|
-
DB_HOST='${this.userConfig.dbUrl}'
|
|
145
|
-
DB_PORT=${this.userConfig.dbPort}
|
|
146
|
-
DB_USERNAME='${this.userConfig.mjAPILogin}'
|
|
147
|
-
DB_PASSWORD='${this.userConfig.mjAPIPwD}'
|
|
148
|
-
DB_DATABASE='${this.userConfig.dbDatabase}'
|
|
149
|
-
${this.userConfig.dbInstance ? "DB_INSTANCE_NAME='" + this.userConfig.dbInstance + "'" : ''}
|
|
150
|
-
${this.userConfig.dbTrustServerCertificate === 'Y' ? 'DB_TRUST_SERVER_CERTIFICATE=1' : ''}
|
|
151
|
-
|
|
152
132
|
PORT=${this.userConfig.graphQLPort}
|
|
153
133
|
|
|
154
134
|
UPDATE_USER_CACHE_WHEN_NOT_FOUND=1
|
|
@@ -164,28 +144,30 @@ AUTH0_CLIENT_ID=${this.userConfig.auth0ClientId}
|
|
|
164
144
|
AUTH0_CLIENT_SECRET=${this.userConfig.auth0ClientSecret}
|
|
165
145
|
AUTH0_DOMAIN=${this.userConfig.auth0Domain}
|
|
166
146
|
|
|
167
|
-
# Name of the schema that MJ has been setup in. This defaults to __mj
|
|
168
|
-
MJ_CORE_SCHEMA='__mj'
|
|
169
|
-
|
|
170
|
-
# If you are using MJAI library, provide your API KEYS here for the various services
|
|
171
|
-
# Format is AI_VENDOR_API_KEY__<DriverClass> Where DriverClass is the DriverClass field from the AI Models Entity in MemberJunction
|
|
172
|
-
AI_VENDOR_API_KEY__OpenAILLM = '${this.userConfig.openAIAPIKey}'
|
|
173
|
-
AI_VENDOR_API_KEY__AnthropicLLM = '${this.userConfig.anthropicAPIKey}'
|
|
174
|
-
AI_VENDOR_API_KEY__MistralLLM = '${this.userConfig.mistralAPIKey}'
|
|
175
|
-
|
|
176
147
|
# Skip API URL, KEY and Org ID
|
|
177
148
|
# YOU MUST ENTER IN THE CORRECT URL and ORG ID for your Skip API USE BELOW
|
|
178
149
|
ASK_SKIP_API_URL = 'http://localhost:8000'
|
|
179
150
|
ASK_SKIP_ORGANIZATION_ID = 1
|
|
180
|
-
|
|
181
|
-
CONFIG_FILE='config.json'
|
|
182
151
|
`;
|
|
183
|
-
fs.writeFileSync(
|
|
152
|
+
fs.writeFileSync('.env', dotenvContent);
|
|
153
|
+
//*******************************************************************
|
|
154
|
+
// Process CodeGen
|
|
155
|
+
//*******************************************************************
|
|
156
|
+
this.log('\nProcessing CodeGen...');
|
|
157
|
+
this.log(' Running npm link for GeneratedEntities...');
|
|
158
|
+
(0, node_child_process_1.execSync)('npm link ../GeneratedEntities', { stdio: 'inherit', cwd: CODEGEN_DIR });
|
|
159
|
+
//*******************************************************************
|
|
160
|
+
// Process MJAPI
|
|
161
|
+
//*******************************************************************
|
|
162
|
+
this.log('\n\nBootstrapping MJAPI...');
|
|
163
|
+
this.log(' Running npm link for generated code...');
|
|
164
|
+
(0, node_child_process_1.execSync)('npm link ../GeneratedEntities ../GeneratedActions', { stdio: 'inherit', cwd: MJAPI_DIR });
|
|
184
165
|
this.log('Running CodeGen...');
|
|
185
166
|
this.renameFolderToMJ_BASE(this.userConfig.dbDatabase);
|
|
186
167
|
// next, run CodeGen
|
|
187
168
|
// We do not manually run the compilation for GeneratedEntities because CodeGen handles that, but notice above that we did npm install for GeneratedEntities otherwise when CodeGen attempts to compile it, it will fail.
|
|
188
|
-
|
|
169
|
+
dotenv.config();
|
|
170
|
+
this.config.runCommand('codegen');
|
|
189
171
|
// Process MJExplorer
|
|
190
172
|
this.log('\nProcessing MJExplorer...');
|
|
191
173
|
this.log('\n Updating environment files...');
|
|
@@ -221,7 +203,7 @@ CONFIG_FILE='config.json'
|
|
|
221
203
|
}
|
|
222
204
|
}
|
|
223
205
|
if (!userConfig) {
|
|
224
|
-
this.log('\n>>> Please answer the following questions to setup the .env files for CodeGen. After this process you can manually edit the .env file
|
|
206
|
+
this.log('\n>>> Please answer the following questions to setup the .env files for CodeGen. After this process you can manually edit the .env file as desired.');
|
|
225
207
|
const dbUrl = await (0, prompts_1.input)({
|
|
226
208
|
message: 'Enter the database server hostname:',
|
|
227
209
|
validate: (v) => configSchema.shape.dbDatabase.safeParse(v).success,
|
|
@@ -256,7 +238,7 @@ CONFIG_FILE='config.json'
|
|
|
256
238
|
const authType = await (0, prompts_1.select)({
|
|
257
239
|
message: 'Will you be using Microsoft Entra (formerly Azure AD), Auth0, or both for authentication services for MJAPI:',
|
|
258
240
|
choices: [
|
|
259
|
-
{ name: 'Microsoft Entra', value: 'MSAL' },
|
|
241
|
+
{ name: 'Microsoft Entra (MSAL)', value: 'MSAL' },
|
|
260
242
|
{ name: 'Auth0', value: 'AUTH0' },
|
|
261
243
|
{ name: 'Both', value: 'BOTH' },
|
|
262
244
|
],
|
|
@@ -422,29 +404,48 @@ CONFIG_FILE='config.json'
|
|
|
422
404
|
}
|
|
423
405
|
}
|
|
424
406
|
/**
|
|
425
|
-
* Updates newUserSetup in the config.
|
|
426
|
-
* @param {string} dirPath - The path to the directory containing the config.json file.
|
|
407
|
+
* Updates newUserSetup in the mj.config.cjs file.
|
|
427
408
|
* @param {string} userName - The new UserName to set.
|
|
428
409
|
* @param {string} firstName - The new FirstName to set.
|
|
429
410
|
* @param {string} lastName - The new LastName to set.
|
|
430
411
|
* @param {string} email - The new Email to set.
|
|
431
412
|
*/
|
|
432
|
-
async updateConfigNewUserSetup(
|
|
413
|
+
async updateConfigNewUserSetup(userName, firstName, lastName, email) {
|
|
433
414
|
try {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
const
|
|
438
|
-
//
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
415
|
+
// Read the mj.config.cjs file
|
|
416
|
+
const configFileContent = await fs.readFile('mj.config.cjs', 'utf8');
|
|
417
|
+
// Parse the content into an AST
|
|
418
|
+
const ast = recast.parse(configFileContent);
|
|
419
|
+
// Modify the AST
|
|
420
|
+
const n = recast.types.namedTypes;
|
|
421
|
+
const b = recast.types.builders;
|
|
422
|
+
recast.types.visit(ast, {
|
|
423
|
+
visitObjectExpression(path) {
|
|
424
|
+
const properties = path.node.properties;
|
|
425
|
+
// Check if newUserSetup key exists
|
|
426
|
+
const newUserSetupProperty = properties.find((prop) => n.Property.check(prop) && n.Identifier.check(prop.key) && prop.key.name === 'newUserSetup');
|
|
427
|
+
const newUserSetupValue = b.objectExpression([
|
|
428
|
+
b.property('init', b.identifier('userName'), b.literal(userName || '')),
|
|
429
|
+
b.property('init', b.identifier('firstName'), b.literal(firstName || '')),
|
|
430
|
+
b.property('init', b.identifier('lastName'), b.literal(lastName || '')),
|
|
431
|
+
b.property('init', b.identifier('email'), b.literal(email || '')),
|
|
432
|
+
]);
|
|
433
|
+
if (newUserSetupProperty && newUserSetupProperty.type === 'Property') {
|
|
434
|
+
// Overwrite the existing newUserSetup key with an object
|
|
435
|
+
newUserSetupProperty.value = newUserSetupValue;
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
// Add a new newUserSetup key
|
|
439
|
+
properties.push(b.property('init', b.identifier('newUserSetup'), newUserSetupValue));
|
|
440
|
+
}
|
|
441
|
+
return false; // Stop traversing this path
|
|
442
|
+
},
|
|
443
|
+
});
|
|
444
|
+
// Serialize the AST back to a string
|
|
445
|
+
const updatedConfigFileContent = recast.prettyPrint(ast).code;
|
|
446
|
+
// Write the updated content back to the file
|
|
447
|
+
await fs.writeFile('mj.config.cjs', updatedConfigFileContent);
|
|
448
|
+
this.log(` Updated mj.config.cjs`);
|
|
448
449
|
}
|
|
449
450
|
catch (err) {
|
|
450
451
|
this.logToStderr('Error:', err);
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
|
-
import { ParserOutput } from '@oclif/core/lib/interfaces/parser';
|
|
3
2
|
export default class Migrate extends Command {
|
|
4
3
|
static description: string;
|
|
5
4
|
static examples: string[];
|
|
6
5
|
static flags: {
|
|
7
|
-
verbose: import("@oclif/core/lib/interfaces
|
|
6
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
tag: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
8
|
};
|
|
9
|
-
flags: ParserOutput<Migrate>['flags'];
|
|
10
9
|
run(): Promise<void>;
|
|
11
10
|
}
|
|
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const core_1 = require("@oclif/core");
|
|
7
7
|
const node_flyway_1 = require("node-flyway");
|
|
8
|
-
const config_1 = require("../../config");
|
|
9
8
|
const ora_classic_1 = __importDefault(require("ora-classic"));
|
|
9
|
+
const config_1 = require("../../config");
|
|
10
10
|
class Migrate extends core_1.Command {
|
|
11
11
|
static description = 'Migrate MemberJunction database to latest version';
|
|
12
12
|
static examples = [
|
|
@@ -15,27 +15,29 @@ class Migrate extends core_1.Command {
|
|
|
15
15
|
];
|
|
16
16
|
static flags = {
|
|
17
17
|
verbose: core_1.Flags.boolean({ char: 'v', description: 'Enable additional logging' }),
|
|
18
|
+
tag: core_1.Flags.string({ char: 't', description: 'Version tag to use for running remote migrations' }),
|
|
18
19
|
};
|
|
19
|
-
flags;
|
|
20
20
|
async run() {
|
|
21
|
-
const
|
|
22
|
-
this.flags = parsed.flags;
|
|
21
|
+
const { flags } = await this.parse(Migrate);
|
|
23
22
|
if (!config_1.config) {
|
|
24
23
|
this.error('No configuration found');
|
|
25
24
|
}
|
|
26
|
-
const flywayConfig = (0, config_1.getFlywayConfig)(config_1.config);
|
|
25
|
+
const flywayConfig = await (0, config_1.getFlywayConfig)(config_1.config, flags.tag);
|
|
27
26
|
const flyway = new node_flyway_1.Flyway(flywayConfig);
|
|
28
|
-
if (
|
|
27
|
+
if (flags.verbose) {
|
|
29
28
|
this.log(`Connecting to ${flywayConfig.url}`);
|
|
30
29
|
this.log(`Migrating ${config_1.config.coreSchema} schema using migrations from:\n\t- ${flywayConfig.migrationLocations.join('\n\t- ')}\n`);
|
|
31
30
|
}
|
|
31
|
+
if (flags.tag) {
|
|
32
|
+
this.log(`Migrating to ${flags.tag}`);
|
|
33
|
+
}
|
|
32
34
|
const spinner = (0, ora_classic_1.default)('Running migrations...');
|
|
33
35
|
spinner.start();
|
|
34
36
|
const result = await flyway.migrate();
|
|
35
37
|
if (result.success) {
|
|
36
38
|
spinner.succeed();
|
|
37
39
|
this.log(`Migrations complete in ${result.additionalDetails.executionTime / 1000}s`);
|
|
38
|
-
if (result.flywayResponse?.success &&
|
|
40
|
+
if (result.flywayResponse?.success && flags.verbose) {
|
|
39
41
|
this.log(`\tUpdated to ${result.flywayResponse?.targetSchemaVersion}`);
|
|
40
42
|
}
|
|
41
43
|
}
|
|
@@ -43,7 +45,7 @@ class Migrate extends core_1.Command {
|
|
|
43
45
|
spinner.fail();
|
|
44
46
|
if (result.error) {
|
|
45
47
|
this.logToStderr(result.error.message);
|
|
46
|
-
if (
|
|
48
|
+
if (flags.verbose) {
|
|
47
49
|
this.logToStderr(`ERROR CODE: ${result.error.errorCode}`);
|
|
48
50
|
this.logToStderr(result.error.stackTrace);
|
|
49
51
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
1
|
import { FlywayConfig } from 'node-flyway/dist/types/types';
|
|
2
|
+
import { z } from 'zod';
|
|
3
3
|
export type MJConfig = z.infer<typeof mjConfigSchema>;
|
|
4
4
|
declare const mjConfigSchema: z.ZodObject<{
|
|
5
5
|
dbHost: z.ZodDefault<z.ZodString>;
|
|
@@ -8,9 +8,10 @@ declare const mjConfigSchema: z.ZodObject<{
|
|
|
8
8
|
codeGenLogin: z.ZodString;
|
|
9
9
|
codeGenPassword: z.ZodString;
|
|
10
10
|
migrationsLocation: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
11
|
-
dbTrustServerCertificate: z.ZodDefault<z.
|
|
11
|
+
dbTrustServerCertificate: z.ZodDefault<z.ZodBoolean>;
|
|
12
12
|
coreSchema: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
13
|
-
cleanDisabled: z.ZodDefault<z.ZodBoolean
|
|
13
|
+
cleanDisabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
14
|
+
mjRepoUrl: z.ZodCatch<z.ZodString>;
|
|
14
15
|
}, "strip", z.ZodTypeAny, {
|
|
15
16
|
cleanDisabled: boolean;
|
|
16
17
|
dbHost: string;
|
|
@@ -19,8 +20,9 @@ declare const mjConfigSchema: z.ZodObject<{
|
|
|
19
20
|
codeGenLogin: string;
|
|
20
21
|
codeGenPassword: string;
|
|
21
22
|
migrationsLocation: string;
|
|
22
|
-
dbTrustServerCertificate:
|
|
23
|
+
dbTrustServerCertificate: boolean;
|
|
23
24
|
coreSchema: string;
|
|
25
|
+
mjRepoUrl: string;
|
|
24
26
|
}, {
|
|
25
27
|
dbDatabase: string;
|
|
26
28
|
codeGenLogin: string;
|
|
@@ -29,8 +31,9 @@ declare const mjConfigSchema: z.ZodObject<{
|
|
|
29
31
|
dbHost?: string | undefined;
|
|
30
32
|
dbPort?: number | undefined;
|
|
31
33
|
migrationsLocation?: string | undefined;
|
|
32
|
-
dbTrustServerCertificate?:
|
|
34
|
+
dbTrustServerCertificate?: boolean | undefined;
|
|
33
35
|
coreSchema?: string | undefined;
|
|
36
|
+
mjRepoUrl?: unknown;
|
|
34
37
|
}>;
|
|
35
38
|
export declare const config: {
|
|
36
39
|
cleanDisabled: boolean;
|
|
@@ -40,9 +43,22 @@ export declare const config: {
|
|
|
40
43
|
codeGenLogin: string;
|
|
41
44
|
codeGenPassword: string;
|
|
42
45
|
migrationsLocation: string;
|
|
43
|
-
dbTrustServerCertificate:
|
|
46
|
+
dbTrustServerCertificate: boolean;
|
|
47
|
+
coreSchema: string;
|
|
48
|
+
mjRepoUrl: string;
|
|
49
|
+
} | undefined;
|
|
50
|
+
export declare const updatedConfig: () => {
|
|
51
|
+
cleanDisabled: boolean;
|
|
52
|
+
dbHost: string;
|
|
53
|
+
dbDatabase: string;
|
|
54
|
+
dbPort: number;
|
|
55
|
+
codeGenLogin: string;
|
|
56
|
+
codeGenPassword: string;
|
|
57
|
+
migrationsLocation: string;
|
|
58
|
+
dbTrustServerCertificate: boolean;
|
|
44
59
|
coreSchema: string;
|
|
60
|
+
mjRepoUrl: string;
|
|
45
61
|
} | undefined;
|
|
46
62
|
export declare const createFlywayUrl: (mjConfig: MJConfig) => string;
|
|
47
|
-
export declare const getFlywayConfig: (mjConfig: MJConfig) => FlywayConfig
|
|
63
|
+
export declare const getFlywayConfig: (mjConfig: MJConfig, tag?: string) => Promise<FlywayConfig>;
|
|
48
64
|
export {};
|
package/dist/config.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getFlywayConfig = exports.createFlywayUrl = exports.config = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
3
|
+
exports.getFlywayConfig = exports.createFlywayUrl = exports.updatedConfig = exports.config = void 0;
|
|
5
4
|
const cosmiconfig_1 = require("cosmiconfig");
|
|
6
|
-
const
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_os_1 = require("node:os");
|
|
7
|
+
const simple_git_1 = require("simple-git");
|
|
8
|
+
const zod_1 = require("zod");
|
|
9
|
+
const MJ_REPO_URL = 'https://github.com/MemberJunction/MJ.git';
|
|
10
|
+
const explorer = (0, cosmiconfig_1.cosmiconfigSync)('mj', { searchStrategy: 'global' });
|
|
7
11
|
const result = explorer.search(process.cwd());
|
|
8
12
|
const mjConfigSchema = zod_1.z.object({
|
|
9
13
|
dbHost: zod_1.z.string().default('localhost'),
|
|
@@ -12,21 +16,39 @@ const mjConfigSchema = zod_1.z.object({
|
|
|
12
16
|
codeGenLogin: zod_1.z.string(),
|
|
13
17
|
codeGenPassword: zod_1.z.string(),
|
|
14
18
|
migrationsLocation: zod_1.z.string().optional().default('filesystem:./migrations'),
|
|
15
|
-
dbTrustServerCertificate: zod_1.z.
|
|
19
|
+
dbTrustServerCertificate: zod_1.z.coerce.boolean().default(false),
|
|
16
20
|
coreSchema: zod_1.z.string().optional().default('__mj'),
|
|
17
|
-
cleanDisabled: zod_1.z.boolean().default(true),
|
|
21
|
+
cleanDisabled: zod_1.z.boolean().optional().default(true),
|
|
22
|
+
mjRepoUrl: zod_1.z.string().url().catch(MJ_REPO_URL),
|
|
18
23
|
});
|
|
19
24
|
const parsedConfig = mjConfigSchema.safeParse(result?.config);
|
|
20
25
|
exports.config = parsedConfig.success ? parsedConfig.data : undefined;
|
|
26
|
+
const updatedConfig = () => {
|
|
27
|
+
const maybeConfig = mjConfigSchema.safeParse(explorer.search(process.cwd())?.config);
|
|
28
|
+
return maybeConfig.success ? maybeConfig.data : undefined;
|
|
29
|
+
};
|
|
30
|
+
exports.updatedConfig = updatedConfig;
|
|
21
31
|
const createFlywayUrl = (mjConfig) => {
|
|
22
|
-
return `jdbc:sqlserver://${mjConfig.dbHost}:${mjConfig.dbPort}; databaseName=${mjConfig.dbDatabase}${mjConfig.dbTrustServerCertificate
|
|
32
|
+
return `jdbc:sqlserver://${mjConfig.dbHost}:${mjConfig.dbPort}; databaseName=${mjConfig.dbDatabase}${mjConfig.dbTrustServerCertificate ? '; trustServerCertificate=true' : ''}`;
|
|
23
33
|
};
|
|
24
34
|
exports.createFlywayUrl = createFlywayUrl;
|
|
25
|
-
const getFlywayConfig = (mjConfig) =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
const getFlywayConfig = async (mjConfig, tag) => {
|
|
36
|
+
let location = mjConfig.migrationsLocation;
|
|
37
|
+
if (tag) {
|
|
38
|
+
// when tag is set, we want to fetch migrations from the github repo using the tag specified
|
|
39
|
+
// we save those to a tmp dir and set that tmp dir as the migration location
|
|
40
|
+
const tmp = (0, node_fs_1.mkdtempSync)((0, node_os_1.tmpdir)());
|
|
41
|
+
const git = (0, simple_git_1.simpleGit)(tmp);
|
|
42
|
+
await git.clone(mjConfig.mjRepoUrl, tmp, ['--sparse', '--depth=1', '--branch', tag]);
|
|
43
|
+
await git.raw(['sparse-checkout', 'set', 'migrations']);
|
|
44
|
+
location = `filesystem:${tmp}`;
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
url: (0, exports.createFlywayUrl)(mjConfig),
|
|
48
|
+
user: mjConfig.codeGenLogin,
|
|
49
|
+
password: mjConfig.codeGenPassword,
|
|
50
|
+
migrationLocations: [location],
|
|
51
|
+
advanced: { schemas: [mjConfig.coreSchema], cleanDisabled: mjConfig.cleanDisabled === false ? false : undefined },
|
|
52
|
+
};
|
|
53
|
+
};
|
|
32
54
|
exports.getFlywayConfig = getFlywayConfig;
|
package/dist/hooks/prerun.js
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const figlet_1 = __importDefault(require("figlet"));
|
|
3
7
|
const hook = async function (options) {
|
|
8
|
+
// Skip banners if --quiet flag is present (or appears to be present)
|
|
9
|
+
if (options.argv?.some((arg) => arg === '--quiet' || (/^-[^-]+/.test(arg) && arg.includes('q')))) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
options.context.log(process.stdout.columns >= 81
|
|
13
|
+
? figlet_1.default.textSync('MemberJunction', {
|
|
14
|
+
font: 'Standard',
|
|
15
|
+
horizontalLayout: 'default',
|
|
16
|
+
verticalLayout: 'default',
|
|
17
|
+
width: 100,
|
|
18
|
+
whitespaceBreak: true,
|
|
19
|
+
})
|
|
20
|
+
: '~ M e m b e r J u n c t i o n ~');
|
|
4
21
|
if (options.Command.id !== 'version') {
|
|
5
22
|
options.context.log(options.config.userAgent + '\n');
|
|
6
23
|
}
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,77 @@
|
|
|
1
1
|
{
|
|
2
2
|
"commands": {
|
|
3
|
+
"bump": {
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"args": {},
|
|
6
|
+
"description": "Bumps MemberJunction dependency versions",
|
|
7
|
+
"examples": [
|
|
8
|
+
{
|
|
9
|
+
"command": "<%= config.bin %> <%= command.id %>",
|
|
10
|
+
"description": "Bump all @memberjunction/* dependencies in the current directory's package.json to the CLI version"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"command": "<%= config.bin %> <%= command.id %> -rdv",
|
|
14
|
+
"description": "Preview all recursive packages bumps without writing any changes."
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"command": "<%= config.bin %> <%= command.id %> -rqt v2.10.0 | xargs -n1 -I{} npm install --prefix {}",
|
|
18
|
+
"description": "Recursively bump all @memberjunction/* dependencies in all packages to version v2.10.0 and output only the paths containing the updated package.json files. Pipe the output to xargs to run npm install in each directory and update the package-lock.json files as well."
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"flags": {
|
|
22
|
+
"verbose": {
|
|
23
|
+
"char": "v",
|
|
24
|
+
"description": "Enable additional logging",
|
|
25
|
+
"name": "verbose",
|
|
26
|
+
"allowNo": false,
|
|
27
|
+
"type": "boolean"
|
|
28
|
+
},
|
|
29
|
+
"recursive": {
|
|
30
|
+
"char": "r",
|
|
31
|
+
"description": "Bump version in current directory and all subdirectories",
|
|
32
|
+
"name": "recursive",
|
|
33
|
+
"allowNo": false,
|
|
34
|
+
"type": "boolean"
|
|
35
|
+
},
|
|
36
|
+
"tag": {
|
|
37
|
+
"char": "t",
|
|
38
|
+
"description": "Version tag to bump target for bump (e.g. v2.10.0), defaults to the CLI version",
|
|
39
|
+
"name": "tag",
|
|
40
|
+
"hasDynamicHelp": false,
|
|
41
|
+
"multiple": false,
|
|
42
|
+
"type": "option"
|
|
43
|
+
},
|
|
44
|
+
"quiet": {
|
|
45
|
+
"char": "q",
|
|
46
|
+
"description": "Only output paths for updated packages",
|
|
47
|
+
"name": "quiet",
|
|
48
|
+
"allowNo": false,
|
|
49
|
+
"type": "boolean"
|
|
50
|
+
},
|
|
51
|
+
"dry": {
|
|
52
|
+
"char": "d",
|
|
53
|
+
"description": "Dry run, do not write changes to package.json files",
|
|
54
|
+
"name": "dry",
|
|
55
|
+
"allowNo": false,
|
|
56
|
+
"type": "boolean"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"hasDynamicHelp": false,
|
|
60
|
+
"hiddenAliases": [],
|
|
61
|
+
"id": "bump",
|
|
62
|
+
"pluginAlias": "@memberjunction/cli",
|
|
63
|
+
"pluginName": "@memberjunction/cli",
|
|
64
|
+
"pluginType": "core",
|
|
65
|
+
"strict": true,
|
|
66
|
+
"enableJsonFlag": false,
|
|
67
|
+
"isESM": false,
|
|
68
|
+
"relativePath": [
|
|
69
|
+
"dist",
|
|
70
|
+
"commands",
|
|
71
|
+
"bump",
|
|
72
|
+
"index.js"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
3
75
|
"clean": {
|
|
4
76
|
"aliases": [],
|
|
5
77
|
"args": {},
|
|
@@ -32,25 +104,24 @@
|
|
|
32
104
|
"index.js"
|
|
33
105
|
]
|
|
34
106
|
},
|
|
35
|
-
"
|
|
107
|
+
"codegen": {
|
|
36
108
|
"aliases": [],
|
|
37
109
|
"args": {},
|
|
38
|
-
"description": "
|
|
110
|
+
"description": "Run CodeGen to generate code and update metadata for MemberJunction",
|
|
39
111
|
"examples": [
|
|
40
112
|
"<%= config.bin %> <%= command.id %>\n"
|
|
41
113
|
],
|
|
42
114
|
"flags": {
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"name": "verbose",
|
|
115
|
+
"skipdb": {
|
|
116
|
+
"description": "Skip database migration",
|
|
117
|
+
"name": "skipdb",
|
|
47
118
|
"allowNo": false,
|
|
48
119
|
"type": "boolean"
|
|
49
120
|
}
|
|
50
121
|
},
|
|
51
122
|
"hasDynamicHelp": false,
|
|
52
123
|
"hiddenAliases": [],
|
|
53
|
-
"id": "
|
|
124
|
+
"id": "codegen",
|
|
54
125
|
"pluginAlias": "@memberjunction/cli",
|
|
55
126
|
"pluginName": "@memberjunction/cli",
|
|
56
127
|
"pluginType": "core",
|
|
@@ -60,7 +131,7 @@
|
|
|
60
131
|
"relativePath": [
|
|
61
132
|
"dist",
|
|
62
133
|
"commands",
|
|
63
|
-
"
|
|
134
|
+
"codegen",
|
|
64
135
|
"index.js"
|
|
65
136
|
]
|
|
66
137
|
},
|
|
@@ -95,7 +166,47 @@
|
|
|
95
166
|
"install",
|
|
96
167
|
"index.js"
|
|
97
168
|
]
|
|
169
|
+
},
|
|
170
|
+
"migrate": {
|
|
171
|
+
"aliases": [],
|
|
172
|
+
"args": {},
|
|
173
|
+
"description": "Migrate MemberJunction database to latest version",
|
|
174
|
+
"examples": [
|
|
175
|
+
"<%= config.bin %> <%= command.id %>\n"
|
|
176
|
+
],
|
|
177
|
+
"flags": {
|
|
178
|
+
"verbose": {
|
|
179
|
+
"char": "v",
|
|
180
|
+
"description": "Enable additional logging",
|
|
181
|
+
"name": "verbose",
|
|
182
|
+
"allowNo": false,
|
|
183
|
+
"type": "boolean"
|
|
184
|
+
},
|
|
185
|
+
"tag": {
|
|
186
|
+
"char": "t",
|
|
187
|
+
"description": "Version tag to use for running remote migrations",
|
|
188
|
+
"name": "tag",
|
|
189
|
+
"hasDynamicHelp": false,
|
|
190
|
+
"multiple": false,
|
|
191
|
+
"type": "option"
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
"hasDynamicHelp": false,
|
|
195
|
+
"hiddenAliases": [],
|
|
196
|
+
"id": "migrate",
|
|
197
|
+
"pluginAlias": "@memberjunction/cli",
|
|
198
|
+
"pluginName": "@memberjunction/cli",
|
|
199
|
+
"pluginType": "core",
|
|
200
|
+
"strict": true,
|
|
201
|
+
"enableJsonFlag": false,
|
|
202
|
+
"isESM": false,
|
|
203
|
+
"relativePath": [
|
|
204
|
+
"dist",
|
|
205
|
+
"commands",
|
|
206
|
+
"migrate",
|
|
207
|
+
"index.js"
|
|
208
|
+
]
|
|
98
209
|
}
|
|
99
210
|
},
|
|
100
|
-
"version": "2.13.
|
|
211
|
+
"version": "2.13.3"
|
|
101
212
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/cli",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.3",
|
|
4
4
|
"description": "MemberJunction command line tools",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"oclif"
|
|
@@ -50,16 +50,20 @@
|
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@inquirer/prompts": "^5.0.1",
|
|
53
|
+
"@memberjunction/codegen-lib": "2.13.3",
|
|
53
54
|
"@oclif/core": "^3",
|
|
54
55
|
"@oclif/plugin-help": "^6",
|
|
55
56
|
"@oclif/plugin-version": "^2.0.17",
|
|
56
57
|
"@oclif/plugin-warn-if-update-available": "^3.0.16",
|
|
57
58
|
"cosmiconfig": "9.0.0",
|
|
58
59
|
"dotenv": "16.4.5",
|
|
60
|
+
"fast-glob": "^3.3.2",
|
|
59
61
|
"figlet": "^1.7.0",
|
|
60
62
|
"fs-extra": "^11.2.0",
|
|
61
63
|
"node-flyway": "0.0.11",
|
|
62
64
|
"ora-classic": "^5.4.2",
|
|
65
|
+
"recast": "^0.23.9",
|
|
66
|
+
"simple-git": "^3.27.0",
|
|
63
67
|
"zod": "^3.23.4"
|
|
64
68
|
},
|
|
65
69
|
"devDependencies": {
|
package/dist/hooks/init.d.ts
DELETED
package/dist/hooks/init.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const figlet_1 = __importDefault(require("figlet"));
|
|
7
|
-
const hook = async function (options) {
|
|
8
|
-
options.context.log(process.stdout.columns >= 81
|
|
9
|
-
? figlet_1.default.textSync('MemberJunction', {
|
|
10
|
-
font: 'Standard',
|
|
11
|
-
horizontalLayout: 'default',
|
|
12
|
-
verticalLayout: 'default',
|
|
13
|
-
width: 100,
|
|
14
|
-
whitespaceBreak: true,
|
|
15
|
-
})
|
|
16
|
-
: '~ M e m b e r J u n c t i o n ~');
|
|
17
|
-
};
|
|
18
|
-
exports.default = hook;
|