opticore-installer 1.2.49

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/dist/index.cjs ADDED
@@ -0,0 +1,974 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/core/installer.core.ts
27
+ var import_prompts12 = require("@clack/prompts");
28
+ var import_chalk6 = __toESM(require("chalk"), 1);
29
+ var import_ansi_colors9 = __toESM(require("ansi-colors"), 1);
30
+
31
+ // src/utils/console/welcomeMessage.util.ts
32
+ var import_cfonts = __toESM(require("cfonts"), 1);
33
+ var import_chalk = __toESM(require("chalk"), 1);
34
+ var UWelcomeMessage = () => {
35
+ import_cfonts.default.say("OpticoreJS", {
36
+ font: "block",
37
+ align: "left",
38
+ colors: ["yellow", "#FF6B35"],
39
+ background: "transparent",
40
+ letterSpacing: 1,
41
+ lineHeight: 1,
42
+ space: true,
43
+ maxLength: "0"
44
+ });
45
+ const orange = import_chalk.default.bold.hex("#FF6B35");
46
+ const dim = import_chalk.default.bold.yellow;
47
+ console.log(` ${orange("OPTICORE F R A M E W O R K I N S T A L L E R")}`);
48
+ console.log(` ${dim("Create \xB7 Configure \xB7 Deploy")}
49
+ `);
50
+ console.log(` ${import_chalk.default.bold.dim("Documentation")} ${import_chalk.default.underline.cyan("https://github.com/opticore/framework-installer")}
51
+ `);
52
+ };
53
+
54
+ // src/domains/services/prompts/select/promptSelect.service.ts
55
+ var import_prompts2 = require("@clack/prompts");
56
+
57
+ // src/utils/operationCancelled.util.ts
58
+ var import_prompts = require("@clack/prompts");
59
+ var import_ansi_colors = __toESM(require("ansi-colors"), 1);
60
+ var import_fs = __toESM(require("fs"), 1);
61
+ var UOperationCancelled = (arg) => {
62
+ (0, import_prompts.cancel)(import_ansi_colors.default.bgRed(import_ansi_colors.default.white(" Operation cancelled ")));
63
+ if (arg) {
64
+ import_fs.default.rmSync(arg, { recursive: true, force: true });
65
+ }
66
+ process.exit(130);
67
+ };
68
+
69
+ // src/domains/services/prompts/select/promptSelect.service.ts
70
+ var SPromptSelect = async (arg) => {
71
+ const outputSelect = await (0, import_prompts2.select)(arg);
72
+ return (0, import_prompts2.isCancel)(outputSelect) ? UOperationCancelled : outputSelect;
73
+ };
74
+
75
+ // src/domains/services/prompts/select/outputPromptSelect.service.ts
76
+ var SOutputPromptSelect = async (arg) => {
77
+ return await SPromptSelect({
78
+ message: arg.message,
79
+ initialValue: arg.initialValue,
80
+ options: arg.options
81
+ });
82
+ };
83
+
84
+ // src/core/abstractions/enums/constants/generalMsg.constant.ts
85
+ var CGeneralMsg = {
86
+ noDbCredentials: "You will have to manually set all the variable values in the .env file.",
87
+ starterMsg: "Which starter project would you like to use ?",
88
+ starterInitValue: "restfull_api_project",
89
+ starterOptionsRestFullLabel: "RestFull API project",
90
+ starterOptionsRestFullValue: "restfull_api_project",
91
+ starterOptionsRestFullHint: "OptiCoreJS app tailored to create a RestFull APIs",
92
+ projectNameMessage: "Enter the name of project :",
93
+ projectNamePlaceholder: "opticore",
94
+ projectNameInvalidValue: "Please the project name can't be empty.",
95
+ projectNameBadPattern: "Please enter a valide project name.",
96
+ wrong: "Something went wrong.",
97
+ existingProject: "already exist, please give it another name."
98
+ };
99
+
100
+ // src/core/abstractions/enums/constants/starterOptions.constant.ts
101
+ var CStarterOptions = [
102
+ // { label: "RestFull API complete project", value: ["complete_restfull_project"], hint: "Everything you'll need to build a server render web project" },
103
+ { label: "Web project", value: ["web_project"], hint: "Everything you'll need to build a server render web project" },
104
+ { label: "Skeleton project", value: ["skeleton_project"], hint: "A lean OptiCoreJS application with the framework core" },
105
+ { label: CGeneralMsg.starterOptionsRestFullLabel, value: [CGeneralMsg.starterOptionsRestFullValue], hint: CGeneralMsg.starterOptionsRestFullHint },
106
+ // { label: "Complete restFull API project", value: ["complete_api_restfull_project"], hint: "OptiCoreJS app tailored to create a complete RestFull APIs" },
107
+ { label: "standard project", value: ["standard_project"], hint: "OptiCoreJS app tailored to create a standard Web project" }
108
+ ];
109
+
110
+ // src/presentations/starter/starterOptions.starter.ts
111
+ var StarterOptions = {
112
+ message: CGeneralMsg.starterMsg,
113
+ initialValue: [CGeneralMsg.starterInitValue],
114
+ options: CStarterOptions
115
+ };
116
+
117
+ // src/domains/services/prompts/text/promptText.service.ts
118
+ var import_prompts3 = require("@clack/prompts");
119
+ var SPromptText = async (arg) => {
120
+ const textOutput = await (0, import_prompts3.text)(arg.textOpt);
121
+ return (0, import_prompts3.isCancel)(textOutput) ? UOperationCancelled : textOutput;
122
+ };
123
+
124
+ // src/domains/services/validate.service.ts
125
+ var SValidate = (value, messageInvalidValue, messageBadPattern, regex) => {
126
+ let pattern = new RegExp(regex);
127
+ if (!value) {
128
+ return messageInvalidValue;
129
+ }
130
+ if (!pattern.test(value)) {
131
+ return messageBadPattern;
132
+ }
133
+ };
134
+
135
+ // src/domains/services/prompts/text/outputPromptText.service.ts
136
+ var SOutputPromptText = async (message, placeholder, messageInvalidValue, messageBadPattern, regex, projectPath, initialValue, defaultValue) => {
137
+ return await SPromptText({
138
+ textOpt: {
139
+ initialValue,
140
+ defaultValue,
141
+ message,
142
+ placeholder,
143
+ validate: (value) => SValidate(value, messageInvalidValue, messageBadPattern, regex)
144
+ },
145
+ projectPath
146
+ });
147
+ };
148
+
149
+ // src/presentations/starter/template.starter.ts
150
+ var import_fs2 = __toESM(require("fs"), 1);
151
+ var import_path = __toESM(require("path"), 1);
152
+ var import_util = require("util");
153
+
154
+ // src/utils/logInfo.util.ts
155
+ var import_prompts4 = require("@clack/prompts");
156
+ var import_chalk2 = __toESM(require("chalk"), 1);
157
+ var ULogInfo = (logMessage) => {
158
+ import_prompts4.log.info(import_chalk2.default.dim(logMessage));
159
+ };
160
+
161
+ // src/utils/logError.util.ts
162
+ var import_prompts5 = require("@clack/prompts");
163
+ var import_chalk3 = __toESM(require("chalk"), 1);
164
+ var ULogError = (logMessage) => {
165
+ import_prompts5.log.error(import_chalk3.default.red(logMessage));
166
+ };
167
+
168
+ // src/presentations/starter/template.starter.ts
169
+ var templateStarter = async (projectName) => {
170
+ const mkdir = (0, import_util.promisify)(import_fs2.default.mkdir);
171
+ if (projectName) {
172
+ const currentPath = process.cwd();
173
+ const projectPath = import_path.default.join(currentPath, projectName);
174
+ if (import_fs2.default.existsSync(projectPath)) {
175
+ ULogInfo(`${projectName} ${CGeneralMsg.existingProject}`);
176
+ import_fs2.default.rmSync(projectPath, { recursive: true, force: true });
177
+ process.exit(1);
178
+ } else {
179
+ import_fs2.default.mkdirSync(projectPath);
180
+ }
181
+ const normalizedPath = import_path.default.normalize(projectPath);
182
+ await mkdir(normalizedPath, { recursive: true });
183
+ const normalizedCurrentPath = import_path.default.normalize(currentPath);
184
+ await mkdir(normalizedCurrentPath, { recursive: true });
185
+ return { normalizedCurrentPath, normalizedPath };
186
+ } else {
187
+ ULogError(CGeneralMsg.wrong);
188
+ process.exit();
189
+ }
190
+ };
191
+
192
+ // src/core/installer.core.ts
193
+ var process5 = __toESM(require("process"), 1);
194
+
195
+ // src/presentations/middlewares/selectDB.middleware.ts
196
+ var import_prompts11 = require("@clack/prompts");
197
+ var import_ansi_colors8 = __toESM(require("ansi-colors"), 1);
198
+ var import_node_process3 = __toESM(require("process"), 1);
199
+
200
+ // src/core/abstractions/enums/constants/selectDBMessage.constant.ts
201
+ var CSelectDBMessage = {
202
+ dbSelect: "Which database would you use ?",
203
+ dbCredentials: "Do you want create database credentials in .env file ?",
204
+ createDBCredentialsLabel: "Create database credentials",
205
+ createDBCredentialsValue: "create_db_credentials",
206
+ noDBCredentialsLabel: "No database credentials",
207
+ noDBCredentialsValue: "no_db_credentials"
208
+ };
209
+
210
+ // src/core/abstractions/enums/constants/dbNameLabel.constant.ts
211
+ var CDbNameLabel = {
212
+ mysql: "MySQL",
213
+ mongodb: "Mongo DB",
214
+ postgresql: "Postgres",
215
+ oracle: "Oracle",
216
+ otherDb: "Other database",
217
+ createDbCredentials: "Create database credentials",
218
+ noDbCredentials: "No database credentials",
219
+ messageDBUser: "Enter your user database :",
220
+ messageDBPwd: "Enter the password of database :",
221
+ messageDBName: "Enter the name of database :",
222
+ placeholderDBUser: "user",
223
+ placeholderDBHost: "localhost",
224
+ placeholderDBName: "db_toto",
225
+ pwdMask: "*",
226
+ dbUserInvalidValue: "Please user database can't be empty.",
227
+ dbPwdInvalidValue: "Please a database password can't be empty.",
228
+ dbHostInvalidValue: "Please a database host can't be empty.",
229
+ dbNameInvalidValue: "Please database name can't be empty.",
230
+ dbUserBadPattern: "Please enter a valide user database.",
231
+ dbHostBadPattern: "Please enter a valide database host.",
232
+ dbPwdBadPattern: "Please enter a valide database password.",
233
+ dbNameBadPattern: "Please enter a valide database name.",
234
+ messageDBHost: "Enter the host of database :",
235
+ messageDBPort: "Enter the port of database :",
236
+ placeholderDBPort: "mysql: 3306",
237
+ dbPortInvalidValue: "Please a database port can't be empty.",
238
+ dbPortBadPattern: "Please enter a valide database port."
239
+ };
240
+
241
+ // src/core/abstractions/enums/constants/dbNameValue.constant.ts
242
+ var CDbNameValue = {
243
+ mysql: "mysql",
244
+ mongodb: "mongodb",
245
+ postgresql: "postgresql",
246
+ oracle: "oracle",
247
+ otherDb: "other_db",
248
+ createDbCredentials: "create_db_credentials",
249
+ noDbCredentials: "no_db_credentials"
250
+ };
251
+
252
+ // src/presentations/middlewares/dbCredentials.middleware.ts
253
+ var import_ansi_colors3 = __toESM(require("ansi-colors"), 1);
254
+ var import_node_process2 = __toESM(require("process"), 1);
255
+ var import_prompts8 = require("@clack/prompts");
256
+
257
+ // src/domains/services/promptsDBCredentials.service.ts
258
+ var import_node_process = __toESM(require("process"), 1);
259
+ var import_prompts7 = require("@clack/prompts");
260
+ var import_ansi_colors2 = __toESM(require("ansi-colors"), 1);
261
+
262
+ // src/domains/services/prompts/password/promptPassword.service.ts
263
+ var import_prompts6 = require("@clack/prompts");
264
+ var SPromptPassword = async (arg) => {
265
+ const outputConfirm = await (0, import_prompts6.password)(arg);
266
+ return (0, import_prompts6.isCancel)(outputConfirm) ? UOperationCancelled : outputConfirm;
267
+ };
268
+
269
+ // src/domains/services/prompts/password/outputPromptPassword.service.ts
270
+ var SOutputPromptPassword = async (message) => {
271
+ return await SPromptPassword({
272
+ message,
273
+ mask: "*",
274
+ validate: (value) => SValidate(
275
+ value,
276
+ "The password is required",
277
+ "The password can not be blank",
278
+ "[a-zA-Z0-9\\P{Z}]"
279
+ )
280
+ });
281
+ };
282
+
283
+ // src/domains/services/promptsDBCredentials.service.ts
284
+ var SPromptsDBCredentials = class {
285
+ projectPath;
286
+ constructor(projectPath) {
287
+ this.projectPath = projectPath;
288
+ }
289
+ async promptTextDatabaseUser() {
290
+ const user = await SOutputPromptText(
291
+ CDbNameLabel.messageDBUser,
292
+ CDbNameLabel.placeholderDBUser,
293
+ CDbNameLabel.dbUserInvalidValue,
294
+ CDbNameLabel.dbUserBadPattern,
295
+ "^[a-zA-Z0-9]+$",
296
+ this.projectPath
297
+ );
298
+ if (user instanceof Function) {
299
+ (0, import_prompts7.cancel)(import_ansi_colors2.default.bgRed(import_ansi_colors2.default.white(" Operation cancelled ")));
300
+ import_node_process.default.exit(130);
301
+ } else {
302
+ return user;
303
+ }
304
+ }
305
+ async promptPasswordDatabasePWD() {
306
+ const password2 = await SOutputPromptPassword(
307
+ CDbNameLabel.messageDBPwd
308
+ );
309
+ if (password2 instanceof Function) {
310
+ (0, import_prompts7.cancel)(import_ansi_colors2.default.bgRed(import_ansi_colors2.default.white(" Operation cancelled ")));
311
+ import_node_process.default.exit(130);
312
+ } else {
313
+ return password2;
314
+ }
315
+ }
316
+ async promptTextDatabaseHost() {
317
+ const host = await SOutputPromptText(
318
+ CDbNameLabel.messageDBHost,
319
+ CDbNameLabel.placeholderDBHost,
320
+ CDbNameLabel.dbHostInvalidValue,
321
+ CDbNameLabel.dbHostBadPattern,
322
+ "^[a-zA-Z]+$",
323
+ this.projectPath
324
+ );
325
+ if (host instanceof Function) {
326
+ (0, import_prompts7.cancel)(import_ansi_colors2.default.bgRed(import_ansi_colors2.default.white(" Operation cancelled ")));
327
+ import_node_process.default.exit(130);
328
+ } else {
329
+ return host;
330
+ }
331
+ }
332
+ async promptTextDatabasePort() {
333
+ const port = await SOutputPromptText(
334
+ CDbNameLabel.messageDBPort,
335
+ CDbNameLabel.placeholderDBPort,
336
+ CDbNameLabel.dbPortInvalidValue,
337
+ CDbNameLabel.dbPortBadPattern,
338
+ "^[0-9]+$",
339
+ this.projectPath
340
+ );
341
+ if (port instanceof Function) {
342
+ (0, import_prompts7.cancel)(import_ansi_colors2.default.bgRed(import_ansi_colors2.default.white(" Operation cancelled ")));
343
+ import_node_process.default.exit(130);
344
+ } else {
345
+ return port;
346
+ }
347
+ }
348
+ async promptTextDatabaseName() {
349
+ const dbName = await SOutputPromptText(
350
+ CDbNameLabel.messageDBName,
351
+ CDbNameLabel.placeholderDBName,
352
+ CDbNameLabel.dbNameInvalidValue,
353
+ CDbNameLabel.dbNameBadPattern,
354
+ "^[a-zA-Z0-9]+$",
355
+ this.projectPath
356
+ );
357
+ if (dbName instanceof Function) {
358
+ (0, import_prompts7.cancel)(import_ansi_colors2.default.bgRed(import_ansi_colors2.default.white(" Operation cancelled ")));
359
+ import_node_process.default.exit(130);
360
+ } else {
361
+ return dbName;
362
+ }
363
+ }
364
+ };
365
+
366
+ // src/presentations/middlewares/dbCredentials.middleware.ts
367
+ var MDbCredentials = async (projectPath, currentPath, projectName) => {
368
+ const outputDBCredentials = await SOutputPromptSelect({
369
+ message: CSelectDBMessage.dbCredentials,
370
+ initialValue: [CDbNameLabel.createDbCredentials],
371
+ options: [
372
+ { label: CDbNameLabel.createDbCredentials, value: [CDbNameValue.createDbCredentials] },
373
+ { label: CDbNameLabel.noDbCredentials, value: [CDbNameValue.noDbCredentials] }
374
+ ]
375
+ });
376
+ let databaseUser;
377
+ let databasePassword;
378
+ let databaseHost;
379
+ let databasePort;
380
+ let databaseName;
381
+ if (outputDBCredentials instanceof Function) {
382
+ (0, import_prompts8.cancel)(import_ansi_colors3.default.bgRed(import_ansi_colors3.default.white(" Operation cancelled ")));
383
+ import_node_process2.default.exit(130);
384
+ } else {
385
+ let credentials;
386
+ outputDBCredentials.map(async (outputDBCredential) => {
387
+ credentials = outputDBCredential;
388
+ });
389
+ if (credentials === CDbNameValue.noDbCredentials) {
390
+ return CDbNameValue.noDbCredentials;
391
+ } else {
392
+ const dbCredentials = new SPromptsDBCredentials(projectPath);
393
+ databaseUser = await dbCredentials.promptTextDatabaseUser();
394
+ databasePassword = await dbCredentials.promptPasswordDatabasePWD();
395
+ databasePort = await dbCredentials.promptTextDatabasePort();
396
+ databaseHost = await dbCredentials.promptTextDatabaseHost();
397
+ databaseName = await dbCredentials.promptTextDatabaseName();
398
+ return {
399
+ credentials,
400
+ databaseUser,
401
+ databasePassword,
402
+ databasePort,
403
+ databaseHost,
404
+ databaseName
405
+ };
406
+ }
407
+ }
408
+ };
409
+
410
+ // src/domains/services/transformDbCredentialsToFusedParams.service.ts
411
+ function transformDbCredentialsToFusedParams(credentials) {
412
+ if (credentials === CDbNameValue.noDbCredentials) {
413
+ return CDbNameValue.noDbCredentials;
414
+ } else {
415
+ return credentials;
416
+ }
417
+ }
418
+
419
+ // src/domains/services/fetchCredentials.service.ts
420
+ var SFetchCredentials = async (projectPath, currentPath, projectName) => {
421
+ let dbParams;
422
+ let envParams;
423
+ let fetchParams = "";
424
+ const dbCredentials = await MDbCredentials(projectPath, currentPath, projectName);
425
+ const params = transformDbCredentialsToFusedParams(dbCredentials);
426
+ if (params === CDbNameValue.noDbCredentials) {
427
+ return params;
428
+ } else {
429
+ const credParams = params;
430
+ dbParams = {
431
+ databaseHost: credParams.databaseHost,
432
+ databaseName: credParams.databaseName,
433
+ databasePassword: credParams.databasePassword,
434
+ databasePort: credParams.databasePort,
435
+ databaseUser: credParams.databaseUser,
436
+ projectPath
437
+ };
438
+ envParams = {
439
+ dbName: credParams.databaseName,
440
+ dbUser: credParams.databaseUser,
441
+ dbPwd: credParams.databasePassword,
442
+ dbHost: credParams.databaseHost,
443
+ dbPort: credParams.databasePort
444
+ };
445
+ const allParams = { dbCredentials, fetchParams, dbParams, envParams };
446
+ return allParams;
447
+ }
448
+ };
449
+
450
+ // src/presentations/starter/projectCreation.starter.ts
451
+ var import_path2 = __toESM(require("path"), 1);
452
+ var import_fs3 = __toESM(require("fs"), 1);
453
+ var import_child_process = __toESM(require("child_process"), 1);
454
+
455
+ // src/utils/console/endingMessage.info.ts
456
+ var import_chalk4 = __toESM(require("chalk"), 1);
457
+ var import_prompts9 = require("@clack/prompts");
458
+ function endingMessageInfo(projectName) {
459
+ import_prompts9.log.success(import_chalk4.default.green.bold("Your OpticoreJs project has been created successfully!"));
460
+ console.log(`
461
+ ${import_chalk4.default.bold("Next steps:")}`);
462
+ console.log(` ${import_chalk4.default.dim("\u276F")} cd ${import_chalk4.default.cyan(projectName)}`);
463
+ console.log(` ${import_chalk4.default.dim("\u276F")} ${import_chalk4.default.cyan("npm run start:dev")}
464
+ `);
465
+ console.log(` ${import_chalk4.default.dim("NB: Before running app, make sure to define in .env file application host and port.")}
466
+ `);
467
+ (0, import_prompts9.outro)(import_chalk4.default.dim("To install opticore components: ") + import_chalk4.default.green("npx opticore list"));
468
+ }
469
+
470
+ // src/presentations/starter/projectCreation.starter.ts
471
+ var import_util2 = require("util");
472
+
473
+ // src/applications/services/packagesVersion.service.ts
474
+ var GetLatestVersion = async (exec, pkgName) => {
475
+ try {
476
+ const { stdout } = await exec(`npm view ${pkgName} version`);
477
+ return stdout.trim();
478
+ } catch {
479
+ return null;
480
+ }
481
+ };
482
+
483
+ // src/applications/services/updateDependencies.service.ts
484
+ var UpdateOpticoreDeps = async (exec, deps) => {
485
+ const updated = { ...deps };
486
+ const opticorePackages = Object.keys(deps).filter((name) => name.startsWith("opticore-"));
487
+ await Promise.all(opticorePackages.map(async (name) => {
488
+ const latest = await GetLatestVersion(exec, name);
489
+ if (latest) updated[name] = `^${latest}`;
490
+ }));
491
+ return updated;
492
+ };
493
+
494
+ // src/presentations/starter/projectCreation.starter.ts
495
+ var SProjectCreation = async (gitRepo, projectPath, currentPath, projectName) => {
496
+ let ora = (await import("ora")).default;
497
+ const exec = (0, import_util2.promisify)(import_child_process.default.exec);
498
+ const rm = (0, import_util2.promisify)(import_fs3.default.rm);
499
+ const gitSpinner = ora("Downloading files and project creation").start();
500
+ try {
501
+ await exec(`git clone --depth 1 ${gitRepo} ${projectPath} --quiet`);
502
+ gitSpinner.succeed();
503
+ const cleanSpinner = ora("Removing useless files").start();
504
+ await exec(`rm -rf ${import_path2.default.join(projectPath, ".git")}`);
505
+ const rmGit = rm(import_path2.default.join(projectPath, ".git"), { recursive: true, force: true });
506
+ const rmBin = rm(import_path2.default.join(currentPath, "opticore-installer"), { recursive: true, force: true });
507
+ await Promise.all([rmGit, rmBin]);
508
+ const escapedPath = projectPath.replace(/^"(.*)"$/, "$1");
509
+ process.chdir(escapedPath);
510
+ const pkgPath = import_path2.default.join(escapedPath, "package.json");
511
+ const pkg = JSON.parse(import_fs3.default.readFileSync(pkgPath, "utf-8"));
512
+ if (pkg.dependencies?.["opticore-feature-module"]) {
513
+ pkg.dependencies["opticore-feature-component"] = pkg.dependencies["opticore-feature-module"];
514
+ delete pkg.dependencies["opticore-feature-module"];
515
+ }
516
+ if (pkg.dependencies) pkg.dependencies = await UpdateOpticoreDeps(exec, pkg.dependencies);
517
+ if (pkg.devDependencies) pkg.devDependencies = await UpdateOpticoreDeps(exec, pkg.devDependencies);
518
+ import_fs3.default.writeFileSync(pkgPath, JSON.stringify(pkg, null, 4));
519
+ const lockPath = import_path2.default.join(escapedPath, "package-lock.json");
520
+ if (import_fs3.default.existsSync(lockPath)) import_fs3.default.unlinkSync(lockPath);
521
+ await exec("npm uninstall ora ansi-colors cli-spinner dotenv gradient-string util tsup path fs node ts-node tslib @types/cli-spinner @clack/prompts");
522
+ cleanSpinner.succeed();
523
+ const npmSpinner = ora("Installing dependencies").start();
524
+ await exec("npm install");
525
+ npmSpinner.succeed();
526
+ import_fs3.default.writeFileSync(import_path2.default.join(escapedPath, ".npmrc"), "loglevel=silent\n");
527
+ endingMessageInfo(projectName);
528
+ } catch (err) {
529
+ console.log("err is : ", err);
530
+ process.exit();
531
+ }
532
+ };
533
+
534
+ // src/core/abstractions/enums/constants/projectTemplatePath.constant.ts
535
+ var CProjectTemplatePath = {
536
+ mysql: "https://github.com/guyzoum77/opticore-api-restfull-template-mysql.git",
537
+ postgresql: "https://github.com/guyzoum77/opticore-api-restfull-template-postgresdb.git",
538
+ mongodb: "https://github.com/guyzoum77/opticore-api-restfull-template-mongodb.git",
539
+ oracle: "https://github.com/guyzoum77/opticore-api-restfull-template-oracle.git",
540
+ nodbcredentials: "https://github.com/guyzoum77/opticore-api-restfull-template-no-db-credential.git",
541
+ otherdb: "https://github.com/guyzoum77/opticore-api-restfull-template-other-db.git"
542
+ };
543
+
544
+ // src/domains/services/updateEnv.service.ts
545
+ var import_fs4 = __toESM(require("fs"), 1);
546
+ var SUpdateEnv = class {
547
+ arg;
548
+ argumentConnection;
549
+ constructor(arg, argumentConnection) {
550
+ this.arg = arg;
551
+ this.argumentConnection = argumentConnection;
552
+ this.__init();
553
+ }
554
+ /**
555
+ *
556
+ * @private
557
+ */
558
+ __init() {
559
+ const envFileLines = import_fs4.default.readFileSync("config/env/.env", "utf8").split("\n");
560
+ this.updateDatabaseSection(envFileLines, this.arg);
561
+ this.updateArgConnexionSection(envFileLines, this.argumentConnection);
562
+ import_fs4.default.writeFileSync("config/env/.env", envFileLines.join("\n"));
563
+ }
564
+ /**
565
+ *
566
+ * @param envFileLines
567
+ * @param arg
568
+ * @protected
569
+ */
570
+ updateDatabaseSection(envFileLines, arg) {
571
+ const sectionHeader = "#DATABASE";
572
+ const sectionStart = envFileLines.findIndex((line) => line.trim() === sectionHeader);
573
+ if (sectionStart === -1) {
574
+ console.warn(`Section ${sectionHeader} not found in .env file`);
575
+ return;
576
+ }
577
+ for (let i = sectionStart + 1; i < envFileLines.length; i++) {
578
+ const line = envFileLines[i].trim();
579
+ if (line.startsWith("#") && line !== sectionHeader) {
580
+ break;
581
+ }
582
+ if (!line || line.startsWith("#")) {
583
+ continue;
584
+ }
585
+ const [key] = line.split("=");
586
+ switch (key) {
587
+ case "DATA_BASE_NAME":
588
+ envFileLines[i] = `${key}=${arg.dbName ?? ""}`;
589
+ break;
590
+ case "DATA_BASE_USER":
591
+ envFileLines[i] = `${key}=${arg.dbUser ?? ""}`;
592
+ break;
593
+ case "DATA_BASE_PASSWORD":
594
+ envFileLines[i] = `${key}=${arg.dbPwd ?? ""}`;
595
+ break;
596
+ case "DATA_BASE_HOST":
597
+ envFileLines[i] = `${key}=${arg.dbHost ?? ""}`;
598
+ break;
599
+ case "DATA_BASE_PORT":
600
+ envFileLines[i] = `${key}=${arg.dbPort ?? ""}`;
601
+ break;
602
+ }
603
+ }
604
+ }
605
+ /**
606
+ *
607
+ * @param envFileLines
608
+ * @param argumentConnection
609
+ * @protected
610
+ */
611
+ updateArgConnexionSection(envFileLines, argumentConnection) {
612
+ const sectionHeader = "#ARG CONNEXION";
613
+ const sectionStart = envFileLines.findIndex((line) => line.trim() === sectionHeader);
614
+ if (sectionStart === -1) {
615
+ console.warn(`Section ${sectionHeader} not found in .env file`);
616
+ return;
617
+ }
618
+ if (argumentConnection === void 0) {
619
+ return;
620
+ }
621
+ let found = false;
622
+ for (let i = sectionStart + 1; i < envFileLines.length; i++) {
623
+ const line = envFileLines[i].trim();
624
+ if (line.startsWith("#") && line !== sectionHeader) {
625
+ break;
626
+ }
627
+ if (!line || line.startsWith("#")) {
628
+ continue;
629
+ }
630
+ const [key] = line.split("=");
631
+ if (key === "ARGUMENTS_DATABASE_CONNECTION") {
632
+ envFileLines[i] = `${key}=${argumentConnection ?? ""}`;
633
+ found = true;
634
+ break;
635
+ }
636
+ }
637
+ if (!found && argumentConnection !== null) {
638
+ const insertPosition = sectionStart + 1;
639
+ envFileLines.splice(insertPosition, 0, `ARGUMENTS_DATABASE_CONNECTION=${argumentConnection}`);
640
+ }
641
+ }
642
+ };
643
+
644
+ // src/presentations/middlewares/templateProject/templateProject.middleware.ts
645
+ var MTemplateProject = async (repoGit, projectPath, currentPath, callback, arg, projectName, argumentConnection) => {
646
+ await SProjectCreation(repoGit, projectPath, currentPath, projectName);
647
+ callback;
648
+ new SUpdateEnv(arg, argumentConnection);
649
+ };
650
+
651
+ // src/presentations/middlewares/database/createMongo.database.ts
652
+ var import_fs6 = __toESM(require("fs"), 1);
653
+ var import_ansi_colors5 = __toESM(require("ansi-colors"), 1);
654
+ var import_mongodb = require("mongodb");
655
+
656
+ // src/utils/logSuccess.util.ts
657
+ var import_prompts10 = require("@clack/prompts");
658
+ var import_chalk5 = __toESM(require("chalk"), 1);
659
+ var ULogSuccess = (logMessage) => {
660
+ import_prompts10.log.success(import_chalk5.default.green(logMessage));
661
+ };
662
+
663
+ // src/core/abstractions/enums/constants/mongoOutputText.constant.ts
664
+ var CMongoText = {
665
+ msg: "Enter a collection of database :",
666
+ pHolder: "db_toto",
667
+ invalidValue: "Please collection's name can't be empty.",
668
+ badPattern: "Please enter a valide collection's name.",
669
+ unReachable: "Sorry, the database couldn't be created. In MongoDB, a database is not created until it gets content! MongoDB waits until you have created a collection (table), with at least one document (record) before it actually creates the database (and collection)."
670
+ };
671
+
672
+ // src/applications/exceptions/handledMongoDB.exception.ts
673
+ var import_ansi_colors4 = __toESM(require("ansi-colors"), 1);
674
+ var import_fs5 = __toESM(require("fs"), 1);
675
+ var handledMongoDBException = (e, databasePort, databaseHost, projectPath) => {
676
+ if (e.code === 18) {
677
+ console.error(`${import_ansi_colors4.default.red(`Authentication failed, be sure the credentials is correct!`)}`);
678
+ import_fs5.default.rmSync(projectPath, { recursive: true, force: true });
679
+ process.exit();
680
+ }
681
+ if (e.cause.code === "ERR_INVALID_URL") {
682
+ console.error(`${import_ansi_colors4.default.red(`Unable to parse ${databaseHost}:${databasePort} with URL`)}`);
683
+ import_fs5.default.rmSync(projectPath, { recursive: true, force: true });
684
+ process.exit();
685
+ }
686
+ if (e.code === void 0) {
687
+ console.error(`${import_ansi_colors4.default.red(`MongoServerSelectionError: getaddrinfo EAI_AGAIN (${databaseHost} is not allow to database connection)`)}`);
688
+ import_fs5.default.rmSync(projectPath, { recursive: true, force: true });
689
+ process.exit();
690
+ }
691
+ };
692
+
693
+ // src/core/config/uri/configMongoUrl.config.ts
694
+ var import_dotenv = __toESM(require("dotenv"), 1);
695
+ var configMongoUrlConfig = (databaseHost, databasePort) => {
696
+ return typeof databasePort === "number" || !isNaN(databasePort) || isFinite(databasePort) ? `mongodb://${databaseHost}:${databasePort}/` : `mongodb://${databaseHost}:${import_dotenv.default.config().parsed.DATA_BASE_PORT}/`;
697
+ };
698
+
699
+ // src/core/config/paramters/mongoClient.parameter.ts
700
+ var import_dotenv2 = __toESM(require("dotenv"), 1);
701
+ var PMongoClient = (databaseUser, databasePassword) => {
702
+ return {
703
+ auth: {
704
+ username: databaseUser ?? import_dotenv2.default.config().parsed.DATA_BASE_USER,
705
+ password: databasePassword ?? import_dotenv2.default.config().parsed.DATA_BASE_PASSWORD
706
+ }
707
+ };
708
+ };
709
+
710
+ // src/presentations/middlewares/database/createMongo.database.ts
711
+ var createMongoDatabase = async (arg) => {
712
+ try {
713
+ const client = new import_mongodb.MongoClient(configMongoUrlConfig(arg.dbHost, arg.dbPort), PMongoClient(arg.dbUser, arg.dbPwd));
714
+ await client.connect();
715
+ const mongoOutputText = await SOutputPromptText(CMongoText.msg, CMongoText.pHolder, CMongoText.invalidValue, CMongoText.badPattern, arg.projectPath);
716
+ if (mongoOutputText) {
717
+ const db = client.db(arg.dbName);
718
+ typeof mongoOutputText === "string" ? await db.createCollection(mongoOutputText) : (() => {
719
+ console.error(mongoOutputText);
720
+ process.exit();
721
+ });
722
+ ULogSuccess(`${import_ansi_colors5.default.green(`Your database ${import_ansi_colors5.default.bgGreen(`${import_ansi_colors5.default.white(`${arg.dbName}`)}`)} has been created successfully.`)}`);
723
+ } else {
724
+ ULogInfo(CMongoText.unReachable);
725
+ import_fs6.default.rmSync(arg.projectPath, { recursive: true, force: true });
726
+ process.exit(0);
727
+ }
728
+ } catch (e) {
729
+ handledMongoDBException(e, arg.dbPort, arg.dbHost, arg.projectPath);
730
+ }
731
+ };
732
+
733
+ // src/presentations/middlewares/database/createPostgres.database.ts
734
+ var import_pg = require("pg");
735
+
736
+ // src/core/config/paramters/postgres.paramaters.ts
737
+ var import_dotenv3 = __toESM(require("dotenv"), 1);
738
+ var PPostgres = (arg) => {
739
+ return {
740
+ host: arg.host ?? import_dotenv3.default.config()?.parsed?.DATA_BASE_HOST,
741
+ user: arg.user ?? import_dotenv3.default.config()?.parsed?.DATA_BASE_USER,
742
+ password: arg.password ?? import_dotenv3.default.config()?.parsed?.DATA_BASE_PASSWORD,
743
+ port: arg.port ?? import_dotenv3.default.config()?.parsed?.DATA_BASE_PORT
744
+ };
745
+ };
746
+
747
+ // src/applications/exceptions/handledPostgres.exception.ts
748
+ var import_ansi_colors6 = __toESM(require("ansi-colors"), 1);
749
+ var import_fs7 = __toESM(require("fs"), 1);
750
+ var handledPostgresException = (arg, err) => {
751
+ console.error(`${import_ansi_colors6.default.red(`An error occurred while creating the database : ${err}`)}`);
752
+ import_fs7.default.rmSync(arg.projectName, { recursive: true, force: true });
753
+ process.exit(0);
754
+ };
755
+
756
+ // src/presentations/middlewares/database/createPostgres.database.ts
757
+ async function createPostgresDatabase(arg) {
758
+ try {
759
+ const client = new import_pg.Client(PPostgres(arg));
760
+ await client.connect();
761
+ await client.query(`CREATE DATABASE "${arg.database}";`);
762
+ await client.end();
763
+ } catch (err) {
764
+ handledPostgresException(arg, err);
765
+ }
766
+ }
767
+
768
+ // src/presentations/middlewares/database/createMySQL.database.ts
769
+ var import_promise = __toESM(require("mysql2/promise"), 1);
770
+
771
+ // src/core/config/paramters/mysql.parameters.ts
772
+ var import_dotenv4 = __toESM(require("dotenv"), 1);
773
+ var PMysql = (arg) => {
774
+ return {
775
+ host: arg.dbHost ?? import_dotenv4.default.config()?.parsed?.DATA_BASE_HOST,
776
+ user: arg.dbUser ?? import_dotenv4.default.config()?.parsed?.DATA_BASE_USER,
777
+ password: arg.dbPwd ?? import_dotenv4.default.config()?.parsed?.DATA_BASE_PASSWORD,
778
+ port: arg.dbPort ?? parseInt(import_dotenv4.default.config()?.parsed?.DATA_BASE_PORT)
779
+ };
780
+ };
781
+
782
+ // src/applications/exceptions/handledMySQL.exception.ts
783
+ var import_fs8 = __toESM(require("fs"), 1);
784
+ var import_ansi_colors7 = __toESM(require("ansi-colors"), 1);
785
+ var handledMySQLException = (arg, err) => {
786
+ import_fs8.default.rmSync(arg.projectPath, { recursive: true, force: true });
787
+ switch (err.code) {
788
+ case "ER_NOT_SUPPORTED_AUTH_MODE":
789
+ console.error(`${import_ansi_colors7.default.red(`Client does not support authentication protocol requested by server. Please try to verify your database credentials.`)}`);
790
+ break;
791
+ case "ERR_SOCKET_BAD_PORT":
792
+ console.error(`${import_ansi_colors7.default.red(`${err.message}.`)}`);
793
+ break;
794
+ case "ERR_INVALID_ARG_TYPE":
795
+ console.error(`${import_ansi_colors7.default.red(`${err.message}.`)}`);
796
+ break;
797
+ case "EAI_AGAIN":
798
+ console.error(`${import_ansi_colors7.default.red(`${err.message}.`)}`);
799
+ break;
800
+ case "ECONNREFUSED":
801
+ console.error(`${import_ansi_colors7.default.red(`${err.message}. Try to check if the port is correct.`)}`);
802
+ break;
803
+ default:
804
+ console.error();
805
+ break;
806
+ }
807
+ console.error(`${import_ansi_colors7.default.red(`An error occurred while creating the database : ${err.message}`)}`);
808
+ import_fs8.default.rmSync(arg.projectPath, { recursive: true, force: true });
809
+ process.exit(0);
810
+ };
811
+
812
+ // src/presentations/middlewares/database/createMySQL.database.ts
813
+ async function createMySQLDatabase(arg) {
814
+ let connection;
815
+ try {
816
+ connection = await import_promise.default.createConnection(PMysql(arg));
817
+ await connection.connect();
818
+ const createDatabaseQuery = `CREATE DATABASE IF NOT EXISTS ${arg.dbName}`;
819
+ await connection.query(createDatabaseQuery);
820
+ await connection.end();
821
+ } catch (err) {
822
+ handledMySQLException(arg, err);
823
+ }
824
+ }
825
+
826
+ // src/core/abstractions/enums/constants/connectionProperties.constant.ts
827
+ var CConnectionProperties = "connection_limit=5&socket_timeout=3";
828
+
829
+ // src/presentations/middlewares/selectDB.middleware.ts
830
+ var MSelectDB = async (projectPath, currentPath, projectName) => {
831
+ const dbSelect = await SOutputPromptSelect({
832
+ message: CSelectDBMessage.dbSelect,
833
+ initialValue: [CDbNameLabel.mysql],
834
+ options: [
835
+ { label: CDbNameLabel.mysql, value: [CDbNameValue.mysql] },
836
+ { label: CDbNameLabel.mongodb, value: [CDbNameValue.mongodb] },
837
+ { label: CDbNameLabel.postgresql, value: [CDbNameValue.postgresql] },
838
+ { label: CDbNameLabel.oracle, value: [CDbNameValue.oracle] },
839
+ { label: CDbNameLabel.otherDb, value: [CDbNameValue.otherDb] }
840
+ ]
841
+ });
842
+ if (dbSelect instanceof Function) {
843
+ (0, import_prompts11.cancel)(import_ansi_colors8.default.bgRed(import_ansi_colors8.default.white(" Operation cancelled ")));
844
+ import_node_process3.default.exit(130);
845
+ } else {
846
+ const params = await SFetchCredentials(projectPath, currentPath, projectName);
847
+ if (params.dbCredentials === void 0) {
848
+ let dbChosen = [];
849
+ dbSelect.map(async (item) => {
850
+ switch (item) {
851
+ case CDbNameValue.mysql:
852
+ await SProjectCreation(CProjectTemplatePath.mysql, projectPath, currentPath, projectName);
853
+ break;
854
+ case CDbNameValue.postgresql:
855
+ await SProjectCreation(CProjectTemplatePath.postgresql, projectPath, currentPath, projectName);
856
+ break;
857
+ case CDbNameValue.mongodb:
858
+ await SProjectCreation(CProjectTemplatePath.mongodb, projectPath, currentPath, projectName);
859
+ break;
860
+ case CDbNameValue.oracle:
861
+ await SProjectCreation(CProjectTemplatePath.oracle, projectPath, currentPath, projectName);
862
+ break;
863
+ case CDbNameValue.otherDb:
864
+ await SProjectCreation(CProjectTemplatePath.otherdb, projectPath, currentPath, projectName);
865
+ break;
866
+ }
867
+ dbChosen.push(item);
868
+ });
869
+ return dbChosen;
870
+ } else {
871
+ dbSelect.map(async (item) => {
872
+ switch (item) {
873
+ case CDbNameValue.mysql:
874
+ await MTemplateProject(
875
+ CProjectTemplatePath.mysql,
876
+ projectPath,
877
+ currentPath,
878
+ async () => await createMySQLDatabase(
879
+ //@ts-ignore
880
+ params.dbParams
881
+ ),
882
+ params.envParams,
883
+ projectName,
884
+ CConnectionProperties
885
+ );
886
+ break;
887
+ case CDbNameValue.postgresql:
888
+ await MTemplateProject(
889
+ CProjectTemplatePath.postgresql,
890
+ projectPath,
891
+ currentPath,
892
+ async () => await createPostgresDatabase(
893
+ //@ts-ignore
894
+ params.dbParams
895
+ ),
896
+ params.envParams,
897
+ projectName
898
+ );
899
+ break;
900
+ case CDbNameValue.mongodb:
901
+ await MTemplateProject(
902
+ CProjectTemplatePath.mongodb,
903
+ projectPath,
904
+ currentPath,
905
+ async () => await createMongoDatabase(params),
906
+ params.envParams,
907
+ projectName
908
+ );
909
+ break;
910
+ case CDbNameValue.oracle:
911
+ await MTemplateProject(
912
+ CProjectTemplatePath.oracle,
913
+ projectPath,
914
+ currentPath,
915
+ async () => {
916
+ },
917
+ params.envParams,
918
+ projectName
919
+ );
920
+ break;
921
+ case CDbNameValue.otherDb:
922
+ await MTemplateProject(
923
+ CProjectTemplatePath.otherdb,
924
+ projectPath,
925
+ currentPath,
926
+ async () => {
927
+ },
928
+ params.envParams,
929
+ projectName
930
+ );
931
+ break;
932
+ }
933
+ });
934
+ }
935
+ }
936
+ };
937
+
938
+ // src/domains/services/shellEscape.service.ts
939
+ var SShellEscape = (str) => {
940
+ return `"${str.replace(/(["$`\\])/g, "\\$1")}"`;
941
+ };
942
+
943
+ // src/core/installer.core.ts
944
+ var installerCore = async () => {
945
+ let projectName;
946
+ UWelcomeMessage();
947
+ (0, import_prompts12.intro)(import_chalk6.default.bgYellow.black(" Opticore Framework Installer "));
948
+ const starter = await SOutputPromptSelect(StarterOptions);
949
+ starter instanceof Function ? (() => {
950
+ (0, import_prompts12.cancel)(import_ansi_colors9.default.bgRed(import_ansi_colors9.default.white(" Operation cancelled ")));
951
+ process5.exit(130);
952
+ })() : starter.map(async (value) => {
953
+ switch (value) {
954
+ case CGeneralMsg.starterInitValue:
955
+ projectName = await SOutputPromptText(
956
+ CGeneralMsg.projectNameMessage,
957
+ CGeneralMsg.projectNamePlaceholder,
958
+ CGeneralMsg.projectNameInvalidValue,
959
+ CGeneralMsg.projectNameBadPattern,
960
+ "^[a-zA-Z0-9]+$"
961
+ );
962
+ if (typeof projectName === "string") {
963
+ const tpl = await templateStarter(projectName);
964
+ const escapedProjectPath = SShellEscape(tpl.normalizedPath);
965
+ const escapedCurrentPath = SShellEscape(tpl.normalizedCurrentPath);
966
+ await MSelectDB(escapedProjectPath, escapedCurrentPath, projectName);
967
+ }
968
+ break;
969
+ }
970
+ });
971
+ };
972
+
973
+ // src/index.ts
974
+ (async () => await installerCore())();