@expressots/cli 1.6.0 → 1.7.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.
- package/bin/@types/config.d.ts +9 -0
- package/bin/app.container.js +4 -5
- package/bin/cli.d.ts +1 -1
- package/bin/cli.js +2 -2
- package/bin/generate/cli.js +2 -2
- package/bin/generate/form.d.ts +13 -0
- package/bin/generate/form.js +17 -377
- package/bin/generate/templates/nonopinionated/controller.tpl +10 -0
- package/bin/generate/templates/nonopinionated/dto.tpl +3 -0
- package/bin/generate/templates/nonopinionated/entity.tpl +4 -0
- package/bin/generate/templates/nonopinionated/middleware.tpl +10 -0
- package/bin/generate/templates/nonopinionated/module.tpl +4 -0
- package/bin/generate/templates/nonopinionated/provider.tpl +4 -0
- package/bin/generate/templates/nonopinionated/usecase.tpl +8 -0
- package/bin/generate/templates/{controller-service-delete.tpl → opinionated/controller-service-delete.tpl} +2 -2
- package/bin/generate/templates/{controller-service.tpl → opinionated/controller-service-get.tpl} +2 -2
- package/bin/generate/templates/{controller-service-patch.tpl → opinionated/controller-service-patch.tpl} +2 -2
- package/bin/generate/templates/{controller-service-post.tpl → opinionated/controller-service-post.tpl} +2 -2
- package/bin/generate/templates/{controller-service-put.tpl → opinionated/controller-service-put.tpl} +2 -2
- package/bin/generate/templates/{entity.tpl → opinionated/entity.tpl} +2 -2
- package/bin/generate/templates/opinionated/usecase-service-delete.tpl +8 -0
- package/bin/generate/utils/command-utils.d.ts +123 -0
- package/bin/generate/utils/command-utils.js +310 -0
- package/bin/generate/utils/nonopininated-cmd.d.ts +9 -0
- package/bin/generate/utils/nonopininated-cmd.js +248 -0
- package/bin/generate/utils/opinionated-cmd.d.ts +11 -0
- package/bin/generate/utils/opinionated-cmd.js +480 -0
- package/bin/help/cli.d.ts +4 -0
- package/bin/help/cli.js +15 -0
- package/bin/help/form.d.ts +2 -0
- package/bin/help/form.js +28 -0
- package/bin/help/index.d.ts +1 -0
- package/bin/help/index.js +2 -0
- package/bin/info/form.d.ts +1 -1
- package/bin/info/form.js +8 -11
- package/bin/new/form.js +1 -0
- package/bin/utils/add-controller-to-module.d.ts +1 -2
- package/bin/utils/add-module-to-container.d.ts +2 -1
- package/bin/utils/add-module-to-container.js +37 -4
- package/bin/utils/cli-ui.d.ts +2 -0
- package/bin/utils/cli-ui.js +10 -2
- package/bin/utils/verify-file-exists.d.ts +1 -1
- package/bin/utils/verify-file-exists.js +6 -4
- package/package.json +3 -1
- package/bin/generate/templates/dto-op.tpl +0 -7
- package/bin/generate/templates/usecase-post.tpl +0 -9
- /package/bin/generate/templates/{controller.tpl → opinionated/controller-service.tpl} +0 -0
- /package/bin/generate/templates/{dto.tpl → opinionated/dto.tpl} +0 -0
- /package/bin/generate/templates/{middleware.tpl → opinionated/middleware.tpl} +0 -0
- /package/bin/generate/templates/{module.tpl → opinionated/module-service.tpl} +0 -0
- /package/bin/generate/templates/{module-default.tpl → opinionated/module.tpl} +0 -0
- /package/bin/generate/templates/{provider.tpl → opinionated/provider.tpl} +0 -0
- /package/bin/generate/templates/{usecase-op.tpl → opinionated/usecase-service.tpl} +0 -0
- /package/bin/generate/templates/{usecase.tpl → opinionated/usecase.tpl} +0 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { ExpressoConfig } from "../../types";
|
|
2
|
+
export declare const enum PathStyle {
|
|
3
|
+
None = "none",
|
|
4
|
+
Single = "single",
|
|
5
|
+
Nested = "nested",
|
|
6
|
+
Sugar = "sugar"
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* File preparation
|
|
10
|
+
* @param schematic
|
|
11
|
+
* @param target
|
|
12
|
+
* @param method
|
|
13
|
+
* @param opinionated
|
|
14
|
+
* @param sourceRoot
|
|
15
|
+
* @returns the file output
|
|
16
|
+
*/
|
|
17
|
+
export type FilePreparation = {
|
|
18
|
+
schematic: string;
|
|
19
|
+
target: string;
|
|
20
|
+
method: string;
|
|
21
|
+
expressoConfig: ExpressoConfig;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* File output
|
|
25
|
+
* @param path
|
|
26
|
+
* @param file
|
|
27
|
+
* @param className
|
|
28
|
+
* @param moduleName
|
|
29
|
+
* @param modulePath
|
|
30
|
+
* @param outputPath
|
|
31
|
+
* @param folderToScaffold
|
|
32
|
+
*/
|
|
33
|
+
export type FileOutput = {
|
|
34
|
+
path: string;
|
|
35
|
+
file: string;
|
|
36
|
+
className: string;
|
|
37
|
+
moduleName: string;
|
|
38
|
+
modulePath: string;
|
|
39
|
+
outputPath: string;
|
|
40
|
+
folderToScaffold: string;
|
|
41
|
+
fileName: string;
|
|
42
|
+
schematic: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Create a template based on the schematic
|
|
46
|
+
* @param fp
|
|
47
|
+
* @returns the file created
|
|
48
|
+
*/
|
|
49
|
+
export declare function validateAndPrepareFile(fp: FilePreparation): Promise<{
|
|
50
|
+
path: string;
|
|
51
|
+
file: string;
|
|
52
|
+
className: string;
|
|
53
|
+
moduleName: string;
|
|
54
|
+
modulePath: string;
|
|
55
|
+
outputPath: string;
|
|
56
|
+
folderToScaffold: string;
|
|
57
|
+
fileName: string;
|
|
58
|
+
schematic: string;
|
|
59
|
+
}>;
|
|
60
|
+
/**
|
|
61
|
+
* Get the file name without the extension
|
|
62
|
+
* @param filePath
|
|
63
|
+
* @returns the file name
|
|
64
|
+
*/
|
|
65
|
+
export declare function getFileNameWithoutExtension(filePath: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Split the target into path, file, class name, module name and module path
|
|
68
|
+
* @param target
|
|
69
|
+
* @param schematic
|
|
70
|
+
* @returns the split target
|
|
71
|
+
*/
|
|
72
|
+
export declare const splitTarget: ({ target, schematic, }: {
|
|
73
|
+
target: string;
|
|
74
|
+
schematic: string;
|
|
75
|
+
}) => Promise<{
|
|
76
|
+
path: string;
|
|
77
|
+
file: string;
|
|
78
|
+
className: string;
|
|
79
|
+
moduleName: string;
|
|
80
|
+
modulePath: string;
|
|
81
|
+
}>;
|
|
82
|
+
/**
|
|
83
|
+
* Write the template based on the http method
|
|
84
|
+
* @param method - the http method
|
|
85
|
+
* @returns decorator - the decorator to be used
|
|
86
|
+
*/
|
|
87
|
+
export declare const getHttpMethod: (method: string) => string;
|
|
88
|
+
/**
|
|
89
|
+
* Write the template based on the schematics
|
|
90
|
+
* @param outputPath - the output path
|
|
91
|
+
* @param template - the template to be used
|
|
92
|
+
* @returns void
|
|
93
|
+
*/
|
|
94
|
+
export declare const writeTemplate: ({ outputPath, template: { path, data }, }: {
|
|
95
|
+
outputPath: string;
|
|
96
|
+
template: {
|
|
97
|
+
path: string;
|
|
98
|
+
data: Record<string, string>;
|
|
99
|
+
};
|
|
100
|
+
}) => void;
|
|
101
|
+
/**
|
|
102
|
+
* Returns the folder where the schematic should be placed
|
|
103
|
+
* @param schematic
|
|
104
|
+
*/
|
|
105
|
+
export declare const schematicFolder: (schematic: string) => string | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* Get the name with the scaffold pattern
|
|
108
|
+
* @param name
|
|
109
|
+
* @returns the name in the scaffold pattern
|
|
110
|
+
*/
|
|
111
|
+
export declare const getNameWithScaffoldPattern: (name: string) => Promise<string>;
|
|
112
|
+
/**
|
|
113
|
+
* Extract the first word from a file and convert it to the scaffold pattern
|
|
114
|
+
* @param file
|
|
115
|
+
* @returns the first word in the scaffold pattern
|
|
116
|
+
*/
|
|
117
|
+
export declare function extractFirstWord(file: string): Promise<string>;
|
|
118
|
+
/**
|
|
119
|
+
* Check if the path is a nested path, a single path or a sugar path
|
|
120
|
+
* @param path
|
|
121
|
+
* @returns the path style
|
|
122
|
+
*/
|
|
123
|
+
export declare const checkPathStyle: (path: string) => PathStyle;
|
|
@@ -0,0 +1,310 @@
|
|
|
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
|
+
exports.checkPathStyle = exports.extractFirstWord = exports.getNameWithScaffoldPattern = exports.schematicFolder = exports.writeTemplate = exports.getHttpMethod = exports.splitTarget = exports.getFileNameWithoutExtension = exports.validateAndPrepareFile = void 0;
|
|
30
|
+
const node_fs_1 = require("node:fs");
|
|
31
|
+
const nodePath = __importStar(require("node:path"));
|
|
32
|
+
const mustache_1 = require("mustache");
|
|
33
|
+
const boost_ts_1 = require("@expressots/boost-ts");
|
|
34
|
+
const cli_ui_1 = require("../../utils/cli-ui");
|
|
35
|
+
const verify_file_exists_1 = require("../../utils/verify-file-exists");
|
|
36
|
+
const compiler_1 = __importDefault(require("../../utils/compiler"));
|
|
37
|
+
/**
|
|
38
|
+
* Create a template based on the schematic
|
|
39
|
+
* @param fp
|
|
40
|
+
* @returns the file created
|
|
41
|
+
*/
|
|
42
|
+
async function validateAndPrepareFile(fp) {
|
|
43
|
+
const { sourceRoot, scaffoldSchematics, opinionated } = fp.expressoConfig;
|
|
44
|
+
if (sourceRoot === "") {
|
|
45
|
+
(0, cli_ui_1.printError)("You must specify a source root in your expressots.config.ts", "sourceRoot");
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
if (opinionated) {
|
|
49
|
+
const folderSchematic = (0, exports.schematicFolder)(fp.schematic);
|
|
50
|
+
const folderToScaffold = `${sourceRoot}/${folderSchematic}`;
|
|
51
|
+
const { path, file, className, moduleName, modulePath } = await (0, exports.splitTarget)({
|
|
52
|
+
target: fp.target,
|
|
53
|
+
schematic: fp.schematic,
|
|
54
|
+
});
|
|
55
|
+
const outputPath = `${folderToScaffold}/${path}/${file}`;
|
|
56
|
+
await (0, verify_file_exists_1.verifyIfFileExists)(outputPath, fp.schematic);
|
|
57
|
+
(0, node_fs_1.mkdirSync)(`${folderToScaffold}/${path}`, { recursive: true });
|
|
58
|
+
return {
|
|
59
|
+
path,
|
|
60
|
+
file,
|
|
61
|
+
className,
|
|
62
|
+
moduleName,
|
|
63
|
+
modulePath,
|
|
64
|
+
outputPath,
|
|
65
|
+
folderToScaffold,
|
|
66
|
+
fileName: getFileNameWithoutExtension(file),
|
|
67
|
+
schematic: fp.schematic,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const folderSchematic = "";
|
|
71
|
+
const folderToScaffold = `${sourceRoot}/${folderSchematic}`;
|
|
72
|
+
const { path, file, className, moduleName, modulePath } = await (0, exports.splitTarget)({
|
|
73
|
+
target: fp.target,
|
|
74
|
+
schematic: fp.schematic,
|
|
75
|
+
});
|
|
76
|
+
const fileBaseSchema = scaffoldSchematics === null || scaffoldSchematics === void 0 ? void 0 : scaffoldSchematics[fp.schematic];
|
|
77
|
+
const validateFileSchema = fileBaseSchema !== undefined
|
|
78
|
+
? file.replace(fp.schematic, fileBaseSchema)
|
|
79
|
+
: file;
|
|
80
|
+
const outputPath = `${folderToScaffold}/${path}/${validateFileSchema}`;
|
|
81
|
+
await (0, verify_file_exists_1.verifyIfFileExists)(outputPath, fp.schematic);
|
|
82
|
+
(0, node_fs_1.mkdirSync)(`${folderToScaffold}/${path}`, { recursive: true });
|
|
83
|
+
return {
|
|
84
|
+
path,
|
|
85
|
+
file,
|
|
86
|
+
className,
|
|
87
|
+
moduleName,
|
|
88
|
+
modulePath,
|
|
89
|
+
outputPath,
|
|
90
|
+
folderToScaffold,
|
|
91
|
+
fileName: getFileNameWithoutExtension(file),
|
|
92
|
+
schematic: fileBaseSchema !== undefined ? fileBaseSchema : fp.schematic,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
exports.validateAndPrepareFile = validateAndPrepareFile;
|
|
96
|
+
/**
|
|
97
|
+
* Get the file name without the extension
|
|
98
|
+
* @param filePath
|
|
99
|
+
* @returns the file name
|
|
100
|
+
*/
|
|
101
|
+
function getFileNameWithoutExtension(filePath) {
|
|
102
|
+
return filePath.split(".")[0];
|
|
103
|
+
}
|
|
104
|
+
exports.getFileNameWithoutExtension = getFileNameWithoutExtension;
|
|
105
|
+
/**
|
|
106
|
+
* Split the target into path, file, class name, module name and module path
|
|
107
|
+
* @param target
|
|
108
|
+
* @param schematic
|
|
109
|
+
* @returns the split target
|
|
110
|
+
*/
|
|
111
|
+
const splitTarget = async ({ target, schematic, }) => {
|
|
112
|
+
const pathContent = target
|
|
113
|
+
.split("/")
|
|
114
|
+
.filter((item) => item !== "");
|
|
115
|
+
const endsWithSlash = target.endsWith("/");
|
|
116
|
+
let path = "";
|
|
117
|
+
let fileName = "";
|
|
118
|
+
let module = "";
|
|
119
|
+
let modulePath = "";
|
|
120
|
+
if (target.includes("/") ||
|
|
121
|
+
target.includes("\\") ||
|
|
122
|
+
target.includes("//")) {
|
|
123
|
+
if (schematic === "service")
|
|
124
|
+
schematic = "controller";
|
|
125
|
+
if (schematic === "service" ||
|
|
126
|
+
(schematic === "controller" && pathContent.length > 4)) {
|
|
127
|
+
(0, cli_ui_1.printError)("Max path depth is 4.", pathContent.join("/"));
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
if (endsWithSlash) {
|
|
131
|
+
fileName = pathContent[pathContent.length - 1];
|
|
132
|
+
path = pathContent.join("/");
|
|
133
|
+
module =
|
|
134
|
+
pathContent.length == 1
|
|
135
|
+
? pathContent[pathContent.length - 1]
|
|
136
|
+
: pathContent[pathContent.length - 2];
|
|
137
|
+
modulePath = pathContent.slice(0, -1).join("/");
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
fileName = pathContent[pathContent.length - 1];
|
|
141
|
+
path = pathContent.slice(0, -1).join("/");
|
|
142
|
+
module =
|
|
143
|
+
pathContent.length == 2
|
|
144
|
+
? pathContent[pathContent.length - 2]
|
|
145
|
+
: pathContent[pathContent.length - 3];
|
|
146
|
+
modulePath = pathContent.slice(0, -2).join("/");
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
path,
|
|
150
|
+
file: `${await (0, exports.getNameWithScaffoldPattern)(fileName)}.${schematic}.ts`,
|
|
151
|
+
className: (0, boost_ts_1.anyCaseToPascalCase)(fileName),
|
|
152
|
+
moduleName: module,
|
|
153
|
+
modulePath,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
if (schematic === "service")
|
|
158
|
+
schematic = "controller";
|
|
159
|
+
// 1. Extract the name (first part of the target)
|
|
160
|
+
const [name, ...remainingPath] = target.split("/");
|
|
161
|
+
// 2. Check if the name is camelCase or kebab-case
|
|
162
|
+
const camelCaseRegex = /[A-Z]/;
|
|
163
|
+
const kebabCaseRegex = /[_\-\s]+/;
|
|
164
|
+
const isCamelCase = camelCaseRegex.test(name);
|
|
165
|
+
const isKebabCase = kebabCaseRegex.test(name);
|
|
166
|
+
if (isCamelCase || isKebabCase) {
|
|
167
|
+
const [wordName, ...path] = name === null || name === void 0 ? void 0 : name.split(isCamelCase ? /(?=[A-Z])/ : kebabCaseRegex).map((word) => word.toLowerCase());
|
|
168
|
+
return {
|
|
169
|
+
path: `${wordName}/${pathEdgeCase(path)}${pathEdgeCase(remainingPath)}`,
|
|
170
|
+
file: `${await (0, exports.getNameWithScaffoldPattern)(name)}.${schematic}.ts`,
|
|
171
|
+
className: (0, boost_ts_1.anyCaseToPascalCase)(name),
|
|
172
|
+
moduleName: wordName,
|
|
173
|
+
modulePath: pathContent[0].split("-")[1],
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
// 3. Return the base case
|
|
177
|
+
return {
|
|
178
|
+
path: "",
|
|
179
|
+
file: `${await (0, exports.getNameWithScaffoldPattern)(name)}.${schematic}.ts`,
|
|
180
|
+
className: (0, boost_ts_1.anyCaseToPascalCase)(name),
|
|
181
|
+
moduleName: name,
|
|
182
|
+
modulePath: "",
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
exports.splitTarget = splitTarget;
|
|
187
|
+
/**
|
|
188
|
+
* Write the template based on the http method
|
|
189
|
+
* @param method - the http method
|
|
190
|
+
* @returns decorator - the decorator to be used
|
|
191
|
+
*/
|
|
192
|
+
const getHttpMethod = (method) => {
|
|
193
|
+
switch (method) {
|
|
194
|
+
case "put":
|
|
195
|
+
return "Put";
|
|
196
|
+
case "post":
|
|
197
|
+
return "Post";
|
|
198
|
+
case "patch":
|
|
199
|
+
return "Patch";
|
|
200
|
+
case "delete":
|
|
201
|
+
return "Delete";
|
|
202
|
+
default:
|
|
203
|
+
return "Get";
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
exports.getHttpMethod = getHttpMethod;
|
|
207
|
+
/**
|
|
208
|
+
* Write the template based on the schematics
|
|
209
|
+
* @param outputPath - the output path
|
|
210
|
+
* @param template - the template to be used
|
|
211
|
+
* @returns void
|
|
212
|
+
*/
|
|
213
|
+
const writeTemplate = ({ outputPath, template: { path, data }, }) => {
|
|
214
|
+
(0, node_fs_1.writeFileSync)(outputPath, (0, mustache_1.render)((0, node_fs_1.readFileSync)(nodePath.join(__dirname, path), "utf8"), data));
|
|
215
|
+
};
|
|
216
|
+
exports.writeTemplate = writeTemplate;
|
|
217
|
+
/**
|
|
218
|
+
* Returns the folder where the schematic should be placed
|
|
219
|
+
* @param schematic
|
|
220
|
+
*/
|
|
221
|
+
const schematicFolder = (schematic) => {
|
|
222
|
+
switch (schematic) {
|
|
223
|
+
case "usecase":
|
|
224
|
+
return "useCases";
|
|
225
|
+
case "controller":
|
|
226
|
+
return "useCases";
|
|
227
|
+
case "dto":
|
|
228
|
+
return "useCases";
|
|
229
|
+
case "service":
|
|
230
|
+
return "useCases";
|
|
231
|
+
case "provider":
|
|
232
|
+
return "providers";
|
|
233
|
+
case "entity":
|
|
234
|
+
return "entities";
|
|
235
|
+
case "middleware":
|
|
236
|
+
return "providers/middlewares";
|
|
237
|
+
case "module":
|
|
238
|
+
return "useCases";
|
|
239
|
+
}
|
|
240
|
+
return undefined;
|
|
241
|
+
};
|
|
242
|
+
exports.schematicFolder = schematicFolder;
|
|
243
|
+
/**
|
|
244
|
+
* Get the name with the scaffold pattern
|
|
245
|
+
* @param name
|
|
246
|
+
* @returns the name in the scaffold pattern
|
|
247
|
+
*/
|
|
248
|
+
const getNameWithScaffoldPattern = async (name) => {
|
|
249
|
+
const configObject = await compiler_1.default.loadConfig();
|
|
250
|
+
switch (configObject.scaffoldPattern) {
|
|
251
|
+
case "lowercase" /* Pattern.LOWER_CASE */:
|
|
252
|
+
return (0, boost_ts_1.anyCaseToLowerCase)(name);
|
|
253
|
+
case "kebab-case" /* Pattern.KEBAB_CASE */:
|
|
254
|
+
return (0, boost_ts_1.anyCaseToKebabCase)(name);
|
|
255
|
+
case "PascalCase" /* Pattern.PASCAL_CASE */:
|
|
256
|
+
return (0, boost_ts_1.anyCaseToPascalCase)(name);
|
|
257
|
+
case "camelCase" /* Pattern.CAMEL_CASE */:
|
|
258
|
+
return (0, boost_ts_1.anyCaseToCamelCase)(name);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
exports.getNameWithScaffoldPattern = getNameWithScaffoldPattern;
|
|
262
|
+
/**
|
|
263
|
+
* Get the path edge case
|
|
264
|
+
* @param path
|
|
265
|
+
* @returns the path edge case from the last element of the path
|
|
266
|
+
*/
|
|
267
|
+
const pathEdgeCase = (path) => {
|
|
268
|
+
return `${path.join("/")}${path.length > 0 ? "/" : ""}`;
|
|
269
|
+
};
|
|
270
|
+
/**
|
|
271
|
+
* Extract the first word from a file and convert it to the scaffold pattern
|
|
272
|
+
* @param file
|
|
273
|
+
* @returns the first word in the scaffold pattern
|
|
274
|
+
*/
|
|
275
|
+
async function extractFirstWord(file) {
|
|
276
|
+
const f = file.split(".")[0];
|
|
277
|
+
const regex = /(?:-|(?<=[a-z])(?=[A-Z]))/;
|
|
278
|
+
const firstWord = f.split(regex)[0];
|
|
279
|
+
const config = await compiler_1.default.loadConfig();
|
|
280
|
+
switch (config.scaffoldPattern) {
|
|
281
|
+
case "lowercase" /* Pattern.LOWER_CASE */:
|
|
282
|
+
return (0, boost_ts_1.anyCaseToLowerCase)(firstWord);
|
|
283
|
+
case "kebab-case" /* Pattern.KEBAB_CASE */:
|
|
284
|
+
return (0, boost_ts_1.anyCaseToKebabCase)(firstWord);
|
|
285
|
+
case "PascalCase" /* Pattern.PASCAL_CASE */:
|
|
286
|
+
return (0, boost_ts_1.anyCaseToPascalCase)(firstWord);
|
|
287
|
+
case "camelCase" /* Pattern.CAMEL_CASE */:
|
|
288
|
+
return (0, boost_ts_1.anyCaseToCamelCase)(firstWord);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
exports.extractFirstWord = extractFirstWord;
|
|
292
|
+
/**
|
|
293
|
+
* Check if the path is a nested path, a single path or a sugar path
|
|
294
|
+
* @param path
|
|
295
|
+
* @returns the path style
|
|
296
|
+
*/
|
|
297
|
+
const checkPathStyle = (path) => {
|
|
298
|
+
const singleOrNestedPathRegex = /\/|\\/;
|
|
299
|
+
const sugarPathRegex = /^\w+-\w+$/;
|
|
300
|
+
if (singleOrNestedPathRegex.test(path)) {
|
|
301
|
+
return "nested" /* PathStyle.Nested */;
|
|
302
|
+
}
|
|
303
|
+
else if (sugarPathRegex.test(path)) {
|
|
304
|
+
return "sugar" /* PathStyle.Sugar */;
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
return "single" /* PathStyle.Single */;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
exports.checkPathStyle = checkPathStyle;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ExpressoConfig } from "../../@types";
|
|
2
|
+
/**
|
|
3
|
+
* Process the non-opinionated command
|
|
4
|
+
* @param schematic - The schematic
|
|
5
|
+
* @param target - The target
|
|
6
|
+
* @param method - The method
|
|
7
|
+
* @param expressoConfig - The expresso config
|
|
8
|
+
*/
|
|
9
|
+
export declare function nonOpinionatedProcess(schematic: string, target: string, method: string, expressoConfig: ExpressoConfig): Promise<string>;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nonOpinionatedProcess = void 0;
|
|
4
|
+
const boost_ts_1 = require("@expressots/boost-ts");
|
|
5
|
+
const cli_ui_1 = require("../../utils/cli-ui");
|
|
6
|
+
const command_utils_1 = require("./command-utils");
|
|
7
|
+
/**
|
|
8
|
+
* Process the non-opinionated command
|
|
9
|
+
* @param schematic - The schematic
|
|
10
|
+
* @param target - The target
|
|
11
|
+
* @param method - The method
|
|
12
|
+
* @param expressoConfig - The expresso config
|
|
13
|
+
*/
|
|
14
|
+
async function nonOpinionatedProcess(schematic, target, method, expressoConfig) {
|
|
15
|
+
let f = await (0, command_utils_1.validateAndPrepareFile)({
|
|
16
|
+
schematic,
|
|
17
|
+
target,
|
|
18
|
+
method,
|
|
19
|
+
expressoConfig,
|
|
20
|
+
});
|
|
21
|
+
switch (schematic) {
|
|
22
|
+
case "service":
|
|
23
|
+
f = await (0, command_utils_1.validateAndPrepareFile)({
|
|
24
|
+
schematic: "controller",
|
|
25
|
+
target,
|
|
26
|
+
method,
|
|
27
|
+
expressoConfig,
|
|
28
|
+
});
|
|
29
|
+
await generateController(f.outputPath, f.className, f.path, method, f.file, f.schematic);
|
|
30
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
31
|
+
f = await (0, command_utils_1.validateAndPrepareFile)({
|
|
32
|
+
schematic: "usecase",
|
|
33
|
+
target,
|
|
34
|
+
method,
|
|
35
|
+
expressoConfig,
|
|
36
|
+
});
|
|
37
|
+
await generateUseCase(f.outputPath, f.className, f.moduleName, f.path, f.fileName, f.schematic, "../templates/nonopinionated/usecase.tpl");
|
|
38
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
39
|
+
f = await (0, command_utils_1.validateAndPrepareFile)({
|
|
40
|
+
schematic: "dto",
|
|
41
|
+
target,
|
|
42
|
+
method,
|
|
43
|
+
expressoConfig,
|
|
44
|
+
});
|
|
45
|
+
await generateDTO(f.outputPath, f.className, f.moduleName, f.path, f.schematic);
|
|
46
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
47
|
+
f = await (0, command_utils_1.validateAndPrepareFile)({
|
|
48
|
+
schematic: "module",
|
|
49
|
+
target,
|
|
50
|
+
method,
|
|
51
|
+
expressoConfig,
|
|
52
|
+
});
|
|
53
|
+
await generateModule(f.outputPath, f.className, f.moduleName, f.path, f.schematic);
|
|
54
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
55
|
+
break;
|
|
56
|
+
case "usecase":
|
|
57
|
+
await generateUseCase(f.outputPath, f.className, f.moduleName, f.path, f.fileName, f.schematic);
|
|
58
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
59
|
+
break;
|
|
60
|
+
case "controller":
|
|
61
|
+
await generateController(f.outputPath, f.className, f.path, method, f.file, f.schematic);
|
|
62
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
63
|
+
break;
|
|
64
|
+
case "dto":
|
|
65
|
+
await generateDTO(f.outputPath, f.className, f.moduleName, f.path, f.schematic);
|
|
66
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
67
|
+
break;
|
|
68
|
+
case "provider":
|
|
69
|
+
await generateProvider(f.outputPath, f.className, f.moduleName, f.path, f.schematic);
|
|
70
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
71
|
+
break;
|
|
72
|
+
case "entity":
|
|
73
|
+
await generateEntity(f.outputPath, f.className, f.moduleName, f.path, f.schematic);
|
|
74
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
75
|
+
break;
|
|
76
|
+
case "middleware":
|
|
77
|
+
await generateMiddleware(f.outputPath, f.className, f.moduleName, f.path, f.schematic);
|
|
78
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
79
|
+
break;
|
|
80
|
+
case "module":
|
|
81
|
+
await generateModule(f.outputPath, f.className, f.moduleName, f.path, f.schematic);
|
|
82
|
+
await (0, cli_ui_1.printGenerateSuccess)(f.schematic, f.file);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
return f.file;
|
|
86
|
+
}
|
|
87
|
+
exports.nonOpinionatedProcess = nonOpinionatedProcess;
|
|
88
|
+
/* Generate Resource */
|
|
89
|
+
/**
|
|
90
|
+
* Generate a use case
|
|
91
|
+
* @param outputPath - The output path
|
|
92
|
+
* @param className - The class name
|
|
93
|
+
* @param moduleName - The module name
|
|
94
|
+
* @param path - The path
|
|
95
|
+
* @param template - The template
|
|
96
|
+
*/
|
|
97
|
+
async function generateUseCase(outputPath, className, moduleName, path, fileName, schematic, template) {
|
|
98
|
+
(0, command_utils_1.writeTemplate)({
|
|
99
|
+
outputPath,
|
|
100
|
+
template: {
|
|
101
|
+
path: template
|
|
102
|
+
? template
|
|
103
|
+
: "../templates/nonopinionated/usecase.tpl",
|
|
104
|
+
data: {
|
|
105
|
+
className,
|
|
106
|
+
moduleName,
|
|
107
|
+
path,
|
|
108
|
+
fileName,
|
|
109
|
+
schematic: (0, boost_ts_1.anyCaseToPascalCase)(schematic),
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generate a controller
|
|
116
|
+
* @param outputPath - The output path
|
|
117
|
+
* @param className - The class name
|
|
118
|
+
* @param path - The path
|
|
119
|
+
* @param method - The method
|
|
120
|
+
* @param file - The file
|
|
121
|
+
*/
|
|
122
|
+
async function generateController(outputPath, className, path, method, file, schematic) {
|
|
123
|
+
const templateBasedMethod = "../templates/nonopinionated/controller.tpl";
|
|
124
|
+
(0, command_utils_1.writeTemplate)({
|
|
125
|
+
outputPath,
|
|
126
|
+
template: {
|
|
127
|
+
path: templateBasedMethod,
|
|
128
|
+
data: {
|
|
129
|
+
className,
|
|
130
|
+
fileName: (0, command_utils_1.getFileNameWithoutExtension)(file),
|
|
131
|
+
useCase: (0, boost_ts_1.anyCaseToCamelCase)(className),
|
|
132
|
+
route: className
|
|
133
|
+
? className.toLowerCase()
|
|
134
|
+
: path.replace(/\/$/, ""),
|
|
135
|
+
construct: (0, boost_ts_1.anyCaseToKebabCase)(className),
|
|
136
|
+
method: (0, command_utils_1.getHttpMethod)(method),
|
|
137
|
+
schematic: (0, boost_ts_1.anyCaseToPascalCase)(schematic),
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Generate a DTO
|
|
144
|
+
* @param outputPath - The output path
|
|
145
|
+
* @param className - The class name
|
|
146
|
+
* @param moduleName - The module name
|
|
147
|
+
* @param path - The path
|
|
148
|
+
*/
|
|
149
|
+
async function generateDTO(outputPath, className, moduleName, path, schematic) {
|
|
150
|
+
(0, command_utils_1.writeTemplate)({
|
|
151
|
+
outputPath,
|
|
152
|
+
template: {
|
|
153
|
+
path: "../templates/nonopinionated/dto.tpl",
|
|
154
|
+
data: {
|
|
155
|
+
className,
|
|
156
|
+
moduleName,
|
|
157
|
+
path,
|
|
158
|
+
schematic: (0, boost_ts_1.anyCaseToPascalCase)(schematic),
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Generate a provider
|
|
165
|
+
* @param outputPath - The output path
|
|
166
|
+
* @param className - The class name
|
|
167
|
+
* @param moduleName - The module name
|
|
168
|
+
* @param path - The path
|
|
169
|
+
*/
|
|
170
|
+
async function generateProvider(outputPath, className, moduleName, path, schematic) {
|
|
171
|
+
(0, command_utils_1.writeTemplate)({
|
|
172
|
+
outputPath,
|
|
173
|
+
template: {
|
|
174
|
+
path: "../templates/nonopinionated/provider.tpl",
|
|
175
|
+
data: {
|
|
176
|
+
className,
|
|
177
|
+
moduleName,
|
|
178
|
+
path,
|
|
179
|
+
schematic: (0, boost_ts_1.anyCaseToPascalCase)(schematic),
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Generate an entity
|
|
186
|
+
* @param outputPath - The output path
|
|
187
|
+
* @param className - The class name
|
|
188
|
+
* @param moduleName - The module name
|
|
189
|
+
* @param path - The path
|
|
190
|
+
*/
|
|
191
|
+
async function generateEntity(outputPath, className, moduleName, path, schematic) {
|
|
192
|
+
(0, command_utils_1.writeTemplate)({
|
|
193
|
+
outputPath,
|
|
194
|
+
template: {
|
|
195
|
+
path: "../templates/nonopinionated/entity.tpl",
|
|
196
|
+
data: {
|
|
197
|
+
className,
|
|
198
|
+
moduleName,
|
|
199
|
+
path,
|
|
200
|
+
schematic: (0, boost_ts_1.anyCaseToPascalCase)(schematic),
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Generate a middleware
|
|
207
|
+
* @param outputPath - The output path
|
|
208
|
+
* @param className - The class name
|
|
209
|
+
* @param moduleName - The module name
|
|
210
|
+
* @param path - The path
|
|
211
|
+
*/
|
|
212
|
+
async function generateMiddleware(outputPath, className, moduleName, path, schematic) {
|
|
213
|
+
(0, command_utils_1.writeTemplate)({
|
|
214
|
+
outputPath,
|
|
215
|
+
template: {
|
|
216
|
+
path: "../templates/nonopinionated/middleware.tpl",
|
|
217
|
+
data: {
|
|
218
|
+
className,
|
|
219
|
+
moduleName,
|
|
220
|
+
path,
|
|
221
|
+
schematic: (0, boost_ts_1.anyCaseToPascalCase)(schematic),
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Generate a module
|
|
228
|
+
* @param outputPath - The output path
|
|
229
|
+
* @param className - The class name
|
|
230
|
+
* @param moduleName - The module name
|
|
231
|
+
* @param path - The path
|
|
232
|
+
*/
|
|
233
|
+
async function generateModule(outputPath, className, moduleName, path, schematic) {
|
|
234
|
+
(0, command_utils_1.writeTemplate)({
|
|
235
|
+
outputPath,
|
|
236
|
+
template: {
|
|
237
|
+
path: "../templates/nonopinionated/module.tpl",
|
|
238
|
+
data: {
|
|
239
|
+
className,
|
|
240
|
+
moduleName: className
|
|
241
|
+
? (0, boost_ts_1.anyCaseToPascalCase)(className)
|
|
242
|
+
: (0, boost_ts_1.anyCaseToPascalCase)(moduleName),
|
|
243
|
+
path,
|
|
244
|
+
schematic: (0, boost_ts_1.anyCaseToPascalCase)(schematic),
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
}
|