opticore-webapp-core 1.0.20 → 1.0.21

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.
Files changed (43) hide show
  1. package/dist/index.d.cts +8 -4
  2. package/dist/index.d.ts +8 -4
  3. package/package.json +7 -8
  4. package/src/application/middlewares/bodyParser.middleware.ts +74 -0
  5. package/src/application/services/asymmetricCryptionDataWithPrivateRSAKey.service.ts +194 -0
  6. package/src/application/services/asymmetricCryptionDataWithPublicRSAKey.service.ts +188 -0
  7. package/src/application/services/loggerFileConfiguration.service.ts +6 -0
  8. package/src/core/config/database/connexion.config.database.ts +116 -0
  9. package/src/core/config/database/middleware/postgresChecker.database.ts +35 -0
  10. package/src/core/config/loaders/localLanguage.loader.ts +31 -0
  11. package/src/core/config/loaders/translateLanguage.loader.ts +27 -0
  12. package/src/core/config/logger/logger.config.ts +33 -0
  13. package/src/core/constants/signRSA/algorithm.constant.ts +54 -0
  14. package/src/core/constants/signRSA/encodingFormat.constant.ts +14 -0
  15. package/src/core/constants/signRSA/keyType.constant.ts +4 -0
  16. package/src/core/constants/signRSA/outputFormat.constant.ts +6 -0
  17. package/src/core/constants/signRSAKeyComponent.constant.ts +11 -0
  18. package/src/core/errors/databaseConnexion.error.ts +107 -0
  19. package/src/core/events/pathModuleVerifier.event.ts +58 -0
  20. package/src/domains/constants/logLevel.constant.ts +6 -0
  21. package/src/index.ts +56 -0
  22. package/src/interfaces/bodyParserOptions.interface.ts +4 -0
  23. package/src/interfaces/responseBodyEndFromResponseEvent.interface.ts +7 -0
  24. package/src/interfaces/responseBodyWriteFromResponseEvent.interface.ts +4 -0
  25. package/src/interfaces/wrappingBodyResponse.interface.ts +4 -0
  26. package/src/types/json.type.ts +18 -0
  27. package/src/types/logLevel.type.ts +3 -0
  28. package/src/types/originalWriteEncoding.type.ts +1 -0
  29. package/src/types/parseFunction.type.ts +1 -0
  30. package/src/types/raw.type.ts +23 -0
  31. package/src/types/text.type.ts +18 -0
  32. package/src/types/urlencoded.type.ts +19 -0
  33. package/src/utils/cryptography/decryption/rsaKey.decryption.ts +19 -0
  34. package/src/utils/cryptography/encryption/rsaKey.encryption.ts +25 -0
  35. package/src/utils/dateTimeFormatted.utils.ts +6 -0
  36. package/src/utils/environment.utils.ts +11 -0
  37. package/src/utils/logMessage.utils.ts +20 -0
  38. package/src/utils/parseUrlencoded.utils.ts +17 -0
  39. package/src/utils/parsing/parsingYaml.utils.ts +81 -0
  40. package/src/utils/utility.utils.ts +154 -0
  41. package/tsup.config.ts +11 -0
  42. /package/{dist → src}/utils/translations/message.translation.en.json +0 -0
  43. /package/{dist → src}/utils/translations/message.translation.fr.json +0 -0
@@ -0,0 +1,18 @@
1
+ import { MBodyParser } from "@webAppCore/application/middlewares/bodyParser.middleware";
2
+ import { IBodyParserOptions } from "@webAppCore/interfaces/bodyParserOptions.interface";
3
+
4
+
5
+ /**
6
+ *
7
+ * @param options
8
+ * @param localLanguage
9
+ * @param environmentPath
10
+ *
11
+ * Use by this: textBodyParserType({ type: 'text/html' })
12
+ *
13
+ * in express, it can be used like this: app.use(textBodyParserType({ type: 'text/html' }));
14
+ *
15
+ */
16
+ export function TTextBodyParser(options: IBodyParserOptions, localLanguage: string, environmentPath: any) {
17
+ return MBodyParser((rawBody: string) => rawBody, options, localLanguage, environmentPath);
18
+ }
@@ -0,0 +1,19 @@
1
+ import { IBodyParserOptions } from "@webAppCore/interfaces/bodyParserOptions.interface";
2
+ import { MBodyParser } from "@webAppCore/application/middlewares/bodyParser.middleware";
3
+ import { UParseUrlencoded } from "@webAppCore/utils/parseUrlencoded.utils";
4
+
5
+
6
+ /**
7
+ *
8
+ * @param options
9
+ * @param localLanguage
10
+ * @param environmentPath
11
+ *
12
+ * Use by this: urlencodedBodyParserType({ type: 'application/x-www-form-urlencoded' })
13
+ *
14
+ * in express, it can be used like this: app.use(urlencodedBodyParserType({ type: 'application/x-www-form-urlencoded' }));
15
+ *
16
+ */
17
+ export function TUrlencodedBodyParser(options: IBodyParserOptions, localLanguage: string, environmentPath: any) {
18
+ return MBodyParser(UParseUrlencoded, options, localLanguage, environmentPath);
19
+ }
@@ -0,0 +1,19 @@
1
+ import crypto from "crypto";
2
+
3
+
4
+ /**
5
+ * This class contains methods that allow to decrypt data using public and private keys.
6
+ */
7
+ export class RSAKeyDecryption {
8
+ static privateDecrypt(privateKey: any, decryptData: any): Buffer {
9
+ const rsaPrivateKey = { key: privateKey };
10
+
11
+ return crypto.privateDecrypt(rsaPrivateKey, decryptData);
12
+ }
13
+
14
+ static publicDecrypt(publicKey: any, decryptData: any): Buffer {
15
+ const rsaPublicKey = { key: publicKey };
16
+
17
+ return crypto.publicDecrypt(rsaPublicKey, decryptData);
18
+ }
19
+ }
@@ -0,0 +1,25 @@
1
+ import crypto from "crypto";
2
+ import { CSignRSAKeyComponent } from "@webAppCore/core/constants/signRSAKeyComponent.constant";
3
+
4
+
5
+ /**
6
+ * This class contains methods which allow encrypting data by passing as arguments
7
+ * the public/private keys and the data to be encrypted.
8
+ */
9
+ export class RSAKeyEncryption {
10
+ static privateEncrypt(privateKey: any, encryptData: any): Buffer {
11
+ const rsaPrivateKey = {
12
+ key: privateKey
13
+ };
14
+ const bufferData: Buffer = Buffer.from(encryptData, CSignRSAKeyComponent.encodingFormat.utf8 as BufferEncoding);
15
+
16
+ return crypto.privateEncrypt(rsaPrivateKey, bufferData);
17
+ }
18
+
19
+ static publicEncrypt(publicKey: any, encryptData: any): Buffer {
20
+ const rsaPublicKey = { key: publicKey };
21
+ const bufferData: Buffer = Buffer.from(encryptData, CSignRSAKeyComponent.encodingFormat.utf8 as BufferEncoding);
22
+
23
+ return crypto.publicEncrypt(rsaPublicKey, bufferData);
24
+ }
25
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Give time like: 6-8-2024 4:30:29
3
+ */
4
+
5
+
6
+ export const dateTimeFormatted: string = `${(new Date().getMonth())}-${(new Date().getDate())}-${(new Date().getFullYear())} ${(new Date().getHours())}:${(new Date().getMinutes())}:${(new Date().getSeconds())}`;
@@ -0,0 +1,11 @@
1
+ export class Environment<T> {
2
+ private readonly config: T;
3
+
4
+ constructor(config: T) {
5
+ this.config = config;
6
+ }
7
+
8
+ get<K extends keyof T>(key: K): T[K] {
9
+ return this.config[key];
10
+ }
11
+ }
@@ -0,0 +1,20 @@
1
+ import colors from "ansi-colors";
2
+ import { dateTimeFormatted as dateTime } from "@webAppCore/utils/dateTimeFormatted.utils";
3
+
4
+ export class LogMessage {
5
+ static success(title: string, action: string, contentAction: string): void {
6
+ console.log(`${colors.green(`✔`)} ${colors.bgGreen(` ${colors.bold(`${colors.white(`${title}`)}`)} `)} ${dateTime} | ${colors.bgGreen(`${colors.white(` Success `)}`)} [ ${action} ] ${contentAction} - [ Status ] ${colors.bgGreen(`${colors.white(` 200 `)}`)}`);
7
+ }
8
+ static warning(title: string, action: string, contentAction: string): void {
9
+ console.warn(`${colors.yellow(`⚠️`)} ${colors.bgYellow(` ${colors.bold(`${colors.white(`${title}`)}`)} `)} ${dateTime} | ${colors.bgYellow(`${colors.white(` Warning `)}`)} ${contentAction}`);
10
+ }
11
+ static info(title: string, action: string, contentAction: string): void {
12
+ console.info(`${colors.cyan(`ⓘ`)} ${colors.bgCyan(` ${colors.bold(`${colors.white(`${title}`)}`)} `)} ${dateTime} | ${colors.bgCyan(`${colors.white(` Info `)}`)} ${contentAction}`);
13
+ }
14
+ static error(title: string, errorType: any, stackTrace: any, messageContent: any, httpCodeValue: number): void {
15
+ console.error(`${colors.red(`✘`)} ${colors.bgRed(` ${colors.bold(`${colors.white(`${title}`)}`)} `)} | ${dateTime} | [ ${colors.red(`${colors.bold(` ${errorType} `)}`)} ] | [ ${colors.bold(`stack trace`)} ] ${colors.red(`${stackTrace}`)} - ${colors.red(`${messageContent}`)} - [ ${colors.red(`${colors.bold(` HttpCode `)}`)} ] ${colors.red(`${colors.bold(` ${httpCodeValue} `)}`)} `);
16
+ }
17
+ static requestError(title: string, errorName: string, errorMessage: string, errorCode: number): void {
18
+ console.error(`[ ${colors.red(`${title}`)} ] ${dateTime} | ${colors.bgRed(`${colors.white(` ERROR `)}`)} ${colors.red(`[ ${errorName} ]`)} ${colors.red(`${errorMessage}`)} - [ Status ] ${colors.bgRed(`${colors.white(` ${errorCode} `)}`)}`);
19
+ }
20
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ *
3
+ * @param rawBody
4
+ *
5
+ * URL-encoded body parse function
6
+ */
7
+ export function UParseUrlencoded(rawBody: string): any {
8
+ const pairs: string[] = rawBody.split('&');
9
+ const result: { [key: string]: string } = {};
10
+ for (const pair of pairs) {
11
+ const [key, value] = pair.split('=');
12
+ if (key && value) {
13
+ result[decodeURIComponent(key)] = decodeURIComponent(value);
14
+ }
15
+ }
16
+ return result;
17
+ }
@@ -0,0 +1,81 @@
1
+ import { readFile } from "fs/promises";
2
+ import { HttpStatusCode } from "opticore-http-response";
3
+ import { ILoggerConfig, LoggerCore } from "opticore-logger";
4
+ import { TranslationLoader } from "opticore-translator";
5
+ import { loggerConfig } from "@webAppCore/core/config/logger/logger.config";
6
+ import { translateWebAppCoreLanguageLoader } from "@webAppCore/core/config/loaders/translateLanguage.loader";
7
+ import path from "path";
8
+
9
+
10
+ export class YamlParsing {
11
+ private readonly logger: LoggerCore;
12
+ private readonly localeLanguage: string;
13
+
14
+ constructor(localeLanguage: string, environmentPath: any) {
15
+ translateWebAppCoreLanguageLoader(environmentPath, localeLanguage);
16
+
17
+ this.localeLanguage = localeLanguage;
18
+ this.logger = new LoggerCore(loggerConfig(environmentPath) as ILoggerConfig);
19
+ }
20
+
21
+ public absolutPath(): string {
22
+ return path.join(process.cwd(), "src", "utils", "translations");
23
+ }
24
+
25
+ public async readFile(filePath: string): Promise<void> {
26
+ try {
27
+ const yamlContent: string = await readFile(filePath, "utf-8");
28
+ await this.parsing(yamlContent);
29
+ } catch (error: any) {
30
+ this.logger.error({
31
+ message: error.message,
32
+ title: TranslationLoader.t("parsingFailed", this.localeLanguage, this.logger),
33
+ errorType: TranslationLoader.t("readingError", this.localeLanguage, this.logger),
34
+ stackTrace: error.stack,
35
+ httpCodeValue: HttpStatusCode.NOT_ACCEPTABLE
36
+ });
37
+ }
38
+ }
39
+
40
+ /**
41
+ *
42
+ * @param content
43
+ * @private
44
+ */
45
+ private async parsing(content: string): Promise<Record<any, any>> {
46
+ const result: Record<string, any> = {};
47
+ const lines: string[] = content.split("\n");
48
+ let currentKey: string | null = null;
49
+
50
+ for (const line of lines) {
51
+ // Ignore empty lines or comments
52
+ if (!line.trim() || line.trim().startsWith("#")) {
53
+ continue;
54
+ }
55
+
56
+ const keyValueMatch: RegExpMatchArray | null = line.match(/^(\s*)([a-zA-Z0-9_]+):(?:\s*(.*))?$/);
57
+ if (keyValueMatch) {
58
+ const [, indent, key, value] = keyValueMatch;
59
+ // Handle nested objects (simple one-level nesting)
60
+ if (indent.length > 0 && currentKey) {
61
+ result[currentKey] = result[currentKey] || {};
62
+ result[currentKey][key] = value?.trim() || null;
63
+ } else {
64
+ currentKey = key;
65
+ result[key] = value?.trim() || null;
66
+ }
67
+
68
+ } else {
69
+ this.logger.error({
70
+ message: TranslationLoader.t("badFormat", this.localeLanguage, {line: line}),
71
+ title: TranslationLoader.t("parsingFailed", this.localeLanguage, this.logger),
72
+ errorType: TranslationLoader.t("unsupportedFormat", this.localeLanguage, this.logger),
73
+ stackTrace: content,
74
+ httpCodeValue: HttpStatusCode.NOT_ACCEPTABLE
75
+ });
76
+ }
77
+ }
78
+
79
+ return result;
80
+ }
81
+ }
@@ -0,0 +1,154 @@
1
+ import process from "node:process";
2
+ import chalk from 'chalk';
3
+ import colors from "ansi-colors";
4
+ import path from "path";
5
+ import fs from "fs";
6
+ import { TranslationLoader } from "opticore-translator";
7
+
8
+
9
+ export class Utility {
10
+ private readonly localLang: string;
11
+
12
+ constructor(localLanguage: string) {
13
+ this.localLang = localLanguage;
14
+ }
15
+
16
+ /**
17
+ *
18
+ * @param data
19
+ * @private
20
+ * Return a string converted in MegaBytes
21
+ */
22
+ private formatMemoryUsage(data: any): string {
23
+ return `${Math.round(data / 1024 / 1024 * 100) / 100} MB`;
24
+ }
25
+
26
+ /**
27
+ * Returns an Object containing a node version, openssl, and v0
28
+ */
29
+ public getVersions() {
30
+ const processVers: NodeJS.ProcessVersions = process.versions;
31
+ const data = {
32
+ "node version" : processVers.node,
33
+ "openssl": processVers.openssl,
34
+ "v8": processVers.v8
35
+ };
36
+
37
+ return {
38
+ "nodeVersion" : data["node version"],
39
+ "openssl": data.openssl,
40
+ "v8": data.v8
41
+ };
42
+ }
43
+
44
+ /**
45
+ * Return an Object containing a Resident Set Size - total memory allocated for the process execution
46
+ * Total size of the allocated heap
47
+ * Actual memory used during the execution
48
+ * Memory usage user
49
+ * and Memory usage system
50
+ */
51
+ public getUsageMemory() {
52
+ const memoryData: NodeJS.MemoryUsage = process.memoryUsage();
53
+ const data = {
54
+ "Resident Set Size - total memory allocated for the process execution": this.formatMemoryUsage(memoryData.rss),
55
+ "Total size of the allocated heap": this.formatMemoryUsage(memoryData.heapTotal),
56
+ "Actual memory used during the execution": this.formatMemoryUsage(memoryData.heapUsed),
57
+ "V8 external memory": this.formatMemoryUsage(memoryData.external),
58
+ "Memory usage user": this.formatMemoryUsage(process.cpuUsage().user),
59
+ "Memory usage system": this.formatMemoryUsage(process.cpuUsage().system),
60
+ }
61
+
62
+ return {
63
+ "rss": data["Resident Set Size - total memory allocated for the process execution"],
64
+ "heapTotal": data["Total size of the allocated heap"],
65
+ "heapUsed": data["Actual memory used during the execution"],
66
+ "external": data["V8 external memory"],
67
+ "user": data["Memory usage user"],
68
+ "system": data["Memory usage system"]
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Return an Object containing a project path and running server time
74
+ */
75
+ public getProjectInfo() {
76
+ const startTime:[number, number] = process.hrtime();
77
+ const endTime:[number, number] = process.hrtime(startTime);
78
+ const executionTime: number = (endTime[0] * 1e9 + endTime[1]) / 1e6; // Convert to milliseconds
79
+ return {
80
+ "projectPath": path.join(process.cwd()),
81
+ "startingTime": `${executionTime.toFixed(5)} ms`
82
+ }
83
+ }
84
+
85
+ /**
86
+ *
87
+ * @param filePath
88
+ * @private
89
+ */
90
+ private getEnvFileLoading(filePath: string): void {
91
+ const fullPath: string = path.resolve(process.cwd(), filePath);
92
+ if (fs.existsSync(fullPath)) {
93
+ const env: string = fs.readFileSync(fullPath, 'utf-8');
94
+ const lines: string[] = env.split('\n');
95
+
96
+ lines.forEach((line: string): void => {
97
+ const match: RegExpMatchArray | null = line.match(/^([^#=]+)=([^#]+)$/);
98
+ if (match) {
99
+ const key: string = match[1].trim();
100
+ process.env[key] = match[2].trim();
101
+ }
102
+ });
103
+ }
104
+ }
105
+
106
+ /**
107
+ *
108
+ * @param development
109
+ * @param production
110
+ */
111
+ public getServerRunningMode(development: string, production: string): string {
112
+ /**
113
+ * Load environment variables from the .env file
114
+ */
115
+ this.getEnvFileLoading('.env');
116
+
117
+ const isDevelopment: boolean = process.env.NODE_ENV === 'development';
118
+ if (isDevelopment) {
119
+ return `${TranslationLoader.t("serverRunning", this.localLang)} ${colors.bgBlue(`${colors.bold(`${development}`)}`)} mode`;
120
+ } else {
121
+ return `${TranslationLoader.t("serverRunning", this.localLang)} ${colors.bgBlue(`${colors.bold(`${production}`)}`)} mode`;
122
+ }
123
+ }
124
+
125
+ public infoServer(nodeVersion: string, startingTime: any, host: string, port: number, rss: string, heapUsed: string, user: string, system: string): void {
126
+ // Padding length
127
+ const paddingLength = 52;
128
+
129
+ // Creating padded messages
130
+ const msg0: string = ' '.padEnd(paddingLength, ' ');
131
+ const msg1: string = ` ${TranslationLoader.t("okServerListening", this.localLang)}`;
132
+ const msg2Value: string = `${colors.bgBlue(`${colors.bold(`${nodeVersion}`)}`)}`;
133
+ const msg2: string = ` ${TranslationLoader.t("webServerUseNodeVersion", this.localLang)}`;
134
+ const msg3Value: string = `${colors.bgBlue(`${colors.bold(`${startingTime}`)}`)}`;
135
+ const msg3: string = ` ${TranslationLoader.t("startupTime", this.localLang)}`;
136
+ const msg4: string = ` ${this.getServerRunningMode('development', 'production')}`;
137
+ const msg5: string = ` ${colors.underline(`http://${host}:${port}`)}`;
138
+
139
+ // display the message
140
+ console.log(chalk.bgGreen.white(msg0.padEnd(paddingLength, ' ')));
141
+ console.log(chalk.bgGreen.white(msg1.padEnd(paddingLength, ' ')));
142
+ console.log(chalk.bgGreen.white(msg2, msg2Value.padEnd(30.5, ' ')));
143
+ console.log(chalk.bgGreen.white(msg3, msg3Value.padEnd(56, ' ')));
144
+ console.log(chalk.bgGreen.white(msg4.padEnd(71, ' ')));
145
+ console.log(chalk.bgGreen.white(msg5.padEnd(61, ' ')));
146
+ console.log(chalk.bgGreen.white(msg0.padEnd(paddingLength, ' ')));
147
+ console.log(``);
148
+ console.log(`${(`${TranslationLoader.t("totalMemory", this.localLang)}`)} ${colors.cyan(`${colors.bold(`${rss}`)}`)}`);
149
+ console.log(`${(`${TranslationLoader.t("memoryUsedDuringExecution", this.localLang)}`)} ${colors.cyan(`${colors.bold(`${heapUsed}`)}`)}`);
150
+ console.log(`${(`${TranslationLoader.t("memoryUsedByUser", this.localLang)}`)} ${colors.cyan(`${colors.bold(`${user}`)}`)}`);
151
+ console.log(`${(`${TranslationLoader.t("memoryUsedBySystem", this.localLang)}`)} ${colors.cyan(`${colors.bold(`${system}`)}`)}`);
152
+ console.log(``);
153
+ }
154
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from "tsup";
2
+
3
+ export default defineConfig({
4
+ name: "webApp-core",
5
+ format: ["cjs", "esm"],
6
+ entry: ['src/index.ts'] ,
7
+ dts: true,
8
+ shims: true,
9
+ skipNodeModulesBundle: true,
10
+ clean: true
11
+ });