@expressots/shared 0.1.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.
@@ -0,0 +1,19 @@
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("./config"), exports);
18
+ __exportStar(require("./env"), exports);
19
+ __exportStar(require("./utils"), exports);
@@ -0,0 +1 @@
1
+ export { Pattern, ExpressoConfig } from "./project-config";
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Enum representing different string patterns.
3
+ *
4
+ * - LOWER_CASE: Represents strings in all lowercase letters. E.g. "hello"
5
+ * - KEBAB_CASE: Represents strings separated by hyphens. E.g. "hello-world"
6
+ * - PASCAL_CASE: Represents strings where the first letter of each word is capitalized. E.g. "HelloWorld"
7
+ * - CAMEL_CASE: Represents strings where the first letter of the first word is lowercase and the first letter of subsequent words are capitalized. E.g. "helloWorld"
8
+ * @public API
9
+ */
10
+ export declare const enum Pattern {
11
+ LOWER_CASE = "lowercase",
12
+ KEBAB_CASE = "kebab-case",
13
+ PASCAL_CASE = "PascalCase",
14
+ CAMEL_CASE = "camelCase"
15
+ }
16
+ /**
17
+ * The configuration object for the Expresso CLI.
18
+ * @property {Pattern} scaffoldPattern - The pattern to use when scaffolding files.
19
+ * @property {string} sourceRoot - The root directory for the source files.
20
+ * @property {boolean} opinionated - Whether or not to use the opinionated configuration.
21
+ * @property {IProviders} providers - Specific configuration for each provider added.
22
+ * @public API
23
+ */
24
+ export interface ExpressoConfig {
25
+ scaffoldPattern: Pattern;
26
+ sourceRoot: string;
27
+ opinionated: boolean;
28
+ scaffoldSchematics?: {
29
+ entity?: string;
30
+ controller?: string;
31
+ usecase?: string;
32
+ dto?: string;
33
+ module?: string;
34
+ provider?: string;
35
+ middleware?: string;
36
+ };
37
+ }
@@ -0,0 +1,7 @@
1
+ import { IConfigOptions } from "./interfaces";
2
+ /**
3
+ * Matches the options passed in the command line
4
+ * @param args - The arguments passed in the command line
5
+ * @returns The options passed in the command line
6
+ */
7
+ export declare function optionMatcher(args: Array<string>): IConfigOptions;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * LINE_REGEX is a regular expression that matches a line in a .env file.
3
+ * It is used to parse the content of the .env file.
4
+ */
5
+ export declare const LINE_REGEX: RegExp;
6
+ /**
7
+ * ENV_VAR_REGEX is a regular expression that matches an environment variable in the command line.
8
+ * It is used to parse the options passed in the command line.
9
+ */
10
+ export declare const ENV_VAR_REGEX: RegExp;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Module EnvOptions
3
+ * Responsible for setting the options for the dotenv configuration if provided otherwise it will use the default values.
4
+ */
5
+ import { IConfigOptions } from "./interfaces";
6
+ /**
7
+ * The options for the dotenv configuration.
8
+ */
9
+ export declare const OPTIONS: IConfigOptions;
@@ -0,0 +1,83 @@
1
+ import { IConfigOptions, IConfigOutput, IEnvObject } from "./interfaces";
2
+ /**
3
+ * Module to parse the .env.vault file
4
+ * @param options - The configuration options
5
+ * @returns The parsed object
6
+ */
7
+ declare function _parseVault(options: IConfigOptions): IEnvObject;
8
+ /**
9
+ * Module to verify and return the .env.vault file path
10
+ * @param options - The configuration options
11
+ * @returns The .env.vault file path
12
+ */
13
+ declare function _vaultPath(options: any): any;
14
+ /**
15
+ * Module to verify and return the DOTENV_KEY vault key
16
+ * @param options - The configuration options
17
+ * @returns The DOTENV_KEY as a string
18
+ */
19
+ declare function _dotenvKey(options?: IConfigOptions): string;
20
+ /**
21
+ * Module to get instructions for decrypting the .env.vault file
22
+ * @param result -
23
+ * @param dotenvKey
24
+ * @returns
25
+ */
26
+ declare function _instructions(result: IConfigOutput, dotenvKey: string): {
27
+ ciphertext: string;
28
+ key: any;
29
+ };
30
+ /**
31
+ * Module responsible to resolve home path
32
+ * @param envPath - The path to resolve
33
+ * @returns The resolved path
34
+ */
35
+ declare function _resolveHome(envPath: string): string;
36
+ /**
37
+ * Module to load environment variables from .env.vault file
38
+ * @param options - The configuration options
39
+ * @returns The parsed object
40
+ */
41
+ export declare function _configVault(options: IConfigOptions): IConfigOutput;
42
+ /**
43
+ * Module to load environment variables from .env file
44
+ * @param options - The configuration options
45
+ * @returns The parsed object
46
+ * @public API
47
+ */
48
+ export declare function config(options?: IConfigOptions): IConfigOutput;
49
+ /**
50
+ * Module to load environment variables from .env file
51
+ * @param options - The configuration options
52
+ * @returns The parsed object
53
+ * @public API
54
+ */
55
+ export declare function configDotenv(options?: IConfigOptions): IConfigOutput;
56
+ /**
57
+ * Module to load environment variables from .env file
58
+ * @param envFile - The source of the .env file
59
+ * @returns The parsed object
60
+ * @public API
61
+ */
62
+ export declare function parse(envFile: Buffer | string): Record<string, string>;
63
+ /**
64
+ * Decrypts a base64 encoded string
65
+ * @param encrypted - The base64 encoded string to decrypt
66
+ * @param keyStr - The key to use for decryption
67
+ * @returns The decrypted string
68
+ * @public API
69
+ */
70
+ export declare function decrypt(encrypted: string, keyStr: string): string;
71
+ /**
72
+ * Populates the environment with the given parsed object
73
+ * @param envObject - The object to populate the environment with (e.g. process.env)
74
+ * @param parsed - The parsed object
75
+ * @param options - The configuration options
76
+ * @public API
77
+ */
78
+ export declare function populate(envObject: IEnvObject, // Usually process.env
79
+ parsed: IEnvObject, options?: IConfigOptions): void;
80
+ /**
81
+ * Test swap for private functions
82
+ */
83
+ export { _parseVault, _vaultPath, _dotenvKey, _instructions, _resolveHome };
@@ -0,0 +1,2 @@
1
+ export { IEnvObject, IConfigOptions, IConfigOutput } from "./interfaces";
2
+ export * from "./environment";
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Interface for config options
3
+ * @public API
4
+ */
5
+ export interface IConfigOptions {
6
+ /**
7
+ * Default: `path.resolve(process.cwd(), '.env')`
8
+ *
9
+ * Specify a custom path if your file containing environment variables is located elsewhere.
10
+ * Can also be an array of strings, specifying multiple paths.
11
+ *
12
+ * example: `require('dotenv').config({ path: '/custom/path/to/.env' })`
13
+ * example: `require('dotenv').config({ path: ['/path/to/first.env', '/path/to/second.env'] })`
14
+ */
15
+ path?: string | Array<string> | URL;
16
+ /**
17
+ * Default: `utf8`
18
+ *
19
+ * Specify the encoding of your file containing environment variables.
20
+ *
21
+ * example: `require('dotenv').config({ encoding: 'latin1' })`
22
+ */
23
+ encoding?: string;
24
+ /**
25
+ * Default: `false`
26
+ *
27
+ * Turn on logging to help debug why certain keys or values are not being set as you expect.
28
+ *
29
+ * example: `require('dotenv').config({ debug: process.env.DEBUG })`
30
+ */
31
+ debug?: boolean;
32
+ /**
33
+ * Default: `false`
34
+ *
35
+ * Override any environment variables that have already been set on your machine with values from your .env file.
36
+ *
37
+ * example: `require('dotenv').config({ override: true })`
38
+ */
39
+ override?: boolean;
40
+ /**
41
+ * Default: `process.env`
42
+ *
43
+ * Specify an object to write your secrets to. Defaults to process.env environment variables.
44
+ *
45
+ * example: `const processEnv = {}; require('dotenv').config({ processEnv: processEnv })`
46
+ */
47
+ envObject?: IEnvObject;
48
+ /**
49
+ * Default: `undefined`
50
+ *
51
+ * Pass the DOTENV_KEY directly to config options. Defaults to looking for process.env.DOTENV_KEY environment variable. Note this only applies to decrypting .env.vault files. If passed as null or undefined, or not passed at all, dotenv falls back to its traditional job of parsing a .env file.
52
+ *
53
+ * example: `require('dotenv').config({ DOTENV_KEY: 'dotenv://:key_1234…@dotenvx.com/vault/.env.vault?environment=production' })`
54
+ */
55
+ vaultEnvKey?: string;
56
+ }
57
+ /**
58
+ * Interface for environment variables
59
+ * @public API
60
+ */
61
+ export interface IEnvObject {
62
+ [name: string]: string;
63
+ }
64
+ /**
65
+ * Interface for dotenv parse output
66
+ * @public API
67
+ */
68
+ export interface IConfigOutput {
69
+ error?: Error;
70
+ parsed?: IEnvObject;
71
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./config";
2
+ export * from "./env";
3
+ export * from "./utils";
@@ -0,0 +1,17 @@
1
+ import { Service } from "ts-node";
2
+ import { ExpressoConfig } from "../config";
3
+ export declare function printError(message: string, component: string): void;
4
+ /**
5
+ * Singleton compiler class
6
+ */
7
+ export declare class Compiler {
8
+ private static instance;
9
+ private constructor();
10
+ static get Instance(): Compiler;
11
+ getService(): Promise<Service>;
12
+ static interopRequireDefault(obj: any): {
13
+ default: any;
14
+ };
15
+ static findConfig(dir: string): Promise<string>;
16
+ static loadConfig(): Promise<ExpressoConfig>;
17
+ }
@@ -0,0 +1 @@
1
+ export { Compiler } from "./compiler";
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Logger utility for dotenv
3
+ */
4
+ export declare enum LogLevel {
5
+ Info = "info",
6
+ Warn = "warn",
7
+ Debug = "debug"
8
+ }
9
+ /**
10
+ * Log a message
11
+ * @param message - The message to log
12
+ * @param logLevel - The log level. Defaults to LogLevel.Info
13
+ */
14
+ export declare function log(message: string, logLevel?: LogLevel): void;
15
+ export declare function printError(message: string, component: string): void;
16
+ export declare function printSuccess(message: string, component: string): void;
17
+ export declare function printWarning(message: string, component?: string): void;
18
+ export declare function printGenerateError(schematic: string, file: string): Promise<void>;
19
+ export declare function printGenerateSuccess(schematic: string, file: string): Promise<void>;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.Compiler = void 0;
30
+ exports.printError = printError;
31
+ /* eslint-disable @typescript-eslint/no-explicit-any */
32
+ const node_fs_1 = require("node:fs");
33
+ const path_1 = __importDefault(require("path"));
34
+ const chalk_1 = __importDefault(require("chalk"));
35
+ function printError(message, component) {
36
+ console.error(chalk_1.default.red(`${message}:`, chalk_1.default.bold(chalk_1.default.white(`[${component}] ❌`))));
37
+ }
38
+ /**
39
+ * The path to the expressots.config.ts file
40
+ */
41
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
42
+ const EXPRESSOTS_CONFIG = path_1.default.join(process.cwd(), "expressots.config.ts");
43
+ /**
44
+ * The config object
45
+ */
46
+ let globalConfigObject = null;
47
+ /**
48
+ * The ts-node register options
49
+ */
50
+ const regOpt = {
51
+ compilerOptions: {
52
+ module: "commonjs",
53
+ },
54
+ moduleTypes: {
55
+ "**": "cjs",
56
+ },
57
+ };
58
+ /**
59
+ * Singleton compiler class
60
+ */
61
+ class Compiler {
62
+ constructor() { }
63
+ static get Instance() {
64
+ if (!Compiler.instance) {
65
+ Compiler.instance = new Compiler();
66
+ }
67
+ return Compiler.instance;
68
+ }
69
+ async getService() {
70
+ const tsnode = await Promise.resolve().then(() => __importStar(require("ts-node")));
71
+ const compiler = tsnode.register(regOpt);
72
+ return compiler;
73
+ }
74
+ static interopRequireDefault(obj) {
75
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
76
+ const module = require(obj);
77
+ return module && module.__esModule ? module : { default: module };
78
+ }
79
+ static async findConfig(dir) {
80
+ const configPath = path_1.default.join(dir, "expressots.config.ts");
81
+ const exists = (0, node_fs_1.existsSync)(configPath);
82
+ if (exists)
83
+ return configPath;
84
+ const parentDir = path_1.default.join(dir, "..");
85
+ if (parentDir === dir) {
86
+ printError("No config file found!", "expressots.config.ts");
87
+ process.exit(1);
88
+ }
89
+ return Compiler.findConfig(parentDir);
90
+ }
91
+ static async loadConfig() {
92
+ const compiler = await Compiler.Instance.getService();
93
+ compiler.enabled(true);
94
+ globalConfigObject = Compiler.interopRequireDefault(await Compiler.findConfig(process.cwd()));
95
+ compiler.enabled(false);
96
+ return globalConfigObject.default;
97
+ }
98
+ }
99
+ exports.Compiler = Compiler;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Compiler = void 0;
4
+ var compiler_1 = require("./compiler");
5
+ Object.defineProperty(exports, "Compiler", { enumerable: true, get: function () { return compiler_1.Compiler; } });
@@ -0,0 +1,72 @@
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.LogLevel = void 0;
7
+ exports.log = log;
8
+ exports.printError = printError;
9
+ exports.printSuccess = printSuccess;
10
+ exports.printWarning = printWarning;
11
+ exports.printGenerateError = printGenerateError;
12
+ exports.printGenerateSuccess = printGenerateSuccess;
13
+ const process_1 = require("process");
14
+ const chalk_1 = __importDefault(require("chalk"));
15
+ /**
16
+ * Logger utility for dotenv
17
+ */
18
+ var LogLevel;
19
+ (function (LogLevel) {
20
+ LogLevel["Info"] = "info";
21
+ LogLevel["Warn"] = "warn";
22
+ LogLevel["Debug"] = "debug";
23
+ })(LogLevel || (exports.LogLevel = LogLevel = {}));
24
+ /**
25
+ * Log a message
26
+ * @param message - The message to log
27
+ * @param logLevel - The log level. Defaults to LogLevel.Info
28
+ */
29
+ function log(message, logLevel = LogLevel.Info) {
30
+ switch (logLevel) {
31
+ case LogLevel.Info:
32
+ process_1.stdout.write(`[ExpressoTS][INFO] ${message}\n`);
33
+ break;
34
+ case LogLevel.Warn:
35
+ process_1.stdout.write(`[ExpressoTS][WARN] ${message}\n`);
36
+ break;
37
+ case LogLevel.Debug:
38
+ process_1.stdout.write(`[ExpressoTS][DEBUG] ${message}\n`);
39
+ break;
40
+ }
41
+ }
42
+ function printError(message, component) {
43
+ const formattedMessage = message ? `${message}: ` : ": ";
44
+ const formattedComponent = component ? `[${component}]` : "[]";
45
+ const output = chalk_1.default.red(`${formattedMessage}${chalk_1.default.bold(chalk_1.default.white(`${formattedComponent} ❌\n`))}`);
46
+ process_1.stdout.write(output);
47
+ }
48
+ function printSuccess(message, component) {
49
+ const formattedMessage = message ? `${message}: ` : ": ";
50
+ const formattedComponent = component ? `[${component}]` : "[]";
51
+ const output = chalk_1.default.green(`${formattedMessage}${chalk_1.default.bold(chalk_1.default.white(`${formattedComponent} ✔️\n`))}`);
52
+ process_1.stdout.write(output);
53
+ }
54
+ function printWarning(message, component) {
55
+ if (component === undefined) {
56
+ process_1.stdout.write(chalk_1.default.yellow(`${message} ⚠️\n`));
57
+ return;
58
+ }
59
+ process_1.stdout.write(chalk_1.default.yellow(`${message}:`, chalk_1.default.bold(chalk_1.default.white(`[${component}] ⚠️\n`))));
60
+ }
61
+ async function printGenerateError(schematic, file) {
62
+ const schematicFormatted = `[${schematic}]`.padEnd(14);
63
+ const fileNameFormatted = chalk_1.default.bold.white(`${file.split(".")[0]} not created! ❌\n`);
64
+ const output = chalk_1.default.redBright(schematicFormatted) + fileNameFormatted;
65
+ process_1.stdout.write(output);
66
+ }
67
+ async function printGenerateSuccess(schematic, file) {
68
+ const schematicFormatted = `[${schematic}]`.padEnd(14);
69
+ const fileNameFormatted = chalk_1.default.bold.white(`${file.split(".")[0]} created! ✔️\n`);
70
+ const output = chalk_1.default.greenBright(schematicFormatted) + fileNameFormatted;
71
+ process_1.stdout.write(output);
72
+ }
@@ -0,0 +1,150 @@
1
+ {
2
+ "name": "@expressots/shared",
3
+ "version": "0.0.1-beta.1",
4
+ "description": "Shared library for ExpressoTS modules 🐎",
5
+ "author": "Richard Zampieri <richard.zampieri@expresso-ts.com>",
6
+ "main": "./lib/cjs/index.js",
7
+ "types": "./lib/cjs/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./lib/esm/types/index.d.ts",
12
+ "default": "./lib/esm/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./lib/cjs/types/index.d.ts",
16
+ "default": "./lib/cjs/index.js"
17
+ }
18
+ }
19
+ },
20
+ "files": [
21
+ "lib/**/*"
22
+ ],
23
+ "license": "MIT",
24
+ "homepage": "https://expresso-ts.com",
25
+ "funding": {
26
+ "type": "github",
27
+ "url": "https://github.com/sponsors/expressots"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/expressots/shared"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/expressots/shared/issues"
35
+ },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "keywords": [
40
+ "expressots",
41
+ "nodejs",
42
+ "typescript",
43
+ "clean-architecture",
44
+ "typescript-framework",
45
+ "framework",
46
+ "server-side",
47
+ "backend",
48
+ "library"
49
+ ],
50
+ "engines": {
51
+ "node": ">=18.10.0"
52
+ },
53
+ "scripts": {
54
+ "prepare": "husky",
55
+ "clean": "node scripts/rm.js lib",
56
+ "copy": "node scripts/copy.js package.json README.md CHANGELOG.md lib",
57
+ "build": "npm run clean && npm run build:cjs && npm run copy",
58
+ "build:cjs": "tsc -p tsconfig.cjs.json",
59
+ "build:esm": "tsc -p tsconfig.esm.json",
60
+ "release": "release-it",
61
+ "prepublish": "npm run build && npm pack",
62
+ "publish": "npm publish --tag latest",
63
+ "test": "jest",
64
+ "test:watch": "jest --watch",
65
+ "coverage": "jest --coverage",
66
+ "format": "prettier --write \"src/**/*.ts\" --cache",
67
+ "lint": "eslint \"src/**/*.ts\"",
68
+ "lint:fix": "eslint \"src/**/*.ts\" --fix"
69
+ },
70
+ "dependencies": {
71
+ "reflect-metadata": "0.2.2",
72
+ "ts-node": "^10.9.2"
73
+ },
74
+ "devDependencies": {
75
+ "@commitlint/cli": "19.4.1",
76
+ "@commitlint/config-conventional": "19.2.2",
77
+ "@release-it/conventional-changelog": "8.0.1",
78
+ "@types/express": "4.17.21",
79
+ "@types/jest": "^29.5.13",
80
+ "@types/node": "20.14.10",
81
+ "@typescript-eslint/eslint-plugin": "7.16.1",
82
+ "@typescript-eslint/parser": "7.16.1",
83
+ "chalk": "^4.1.2",
84
+ "eslint": "8.57.0",
85
+ "eslint-config-prettier": "9.1.0",
86
+ "husky": "9.1.1",
87
+ "jest": "^29.7.0",
88
+ "prettier": "3.3.3",
89
+ "release-it": "17.6.0",
90
+ "ts-jest": "^29.2.5",
91
+ "typescript": "5.5.3"
92
+ },
93
+ "release-it": {
94
+ "git": {
95
+ "commitMessage": "chore(release): ${version}"
96
+ },
97
+ "github": {
98
+ "release": true
99
+ },
100
+ "npm": {
101
+ "publish": false
102
+ },
103
+ "plugins": {
104
+ "@release-it/conventional-changelog": {
105
+ "infile": "CHANGELOG.md",
106
+ "preset": {
107
+ "name": "conventionalcommits",
108
+ "types": [
109
+ {
110
+ "type": "feat",
111
+ "section": "Features"
112
+ },
113
+ {
114
+ "type": "fix",
115
+ "section": "Bug Fixes"
116
+ },
117
+ {
118
+ "type": "perf",
119
+ "section": "Performance Improvements"
120
+ },
121
+ {
122
+ "type": "revert",
123
+ "section": "Reverts"
124
+ },
125
+ {
126
+ "type": "docs",
127
+ "section": "Documentation"
128
+ },
129
+ {
130
+ "type": "refactor",
131
+ "section": "Code Refactoring"
132
+ },
133
+ {
134
+ "type": "test",
135
+ "section": "Tests"
136
+ },
137
+ {
138
+ "type": "build",
139
+ "section": "Build System"
140
+ },
141
+ {
142
+ "type": "ci",
143
+ "section": "Continuous Integrations"
144
+ }
145
+ ]
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }