@expressots/cli 1.3.4 → 1.5.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 +10 -0
- package/bin/app.container.js +1 -1
- package/bin/cli.js +2 -0
- package/bin/generate/cli.js +4 -7
- package/bin/generate/form.js +6 -1
- package/bin/generate/templates/module-default.tpl +3 -0
- package/bin/new/cli.js +11 -3
- package/bin/new/form.js +16 -3
- package/bin/providers/cli.d.ts +4 -0
- package/bin/providers/cli.js +38 -0
- package/bin/providers/index.d.ts +1 -0
- package/bin/providers/index.js +17 -0
- package/bin/providers/prisma/prisma.provider.d.ts +2 -0
- package/bin/providers/prisma/prisma.provider.js +277 -0
- package/bin/providers/prisma/templates/base-repository.interface.tpl +57 -0
- package/bin/providers/prisma/templates/base-repository.tpl +146 -0
- package/bin/utils/add-controller-to-module.js +13 -7
- package/bin/utils/add-module-to-container.js +26 -14
- package/bin/utils/center-text.js +1 -1
- package/bin/utils/find-folder.d.ts +5 -0
- package/bin/utils/find-folder.js +37 -0
- package/bin/utils/verify-file-exists.js +2 -2
- package/package.json +21 -14
package/bin/@types/config.d.ts
CHANGED
|
@@ -4,6 +4,14 @@ export declare const enum Pattern {
|
|
|
4
4
|
PASCAL_CASE = "PascalCase",
|
|
5
5
|
CAMEL_CASE = "camelCase"
|
|
6
6
|
}
|
|
7
|
+
interface IProviders {
|
|
8
|
+
prisma?: {
|
|
9
|
+
schemaName: string;
|
|
10
|
+
schemaPath: string;
|
|
11
|
+
entitiesPath: string;
|
|
12
|
+
entityNamePattern: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
7
15
|
/**
|
|
8
16
|
* The configuration object for the Expresso CLI.
|
|
9
17
|
*
|
|
@@ -17,4 +25,6 @@ export interface ExpressoConfig {
|
|
|
17
25
|
scaffoldPattern: Pattern;
|
|
18
26
|
sourceRoot: string;
|
|
19
27
|
opinionated: boolean;
|
|
28
|
+
providers?: IProviders;
|
|
20
29
|
}
|
|
30
|
+
export {};
|
package/bin/app.container.js
CHANGED
package/bin/cli.js
CHANGED
|
@@ -10,11 +10,13 @@ const helpers_1 = require("yargs/helpers");
|
|
|
10
10
|
const generate_1 = require("./generate");
|
|
11
11
|
const info_1 = require("./info");
|
|
12
12
|
const new_1 = require("./new");
|
|
13
|
+
const providers_1 = require("./providers");
|
|
13
14
|
exports.CLI_VERSION = "1.3.4";
|
|
14
15
|
console.log(`\n[🐎 Expressots]\n`);
|
|
15
16
|
(0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
16
17
|
.scriptName("expressots")
|
|
17
18
|
.command((0, new_1.createProject)())
|
|
19
|
+
.command((0, providers_1.generateProviders)())
|
|
18
20
|
.command((0, generate_1.generateProject)())
|
|
19
21
|
.command((0, info_1.infoProject)())
|
|
20
22
|
.example("$0 new expressots-demo", "Create interactively")
|
package/bin/generate/cli.js
CHANGED
|
@@ -16,6 +16,8 @@ const coerceSchematicAliases = (arg) => {
|
|
|
16
16
|
return "provider";
|
|
17
17
|
case "e":
|
|
18
18
|
return "entity";
|
|
19
|
+
case "m":
|
|
20
|
+
return "module";
|
|
19
21
|
default:
|
|
20
22
|
return arg;
|
|
21
23
|
}
|
|
@@ -34,6 +36,7 @@ const generateProject = () => {
|
|
|
34
36
|
"service",
|
|
35
37
|
"provider",
|
|
36
38
|
"entity",
|
|
39
|
+
"module",
|
|
37
40
|
],
|
|
38
41
|
describe: "The schematic to generate",
|
|
39
42
|
type: "string",
|
|
@@ -45,13 +48,7 @@ const generateProject = () => {
|
|
|
45
48
|
alias: "d",
|
|
46
49
|
});
|
|
47
50
|
yargs.positional("method", {
|
|
48
|
-
choices: [
|
|
49
|
-
"get",
|
|
50
|
-
"post",
|
|
51
|
-
"put",
|
|
52
|
-
"patch",
|
|
53
|
-
"delete",
|
|
54
|
-
],
|
|
51
|
+
choices: ["get", "post", "put", "patch", "delete"],
|
|
55
52
|
describe: "HTTP method",
|
|
56
53
|
type: "string",
|
|
57
54
|
alias: "m",
|
package/bin/generate/form.js
CHANGED
|
@@ -77,12 +77,17 @@ const createTemplate = async ({ schematic, path: target, method, }) => {
|
|
|
77
77
|
else {
|
|
78
78
|
routeSchema = path.replace(/\/$/, "");
|
|
79
79
|
}
|
|
80
|
+
let templateBasedSchematic = schematic;
|
|
81
|
+
if (schematic === "module") {
|
|
82
|
+
templateBasedSchematic = "module-default";
|
|
83
|
+
}
|
|
80
84
|
writeTemplate({
|
|
81
85
|
outputPath: `${usecaseDir}/${path}/${file}`,
|
|
82
86
|
template: {
|
|
83
|
-
path: `./templates/${
|
|
87
|
+
path: `./templates/${templateBasedSchematic}.tpl`,
|
|
84
88
|
data: {
|
|
85
89
|
className,
|
|
90
|
+
moduleName: className,
|
|
86
91
|
route: routeSchema,
|
|
87
92
|
construct: (0, boost_ts_1.anyCaseToKebabCase)(className),
|
|
88
93
|
method: getHttpMethod(method),
|
package/bin/new/cli.js
CHANGED
|
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createProject = void 0;
|
|
4
4
|
const form_1 = require("./form");
|
|
5
5
|
const createProject = () => {
|
|
6
|
+
const packageManagers = ["npm", "yarn", "pnpm"];
|
|
7
|
+
if (process.platform !== "win32") {
|
|
8
|
+
packageManagers.push("bun");
|
|
9
|
+
}
|
|
6
10
|
return {
|
|
7
11
|
command: "new <project-name> [package-manager] [template] [directory]",
|
|
8
12
|
describe: "Create a new project",
|
|
@@ -21,7 +25,7 @@ const createProject = () => {
|
|
|
21
25
|
.option("package-manager", {
|
|
22
26
|
describe: "The package manager to use",
|
|
23
27
|
type: "string",
|
|
24
|
-
choices:
|
|
28
|
+
choices: packageManagers,
|
|
25
29
|
alias: "p",
|
|
26
30
|
})
|
|
27
31
|
.option("directory", {
|
|
@@ -33,8 +37,12 @@ const createProject = () => {
|
|
|
33
37
|
.implies("template", "package-manager");
|
|
34
38
|
return yargs;
|
|
35
39
|
},
|
|
36
|
-
handler: async ({ projectName, packageManager, template, directory }) => {
|
|
37
|
-
return await (0, form_1.projectForm)(projectName, [
|
|
40
|
+
handler: async ({ projectName, packageManager, template, directory, }) => {
|
|
41
|
+
return await (0, form_1.projectForm)(projectName, [
|
|
42
|
+
packageManager,
|
|
43
|
+
template,
|
|
44
|
+
directory,
|
|
45
|
+
]);
|
|
38
46
|
},
|
|
39
47
|
};
|
|
40
48
|
};
|
package/bin/new/form.js
CHANGED
|
@@ -73,7 +73,10 @@ const projectForm = async (projectName, args) => {
|
|
|
73
73
|
// Resolving the argument order problem
|
|
74
74
|
for (const arg of args) {
|
|
75
75
|
if (args.length >= 3) {
|
|
76
|
-
if (arg === "npm" ||
|
|
76
|
+
if (arg === "npm" ||
|
|
77
|
+
arg === "yarn" ||
|
|
78
|
+
arg === "pnpm" ||
|
|
79
|
+
arg === "bun") {
|
|
77
80
|
packageManager = arg;
|
|
78
81
|
}
|
|
79
82
|
else if (arg === "non-opinionated" || arg === "opinionated") {
|
|
@@ -107,7 +110,7 @@ const projectForm = async (projectName, args) => {
|
|
|
107
110
|
type: "list",
|
|
108
111
|
name: "packageManager",
|
|
109
112
|
message: "Package manager",
|
|
110
|
-
choices: ["npm", "yarn", "pnpm"],
|
|
113
|
+
choices: ["npm", "yarn", "pnpm", "bun"],
|
|
111
114
|
},
|
|
112
115
|
{
|
|
113
116
|
type: "list",
|
|
@@ -141,10 +144,17 @@ const projectForm = async (projectName, args) => {
|
|
|
141
144
|
Opinionated: "opinionated",
|
|
142
145
|
};
|
|
143
146
|
if (answer.confirm) {
|
|
147
|
+
// Check if package manager is bun and OS is Windows
|
|
148
|
+
if (answer.packageManager === "bun" && process.platform === "win32") {
|
|
149
|
+
(0, cli_ui_1.printError)("bun is not supported on Windows. Please use", "npm, yarn or pnpm");
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
144
152
|
await checkIfPackageManagerExists(answer.packageManager);
|
|
145
153
|
console.log("\n");
|
|
146
154
|
const progressBar = new cli_progress_1.SingleBar({
|
|
147
|
-
format: "Progress |" +
|
|
155
|
+
format: "Progress |" +
|
|
156
|
+
chalk_1.default.green("{bar}") +
|
|
157
|
+
"| {percentage}% || {doing}",
|
|
148
158
|
hideCursor: true,
|
|
149
159
|
}, cli_progress_1.Presets.shades_classic);
|
|
150
160
|
progressBar.start(100, 0, {
|
|
@@ -188,6 +198,9 @@ const projectForm = async (projectName, args) => {
|
|
|
188
198
|
case "pnpm":
|
|
189
199
|
console.log(chalk_1.default.bold.gray("$ pnpm run dev"));
|
|
190
200
|
break;
|
|
201
|
+
case "bun":
|
|
202
|
+
console.log(chalk_1.default.bold.gray("$ bun dev"));
|
|
203
|
+
break;
|
|
191
204
|
}
|
|
192
205
|
console.log("\n");
|
|
193
206
|
console.log(chalk_1.default.bold.green((0, center_text_1.centerText)("Happy coding!")));
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateProviders = void 0;
|
|
4
|
+
const prisma_provider_1 = require("./prisma/prisma.provider");
|
|
5
|
+
const generateProviders = () => {
|
|
6
|
+
return {
|
|
7
|
+
command: "add <provider> [library-version] [provider-version]",
|
|
8
|
+
describe: "Scaffold a new provider",
|
|
9
|
+
aliases: ["a"],
|
|
10
|
+
builder: (yargs) => {
|
|
11
|
+
yargs
|
|
12
|
+
.positional("provider", {
|
|
13
|
+
choices: ["prisma"],
|
|
14
|
+
describe: "The provider to add to the project",
|
|
15
|
+
type: "string",
|
|
16
|
+
})
|
|
17
|
+
.option("library-version", {
|
|
18
|
+
describe: "The library version to install",
|
|
19
|
+
type: "string",
|
|
20
|
+
default: "latest",
|
|
21
|
+
alias: "v",
|
|
22
|
+
})
|
|
23
|
+
.option("provider-version", {
|
|
24
|
+
describe: "The version of the provider to install",
|
|
25
|
+
type: "string",
|
|
26
|
+
default: "latest",
|
|
27
|
+
alias: "vp",
|
|
28
|
+
});
|
|
29
|
+
return yargs;
|
|
30
|
+
},
|
|
31
|
+
handler: async ({ provider, libraryVersion, providerVersion }) => {
|
|
32
|
+
if (provider === "prisma") {
|
|
33
|
+
await (0, prisma_provider_1.prismaProvider)(libraryVersion, providerVersion);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
exports.generateProviders = generateProviders;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./cli";
|
|
@@ -0,0 +1,17 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./cli"), exports);
|
|
@@ -0,0 +1,277 @@
|
|
|
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
|
+
exports.prismaProvider = void 0;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
|
+
const node_child_process_1 = require("node:child_process");
|
|
10
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
11
|
+
const cli_ui_1 = require("../../utils/cli-ui");
|
|
12
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
13
|
+
const node_process_1 = require("node:process");
|
|
14
|
+
const compiler_1 = __importDefault(require("../../utils/compiler"));
|
|
15
|
+
const find_folder_1 = require("../../utils/find-folder");
|
|
16
|
+
const prismaProvider = async (version, providerVersion) => {
|
|
17
|
+
var _a;
|
|
18
|
+
const choices = [
|
|
19
|
+
{ name: "CockroachDB", value: "cockroachdb" },
|
|
20
|
+
{ name: "Microsoft SQL Server", value: "sqlserver" },
|
|
21
|
+
{ name: "MongoDB", value: "mongodb" },
|
|
22
|
+
{ name: "MySQL", value: "mysql" },
|
|
23
|
+
{ name: "PostgreSQL", value: "postgresql" },
|
|
24
|
+
{ name: "SQLite", value: "sqlite" },
|
|
25
|
+
];
|
|
26
|
+
const drivers = {
|
|
27
|
+
PostgreSQL: "pg",
|
|
28
|
+
MySQL: "mysql2",
|
|
29
|
+
SQLite: "sqlite3",
|
|
30
|
+
"Microsoft SQL Server": "mssql",
|
|
31
|
+
MongoDB: "mongodb",
|
|
32
|
+
CockroachDB: "pg",
|
|
33
|
+
};
|
|
34
|
+
const answerPt1 = await inquirer_1.default.prompt([
|
|
35
|
+
{
|
|
36
|
+
type: "input",
|
|
37
|
+
name: "prismaClientVersion",
|
|
38
|
+
message: "Type the prisma client version (default=latest):",
|
|
39
|
+
default: "latest",
|
|
40
|
+
transformer: (input) => {
|
|
41
|
+
return chalk_1.default.yellow(chalk_1.default.bold(input));
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: "input",
|
|
46
|
+
name: "schemaName",
|
|
47
|
+
message: "Type the schema name (default=schema):",
|
|
48
|
+
default: "schema",
|
|
49
|
+
transformer: (input) => {
|
|
50
|
+
return chalk_1.default.yellow(chalk_1.default.bold(input));
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: "input",
|
|
55
|
+
name: "schemaPath",
|
|
56
|
+
message: "Where do you want to save your prisma schema (default=./):",
|
|
57
|
+
default: ".",
|
|
58
|
+
transformer: (input) => {
|
|
59
|
+
return chalk_1.default.yellow(chalk_1.default.bold(input));
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
type: "list",
|
|
64
|
+
name: "databaseName",
|
|
65
|
+
message: "Select your database:",
|
|
66
|
+
choices: choices.map((choice) => choice.name),
|
|
67
|
+
},
|
|
68
|
+
]);
|
|
69
|
+
const answerPt2 = await inquirer_1.default.prompt([
|
|
70
|
+
{
|
|
71
|
+
type: "confirm",
|
|
72
|
+
name: "installDriver",
|
|
73
|
+
message: `Do you want to install the latest recommended database driver for ${answerPt1.databaseName}?`,
|
|
74
|
+
default: true,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: "confirm",
|
|
78
|
+
name: "baseRepository",
|
|
79
|
+
message: "Do you want to add BaseRepository Pattern in this project?\nthis will replace the existing BaseRepository and BaseRespositoryInterface if it exists.",
|
|
80
|
+
default: true,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: "confirm",
|
|
84
|
+
name: "confirm",
|
|
85
|
+
message: "Do you want to add prisma provider in this project?",
|
|
86
|
+
default: true,
|
|
87
|
+
},
|
|
88
|
+
]);
|
|
89
|
+
const answer = Object.assign(Object.assign({}, answerPt1), answerPt2);
|
|
90
|
+
if (answer.confirm) {
|
|
91
|
+
// Find which package manager the user has used to install the desired prisma version
|
|
92
|
+
const packageManager = node_fs_1.default.existsSync("package-lock.json" || "yarn.lock" || "pnpm-lock.yaml")
|
|
93
|
+
? "npm"
|
|
94
|
+
: node_fs_1.default.existsSync("yarn.lock")
|
|
95
|
+
? "yarn"
|
|
96
|
+
: node_fs_1.default.existsSync("pnpm-lock.yaml")
|
|
97
|
+
? "pnpm"
|
|
98
|
+
: null;
|
|
99
|
+
if (packageManager) {
|
|
100
|
+
// Install prisma in the project
|
|
101
|
+
console.log(`Installing prisma with ${packageManager}...`);
|
|
102
|
+
await execProcess({
|
|
103
|
+
commandArg: packageManager,
|
|
104
|
+
args: ["add", `prisma@${providerVersion}`, "-D"],
|
|
105
|
+
directory: process.cwd(),
|
|
106
|
+
});
|
|
107
|
+
// Install Prisma Client
|
|
108
|
+
console.log(`Installing Prisma Client with ${packageManager}...`);
|
|
109
|
+
await execProcess({
|
|
110
|
+
commandArg: packageManager,
|
|
111
|
+
args: ["add", `@prisma/client@${answer.prismaClientVersion}`],
|
|
112
|
+
directory: process.cwd(),
|
|
113
|
+
});
|
|
114
|
+
if (answer.installDriver) {
|
|
115
|
+
// Install database driver
|
|
116
|
+
console.log(`Installing the latest recommended database driver for ${answer.databaseName}: ${drivers[answer.databaseName]} ...`);
|
|
117
|
+
await execProcess({
|
|
118
|
+
commandArg: packageManager,
|
|
119
|
+
args: ["add", drivers[answer.databaseName]],
|
|
120
|
+
directory: process.cwd(),
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// Install @expressots/prisma in the project
|
|
124
|
+
console.log(`Installing @expressots/prisma with ${packageManager}...`);
|
|
125
|
+
await execProcess({
|
|
126
|
+
commandArg: packageManager,
|
|
127
|
+
args: ["add", `@expressots/prisma@${version}`],
|
|
128
|
+
directory: process.cwd(),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
(0, cli_ui_1.printError)(`Could not find a package manager installed in this project.\nPlease install prisma and @expressots/prisma manually.`, "prisma");
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
// Map choices to find the corresponding value
|
|
136
|
+
answer.databaseName = (_a = choices.find((choice) => choice.name === answer.databaseName)) === null || _a === void 0 ? void 0 : _a.value;
|
|
137
|
+
// Init prisma
|
|
138
|
+
console.log(`Initializing prisma...`);
|
|
139
|
+
const prismaFolder = (0, find_folder_1.hasFolder)(process.cwd(), ["node_modules", ".git"]);
|
|
140
|
+
if (prismaFolder.found) {
|
|
141
|
+
const prismaEnquirer = await inquirer_1.default.prompt([
|
|
142
|
+
{
|
|
143
|
+
type: "confirm",
|
|
144
|
+
name: "confirm",
|
|
145
|
+
message: "Prisma is already initialized. Do you want to override it?",
|
|
146
|
+
default: true,
|
|
147
|
+
},
|
|
148
|
+
]);
|
|
149
|
+
if ((prismaEnquirer === null || prismaEnquirer === void 0 ? void 0 : prismaEnquirer.confirm) === false) {
|
|
150
|
+
console.log(chalk_1.default.red("Prisma init aborted!"));
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
node_fs_1.default.rmSync(prismaFolder.path, {
|
|
154
|
+
recursive: true,
|
|
155
|
+
force: true,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
await execProcess({
|
|
159
|
+
commandArg: "npx",
|
|
160
|
+
args: [
|
|
161
|
+
"prisma",
|
|
162
|
+
"init",
|
|
163
|
+
"--datasource-provider",
|
|
164
|
+
answer.databaseName,
|
|
165
|
+
],
|
|
166
|
+
directory: process.cwd(),
|
|
167
|
+
});
|
|
168
|
+
const oldFileName = node_path_1.default.join(process.cwd(), "/prisma/schema.prisma");
|
|
169
|
+
const newFileName = node_path_1.default.join(process.cwd(), `/prisma/${answer.schemaName}.prisma`);
|
|
170
|
+
node_fs_1.default.renameSync(oldFileName, newFileName);
|
|
171
|
+
// Move the folder to the destination
|
|
172
|
+
const schemaPath = node_path_1.default.join(process.cwd(), `${answer.schemaPath}/prisma/${answer.schemaName}.prisma`);
|
|
173
|
+
if (!node_fs_1.default.existsSync(schemaPath)) {
|
|
174
|
+
node_fs_1.default.mkdirSync(node_path_1.default.join(process.cwd(), `${answer.schemaPath}/prisma`), { recursive: true });
|
|
175
|
+
}
|
|
176
|
+
node_fs_1.default.renameSync(newFileName, schemaPath);
|
|
177
|
+
// Remove the source folder
|
|
178
|
+
if (newFileName !== schemaPath) {
|
|
179
|
+
node_fs_1.default.rmSync(node_path_1.default.join(process.cwd(), "/prisma"), { recursive: true });
|
|
180
|
+
}
|
|
181
|
+
// Add prisma to package.json
|
|
182
|
+
prismaPackage(answer);
|
|
183
|
+
if (answer.baseRepository) {
|
|
184
|
+
const { opinionated, sourceRoot } = await compiler_1.default.loadConfig();
|
|
185
|
+
let folderMatch = "";
|
|
186
|
+
if (opinionated) {
|
|
187
|
+
folderMatch = "repositories";
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
folderMatch = "";
|
|
191
|
+
}
|
|
192
|
+
const repositoryDir = `${sourceRoot}/${folderMatch}`;
|
|
193
|
+
console.log(`Generating BaseRepository Pattern...`);
|
|
194
|
+
const baseRepositoryInterfaceTplPath = node_path_1.default.join(__dirname, "./templates/base-repository.interface.tpl");
|
|
195
|
+
const baseRepositoryTplPath = node_path_1.default.join(__dirname, "./templates/base-repository.tpl");
|
|
196
|
+
const baseRepositoryInterfaceTemplate = node_fs_1.default.readFileSync(baseRepositoryInterfaceTplPath, "utf8");
|
|
197
|
+
const baseRepositoryTemplate = node_fs_1.default.readFileSync(baseRepositoryTplPath, "utf8");
|
|
198
|
+
node_fs_1.default.writeFileSync(node_path_1.default.join(repositoryDir, "base-repository.interface.ts"), baseRepositoryInterfaceTemplate);
|
|
199
|
+
node_fs_1.default.writeFileSync(node_path_1.default.join(repositoryDir, "base-repository.ts"), baseRepositoryTemplate);
|
|
200
|
+
}
|
|
201
|
+
// Install @expressots/prisma in the project
|
|
202
|
+
console.log(`Mapping configurations to expressots.config...`);
|
|
203
|
+
await addProviderConfigInExpressotsConfig(answer.schemaName, `${answer.schemaPath}/prisma`);
|
|
204
|
+
console.log("Now configure your database connection in the project.");
|
|
205
|
+
console.log(chalk_1.default.green("\n👍 Prisma provider added successfully!"));
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
console.log(chalk_1.default.red("Prisma provider not added!"));
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
exports.prismaProvider = prismaProvider;
|
|
212
|
+
async function execProcess({ commandArg, args, directory, }) {
|
|
213
|
+
return new Promise((resolve, reject) => {
|
|
214
|
+
const isWindows = process.platform === "win32";
|
|
215
|
+
const command = isWindows ? `${commandArg}.cmd` : commandArg;
|
|
216
|
+
const installProcess = (0, node_child_process_1.spawn)(command, args, {
|
|
217
|
+
cwd: directory,
|
|
218
|
+
});
|
|
219
|
+
console.log(chalk_1.default.bold.blue(`Executing: ${command} ${args.join(" ")}`));
|
|
220
|
+
console.log(chalk_1.default.yellow("---------------------------------------"));
|
|
221
|
+
installProcess.stdout.on("data", (data) => {
|
|
222
|
+
console.log(chalk_1.default.green(data.toString().trim())); // Display regular messages in green
|
|
223
|
+
});
|
|
224
|
+
installProcess.stderr.on("data", (data) => {
|
|
225
|
+
console.error(chalk_1.default.red(data.toString().trim())); // Display error messages in red
|
|
226
|
+
});
|
|
227
|
+
installProcess.on("close", (code) => {
|
|
228
|
+
if (code === 0) {
|
|
229
|
+
console.log(chalk_1.default.bold.green("---------------------------------------"));
|
|
230
|
+
console.log(chalk_1.default.bold.green("Installation Done!"));
|
|
231
|
+
resolve("Installation Done!");
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
console.error(chalk_1.default.bold.red("---------------------------------------"));
|
|
235
|
+
console.error(chalk_1.default.bold.red(`Command ${command} ${args.join(" ")} exited with code ${code}`));
|
|
236
|
+
reject(new Error(`Command ${command} ${args.join(" ")} exited with code ${code}`));
|
|
237
|
+
(0, node_process_1.exit)(1);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
function prismaPackage(answer) {
|
|
243
|
+
// Get the absolute path of the input directory parameter
|
|
244
|
+
const absDirPath = node_path_1.default.resolve(process.cwd());
|
|
245
|
+
// Load the package.json file
|
|
246
|
+
const packageJsonPath = node_path_1.default.join(absDirPath, "package.json");
|
|
247
|
+
const fileContents = node_fs_1.default.readFileSync(packageJsonPath, "utf-8");
|
|
248
|
+
const packageJson = JSON.parse(fileContents);
|
|
249
|
+
// Add the Prisma configuration to the package.json
|
|
250
|
+
packageJson.prisma = {
|
|
251
|
+
schema: `${answer.schemaPath}/prisma/${answer.schemaName}.prisma`,
|
|
252
|
+
};
|
|
253
|
+
// Add the Prisma script to the package.json
|
|
254
|
+
packageJson.scripts = Object.assign(Object.assign({}, packageJson.scripts), { prisma: "npx @expressots/prisma codegen" });
|
|
255
|
+
// Save the package.json file
|
|
256
|
+
node_fs_1.default.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
257
|
+
}
|
|
258
|
+
async function addProviderConfigInExpressotsConfig(schemaName, schemaPath) {
|
|
259
|
+
const absDirPath = node_path_1.default.resolve(process.cwd());
|
|
260
|
+
const expressotsConfigPath = node_path_1.default.join(absDirPath, "expressots.config.ts");
|
|
261
|
+
let fileContents = node_fs_1.default.readFileSync(expressotsConfigPath, "utf-8");
|
|
262
|
+
const config = await compiler_1.default.loadConfig();
|
|
263
|
+
const providersObject = `opinionated: ${config.opinionated},\n\tproviders: {
|
|
264
|
+
prisma: {
|
|
265
|
+
schemaName: "${schemaName}",
|
|
266
|
+
schemaPath: "${schemaPath}",
|
|
267
|
+
entitiesPath: "entities",
|
|
268
|
+
entityNamePattern: "entity",
|
|
269
|
+
},
|
|
270
|
+
},`;
|
|
271
|
+
if (config.providers) {
|
|
272
|
+
// delete the providers object until the last closing curly brace
|
|
273
|
+
fileContents = fileContents.replace(/\n([\s]*?)providers: {([\s\S]*?)};/, "\n};");
|
|
274
|
+
}
|
|
275
|
+
const newFileContents = fileContents.replace(/opinionated: (.*)/, providersObject);
|
|
276
|
+
node_fs_1.default.writeFileSync(expressotsConfigPath, newFileContents);
|
|
277
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Prisma, PrismaClient } from "@prisma/client";
|
|
2
|
+
import {
|
|
3
|
+
CreateInput,
|
|
4
|
+
ModelsOf,
|
|
5
|
+
DeleteWhere,
|
|
6
|
+
Select,
|
|
7
|
+
PrismaAction,
|
|
8
|
+
} from "@expressots/prisma";
|
|
9
|
+
|
|
10
|
+
interface IBaseRepository<ModelName extends ModelsOf<PrismaClient>> {
|
|
11
|
+
aggregate: (args: PrismaAction<ModelName, "aggregate">) => Promise<any>;
|
|
12
|
+
count: (args: PrismaAction<ModelName, "count">) => Promise<number>;
|
|
13
|
+
create: (
|
|
14
|
+
data:
|
|
15
|
+
| CreateInput<ModelName>["data"]
|
|
16
|
+
| {
|
|
17
|
+
data: CreateInput<ModelName>["data"];
|
|
18
|
+
select?: Select<ModelName, "create">["select"];
|
|
19
|
+
},
|
|
20
|
+
) => Promise<ModelName | never>;
|
|
21
|
+
delete: (
|
|
22
|
+
where: DeleteWhere<ModelName>["where"],
|
|
23
|
+
response?: Select<ModelName, "delete">["select"],
|
|
24
|
+
) => Promise<ModelName | never>;
|
|
25
|
+
deleteMany: (
|
|
26
|
+
args?: PrismaAction<ModelName, "deleteMany">,
|
|
27
|
+
) => Promise<Prisma.BatchPayload>;
|
|
28
|
+
findFirst: (
|
|
29
|
+
args: PrismaAction<ModelName, "findFirst">,
|
|
30
|
+
) => Promise<ModelName | null>;
|
|
31
|
+
findFirstOrThrow: (
|
|
32
|
+
args?: PrismaAction<ModelName, "findFirstOrThrow">,
|
|
33
|
+
) => Promise<ModelName | never>;
|
|
34
|
+
findMany: (
|
|
35
|
+
args: PrismaAction<ModelName, "findMany">,
|
|
36
|
+
) => Promise<ModelName[]>;
|
|
37
|
+
findUnique: (
|
|
38
|
+
args: PrismaAction<ModelName, "findUnique">,
|
|
39
|
+
) => Promise<ModelName | null>;
|
|
40
|
+
findUniqueOrThrow: (
|
|
41
|
+
args?: PrismaAction<ModelName, "findFirstOrThrow">,
|
|
42
|
+
) => Promise<ModelName | never>;
|
|
43
|
+
groupBy: (
|
|
44
|
+
args: PrismaAction<ModelName, "groupBy">,
|
|
45
|
+
) => Promise<ModelName | never>;
|
|
46
|
+
update: (
|
|
47
|
+
args: PrismaAction<ModelName, "update">,
|
|
48
|
+
) => Promise<ModelName | never>;
|
|
49
|
+
updateMany: (
|
|
50
|
+
args: PrismaAction<ModelName, "updateMany">,
|
|
51
|
+
) => Promise<Prisma.BatchPayload>;
|
|
52
|
+
upsert: (
|
|
53
|
+
args: PrismaAction<ModelName, "upsert">,
|
|
54
|
+
) => Promise<ModelName | never>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { IBaseRepository };
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { PrismaClient, Prisma } from "@prisma/client";
|
|
2
|
+
import {
|
|
3
|
+
CreateInput,
|
|
4
|
+
ModelsOf,
|
|
5
|
+
DeleteWhere,
|
|
6
|
+
Select,
|
|
7
|
+
PrismaAction,
|
|
8
|
+
} from "@expressots/prisma";
|
|
9
|
+
import { provide } from "inversify-binding-decorators";
|
|
10
|
+
import { IBaseRepository } from "./base-repository.interface";
|
|
11
|
+
|
|
12
|
+
@provide(BaseRepository)
|
|
13
|
+
class BaseRepository<ModelName extends ModelsOf<PrismaClient>>
|
|
14
|
+
implements IBaseRepository<ModelName>
|
|
15
|
+
{
|
|
16
|
+
protected prismaModel: any;
|
|
17
|
+
protected prismaClient: PrismaClient;
|
|
18
|
+
constructor(modelName: keyof PrismaClient) {
|
|
19
|
+
this.prismaClient = new PrismaClient();
|
|
20
|
+
this.prismaModel = this.prismaClient[modelName];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async aggregate(args: PrismaAction<ModelName, "aggregate">): Promise<any> {
|
|
24
|
+
return await this.prismaModel.aggregate(args);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async count(args: PrismaAction<ModelName, "count">): Promise<number> {
|
|
28
|
+
return await this.prismaModel.count(args);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async create(
|
|
32
|
+
data:
|
|
33
|
+
| CreateInput<ModelName>["data"]
|
|
34
|
+
| {
|
|
35
|
+
data: CreateInput<ModelName>["data"];
|
|
36
|
+
select?: Select<ModelName, "create">["select"];
|
|
37
|
+
},
|
|
38
|
+
): Promise<ModelName | never> {
|
|
39
|
+
if (!data) {
|
|
40
|
+
throw new Error("Data cannot be null or undefined");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (typeof data === "object" && "data" in data) {
|
|
44
|
+
return await this.prismaModel.create(data);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return await this.prismaModel.create({ data });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async delete(
|
|
51
|
+
where: DeleteWhere<ModelName>["where"],
|
|
52
|
+
select?: Select<ModelName, "delete">["select"],
|
|
53
|
+
): Promise<ModelName | never> {
|
|
54
|
+
if (!where) {
|
|
55
|
+
throw new Error("Data cannot be null or undefined");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const obj = await this.prismaModel.delete({ where });
|
|
59
|
+
|
|
60
|
+
if (select) {
|
|
61
|
+
const entries = Object.entries(select);
|
|
62
|
+
|
|
63
|
+
const hasTrueField = entries.some(([, value]) => value);
|
|
64
|
+
|
|
65
|
+
if (hasTrueField) {
|
|
66
|
+
const result: any = {};
|
|
67
|
+
for (const [key, value] of entries) {
|
|
68
|
+
if (value) {
|
|
69
|
+
result[key] = obj[key as keyof typeof obj];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result as ModelName;
|
|
73
|
+
} else {
|
|
74
|
+
for (const [key, value] of entries) {
|
|
75
|
+
if (!value) {
|
|
76
|
+
delete obj[key as keyof typeof obj];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return obj;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async deleteMany(
|
|
86
|
+
args?: PrismaAction<ModelName, "deleteMany">,
|
|
87
|
+
): Promise<Prisma.BatchPayload> {
|
|
88
|
+
return await this.prismaModel.deleteMany(args);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async findFirst(
|
|
92
|
+
args?: PrismaAction<ModelName, "findFirst">,
|
|
93
|
+
): Promise<ModelName | null> {
|
|
94
|
+
return await this.prismaModel.findFirst(args);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async findFirstOrThrow(
|
|
98
|
+
args?: PrismaAction<ModelName, "findFirstOrThrow">,
|
|
99
|
+
): Promise<ModelName | never> {
|
|
100
|
+
return await this.prismaModel.findFirstOrThrow(args);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async findMany(
|
|
104
|
+
args: PrismaAction<ModelName, "findMany">,
|
|
105
|
+
): Promise<ModelName[]> {
|
|
106
|
+
return await this.prismaModel.findMany(args);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async findUnique(
|
|
110
|
+
args: PrismaAction<ModelName, "findUnique">,
|
|
111
|
+
): Promise<ModelName | null> {
|
|
112
|
+
return this.prismaModel.findUnique(args);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async findUniqueOrThrow(
|
|
116
|
+
args?: PrismaAction<ModelName, "findUniqueOrThrow">,
|
|
117
|
+
): Promise<ModelName | never> {
|
|
118
|
+
return await this.prismaModel.findUniqueOrThrow(args);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async groupBy(
|
|
122
|
+
args: PrismaAction<ModelName, "groupBy">,
|
|
123
|
+
): Promise<ModelName | never> {
|
|
124
|
+
return await this.prismaModel.groupBy(args);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async update(
|
|
128
|
+
args: PrismaAction<ModelName, "update">,
|
|
129
|
+
): Promise<ModelName | never> {
|
|
130
|
+
return await this.prismaModel.update(args);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async updateMany(
|
|
134
|
+
args: PrismaAction<ModelName, "updateMany">,
|
|
135
|
+
): Promise<Prisma.BatchPayload> {
|
|
136
|
+
return await this.prismaModel.updateMany(args);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async upsert(
|
|
140
|
+
args: PrismaAction<ModelName, "upsert">,
|
|
141
|
+
): Promise<ModelName | never> {
|
|
142
|
+
return await this.prismaModel.upsert(args);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export { BaseRepository };
|
|
@@ -6,11 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.addControllerToModule = void 0;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
async function addControllerToModule(filePath, controllerName, controllerPath) {
|
|
9
|
-
const fileContent = await node_fs_1.default.promises.readFile(filePath,
|
|
9
|
+
const fileContent = await node_fs_1.default.promises.readFile(filePath, "utf8");
|
|
10
10
|
const imports = [];
|
|
11
11
|
const notImports = [];
|
|
12
|
-
fileContent.split(
|
|
13
|
-
if (line.startsWith(
|
|
12
|
+
fileContent.split("\n").forEach((line) => {
|
|
13
|
+
if (line.startsWith("import")) {
|
|
14
14
|
imports.push(line);
|
|
15
15
|
}
|
|
16
16
|
else {
|
|
@@ -27,14 +27,20 @@ async function addControllerToModule(filePath, controllerName, controllerPath) {
|
|
|
27
27
|
if (!moduleDeclarationMatch) {
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
|
-
const controllers = moduleDeclarationMatch[1]
|
|
30
|
+
const controllers = moduleDeclarationMatch[1]
|
|
31
|
+
.trim()
|
|
32
|
+
.split(",")
|
|
33
|
+
.map((c) => c.trim())
|
|
34
|
+
.filter((c) => c);
|
|
31
35
|
if (controllers.includes(controllerName)) {
|
|
32
36
|
return;
|
|
33
37
|
}
|
|
34
38
|
controllers.push(controllerName);
|
|
35
|
-
const newControllers = controllers.join(
|
|
39
|
+
const newControllers = controllers.join(", ");
|
|
36
40
|
const newModuleDeclaration = `CreateModule([${newControllers}]`;
|
|
37
|
-
const newFileContent = [...imports, ...notImports]
|
|
38
|
-
|
|
41
|
+
const newFileContent = [...imports, ...notImports]
|
|
42
|
+
.join("\n")
|
|
43
|
+
.replace(moduleDeclarationRegex, newModuleDeclaration);
|
|
44
|
+
await node_fs_1.default.promises.writeFile(filePath, newFileContent, "utf8");
|
|
39
45
|
}
|
|
40
46
|
exports.addControllerToModule = addControllerToModule;
|
|
@@ -14,14 +14,17 @@ async function validateAppContainer() {
|
|
|
14
14
|
const { sourceRoot } = await compiler_1.default.loadConfig();
|
|
15
15
|
const imports = [];
|
|
16
16
|
const notImports = [];
|
|
17
|
-
const path = (0, glob_1.globSync)(`./${sourceRoot}/${APP_CONTAINER}`, {
|
|
17
|
+
const path = (0, glob_1.globSync)(`./${sourceRoot}/${APP_CONTAINER}`, {
|
|
18
|
+
absolute: true,
|
|
19
|
+
ignore: "**/node_modules/**",
|
|
20
|
+
});
|
|
18
21
|
if (!path.length) {
|
|
19
|
-
(0, cli_ui_1.printError)(
|
|
22
|
+
(0, cli_ui_1.printError)("Module not added to Container. Container file not found!", APP_CONTAINER);
|
|
20
23
|
process.exit(1);
|
|
21
24
|
}
|
|
22
|
-
const fileContent = await node_fs_1.default.promises.readFile(path[0],
|
|
23
|
-
fileContent.split(
|
|
24
|
-
if (line.startsWith(
|
|
25
|
+
const fileContent = await node_fs_1.default.promises.readFile(path[0], "utf8");
|
|
26
|
+
fileContent.split("\n").forEach((line) => {
|
|
27
|
+
if (line.startsWith("import")) {
|
|
25
28
|
imports.push(line);
|
|
26
29
|
}
|
|
27
30
|
else {
|
|
@@ -32,17 +35,21 @@ async function validateAppContainer() {
|
|
|
32
35
|
const moduleDeclarationRegex = /.create\(\s*\[([\s\S]*?)]/;
|
|
33
36
|
const moduleDeclarationMatch = fileContent.match(moduleDeclarationRegex);
|
|
34
37
|
if (!moduleDeclarationMatch) {
|
|
35
|
-
(0, cli_ui_1.printError)(
|
|
38
|
+
(0, cli_ui_1.printError)("Container format incorrect!", APP_CONTAINER);
|
|
36
39
|
process.exit(1);
|
|
37
40
|
}
|
|
38
|
-
const modules = moduleDeclarationMatch[1]
|
|
41
|
+
const modules = moduleDeclarationMatch[1]
|
|
42
|
+
.trim()
|
|
43
|
+
.split(",")
|
|
44
|
+
.filter((m) => m.trim() !== "")
|
|
45
|
+
.map((m) => m.trim());
|
|
39
46
|
return {
|
|
40
47
|
regex: moduleDeclarationRegex,
|
|
41
48
|
path: path[0],
|
|
42
49
|
content: moduleDeclarationMatch,
|
|
43
50
|
modules,
|
|
44
51
|
imports,
|
|
45
|
-
notImports
|
|
52
|
+
notImports,
|
|
46
53
|
};
|
|
47
54
|
}
|
|
48
55
|
async function addModuleToContainer(name, modulePath, path) {
|
|
@@ -59,7 +66,7 @@ async function addModuleToContainer(name, modulePath, path) {
|
|
|
59
66
|
let newImport = "";
|
|
60
67
|
const modulePathRegex = /^[^/]=$/;
|
|
61
68
|
if (!modulePathRegex.test(modulePath)) {
|
|
62
|
-
if (path.split(
|
|
69
|
+
if (path.split("/").length > 1) {
|
|
63
70
|
newImport = `import { ${moduleName}Module } from "${usecaseDir}${modulePath}/${name}.module";`;
|
|
64
71
|
}
|
|
65
72
|
else {
|
|
@@ -69,16 +76,21 @@ async function addModuleToContainer(name, modulePath, path) {
|
|
|
69
76
|
else {
|
|
70
77
|
newImport = `import { ${moduleName}Module } from "${usecaseDir}${name}/${name}.module";`;
|
|
71
78
|
}
|
|
72
|
-
if (containerData.imports.includes(newImport) &&
|
|
79
|
+
if (containerData.imports.includes(newImport) &&
|
|
80
|
+
containerData.modules.includes(`${moduleName}Module`)) {
|
|
73
81
|
return;
|
|
74
82
|
}
|
|
75
83
|
containerData.imports.push(newImport);
|
|
76
84
|
containerData.modules.push(`${moduleName}Module`);
|
|
77
|
-
const newModule = containerData.modules.join(
|
|
85
|
+
const newModule = containerData.modules.join(", ");
|
|
78
86
|
const newModuleDeclaration = `.create([${newModule}]`;
|
|
79
|
-
const newFileContent = [
|
|
80
|
-
|
|
87
|
+
const newFileContent = [
|
|
88
|
+
...containerData.imports,
|
|
89
|
+
...containerData.notImports,
|
|
90
|
+
]
|
|
91
|
+
.join("\n")
|
|
92
|
+
.replace(containerData.regex, newModuleDeclaration);
|
|
81
93
|
console.log(" ", chalk_1.default.greenBright(`[container]`.padEnd(14)), chalk_1.default.bold.white(`${moduleName}Module added to ${APP_CONTAINER}! ✔️`));
|
|
82
|
-
await node_fs_1.default.promises.writeFile(containerData.path, newFileContent,
|
|
94
|
+
await node_fs_1.default.promises.writeFile(containerData.path, newFileContent, "utf8");
|
|
83
95
|
}
|
|
84
96
|
exports.addModuleToContainer = addModuleToContainer;
|
package/bin/utils/center-text.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.centerText = void 0;
|
|
|
4
4
|
function centerText(text) {
|
|
5
5
|
const terminalWidth = process.stdout.columns;
|
|
6
6
|
const padding = Math.floor((terminalWidth - text.length) / 2);
|
|
7
|
-
const centeredText =
|
|
7
|
+
const centeredText = " ".repeat(padding) + text;
|
|
8
8
|
return centeredText;
|
|
9
9
|
}
|
|
10
10
|
exports.centerText = centerText;
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
exports.hasFolder = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function hasFolder(rootDir, ignoreList = []) {
|
|
10
|
+
function searchDir(directory) {
|
|
11
|
+
const files = fs_1.default.readdirSync(directory);
|
|
12
|
+
for (const file of files) {
|
|
13
|
+
if (ignoreList.includes(file))
|
|
14
|
+
continue; // Skip if the file/folder is in the ignore list
|
|
15
|
+
const filePath = path_1.default.join(directory, file);
|
|
16
|
+
const stats = fs_1.default.statSync(filePath);
|
|
17
|
+
if (stats.isDirectory()) {
|
|
18
|
+
if (file === "prisma") {
|
|
19
|
+
return filePath; // Return full path of the 'prisma' folder
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
const result = searchDir(filePath); // Search inside other directories recursively
|
|
23
|
+
if (result) {
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return null; // 'prisma' folder was not found in this directory
|
|
30
|
+
}
|
|
31
|
+
const foundPath = searchDir(rootDir);
|
|
32
|
+
return {
|
|
33
|
+
found: !!foundPath,
|
|
34
|
+
path: foundPath,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
exports.hasFolder = hasFolder;
|
|
@@ -18,9 +18,9 @@ async function verifyIfFileExists(path) {
|
|
|
18
18
|
default: true,
|
|
19
19
|
},
|
|
20
20
|
]);
|
|
21
|
-
const fileName = path.split(
|
|
21
|
+
const fileName = path.split("/").pop();
|
|
22
22
|
if (!answer.confirm) {
|
|
23
|
-
(0, cli_ui_1.printError)(
|
|
23
|
+
(0, cli_ui_1.printError)("File not created!", fileName);
|
|
24
24
|
process.exit(1);
|
|
25
25
|
}
|
|
26
26
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expressots/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Expressots CLI - modern, fast, lightweight nodejs web framework (@cli)",
|
|
5
5
|
"author": "Richard Zampieri",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,26 +31,31 @@
|
|
|
31
31
|
"Scaffolding"
|
|
32
32
|
],
|
|
33
33
|
"scripts": {
|
|
34
|
+
"prepare": "husky install",
|
|
34
35
|
"start:build": "npm run build && npm run start",
|
|
35
36
|
"start": "node ./bin/cli.js",
|
|
36
37
|
"start:dev": "tsnd ./src/cli.ts",
|
|
37
38
|
"build": "npm run clean && tsc -p tsconfig.json && yarn cp:templates && chmod +x ./bin/cli.js",
|
|
38
|
-
"cp:templates": "cp -r ./src/generate/templates ./bin/generate/templates",
|
|
39
|
+
"cp:templates": "cp -r ./src/generate/templates ./bin/generate/templates && cp -r ./src/providers/prisma/templates ./bin/providers/prisma/templates",
|
|
39
40
|
"clean": "rimraf ./bin",
|
|
40
|
-
"
|
|
41
|
+
"format": "prettier --write \"./src/**/*.ts\" --cache",
|
|
42
|
+
"lint": "eslint \"./src/**/*.ts\"",
|
|
43
|
+
"lint:fix": "eslint \"./src/**/*.ts\" --fix",
|
|
41
44
|
"release": "release-it",
|
|
42
|
-
"
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest",
|
|
47
|
+
"test:coverage": "vitest run --coverage"
|
|
43
48
|
},
|
|
44
49
|
"dependencies": {
|
|
45
|
-
"@expressots/boost-ts": "
|
|
46
|
-
"chalk-animation": "
|
|
47
|
-
"cli-progress": "
|
|
48
|
-
"degit": "
|
|
49
|
-
"glob": "
|
|
50
|
-
"inquirer": "
|
|
51
|
-
"mustache": "
|
|
52
|
-
"ts-node": "
|
|
53
|
-
"yargs": "
|
|
50
|
+
"@expressots/boost-ts": "1.1.1",
|
|
51
|
+
"chalk-animation": "2.0.3",
|
|
52
|
+
"cli-progress": "3.11.2",
|
|
53
|
+
"degit": "2.8.4",
|
|
54
|
+
"glob": "10.2.6",
|
|
55
|
+
"inquirer": "8.0.0",
|
|
56
|
+
"mustache": "4.2.0",
|
|
57
|
+
"ts-node": "10.9.1",
|
|
58
|
+
"yargs": "17.6.2"
|
|
54
59
|
},
|
|
55
60
|
"devDependencies": {
|
|
56
61
|
"@commitlint/cli": "^17.7.1",
|
|
@@ -74,7 +79,9 @@
|
|
|
74
79
|
"release-it": "^16.1.5",
|
|
75
80
|
"rimraf": "^4.1.2",
|
|
76
81
|
"ts-node-dev": "^2.0.0",
|
|
77
|
-
"typescript": "^4.9.5"
|
|
82
|
+
"typescript": "^4.9.5",
|
|
83
|
+
"vite": "^4.4.9",
|
|
84
|
+
"vitest": "^0.34.4"
|
|
78
85
|
},
|
|
79
86
|
"release-it": {
|
|
80
87
|
"git": {
|