@navios/core 0.6.0 → 0.7.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/CHANGELOG.md +115 -0
- package/README.md +18 -1
- package/docs/README.md +1 -0
- package/docs/legacy-compat.md +320 -0
- package/docs/testing.md +140 -17
- package/lib/index-DW9EPAE6.d.mts +2156 -0
- package/lib/index-DW9EPAE6.d.mts.map +1 -0
- package/lib/index-pHp-dIGt.d.cts +2156 -0
- package/lib/index-pHp-dIGt.d.cts.map +1 -0
- package/lib/index.cjs +157 -0
- package/lib/index.d.cts +3 -0
- package/lib/index.d.mts +3 -190
- package/lib/index.mjs +4 -1459
- package/lib/legacy-compat/index.cjs +315 -0
- package/lib/legacy-compat/index.cjs.map +1 -0
- package/lib/legacy-compat/index.d.cts +219 -0
- package/lib/legacy-compat/index.d.cts.map +1 -0
- package/lib/legacy-compat/index.d.mts +219 -0
- package/lib/legacy-compat/index.d.mts.map +1 -0
- package/lib/legacy-compat/index.mjs +308 -0
- package/lib/legacy-compat/index.mjs.map +1 -0
- package/lib/src-DyvCDuKO.mjs +5443 -0
- package/lib/src-DyvCDuKO.mjs.map +1 -0
- package/lib/src-QnxR5b7c.cjs +5800 -0
- package/lib/src-QnxR5b7c.cjs.map +1 -0
- package/lib/testing/index.cjs +106 -0
- package/lib/testing/index.cjs.map +1 -0
- package/lib/testing/index.d.cts +156 -0
- package/lib/testing/index.d.cts.map +1 -0
- package/lib/testing/index.d.mts +156 -0
- package/lib/testing/index.d.mts.map +1 -0
- package/lib/testing/index.mjs +100 -0
- package/lib/testing/index.mjs.map +1 -0
- package/lib/use-guards.decorator-B6q_N0sf.cjs +622 -0
- package/lib/use-guards.decorator-B6q_N0sf.cjs.map +1 -0
- package/lib/use-guards.decorator-kZ3lNK8v.mjs +454 -0
- package/lib/use-guards.decorator-kZ3lNK8v.mjs.map +1 -0
- package/package.json +28 -8
- package/project.json +2 -2
- package/src/attribute.factory.mts +154 -0
- package/src/config/config-service.interface.mts +31 -0
- package/src/config/config.provider.mts +36 -0
- package/src/config/config.service.mts +94 -4
- package/src/decorators/controller.decorator.mts +28 -0
- package/src/decorators/endpoint.decorator.mts +76 -0
- package/src/decorators/header.decorator.mts +19 -0
- package/src/decorators/http-code.decorator.mts +20 -0
- package/src/decorators/module.decorator.mts +34 -0
- package/src/decorators/multipart.decorator.mts +41 -0
- package/src/decorators/stream.decorator.mts +33 -0
- package/src/decorators/use-guards.decorator.mts +29 -0
- package/src/exceptions/bad-request.exception.mts +21 -0
- package/src/exceptions/conflict.exception.mts +24 -0
- package/src/exceptions/forbidden.exception.mts +23 -0
- package/src/exceptions/http.exception.mts +26 -0
- package/src/exceptions/internal-server-error.exception.mts +26 -0
- package/src/exceptions/not-found.exception.mts +23 -0
- package/src/exceptions/unauthorized.exception.mts +23 -0
- package/src/index.mts +1 -0
- package/src/interfaces/abstract-execution-context.inteface.mts +35 -0
- package/src/interfaces/abstract-http-adapter.interface.mts +52 -0
- package/src/interfaces/abstract-http-handler-adapter.interface.mts +2 -2
- package/src/interfaces/can-activate.mts +31 -0
- package/src/interfaces/index.mts +1 -0
- package/src/interfaces/navios-module.mts +25 -0
- package/src/interfaces/plugin.interface.mts +105 -0
- package/src/legacy-compat/__type-tests__/legacy-decorators.spec-d.mts +420 -0
- package/src/legacy-compat/__type-tests__/tsconfig.json +15 -0
- package/src/legacy-compat/context-compat.mts +93 -0
- package/src/legacy-compat/decorators/controller.decorator.mts +31 -0
- package/src/legacy-compat/decorators/endpoint.decorator.mts +99 -0
- package/src/legacy-compat/decorators/header.decorator.mts +42 -0
- package/src/legacy-compat/decorators/http-code.decorator.mts +38 -0
- package/src/legacy-compat/decorators/index.mts +9 -0
- package/src/legacy-compat/decorators/module.decorator.mts +37 -0
- package/src/legacy-compat/decorators/multipart.decorator.mts +93 -0
- package/src/legacy-compat/decorators/stream.decorator.mts +76 -0
- package/src/legacy-compat/decorators/use-guards.decorator.mts +80 -0
- package/src/legacy-compat/index.mts +40 -0
- package/src/logger/console-logger.service.mts +15 -2
- package/src/logger/log-levels.mts +9 -0
- package/src/logger/logger.service.mts +21 -0
- package/src/logger/logger.tokens.mts +23 -0
- package/src/navios.application.mts +228 -4
- package/src/navios.factory.mts +60 -1
- package/src/services/guard-runner.service.mts +12 -11
- package/src/services/module-loader.service.mts +118 -12
- package/src/stores/index.mts +1 -0
- package/src/stores/request-id.store.mts +43 -0
- package/src/testing/index.mts +2 -0
- package/src/testing/testing-module.mts +231 -0
- package/tsconfig.lib.json +1 -1
- package/tsconfig.spec.json +3 -0
- package/tsdown.config.mts +35 -0
- package/vitest.config.mts +6 -0
- package/lib/_tsup-dts-rollup.d.mts +0 -1365
- package/lib/_tsup-dts-rollup.d.ts +0 -1365
- package/lib/index.d.ts +0 -190
- package/lib/index.js +0 -1540
- package/lib/index.js.map +0 -1
- package/lib/index.mjs.map +0 -1
- package/tsup.config.mts +0 -13
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClassTypeWithInstance } from '@navios/di'
|
|
1
|
+
import type { ClassType, ClassTypeWithInstance } from '@navios/di'
|
|
2
2
|
|
|
3
3
|
import { Container, inject, Injectable } from '@navios/di'
|
|
4
4
|
|
|
@@ -8,6 +8,30 @@ import type { ModuleMetadata } from '../metadata/index.mjs'
|
|
|
8
8
|
import { Logger } from '../logger/index.mjs'
|
|
9
9
|
import { extractModuleMetadata } from '../metadata/index.mjs'
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Extension definition for dynamically adding to the module tree.
|
|
13
|
+
* Used by plugins to inject controllers or entire modules.
|
|
14
|
+
*/
|
|
15
|
+
export interface ModuleExtension {
|
|
16
|
+
/**
|
|
17
|
+
* Module class to add. If provided, the module and all its
|
|
18
|
+
* controllers/imports will be processed.
|
|
19
|
+
*/
|
|
20
|
+
module?: ClassTypeWithInstance<NaviosModule>
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Controllers to add directly without a wrapper module.
|
|
24
|
+
* Will be registered under a synthetic module named after the plugin.
|
|
25
|
+
*/
|
|
26
|
+
controllers?: ClassType[]
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Name for the synthetic module when using controllers directly.
|
|
30
|
+
* Required if `controllers` is provided without `module`.
|
|
31
|
+
*/
|
|
32
|
+
moduleName?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
11
35
|
@Injectable()
|
|
12
36
|
export class ModuleLoaderService {
|
|
13
37
|
private logger = inject(Logger, {
|
|
@@ -26,6 +50,83 @@ export class ModuleLoaderService {
|
|
|
26
50
|
this.initialized = true
|
|
27
51
|
}
|
|
28
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Extends the module tree with additional modules or controllers.
|
|
55
|
+
*
|
|
56
|
+
* This method is designed to be called by plugins during registration,
|
|
57
|
+
* which happens after initial module loading but before route registration.
|
|
58
|
+
*
|
|
59
|
+
* @param extensions - Array of module extensions to add
|
|
60
|
+
* @throws Error if not initialized (loadModules must be called first)
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* // In plugin registration
|
|
65
|
+
* const moduleLoader = await context.container.get(ModuleLoaderService)
|
|
66
|
+
* await moduleLoader.extendModules([{
|
|
67
|
+
* controllers: [OpenApiJsonController, OpenApiYamlController],
|
|
68
|
+
* moduleName: 'OpenApiBunModule',
|
|
69
|
+
* }])
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
async extendModules(extensions: ModuleExtension[]): Promise<void> {
|
|
73
|
+
if (!this.initialized) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
'ModuleLoaderService must be initialized before extending. Call loadModules() first.',
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const extension of extensions) {
|
|
80
|
+
if (extension.module) {
|
|
81
|
+
// Process a full module with its imports and controllers
|
|
82
|
+
await this.traverseModules(extension.module)
|
|
83
|
+
} else if (extension.controllers && extension.moduleName) {
|
|
84
|
+
// Create synthetic module metadata for loose controllers
|
|
85
|
+
await this.registerControllers(
|
|
86
|
+
extension.controllers,
|
|
87
|
+
extension.moduleName,
|
|
88
|
+
)
|
|
89
|
+
} else if (extension.controllers) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
'moduleName is required when providing controllers without a module',
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Registers controllers under a synthetic module.
|
|
99
|
+
* Used when plugins want to add controllers without a full module class.
|
|
100
|
+
*/
|
|
101
|
+
private async registerControllers(
|
|
102
|
+
controllers: ClassType[],
|
|
103
|
+
moduleName: string,
|
|
104
|
+
): Promise<void> {
|
|
105
|
+
if (this.modulesMetadata.has(moduleName)) {
|
|
106
|
+
// Merge controllers into existing module
|
|
107
|
+
const existing = this.modulesMetadata.get(moduleName)!
|
|
108
|
+
for (const controller of controllers) {
|
|
109
|
+
existing.controllers.add(controller)
|
|
110
|
+
}
|
|
111
|
+
this.logger.debug(
|
|
112
|
+
`Extended module ${moduleName} with ${controllers.length} controllers`,
|
|
113
|
+
)
|
|
114
|
+
} else {
|
|
115
|
+
// Create new synthetic module metadata
|
|
116
|
+
const metadata: ModuleMetadata = {
|
|
117
|
+
controllers: new Set(controllers),
|
|
118
|
+
imports: new Set(),
|
|
119
|
+
guards: new Set(),
|
|
120
|
+
customAttributes: new Map(),
|
|
121
|
+
}
|
|
122
|
+
this.modulesMetadata.set(moduleName, metadata)
|
|
123
|
+
|
|
124
|
+
this.logger.debug(
|
|
125
|
+
`Created module ${moduleName} with ${controllers.length} controllers`,
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
29
130
|
private async traverseModules(
|
|
30
131
|
module: ClassTypeWithInstance<NaviosModule>,
|
|
31
132
|
parentMetadata?: ModuleMetadata,
|
|
@@ -38,18 +139,23 @@ export class ModuleLoaderService {
|
|
|
38
139
|
if (this.modulesMetadata.has(moduleName)) {
|
|
39
140
|
return
|
|
40
141
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
142
|
+
try {
|
|
143
|
+
this.modulesMetadata.set(moduleName, metadata)
|
|
144
|
+
const imports = metadata.imports ?? new Set()
|
|
145
|
+
const loadingPromises = Array.from(imports).map(async (importedModule) =>
|
|
146
|
+
this.traverseModules(importedModule, metadata),
|
|
147
|
+
)
|
|
148
|
+
await Promise.all(loadingPromises)
|
|
149
|
+
const instance = await this.container.get(module)
|
|
150
|
+
if (instance.onModuleInit) {
|
|
151
|
+
await instance.onModuleInit()
|
|
152
|
+
}
|
|
153
|
+
this.logger.debug(`Module ${moduleName} loaded`)
|
|
154
|
+
this.loadedModules.set(moduleName, instance)
|
|
155
|
+
} catch (error) {
|
|
156
|
+
this.logger.error(`Error loading module ${moduleName}`, error)
|
|
157
|
+
throw error
|
|
50
158
|
}
|
|
51
|
-
this.logger.debug(`Module ${moduleName} loaded`)
|
|
52
|
-
this.loadedModules.set(moduleName, instance)
|
|
53
159
|
}
|
|
54
160
|
|
|
55
161
|
private mergeMetadata(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './request-id.store.mjs'
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AsyncLocalStorage store for the current request ID.
|
|
5
|
+
*
|
|
6
|
+
* This allows logging and other services to access the current request ID
|
|
7
|
+
* without explicitly passing it through the call stack.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { requestIdStore, runWithRequestId, getRequestId } from '@navios/core'
|
|
12
|
+
*
|
|
13
|
+
* // Run code with a request ID in context
|
|
14
|
+
* runWithRequestId('req-123', () => {
|
|
15
|
+
* // Inside this callback, getRequestId() returns 'req-123'
|
|
16
|
+
* logger.log('Processing request') // Will include request ID if logger is configured
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* // Get current request ID (returns undefined if not in a request context)
|
|
20
|
+
* const currentId = getRequestId()
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const requestIdStore = new AsyncLocalStorage<string>()
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Runs a function with a request ID in the async local storage context.
|
|
27
|
+
*
|
|
28
|
+
* @param requestId - The request ID to set for this context
|
|
29
|
+
* @param fn - The function to run within this context
|
|
30
|
+
* @returns The return value of the function
|
|
31
|
+
*/
|
|
32
|
+
export function runWithRequestId<R>(requestId: string, fn: () => R): R {
|
|
33
|
+
return requestIdStore.run(requestId, fn)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Gets the current request ID from the async local storage context.
|
|
38
|
+
*
|
|
39
|
+
* @returns The current request ID, or undefined if not in a request context
|
|
40
|
+
*/
|
|
41
|
+
export function getRequestId(): string | undefined {
|
|
42
|
+
return requestIdStore.getStore()
|
|
43
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import type { ClassType, ClassTypeWithInstance, InjectionToken } from '@navios/di'
|
|
2
|
+
import type { NaviosModule } from '../interfaces/index.mjs'
|
|
3
|
+
import type { NaviosApplicationOptions } from '../navios.application.mjs'
|
|
4
|
+
|
|
5
|
+
import { TestContainer } from '@navios/di/testing'
|
|
6
|
+
|
|
7
|
+
import { NaviosApplication } from '../navios.application.mjs'
|
|
8
|
+
import { NaviosFactory } from '../navios.factory.mjs'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Configuration for overriding a provider in the testing module.
|
|
12
|
+
*
|
|
13
|
+
* @typeParam T - The type of the provider being overridden
|
|
14
|
+
*/
|
|
15
|
+
export interface TestingModuleOverride<T = any> {
|
|
16
|
+
/**
|
|
17
|
+
* The injection token or class to override.
|
|
18
|
+
*/
|
|
19
|
+
token: ClassType | InjectionToken<T, any>
|
|
20
|
+
/**
|
|
21
|
+
* Value to use instead of the original provider.
|
|
22
|
+
*/
|
|
23
|
+
useValue?: T
|
|
24
|
+
/**
|
|
25
|
+
* Class to use instead of the original provider.
|
|
26
|
+
*/
|
|
27
|
+
useClass?: ClassType
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Options for creating a testing module.
|
|
32
|
+
*
|
|
33
|
+
* Extends NaviosApplicationOptions but excludes the container option,
|
|
34
|
+
* as TestingModule manages its own TestContainer.
|
|
35
|
+
*/
|
|
36
|
+
export interface TestingModuleOptions
|
|
37
|
+
extends Omit<NaviosApplicationOptions, 'container'> {
|
|
38
|
+
/**
|
|
39
|
+
* Initial provider overrides to apply when creating the testing module.
|
|
40
|
+
*
|
|
41
|
+
* You can also use `overrideProvider()` method for a fluent API.
|
|
42
|
+
*/
|
|
43
|
+
overrides?: TestingModuleOverride[]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* A testing-optimized wrapper around NaviosApplication.
|
|
48
|
+
* Provides utilities for setting up test environments with mock dependencies.
|
|
49
|
+
*/
|
|
50
|
+
export class TestingModule {
|
|
51
|
+
private app: NaviosApplication | null = null
|
|
52
|
+
|
|
53
|
+
constructor(
|
|
54
|
+
private readonly appModule: ClassTypeWithInstance<NaviosModule>,
|
|
55
|
+
private readonly container: TestContainer,
|
|
56
|
+
private readonly options: TestingModuleOptions,
|
|
57
|
+
) {}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Compiles the testing module and returns the NaviosApplication.
|
|
61
|
+
* Call this after setting up all overrides.
|
|
62
|
+
*/
|
|
63
|
+
async compile(): Promise<NaviosApplication> {
|
|
64
|
+
this.app = await NaviosFactory.create(this.appModule, {
|
|
65
|
+
...this.options,
|
|
66
|
+
container: this.container,
|
|
67
|
+
})
|
|
68
|
+
return this.app
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Initializes the application (loads modules, sets up HTTP if configured).
|
|
73
|
+
* This is equivalent to calling app.init() on the compiled application.
|
|
74
|
+
*/
|
|
75
|
+
async init(): Promise<NaviosApplication> {
|
|
76
|
+
if (!this.app) {
|
|
77
|
+
await this.compile()
|
|
78
|
+
}
|
|
79
|
+
await this.app!.init()
|
|
80
|
+
return this.app!
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Gets the underlying TestContainer for direct manipulation.
|
|
85
|
+
*/
|
|
86
|
+
getContainer(): TestContainer {
|
|
87
|
+
return this.container
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Gets the compiled application. Throws if not yet compiled.
|
|
92
|
+
*/
|
|
93
|
+
getApplication(): NaviosApplication {
|
|
94
|
+
if (!this.app) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
'TestingModule not compiled. Call compile() or init() first.',
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
return this.app
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Override a provider with a mock value.
|
|
104
|
+
*/
|
|
105
|
+
overrideProvider<T>(token: ClassType | InjectionToken<T, any>): {
|
|
106
|
+
useValue: (value: T) => TestingModule
|
|
107
|
+
useClass: (target: ClassType) => TestingModule
|
|
108
|
+
} {
|
|
109
|
+
return {
|
|
110
|
+
useValue: (value: T) => {
|
|
111
|
+
this.container.bind(token as any).toValue(value)
|
|
112
|
+
return this
|
|
113
|
+
},
|
|
114
|
+
useClass: (target: ClassType) => {
|
|
115
|
+
this.container.bind(token as any).toClass(target)
|
|
116
|
+
return this
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Gets an instance from the container.
|
|
123
|
+
*/
|
|
124
|
+
async get<T>(token: ClassTypeWithInstance<T> | InjectionToken<T, any>): Promise<T> {
|
|
125
|
+
return this.container.get(token as any)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Disposes the testing module and cleans up resources.
|
|
130
|
+
*/
|
|
131
|
+
async close(): Promise<void> {
|
|
132
|
+
if (this.app) {
|
|
133
|
+
await this.app.close()
|
|
134
|
+
}
|
|
135
|
+
await this.container.dispose()
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Fluent builder interface for TestingModule.
|
|
141
|
+
*
|
|
142
|
+
* Provides a chainable API for configuring and using a testing module.
|
|
143
|
+
*/
|
|
144
|
+
export interface TestingModuleBuilder {
|
|
145
|
+
/**
|
|
146
|
+
* Override a provider with a mock value or class.
|
|
147
|
+
*
|
|
148
|
+
* @param token - The injection token or class to override
|
|
149
|
+
* @returns An object with `useValue` and `useClass` methods for chaining
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const testingModule = await createTestingModule(AppModule)
|
|
154
|
+
* .overrideProvider(DatabaseService)
|
|
155
|
+
* .useValue(mockDatabaseService)
|
|
156
|
+
* .compile()
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
overrideProvider<T>(token: ClassType | InjectionToken<T, any>): {
|
|
160
|
+
useValue: (value: T) => TestingModuleBuilder
|
|
161
|
+
useClass: (target: ClassType) => TestingModuleBuilder
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Compiles the testing module and returns the NaviosApplication.
|
|
166
|
+
*
|
|
167
|
+
* This creates the application instance but does not initialize it.
|
|
168
|
+
* Call `init()` if you need the application to be fully initialized.
|
|
169
|
+
*/
|
|
170
|
+
compile(): Promise<NaviosApplication>
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Initializes the application (loads modules, sets up HTTP if configured).
|
|
174
|
+
*
|
|
175
|
+
* This is equivalent to calling `compile()` followed by `app.init()`.
|
|
176
|
+
*/
|
|
177
|
+
init(): Promise<NaviosApplication>
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Gets the underlying TestContainer for direct manipulation.
|
|
181
|
+
*/
|
|
182
|
+
getContainer(): TestContainer
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Gets an instance from the container.
|
|
186
|
+
*
|
|
187
|
+
* @typeParam T - The type of the instance to retrieve
|
|
188
|
+
* @param token - The injection token or class
|
|
189
|
+
* @returns The resolved instance
|
|
190
|
+
*/
|
|
191
|
+
get<T>(token: ClassTypeWithInstance<T> | InjectionToken<T, any>): Promise<T>
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Disposes the testing module and cleans up resources.
|
|
195
|
+
*/
|
|
196
|
+
close(): Promise<void>
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Creates a testing module for the given app module.
|
|
201
|
+
* This is the main entry point for setting up tests.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* const testingModule = await createTestingModule(AppModule, {
|
|
206
|
+
* adapter: [],
|
|
207
|
+
* })
|
|
208
|
+
* .overrideProvider(DatabaseService)
|
|
209
|
+
* .useValue(mockDatabaseService)
|
|
210
|
+
* .compile()
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
export function createTestingModule(
|
|
214
|
+
appModule: ClassTypeWithInstance<NaviosModule>,
|
|
215
|
+
options: TestingModuleOptions = { adapter: [] },
|
|
216
|
+
): TestingModule {
|
|
217
|
+
const container = new TestContainer()
|
|
218
|
+
|
|
219
|
+
// Apply initial overrides if provided
|
|
220
|
+
if (options.overrides) {
|
|
221
|
+
for (const override of options.overrides) {
|
|
222
|
+
if (override.useValue !== undefined) {
|
|
223
|
+
container.bind(override.token as any).toValue(override.useValue)
|
|
224
|
+
} else if (override.useClass) {
|
|
225
|
+
container.bind(override.token as any).toClass(override.useClass)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return new TestingModule(appModule, container, options)
|
|
231
|
+
}
|
package/tsconfig.lib.json
CHANGED
package/tsconfig.spec.json
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { withFilter } from 'rolldown/filter'
|
|
2
|
+
import { defineConfig } from 'tsdown'
|
|
3
|
+
import swc from 'unplugin-swc'
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
entry: ['src/index.mts', 'src/testing/index.mts', 'src/legacy-compat/index.mts'],
|
|
7
|
+
outDir: 'lib',
|
|
8
|
+
format: ['esm', 'cjs'],
|
|
9
|
+
clean: true,
|
|
10
|
+
tsconfig: 'tsconfig.lib.json',
|
|
11
|
+
treeshake: true,
|
|
12
|
+
sourcemap: true,
|
|
13
|
+
platform: 'node',
|
|
14
|
+
external: ['@navios/di'],
|
|
15
|
+
dts: true,
|
|
16
|
+
target: 'es2022',
|
|
17
|
+
plugins: [
|
|
18
|
+
withFilter(
|
|
19
|
+
swc.rolldown({
|
|
20
|
+
jsc: {
|
|
21
|
+
target: 'es2022',
|
|
22
|
+
parser: {
|
|
23
|
+
syntax: 'typescript',
|
|
24
|
+
decorators: true,
|
|
25
|
+
},
|
|
26
|
+
transform: {
|
|
27
|
+
decoratorVersion: '2022-03',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
}),
|
|
31
|
+
// Only run this transform if the file contains a decorator.
|
|
32
|
+
{ transform: { code: '@' } },
|
|
33
|
+
),
|
|
34
|
+
],
|
|
35
|
+
})
|
package/vitest.config.mts
CHANGED