@magek/cli 0.0.1
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/bin/run +5 -0
- package/bin/run.cmd +3 -0
- package/dist/commands/add/projection.js +51 -0
- package/dist/commands/add/reducer.js +52 -0
- package/dist/commands/build.js +35 -0
- package/dist/commands/clean.js +35 -0
- package/dist/commands/deploy.js +47 -0
- package/dist/commands/new/command.js +71 -0
- package/dist/commands/new/entity.js +84 -0
- package/dist/commands/new/event-handler.js +73 -0
- package/dist/commands/new/event.js +65 -0
- package/dist/commands/new/query.js +71 -0
- package/dist/commands/new/read-model.js +85 -0
- package/dist/commands/new/scheduled-command.js +60 -0
- package/dist/commands/new/type.js +53 -0
- package/dist/commands/nuke.js +63 -0
- package/dist/commands/start.js +52 -0
- package/dist/commands/stub/publish.js +44 -0
- package/dist/commands/synth.js +45 -0
- package/dist/common/base-command.js +18 -0
- package/dist/common/brand.js +38 -0
- package/dist/common/errors.js +24 -0
- package/dist/common/filenames.js +45 -0
- package/dist/common/provider.js +2 -0
- package/dist/common/sandbox.js +45 -0
- package/dist/common/script.js +102 -0
- package/dist/hooks/command_not_found/custom-parse.js +40 -0
- package/dist/index.js +4 -0
- package/dist/services/config-service.js +76 -0
- package/dist/services/environment.js +22 -0
- package/dist/services/file-system/index.js +12 -0
- package/dist/services/file-system/live.impl.js +26 -0
- package/dist/services/generator/target/index.js +5 -0
- package/dist/services/generator/target/parsing.js +64 -0
- package/dist/services/generator/target/types.js +2 -0
- package/dist/services/generator.js +40 -0
- package/dist/services/logger.js +23 -0
- package/dist/services/method-generator.js +81 -0
- package/dist/services/package-manager/common.js +74 -0
- package/dist/services/package-manager/index.js +21 -0
- package/dist/services/package-manager/live.impl.js +35 -0
- package/dist/services/package-manager/npm.impl.js +8 -0
- package/dist/services/package-manager/pnpm.impl.js +8 -0
- package/dist/services/package-manager/rush.impl.js +50 -0
- package/dist/services/package-manager/yarn.impl.js +8 -0
- package/dist/services/process/index.js +12 -0
- package/dist/services/process/live.impl.js +30 -0
- package/dist/services/project-checker.js +152 -0
- package/dist/services/provider-service.js +53 -0
- package/dist/services/semver.js +29 -0
- package/dist/services/stub-publisher.js +42 -0
- package/dist/services/user-prompt.js +31 -0
- package/dist/templates/command.stub +17 -0
- package/dist/templates/entity.stub +22 -0
- package/dist/templates/event-handler.stub +8 -0
- package/dist/templates/event.stub +16 -0
- package/dist/templates/query.stub +17 -0
- package/dist/templates/read-model.stub +24 -0
- package/dist/templates/scheduled-command.stub +13 -0
- package/dist/templates/type.stub +7 -0
- package/package.json +91 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRushPackageManager = void 0;
|
|
4
|
+
const index_js_1 = require("./index.js");
|
|
5
|
+
const common_js_1 = require("./common.js");
|
|
6
|
+
// TODO: Look recursively up for a rush.json file and run ./common/scripts/install-run-rushx.js
|
|
7
|
+
const createRushPackageManager = (deps) => {
|
|
8
|
+
const { processService } = deps;
|
|
9
|
+
// Create a reference to store the current project directory
|
|
10
|
+
const projectDirRef = { value: '' };
|
|
11
|
+
// Create a function to run a script in the project directory
|
|
12
|
+
const runRush = (0, common_js_1.makeScopedRun)('rush', processService, projectDirRef);
|
|
13
|
+
const runRushX = (0, common_js_1.makeScopedRun)('rushx', processService, projectDirRef);
|
|
14
|
+
const commonService = (0, common_js_1.createPackageManagerService)('rush', deps);
|
|
15
|
+
const service = {
|
|
16
|
+
...commonService,
|
|
17
|
+
setProjectRoot: (projectDir) => {
|
|
18
|
+
projectDirRef.value = projectDir;
|
|
19
|
+
},
|
|
20
|
+
runScript: async (scriptName, args) => {
|
|
21
|
+
try {
|
|
22
|
+
return await runRushX(scriptName, null, args);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
throw new index_js_1.RunScriptError(`Failed to run script ${scriptName}`, error instanceof Error ? error : undefined);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
build: async (args) => {
|
|
29
|
+
try {
|
|
30
|
+
return await runRush('build', null, args);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
throw new index_js_1.RunScriptError('Failed to build', error instanceof Error ? error : undefined);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
installProductionDependencies: async () => {
|
|
37
|
+
throw new index_js_1.InstallDependenciesError('Rush is a monorepo manager, so it does not support installing production dependencies');
|
|
38
|
+
},
|
|
39
|
+
installAllDependencies: async () => {
|
|
40
|
+
try {
|
|
41
|
+
await runRush('update', null, []);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
throw new index_js_1.InstallDependenciesError('Failed to install dependencies', error instanceof Error ? error : undefined);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
return service;
|
|
49
|
+
};
|
|
50
|
+
exports.createRushPackageManager = createRushPackageManager;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createYarnPackageManager = void 0;
|
|
4
|
+
const common_js_1 = require("./common.js");
|
|
5
|
+
const createYarnPackageManager = (deps) => {
|
|
6
|
+
return (0, common_js_1.createPackageManagerService)('yarn', deps);
|
|
7
|
+
};
|
|
8
|
+
exports.createYarnPackageManager = createYarnPackageManager;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProcessError = void 0;
|
|
4
|
+
class ProcessError extends Error {
|
|
5
|
+
constructor(message, cause) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.cause = cause;
|
|
8
|
+
this._tag = 'ProcessError';
|
|
9
|
+
this.name = 'ProcessError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.ProcessError = ProcessError;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.liveProcessService = exports.createProcessService = void 0;
|
|
4
|
+
const index_js_1 = require("./index.js");
|
|
5
|
+
const lazyExecaCommand = async (command, options) => {
|
|
6
|
+
const { execaCommand } = await import('execa');
|
|
7
|
+
return execaCommand(command, options);
|
|
8
|
+
};
|
|
9
|
+
const unknownToError = (e) => e instanceof Error ? e : new Error(String(e));
|
|
10
|
+
const createProcessService = (execaCommand = lazyExecaCommand) => ({
|
|
11
|
+
exec: async (command, cwd) => {
|
|
12
|
+
try {
|
|
13
|
+
const { stdout, stderr } = await execaCommand(command, { cwd });
|
|
14
|
+
return `\n${stderr ? `There were some issues running the command: ${stderr}\n` : ''}\n${stdout}\n`;
|
|
15
|
+
}
|
|
16
|
+
catch (reason) {
|
|
17
|
+
throw new index_js_1.ProcessError('Failed to execute command', unknownToError(reason));
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
cwd: () => {
|
|
21
|
+
try {
|
|
22
|
+
return process.cwd();
|
|
23
|
+
}
|
|
24
|
+
catch (reason) {
|
|
25
|
+
throw new index_js_1.ProcessError('Failed to get current working directory', unknownToError(reason));
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
exports.createProcessService = createProcessService;
|
|
30
|
+
exports.liveProcessService = (0, exports.createProcessService)();
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkItIsAMagekProject = exports.checkCurrentDirMagekVersion = exports.checkResourceExists = exports.checkProjectAlreadyExists = exports.checkCurrentDirIsAMagekProject = exports.projectChecker = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fsExtra = tslib_1.__importStar(require("fs-extra"));
|
|
6
|
+
const path = tslib_1.__importStar(require("path"));
|
|
7
|
+
const brand_js_1 = tslib_1.__importDefault(require("../common/brand.js"));
|
|
8
|
+
const generator_js_1 = require("./generator.js");
|
|
9
|
+
const filenames_js_1 = require("../common/filenames.js");
|
|
10
|
+
const logger_js_1 = require("../services/logger.js");
|
|
11
|
+
const user_prompt_js_1 = tslib_1.__importDefault(require("../services/user-prompt.js"));
|
|
12
|
+
const semver_js_1 = tslib_1.__importDefault(require("../services/semver.js"));
|
|
13
|
+
const fileSystem = fsExtra;
|
|
14
|
+
function projectDir(projectName) {
|
|
15
|
+
return path.join(process.cwd(), projectName);
|
|
16
|
+
}
|
|
17
|
+
function checkIndexFileIsMagek(indexFilePath) {
|
|
18
|
+
const contents = fileSystem.readFileSync(indexFilePath);
|
|
19
|
+
if (!contents.includes('Magek.start(')) {
|
|
20
|
+
throw new Error('The main application file does not start a Magek application. Verify you are in the right project');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const checkCurrentDirIsAMagekProjectImpl = async () => {
|
|
24
|
+
return checkItIsAMagekProjectImpl(process.cwd());
|
|
25
|
+
};
|
|
26
|
+
const checkItIsAMagekProjectImpl = async (projectPath) => {
|
|
27
|
+
const projectAbsolutePath = path.resolve(projectPath);
|
|
28
|
+
try {
|
|
29
|
+
const tsConfigJsonContents = require(path.join(projectAbsolutePath, 'tsconfig.json'));
|
|
30
|
+
const indexFilePath = path.normalize(path.join(projectAbsolutePath, tsConfigJsonContents.compilerOptions.rootDir, 'index.ts'));
|
|
31
|
+
checkIndexFileIsMagek(indexFilePath);
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
throw new Error(`There was an error when recognizing the application. Make sure you are in the root path of a Magek project:\n${e.message}`);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const checkProjectAlreadyExistsImpl = async (name) => {
|
|
38
|
+
const projectDirectoryPath = projectDir(name);
|
|
39
|
+
const projectDirectoryExists = fileSystem.existsSync(projectDirectoryPath);
|
|
40
|
+
if (projectDirectoryExists) {
|
|
41
|
+
await user_prompt_js_1.default.confirmPrompt({
|
|
42
|
+
message: brand_js_1.default.dangerize(`Project folder "${name}" already exists. Do you want to overwrite it?`),
|
|
43
|
+
}).then((confirm) => {
|
|
44
|
+
if (!confirm)
|
|
45
|
+
throw new Error("The folder you're trying to use already exists. Please use another project name");
|
|
46
|
+
fileSystem.removeSync(projectDirectoryPath);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const checkResourceExistsImpl = async (name, placementDir, extension) => {
|
|
51
|
+
const resourcePath = (0, generator_js_1.filePath)({ name, placementDir, extension });
|
|
52
|
+
const resourceExists = fileSystem.existsSync(resourcePath);
|
|
53
|
+
const resourceName = (0, filenames_js_1.classNameToFileName)(name);
|
|
54
|
+
const resourceType = (0, generator_js_1.getResourceType)(placementDir);
|
|
55
|
+
logger_js_1.logger.info(brand_js_1.default.mellancholize('Checking if resource already exists...'));
|
|
56
|
+
if (resourceExists) {
|
|
57
|
+
await user_prompt_js_1.default.confirmPrompt({
|
|
58
|
+
message: brand_js_1.default.dangerize(`Resource: "${resourceName}${extension}" already exists. Do you want to overwrite it?`),
|
|
59
|
+
}).then((confirm) => {
|
|
60
|
+
if (!confirm)
|
|
61
|
+
throw new Error(`The '${resourceType}' resource "${resourceName}${extension}" already exists. Please use another resource name`);
|
|
62
|
+
fileSystem.removeSync(resourcePath);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const checkCurrentDirMagekVersionImpl = async (version) => {
|
|
67
|
+
return checkMagekVersion(version, process.cwd());
|
|
68
|
+
};
|
|
69
|
+
async function checkMagekVersion(cliVersion, projectPath) {
|
|
70
|
+
const projectVersion = await getMagekVersion(projectPath);
|
|
71
|
+
await compareVersionsAndDisplayMessages(cliVersion, projectVersion);
|
|
72
|
+
}
|
|
73
|
+
async function getMagekVersion(projectPath) {
|
|
74
|
+
const projectAbsolutePath = path.resolve(projectPath);
|
|
75
|
+
try {
|
|
76
|
+
const packageJsonContents = require(path.join(projectAbsolutePath, 'package.json'));
|
|
77
|
+
const version = packageJsonContents.dependencies['@magek/core'];
|
|
78
|
+
const versionParts = version
|
|
79
|
+
.replace('workspace:', '') // We remove the workspace protocol in case we're in the Magek monorepo
|
|
80
|
+
.replace('^', '')
|
|
81
|
+
.replace('.tgz', '')
|
|
82
|
+
.split('-');
|
|
83
|
+
return versionParts[versionParts.length - 1];
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
throw new Error(`There was an error when recognizing the application. Make sure you are in the root path of a Magek project:\n${e.message}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
class HigherCliVersionError extends Error {
|
|
90
|
+
constructor(cliVersion, projectVersion, section) {
|
|
91
|
+
super(`CLI version ${cliVersion} is higher than your project Magek version ${projectVersion} in the '${section}' section. Please upgrade your project Magek dependencies.`);
|
|
92
|
+
this.cliVersion = cliVersion;
|
|
93
|
+
this.projectVersion = projectVersion;
|
|
94
|
+
this.section = section;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
class LowerCliVersionError extends Error {
|
|
98
|
+
constructor(cliVersion, projectVersion, section) {
|
|
99
|
+
super(`CLI version ${cliVersion} is lower than your project Magek version ${projectVersion}. Please upgrade your @magek/cli to the same version with "npm install -g @magek/cli@${projectVersion}"`);
|
|
100
|
+
this.cliVersion = cliVersion;
|
|
101
|
+
this.projectVersion = projectVersion;
|
|
102
|
+
this.section = section;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function compareVersionsAndDisplayMessages(cliVersion, projectVersion) {
|
|
106
|
+
const cliSemVersion = new semver_js_1.default(cliVersion);
|
|
107
|
+
const projectSemVersion = new semver_js_1.default(projectVersion);
|
|
108
|
+
if (cliSemVersion.equals(projectSemVersion)) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (cliSemVersion.equalsInBreakingSection(projectSemVersion)) {
|
|
112
|
+
if (cliSemVersion.equalsInFeatureSection(projectSemVersion)) {
|
|
113
|
+
if (!cliSemVersion.equalsInFixSection(projectSemVersion)) {
|
|
114
|
+
//differences in the 'fix' part
|
|
115
|
+
logger_js_1.logger.info(`WARNING: Project Magek version differs in the 'fix' section. CLI version: ${cliVersion}. Project Magek version: ${projectVersion}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else if (cliSemVersion.greaterInFeatureSectionThan(projectSemVersion)) {
|
|
119
|
+
//cli higher than project in 'feat' section
|
|
120
|
+
throw new HigherCliVersionError(cliVersion, projectVersion, 'feature');
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
//cli lower than project in 'feat' section
|
|
124
|
+
throw new LowerCliVersionError(cliVersion, projectVersion, 'feature');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else if (cliSemVersion.greaterInBreakingSectionThan(projectSemVersion)) {
|
|
128
|
+
//cli higher than project in 'breaking' section
|
|
129
|
+
throw new HigherCliVersionError(cliVersion, projectVersion, 'breaking');
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
//cli lower than project in 'breaking' section
|
|
133
|
+
throw new LowerCliVersionError(cliVersion, projectVersion, 'breaking');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.projectChecker = {
|
|
137
|
+
checkCurrentDirIsAMagekProject: checkCurrentDirIsAMagekProjectImpl,
|
|
138
|
+
checkProjectAlreadyExists: checkProjectAlreadyExistsImpl,
|
|
139
|
+
checkResourceExists: checkResourceExistsImpl,
|
|
140
|
+
checkCurrentDirMagekVersion: checkCurrentDirMagekVersionImpl,
|
|
141
|
+
checkItIsAMagekProject: checkItIsAMagekProjectImpl,
|
|
142
|
+
};
|
|
143
|
+
const checkCurrentDirIsAMagekProject = (...args) => exports.projectChecker.checkCurrentDirIsAMagekProject(...args);
|
|
144
|
+
exports.checkCurrentDirIsAMagekProject = checkCurrentDirIsAMagekProject;
|
|
145
|
+
const checkProjectAlreadyExists = (...args) => exports.projectChecker.checkProjectAlreadyExists(...args);
|
|
146
|
+
exports.checkProjectAlreadyExists = checkProjectAlreadyExists;
|
|
147
|
+
const checkResourceExists = (...args) => exports.projectChecker.checkResourceExists(...args);
|
|
148
|
+
exports.checkResourceExists = checkResourceExists;
|
|
149
|
+
const checkCurrentDirMagekVersion = (...args) => exports.projectChecker.checkCurrentDirMagekVersion(...args);
|
|
150
|
+
exports.checkCurrentDirMagekVersion = checkCurrentDirMagekVersion;
|
|
151
|
+
const checkItIsAMagekProject = (...args) => exports.projectChecker.checkItIsAMagekProject(...args);
|
|
152
|
+
exports.checkItIsAMagekProject = checkItIsAMagekProject;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startProvider = exports.nukeCloudProviderResources = exports.synthToProvider = exports.deployToCloudProvider = exports.providerService = void 0;
|
|
4
|
+
exports.assertNameIsCorrect = assertNameIsCorrect;
|
|
5
|
+
function assertNameIsCorrect(name) {
|
|
6
|
+
// Current characters max length: 37
|
|
7
|
+
// Lambda name limit is 64 characters
|
|
8
|
+
// `-subscriptions-notifier` lambda is 23 characters
|
|
9
|
+
// `-app` prefix is added to application stack
|
|
10
|
+
// which is 64 - 23 - 4 = 37
|
|
11
|
+
const maxProjectNameLength = 37;
|
|
12
|
+
if (name.length > maxProjectNameLength)
|
|
13
|
+
throw new ForbiddenProjectName(name, `be longer than ${maxProjectNameLength} characters`);
|
|
14
|
+
if (name.includes(' '))
|
|
15
|
+
throw new ForbiddenProjectName(name, 'contain spaces');
|
|
16
|
+
if (name.toLowerCase() !== name)
|
|
17
|
+
throw new ForbiddenProjectName(name, 'contain uppercase letters');
|
|
18
|
+
if (name.includes('_'))
|
|
19
|
+
throw new ForbiddenProjectName(name, 'contain underscore');
|
|
20
|
+
}
|
|
21
|
+
class ForbiddenProjectName extends Error {
|
|
22
|
+
constructor(name, restrictionText) {
|
|
23
|
+
super(`Project name cannot ${restrictionText}:\n\n Found: '${name}'`);
|
|
24
|
+
this.name = name;
|
|
25
|
+
this.restrictionText = restrictionText;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function supportedInfrastructureMethodOrDie(methodName, config) {
|
|
29
|
+
assertNameIsCorrect(config.appName);
|
|
30
|
+
const method = config.provider.infrastructure()[methodName];
|
|
31
|
+
if (!method) {
|
|
32
|
+
throw new Error(`Attempted to perform the '${methodName}' operation with a provider that does not support this feature, please check your environment configuration.`);
|
|
33
|
+
}
|
|
34
|
+
return method;
|
|
35
|
+
}
|
|
36
|
+
const deployToCloudProviderImpl = (config) => supportedInfrastructureMethodOrDie('deploy', config)(config);
|
|
37
|
+
const synthToProviderImpl = (config) => supportedInfrastructureMethodOrDie('synth', config)(config);
|
|
38
|
+
const nukeCloudProviderResourcesImpl = (config) => supportedInfrastructureMethodOrDie('nuke', config)(config);
|
|
39
|
+
const startProviderImpl = (port, config) => supportedInfrastructureMethodOrDie('start', config)(config, port);
|
|
40
|
+
exports.providerService = {
|
|
41
|
+
deployToCloudProvider: deployToCloudProviderImpl,
|
|
42
|
+
synthToProvider: synthToProviderImpl,
|
|
43
|
+
nukeCloudProviderResources: nukeCloudProviderResourcesImpl,
|
|
44
|
+
startProvider: startProviderImpl,
|
|
45
|
+
};
|
|
46
|
+
const deployToCloudProvider = (...args) => exports.providerService.deployToCloudProvider(...args);
|
|
47
|
+
exports.deployToCloudProvider = deployToCloudProvider;
|
|
48
|
+
const synthToProvider = (...args) => exports.providerService.synthToProvider(...args);
|
|
49
|
+
exports.synthToProvider = synthToProvider;
|
|
50
|
+
const nukeCloudProviderResources = (...args) => exports.providerService.nukeCloudProviderResources(...args);
|
|
51
|
+
exports.nukeCloudProviderResources = nukeCloudProviderResources;
|
|
52
|
+
const startProvider = (...args) => exports.providerService.startProvider(...args);
|
|
53
|
+
exports.startProvider = startProvider;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class Semver {
|
|
4
|
+
constructor(semverString) {
|
|
5
|
+
this.versionParts = semverString.split('.').map((v) => parseInt(v, 10));
|
|
6
|
+
if (this.versionParts.length !== 3) {
|
|
7
|
+
throw new Error(`Versions must follow semantic convention X.Y.Z | current version: ${semverString}.`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
equalsInBreakingSection(version) {
|
|
11
|
+
return this.versionParts[0] === version.versionParts[0];
|
|
12
|
+
}
|
|
13
|
+
equalsInFeatureSection(version) {
|
|
14
|
+
return this.versionParts[1] === version.versionParts[1];
|
|
15
|
+
}
|
|
16
|
+
equalsInFixSection(version) {
|
|
17
|
+
return this.versionParts[2] === version.versionParts[2];
|
|
18
|
+
}
|
|
19
|
+
equals(version) {
|
|
20
|
+
return (this.equalsInBreakingSection(version) && this.equalsInFeatureSection(version) && this.equalsInFixSection(version));
|
|
21
|
+
}
|
|
22
|
+
greaterInBreakingSectionThan(version) {
|
|
23
|
+
return this.versionParts[0] > version.versionParts[0];
|
|
24
|
+
}
|
|
25
|
+
greaterInFeatureSectionThan(version) {
|
|
26
|
+
return this.versionParts[1] > version.versionParts[1];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.default = Semver;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.copyStubFile = exports.createTemplateFileMap = exports.createStubsFolder = exports.checkResourceStubFileExists = exports.checkStubsFolderExists = exports.resourceTemplateFilePath = exports.resourceStubFilePath = exports.resourceTemplatesPath = void 0;
|
|
4
|
+
exports.publishStubFiles = publishStubFiles;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const fsExtra = tslib_1.__importStar(require("fs-extra"));
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const errors_js_1 = require("../common/errors.js");
|
|
9
|
+
const currentDir = typeof __dirname !== 'undefined' ? __dirname : process.cwd();
|
|
10
|
+
exports.resourceTemplatesPath = (0, path_1.join)(currentDir, '..', 'templates');
|
|
11
|
+
const resourceStubFilePath = (fileName) => (0, path_1.join)(process.cwd(), 'stubs', fileName);
|
|
12
|
+
exports.resourceStubFilePath = resourceStubFilePath;
|
|
13
|
+
const resourceTemplateFilePath = (fileName) => (0, path_1.join)(exports.resourceTemplatesPath, fileName);
|
|
14
|
+
exports.resourceTemplateFilePath = resourceTemplateFilePath;
|
|
15
|
+
const checkStubsFolderExists = () => fsExtra.existsSync((0, path_1.join)(process.cwd(), 'stubs'));
|
|
16
|
+
exports.checkStubsFolderExists = checkStubsFolderExists;
|
|
17
|
+
const checkResourceStubFileExists = (filePath) => fsExtra.existsSync(filePath);
|
|
18
|
+
exports.checkResourceStubFileExists = checkResourceStubFileExists;
|
|
19
|
+
const createStubsFolder = () => fsExtra.mkdirSync((0, path_1.join)(process.cwd(), 'stubs'));
|
|
20
|
+
exports.createStubsFolder = createStubsFolder;
|
|
21
|
+
const createTemplateFileMap = (files) => files
|
|
22
|
+
.filter((file) => file.isFile() && file.name.includes('.stub'))
|
|
23
|
+
.reduce((files, file) => {
|
|
24
|
+
const resourceTemplatePath = (0, path_1.join)(exports.resourceTemplatesPath, file.name);
|
|
25
|
+
files[resourceTemplatePath] = (0, path_1.join)(process.cwd(), 'stubs', file.name);
|
|
26
|
+
return files;
|
|
27
|
+
}, {});
|
|
28
|
+
exports.createTemplateFileMap = createTemplateFileMap;
|
|
29
|
+
async function publishStubFiles() {
|
|
30
|
+
const files = fsExtra.readdirSync(exports.resourceTemplatesPath, { withFileTypes: true });
|
|
31
|
+
const templateFilesMap = (0, exports.createTemplateFileMap)(files);
|
|
32
|
+
try {
|
|
33
|
+
for (const [from, to] of Object.entries(templateFilesMap)) {
|
|
34
|
+
(0, exports.copyStubFile)(from, to);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
throw (0, errors_js_1.wrapExecError)(e, 'Error when publishing stubs');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const copyStubFile = (from, to) => fsExtra.writeFileSync(to, fsExtra.readFileSync(from));
|
|
42
|
+
exports.copyStubFile = copyStubFile;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
5
|
+
class Prompter {
|
|
6
|
+
async defaultOrPrompt(value, promptMessage) {
|
|
7
|
+
if (value) {
|
|
8
|
+
return Promise.resolve(value.replace(/\"/g, '\\"'));
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
const res = await inquirer_1.default.prompt([{ name: 'value', type: 'input', message: promptMessage }]);
|
|
12
|
+
return Promise.resolve(res.value.replace(/\"/g, '\\"'));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
async defaultOrChoose(value, promptMessage, options) {
|
|
16
|
+
if (value) {
|
|
17
|
+
return Promise.resolve(value);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
const res = await inquirer_1.default.prompt([{ name: 'value', type: 'list', message: promptMessage, choices: options }]);
|
|
21
|
+
return Promise.resolve(res.value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
static async confirmPrompt(promptParams) {
|
|
25
|
+
const confirm = await inquirer_1.default
|
|
26
|
+
.prompt([{ name: 'confirm', type: 'confirm', default: false, ...promptParams }])
|
|
27
|
+
.then(({ confirm }) => confirm);
|
|
28
|
+
return Promise.resolve(confirm);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.default = Prompter;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{{#imports}}
|
|
2
|
+
import { {{commaSeparatedComponents}} } from '{{{packagePath}}}'
|
|
3
|
+
{{/imports}}
|
|
4
|
+
|
|
5
|
+
@Command({
|
|
6
|
+
authorize: // Specify authorized roles here. Use 'all' to authorize anyone
|
|
7
|
+
})
|
|
8
|
+
export class {{{ name }}} {
|
|
9
|
+
{{#fields}}
|
|
10
|
+
@Field()
|
|
11
|
+
readonly {{{name}}}!: {{{type}}}
|
|
12
|
+
|
|
13
|
+
{{/fields}}
|
|
14
|
+
public static async handle(command: {{{ name }}} , register: Register): Promise<void> {
|
|
15
|
+
register.events( /* YOUR EVENT HERE */)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{{#imports}}
|
|
2
|
+
import { {{commaSeparatedComponents}} } from '{{{packagePath}}}'
|
|
3
|
+
{{/imports}}
|
|
4
|
+
|
|
5
|
+
@Entity
|
|
6
|
+
export class {{{name}}} {
|
|
7
|
+
@Field(type => UUID)
|
|
8
|
+
public id!: UUID
|
|
9
|
+
|
|
10
|
+
{{#fields}}
|
|
11
|
+
@Field()
|
|
12
|
+
readonly {{{name}}}!: {{{type}}}
|
|
13
|
+
|
|
14
|
+
{{/fields}}
|
|
15
|
+
{{#events}}
|
|
16
|
+
@Reduces({{{eventName}}})
|
|
17
|
+
public static reduce{{{eventName}}}(event: {{{eventName}}}, current{{{name}}}?: {{{name}}}): {{{name}}} {
|
|
18
|
+
return /* NEW {{name}} HERE */
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
{{/events}}
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{{#imports}}
|
|
2
|
+
import { {{commaSeparatedComponents}} } from '{{{packagePath}}}'
|
|
3
|
+
{{/imports}}
|
|
4
|
+
|
|
5
|
+
@Event
|
|
6
|
+
export class {{{ name }}} {
|
|
7
|
+
public constructor(
|
|
8
|
+
{{#fields}}
|
|
9
|
+
readonly {{{name}}}: {{{type}}},
|
|
10
|
+
{{/fields}}
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
public entityID(): UUID {
|
|
14
|
+
return /* the associated entity ID */
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{{#imports}}
|
|
2
|
+
import { {{commaSeparatedComponents}} } from '{{{packagePath}}}'
|
|
3
|
+
{{/imports}}
|
|
4
|
+
|
|
5
|
+
@Query({
|
|
6
|
+
authorize: // Specify authorized roles here. Use 'all' to authorize anyone
|
|
7
|
+
})
|
|
8
|
+
export class {{{ name }}} {
|
|
9
|
+
{{#fields}}
|
|
10
|
+
@Field()
|
|
11
|
+
readonly {{{name}}}!: {{{type}}}
|
|
12
|
+
|
|
13
|
+
{{/fields}}
|
|
14
|
+
public static async handle(query: {{{ name }}}, queryInfo?: QueryInfo): Promise<string> {
|
|
15
|
+
/* YOUR CODE HERE */
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{{#imports}}
|
|
2
|
+
import { {{commaSeparatedComponents}} } from '{{{packagePath}}}'
|
|
3
|
+
{{/imports}}
|
|
4
|
+
|
|
5
|
+
@ReadModel({
|
|
6
|
+
authorize: // Specify authorized roles here. Use 'all' to authorize anyone
|
|
7
|
+
})
|
|
8
|
+
export class {{{name}}} {
|
|
9
|
+
@Field(type => UUID)
|
|
10
|
+
public id!: UUID
|
|
11
|
+
|
|
12
|
+
{{#fields}}
|
|
13
|
+
@Field()
|
|
14
|
+
readonly {{{name}}}!: {{{type}}}
|
|
15
|
+
|
|
16
|
+
{{/fields}}
|
|
17
|
+
{{#projections}}
|
|
18
|
+
@Projects({{{entityName}}}, "{{{entityId}}}")
|
|
19
|
+
public static project{{{entityName}}}(entity: {{{entityName}}}, current{{{name}}}?: {{{name}}}): ProjectionResult<{{{name}}}> {
|
|
20
|
+
return /* NEW {{name}} HERE */
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
{{/projections}}
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{{#imports}}
|
|
2
|
+
import { {{commaSeparatedComponents}} } from '{{{packagePath}}}'
|
|
3
|
+
{{/imports}}
|
|
4
|
+
|
|
5
|
+
@ScheduledCommand({
|
|
6
|
+
// Specify schedule settings here. By default, it will be triggered every 30 minutes
|
|
7
|
+
minute: '0/30',
|
|
8
|
+
})
|
|
9
|
+
export class {{{ name }}} {
|
|
10
|
+
public static async handle(register: Register): Promise<void> {
|
|
11
|
+
/* YOUR CODE HERE */
|
|
12
|
+
}
|
|
13
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@magek/cli",
|
|
3
|
+
"description": "CLI of the Magek Framework, the next level of abstraction for cloud-native applications",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"author": "Boosterin Labs SLU",
|
|
6
|
+
"homepage": "https://magek.ai",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"magek": "./bin/run"
|
|
12
|
+
},
|
|
13
|
+
"bugs": "https://github.com/theam/magek/issues",
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@magek/core": "^0.0.1",
|
|
16
|
+
"@magek/common": "^0.0.1",
|
|
17
|
+
"@oclif/core": "4.8.0",
|
|
18
|
+
"@oclif/plugin-help": "6.2.36",
|
|
19
|
+
"chalk": "5.6.2",
|
|
20
|
+
"execa": "9.6.1",
|
|
21
|
+
"fp-ts": "2.16.11",
|
|
22
|
+
"fs-extra": "11.3.3",
|
|
23
|
+
"inflected": "2.1.0",
|
|
24
|
+
"inquirer": "13.1.0",
|
|
25
|
+
"mustache": "4.2.0",
|
|
26
|
+
"ora": "9.0.0",
|
|
27
|
+
"ts-morph": "27.0.2",
|
|
28
|
+
"tslib": "2.8.1"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@magek/eslint-config": "^0.0.1",
|
|
32
|
+
"@oclif/test": "4.1.15",
|
|
33
|
+
"@types/chai": "5.2.3",
|
|
34
|
+
"@types/chai-as-promised": "8.0.2",
|
|
35
|
+
"@types/fs-extra": "11.0.4",
|
|
36
|
+
"@types/inflected": "2.1.3",
|
|
37
|
+
"@types/mocha": "10.0.10",
|
|
38
|
+
"@types/mustache": "4.2.6",
|
|
39
|
+
"@types/node": "22.19.3",
|
|
40
|
+
"@types/sinon": "21.0.0",
|
|
41
|
+
"@types/sinon-chai": "4.0.0",
|
|
42
|
+
"chai": "6.2.2",
|
|
43
|
+
"chai-as-promised": "8.0.2",
|
|
44
|
+
"copyfiles": "2.4.1",
|
|
45
|
+
"mocha": "11.7.5",
|
|
46
|
+
"c8": "^10.1.3",
|
|
47
|
+
"rimraf": "6.1.2",
|
|
48
|
+
"sinon": "21.0.1",
|
|
49
|
+
"sinon-chai": "4.0.1",
|
|
50
|
+
"tsx": "^4.19.2",
|
|
51
|
+
"typescript": "5.9.3"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=22.0.0 <23.0.0"
|
|
55
|
+
},
|
|
56
|
+
"files": [
|
|
57
|
+
"/bin",
|
|
58
|
+
"/dist",
|
|
59
|
+
"/npm-shrinkwrap.json",
|
|
60
|
+
"/oclif.manifest.json"
|
|
61
|
+
],
|
|
62
|
+
"keywords": [
|
|
63
|
+
"oclif"
|
|
64
|
+
],
|
|
65
|
+
"license": "Apache-2.0",
|
|
66
|
+
"main": "dist/index.js",
|
|
67
|
+
"oclif": {
|
|
68
|
+
"commands": "./dist/commands",
|
|
69
|
+
"bin": "magek",
|
|
70
|
+
"plugins": [
|
|
71
|
+
"@oclif/plugin-help"
|
|
72
|
+
],
|
|
73
|
+
"hooks": {
|
|
74
|
+
"command_not_found": "./dist/hooks/command_not_found/custom-parse"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"repository": {
|
|
78
|
+
"type": "git",
|
|
79
|
+
"url": "git+https://github.com/theam/magek.git"
|
|
80
|
+
},
|
|
81
|
+
"types": "lib/index.d.ts",
|
|
82
|
+
"scripts": {
|
|
83
|
+
"format": "prettier --write --ext '.js,.ts' **/*.ts **/*/*.ts",
|
|
84
|
+
"lint:check": "eslint \"**/*.ts\"",
|
|
85
|
+
"lint:fix": "eslint --quiet --fix \"**/*.ts\"",
|
|
86
|
+
"build": "tsc -b tsconfig.json && copyfiles -f src/templates/*.stub dist/templates",
|
|
87
|
+
"clean": "rimraf ./dist tsconfig.tsbuildinfo",
|
|
88
|
+
"test:cli": "npm run test",
|
|
89
|
+
"test": "tsc --noEmit -p tsconfig.test.json && c8 mocha --config .mocharc.json --forbid-only \"test/**/*.test.ts\""
|
|
90
|
+
}
|
|
91
|
+
}
|