@nest-forge/core 0.0.1
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/.prettierignore +3 -0
- package/.prettierrc +7 -0
- package/README.md +0 -0
- package/dist/extensions/extension.d.ts +39 -0
- package/dist/extensions/extension.js +39 -0
- package/dist/extensions/index.d.ts +1 -0
- package/dist/extensions/index.js +4 -0
- package/dist/forge-options.interface.d.ts +9 -0
- package/dist/forge-options.interface.js +2 -0
- package/dist/forge.factory.d.ts +21 -0
- package/dist/forge.factory.js +108 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -0
- package/eslint.config.mjs +31 -0
- package/package.json +55 -0
- package/tsconfig.json +30 -0
package/.prettierignore
ADDED
package/.prettierrc
ADDED
package/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { INestApplication, INestApplicationContext, MiddlewareConsumer, ModuleMetadata } from '@nestjs/common';
|
|
2
|
+
export declare abstract class ForgeExtension {
|
|
3
|
+
/**
|
|
4
|
+
* The metdata for this extension.
|
|
5
|
+
*/
|
|
6
|
+
private readonly _metadata;
|
|
7
|
+
/**
|
|
8
|
+
* Constructs a new forge extension instance.
|
|
9
|
+
*/
|
|
10
|
+
constructor(options?: ForgeExtensionMetadata);
|
|
11
|
+
/**
|
|
12
|
+
* Configures a Nest application instance.
|
|
13
|
+
*/
|
|
14
|
+
configureHttpApplication(application: INestApplication): any;
|
|
15
|
+
/**
|
|
16
|
+
* Configures a Nest application context. This is
|
|
17
|
+
*/
|
|
18
|
+
configureStandaloneApplication(context: INestApplicationContext): any;
|
|
19
|
+
/**
|
|
20
|
+
* Configures the root module of the application.
|
|
21
|
+
*/
|
|
22
|
+
configureRootModule(consumer: MiddlewareConsumer): any;
|
|
23
|
+
/**
|
|
24
|
+
* Instruments the application context. If a value is returned, the instance is replaced with that value, and no further extensions are
|
|
25
|
+
* queried.
|
|
26
|
+
*/
|
|
27
|
+
instrument(instance: unknown): any;
|
|
28
|
+
/**
|
|
29
|
+
* Returns the metadata for this extension.
|
|
30
|
+
*/
|
|
31
|
+
getMetadata(): ForgeExtensionMetadata;
|
|
32
|
+
}
|
|
33
|
+
export interface ForgeExtensionMetadata extends ModuleMetadata {
|
|
34
|
+
/**
|
|
35
|
+
* An optional array of nested extensions to import.
|
|
36
|
+
*/
|
|
37
|
+
extensions?: ForgeExtensionResolvable[];
|
|
38
|
+
}
|
|
39
|
+
export type ForgeExtensionResolvable = ForgeExtension | (new () => ForgeExtension) | null | undefined | false;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ForgeExtension = void 0;
|
|
4
|
+
class ForgeExtension {
|
|
5
|
+
/**
|
|
6
|
+
* The metdata for this extension.
|
|
7
|
+
*/
|
|
8
|
+
_metadata;
|
|
9
|
+
/**
|
|
10
|
+
* Constructs a new forge extension instance.
|
|
11
|
+
*/
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this._metadata = options || {};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Configures a Nest application instance.
|
|
17
|
+
*/
|
|
18
|
+
configureHttpApplication(application) { }
|
|
19
|
+
/**
|
|
20
|
+
* Configures a Nest application context. This is
|
|
21
|
+
*/
|
|
22
|
+
configureStandaloneApplication(context) { }
|
|
23
|
+
/**
|
|
24
|
+
* Configures the root module of the application.
|
|
25
|
+
*/
|
|
26
|
+
configureRootModule(consumer) { }
|
|
27
|
+
/**
|
|
28
|
+
* Instruments the application context. If a value is returned, the instance is replaced with that value, and no further extensions are
|
|
29
|
+
* queried.
|
|
30
|
+
*/
|
|
31
|
+
instrument(instance) { }
|
|
32
|
+
/**
|
|
33
|
+
* Returns the metadata for this extension.
|
|
34
|
+
*/
|
|
35
|
+
getMetadata() {
|
|
36
|
+
return this._metadata;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.ForgeExtension = ForgeExtension;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './extension';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { NestApplicationOptions } from '@nestjs/common';
|
|
2
|
+
import { ForgeExtensionResolvable } from './extensions';
|
|
3
|
+
import { NestApplicationContextOptions } from '@nestjs/common/interfaces/nest-application-context-options.interface';
|
|
4
|
+
export interface ForgeApplicationOptions extends NestApplicationOptions {
|
|
5
|
+
extensions?: ForgeExtensionResolvable | ForgeExtensionResolvable[];
|
|
6
|
+
}
|
|
7
|
+
export interface ForgeApplicationContextOptions extends NestApplicationContextOptions {
|
|
8
|
+
extensions?: ForgeExtensionResolvable | ForgeExtensionResolvable[];
|
|
9
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DynamicModule, ForwardReference, MiddlewareConsumer, Type } from '@nestjs/common';
|
|
2
|
+
import { ForgeApplicationContextOptions, ForgeApplicationOptions } from './forge-options.interface';
|
|
3
|
+
import { ForgeExtension, ForgeExtensionResolvable } from './extensions';
|
|
4
|
+
declare class Forge {
|
|
5
|
+
create(appModule: IEntryNestModule, options?: ForgeApplicationOptions): Promise<import("@nestjs/common").INestApplication<any>>;
|
|
6
|
+
createApplicationContext(appModule: IEntryNestModule, options: ForgeApplicationContextOptions): Promise<import("@nestjs/common").INestApplicationContext>;
|
|
7
|
+
protected discoverExtensions(resolvables: ForgeExtensionResolvable | ForgeExtensionResolvable[]): ForgeExtension[];
|
|
8
|
+
protected resolveExtension(resolvable: ForgeExtensionResolvable): ForgeExtension;
|
|
9
|
+
protected createRootModule(appModule: IEntryNestModule, extensions: ForgeExtension[]): {
|
|
10
|
+
new (): {
|
|
11
|
+
configure(consumer: MiddlewareConsumer): void;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
protected createInstrument(extensions: ForgeExtension[], originalInstrument?: Instrument): Instrument;
|
|
15
|
+
}
|
|
16
|
+
type IEntryNestModule = Type<any> | DynamicModule | ForwardReference | Promise<IEntryNestModule>;
|
|
17
|
+
type Instrument = {
|
|
18
|
+
instanceDecorator: (instance: unknown) => unknown;
|
|
19
|
+
};
|
|
20
|
+
declare const forge: Forge;
|
|
21
|
+
export { forge as Forge };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Forge = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const core_1 = require("@nestjs/core");
|
|
7
|
+
class Forge {
|
|
8
|
+
async create(appModule, options) {
|
|
9
|
+
const extensions = this.discoverExtensions(options?.extensions ?? []);
|
|
10
|
+
const root = this.createRootModule(appModule, extensions);
|
|
11
|
+
const app = await core_1.NestFactory.create(root, {
|
|
12
|
+
...options,
|
|
13
|
+
instrument: this.createInstrument(extensions, options.instrument),
|
|
14
|
+
});
|
|
15
|
+
for (const extension of extensions) {
|
|
16
|
+
extension.configureHttpApplication(app);
|
|
17
|
+
}
|
|
18
|
+
return app;
|
|
19
|
+
}
|
|
20
|
+
async createApplicationContext(appModule, options) {
|
|
21
|
+
const extensions = this.discoverExtensions(options?.extensions ?? []);
|
|
22
|
+
const root = this.createRootModule(appModule, extensions);
|
|
23
|
+
const app = await core_1.NestFactory.createApplicationContext(root, {
|
|
24
|
+
...options,
|
|
25
|
+
instrument: this.createInstrument(extensions, options.instrument),
|
|
26
|
+
});
|
|
27
|
+
for (const extension of extensions) {
|
|
28
|
+
extension.configureStandaloneApplication(app);
|
|
29
|
+
}
|
|
30
|
+
return app;
|
|
31
|
+
}
|
|
32
|
+
discoverExtensions(resolvables) {
|
|
33
|
+
const extensions = new Map();
|
|
34
|
+
if (!Array.isArray(resolvables)) {
|
|
35
|
+
resolvables = [resolvables];
|
|
36
|
+
}
|
|
37
|
+
for (const resolvable of resolvables) {
|
|
38
|
+
const extension = this.resolveExtension(resolvable);
|
|
39
|
+
if (extension !== null) {
|
|
40
|
+
const metadata = extension.getMetadata();
|
|
41
|
+
for (const nestedExtension of this.discoverExtensions(metadata.extensions)) {
|
|
42
|
+
extensions.delete(nestedExtension.constructor);
|
|
43
|
+
extensions.set(nestedExtension.constructor, nestedExtension);
|
|
44
|
+
}
|
|
45
|
+
extensions.delete(extension.constructor);
|
|
46
|
+
extensions.set(extension.constructor, extension);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return Array.from(extensions.values());
|
|
50
|
+
}
|
|
51
|
+
resolveExtension(resolvable) {
|
|
52
|
+
if (resolvable === false || resolvable === null || resolvable === undefined) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
if (typeof resolvable === 'object') {
|
|
56
|
+
return resolvable;
|
|
57
|
+
}
|
|
58
|
+
if (typeof resolvable === 'function') {
|
|
59
|
+
return new resolvable();
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Unsupported extension resolvable "${String(resolvable)}"`);
|
|
62
|
+
}
|
|
63
|
+
createRootModule(appModule, extensions) {
|
|
64
|
+
const meta = {
|
|
65
|
+
imports: [appModule],
|
|
66
|
+
controllers: [],
|
|
67
|
+
providers: [],
|
|
68
|
+
exports: [],
|
|
69
|
+
};
|
|
70
|
+
for (const extension of extensions) {
|
|
71
|
+
const extensionMeta = extension.getMetadata();
|
|
72
|
+
meta.imports.push(...(extensionMeta.imports ?? []));
|
|
73
|
+
meta.controllers.push(...(extensionMeta.controllers ?? []));
|
|
74
|
+
meta.providers.push(...(extensionMeta.providers ?? []));
|
|
75
|
+
meta.exports.push(...(extensionMeta.exports ?? []));
|
|
76
|
+
}
|
|
77
|
+
let ForgeRootModule = class ForgeRootModule {
|
|
78
|
+
configure(consumer) {
|
|
79
|
+
for (const extension of extensions) {
|
|
80
|
+
extension.configureRootModule(consumer);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
ForgeRootModule = tslib_1.__decorate([
|
|
85
|
+
(0, common_1.Module)(meta)
|
|
86
|
+
], ForgeRootModule);
|
|
87
|
+
return ForgeRootModule;
|
|
88
|
+
}
|
|
89
|
+
createInstrument(extensions, originalInstrument) {
|
|
90
|
+
const hasOriginalInstrument = originalInstrument && originalInstrument.instanceDecorator;
|
|
91
|
+
return {
|
|
92
|
+
instanceDecorator(instance) {
|
|
93
|
+
for (const extension of extensions) {
|
|
94
|
+
const response = extension.instrument(instance);
|
|
95
|
+
if (response !== undefined) {
|
|
96
|
+
return response;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (hasOriginalInstrument) {
|
|
100
|
+
return originalInstrument.instanceDecorator(instance);
|
|
101
|
+
}
|
|
102
|
+
return instance;
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const forge = new Forge();
|
|
108
|
+
exports.Forge = forge;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./forge.factory"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./forge-options.interface"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./extensions"), exports);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import eslint from '@eslint/js';
|
|
2
|
+
import { defineConfig } from 'eslint/config';
|
|
3
|
+
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
|
4
|
+
import tseslint from 'typescript-eslint';
|
|
5
|
+
import globals from 'globals';
|
|
6
|
+
|
|
7
|
+
export default defineConfig(
|
|
8
|
+
{
|
|
9
|
+
ignores: ['node_modules', '**/node_modules/**', '**/*.js', '**/*.d.ts']
|
|
10
|
+
},
|
|
11
|
+
eslint.configs.recommended,
|
|
12
|
+
...tseslint.configs.recommendedTypeChecked,
|
|
13
|
+
eslintPluginPrettierRecommended,
|
|
14
|
+
{
|
|
15
|
+
languageOptions: {
|
|
16
|
+
globals: {
|
|
17
|
+
...globals.node,
|
|
18
|
+
...globals.jest
|
|
19
|
+
},
|
|
20
|
+
ecmaVersion: 2024,
|
|
21
|
+
sourceType: 'module',
|
|
22
|
+
parserOptions: {
|
|
23
|
+
projectService: true,
|
|
24
|
+
tsconfigRootDir: import.meta.dirname
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
rules: {}
|
|
30
|
+
}
|
|
31
|
+
);
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nest-forge/core",
|
|
3
|
+
"description": "",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "rimraf dist && tsc -p tsconfig.json",
|
|
7
|
+
"watch": "rimraf dist && tsc -w -p tsconfig.json",
|
|
8
|
+
"format": "prettier --write \"{src,apps,libs,test}/**/*.ts\"",
|
|
9
|
+
"lint": "eslint --ignore-pattern .gitignore \"{src,apps,libs,test}/**/*.ts\""
|
|
10
|
+
},
|
|
11
|
+
"directories": {
|
|
12
|
+
"lib": "src"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"license": "UNLICENSED",
|
|
18
|
+
"homepage": "https://github.com/nest-forge",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/nest-forge/core"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/nest-forge/core/issues"
|
|
25
|
+
},
|
|
26
|
+
"author": "Bailey Herbert <hello@bailey.sh>",
|
|
27
|
+
"contributors": [],
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"tslib": "^2.8.1"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@eslint/eslintrc": "^3.3.3",
|
|
33
|
+
"@eslint/js": "^9.39.2",
|
|
34
|
+
"@types/node": "~25.0.0",
|
|
35
|
+
"eslint": "^9.18.0",
|
|
36
|
+
"eslint-config-prettier": "^10.1.8",
|
|
37
|
+
"eslint-plugin-import": "^2.32.0",
|
|
38
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
39
|
+
"globals": "^16.0.0",
|
|
40
|
+
"prettier": "3.7.4",
|
|
41
|
+
"reflect-metadata": "^0.2.2",
|
|
42
|
+
"rimraf": "^6.1.2",
|
|
43
|
+
"typescript": "^5.9.0",
|
|
44
|
+
"typescript-eslint": "^8.51.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"@nestjs/common": "^10.2.0 || ^11.0.0",
|
|
48
|
+
"@nestjs/core": "^10.2.0 || ^11.0.0",
|
|
49
|
+
"reflect-metadata": "^0.2.1"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=24",
|
|
53
|
+
"npm": ">=10.0.0"
|
|
54
|
+
}
|
|
55
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "commonjs",
|
|
4
|
+
"declaration": true,
|
|
5
|
+
"noImplicitAny": false,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"noUnusedLocals": false,
|
|
8
|
+
"importHelpers": true,
|
|
9
|
+
"removeComments": false,
|
|
10
|
+
"noLib": false,
|
|
11
|
+
"emitDecoratorMetadata": true,
|
|
12
|
+
"experimentalDecorators": true,
|
|
13
|
+
"useUnknownInCatchVariables": false,
|
|
14
|
+
"target": "ES2024",
|
|
15
|
+
"sourceMap": false,
|
|
16
|
+
"allowJs": false,
|
|
17
|
+
"outDir": "./dist",
|
|
18
|
+
"baseUrl": ".",
|
|
19
|
+
"forceConsistentCasingInFileNames": true,
|
|
20
|
+
"strictPropertyInitialization": false,
|
|
21
|
+
"stripInternal": true
|
|
22
|
+
},
|
|
23
|
+
"include": [
|
|
24
|
+
"src/**/*"
|
|
25
|
+
],
|
|
26
|
+
"exclude": [
|
|
27
|
+
"node_modules",
|
|
28
|
+
"dist"
|
|
29
|
+
]
|
|
30
|
+
}
|