@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.
Files changed (102) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +18 -1
  3. package/docs/README.md +1 -0
  4. package/docs/legacy-compat.md +320 -0
  5. package/docs/testing.md +140 -17
  6. package/lib/index-DW9EPAE6.d.mts +2156 -0
  7. package/lib/index-DW9EPAE6.d.mts.map +1 -0
  8. package/lib/index-pHp-dIGt.d.cts +2156 -0
  9. package/lib/index-pHp-dIGt.d.cts.map +1 -0
  10. package/lib/index.cjs +157 -0
  11. package/lib/index.d.cts +3 -0
  12. package/lib/index.d.mts +3 -190
  13. package/lib/index.mjs +4 -1459
  14. package/lib/legacy-compat/index.cjs +315 -0
  15. package/lib/legacy-compat/index.cjs.map +1 -0
  16. package/lib/legacy-compat/index.d.cts +219 -0
  17. package/lib/legacy-compat/index.d.cts.map +1 -0
  18. package/lib/legacy-compat/index.d.mts +219 -0
  19. package/lib/legacy-compat/index.d.mts.map +1 -0
  20. package/lib/legacy-compat/index.mjs +308 -0
  21. package/lib/legacy-compat/index.mjs.map +1 -0
  22. package/lib/src-DyvCDuKO.mjs +5443 -0
  23. package/lib/src-DyvCDuKO.mjs.map +1 -0
  24. package/lib/src-QnxR5b7c.cjs +5800 -0
  25. package/lib/src-QnxR5b7c.cjs.map +1 -0
  26. package/lib/testing/index.cjs +106 -0
  27. package/lib/testing/index.cjs.map +1 -0
  28. package/lib/testing/index.d.cts +156 -0
  29. package/lib/testing/index.d.cts.map +1 -0
  30. package/lib/testing/index.d.mts +156 -0
  31. package/lib/testing/index.d.mts.map +1 -0
  32. package/lib/testing/index.mjs +100 -0
  33. package/lib/testing/index.mjs.map +1 -0
  34. package/lib/use-guards.decorator-B6q_N0sf.cjs +622 -0
  35. package/lib/use-guards.decorator-B6q_N0sf.cjs.map +1 -0
  36. package/lib/use-guards.decorator-kZ3lNK8v.mjs +454 -0
  37. package/lib/use-guards.decorator-kZ3lNK8v.mjs.map +1 -0
  38. package/package.json +28 -8
  39. package/project.json +2 -2
  40. package/src/attribute.factory.mts +154 -0
  41. package/src/config/config-service.interface.mts +31 -0
  42. package/src/config/config.provider.mts +36 -0
  43. package/src/config/config.service.mts +94 -4
  44. package/src/decorators/controller.decorator.mts +28 -0
  45. package/src/decorators/endpoint.decorator.mts +76 -0
  46. package/src/decorators/header.decorator.mts +19 -0
  47. package/src/decorators/http-code.decorator.mts +20 -0
  48. package/src/decorators/module.decorator.mts +34 -0
  49. package/src/decorators/multipart.decorator.mts +41 -0
  50. package/src/decorators/stream.decorator.mts +33 -0
  51. package/src/decorators/use-guards.decorator.mts +29 -0
  52. package/src/exceptions/bad-request.exception.mts +21 -0
  53. package/src/exceptions/conflict.exception.mts +24 -0
  54. package/src/exceptions/forbidden.exception.mts +23 -0
  55. package/src/exceptions/http.exception.mts +26 -0
  56. package/src/exceptions/internal-server-error.exception.mts +26 -0
  57. package/src/exceptions/not-found.exception.mts +23 -0
  58. package/src/exceptions/unauthorized.exception.mts +23 -0
  59. package/src/index.mts +1 -0
  60. package/src/interfaces/abstract-execution-context.inteface.mts +35 -0
  61. package/src/interfaces/abstract-http-adapter.interface.mts +52 -0
  62. package/src/interfaces/abstract-http-handler-adapter.interface.mts +2 -2
  63. package/src/interfaces/can-activate.mts +31 -0
  64. package/src/interfaces/index.mts +1 -0
  65. package/src/interfaces/navios-module.mts +25 -0
  66. package/src/interfaces/plugin.interface.mts +105 -0
  67. package/src/legacy-compat/__type-tests__/legacy-decorators.spec-d.mts +420 -0
  68. package/src/legacy-compat/__type-tests__/tsconfig.json +15 -0
  69. package/src/legacy-compat/context-compat.mts +93 -0
  70. package/src/legacy-compat/decorators/controller.decorator.mts +31 -0
  71. package/src/legacy-compat/decorators/endpoint.decorator.mts +99 -0
  72. package/src/legacy-compat/decorators/header.decorator.mts +42 -0
  73. package/src/legacy-compat/decorators/http-code.decorator.mts +38 -0
  74. package/src/legacy-compat/decorators/index.mts +9 -0
  75. package/src/legacy-compat/decorators/module.decorator.mts +37 -0
  76. package/src/legacy-compat/decorators/multipart.decorator.mts +93 -0
  77. package/src/legacy-compat/decorators/stream.decorator.mts +76 -0
  78. package/src/legacy-compat/decorators/use-guards.decorator.mts +80 -0
  79. package/src/legacy-compat/index.mts +40 -0
  80. package/src/logger/console-logger.service.mts +15 -2
  81. package/src/logger/log-levels.mts +9 -0
  82. package/src/logger/logger.service.mts +21 -0
  83. package/src/logger/logger.tokens.mts +23 -0
  84. package/src/navios.application.mts +228 -4
  85. package/src/navios.factory.mts +60 -1
  86. package/src/services/guard-runner.service.mts +12 -11
  87. package/src/services/module-loader.service.mts +118 -12
  88. package/src/stores/index.mts +1 -0
  89. package/src/stores/request-id.store.mts +43 -0
  90. package/src/testing/index.mts +2 -0
  91. package/src/testing/testing-module.mts +231 -0
  92. package/tsconfig.lib.json +1 -1
  93. package/tsconfig.spec.json +3 -0
  94. package/tsdown.config.mts +35 -0
  95. package/vitest.config.mts +6 -0
  96. package/lib/_tsup-dts-rollup.d.mts +0 -1365
  97. package/lib/_tsup-dts-rollup.d.ts +0 -1365
  98. package/lib/index.d.ts +0 -190
  99. package/lib/index.js +0 -1540
  100. package/lib/index.js.map +0 -1
  101. package/lib/index.mjs.map +0 -1
  102. package/tsup.config.mts +0 -13
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Compatibility layer for converting legacy decorator signatures to Stage 3 format.
3
+ *
4
+ * This module provides utilities to create mock Stage 3 decorator contexts
5
+ * from legacy decorator arguments, and manages metadata storage using WeakMap.
6
+ */
7
+
8
+ import type { ClassType } from '@navios/di'
9
+
10
+ // WeakMap to store metadata for legacy decorators
11
+ // Keyed by class constructor for class decorators
12
+ // For method decorators, we use the class constructor (extracted from the prototype)
13
+ const classMetadataMap = new WeakMap<ClassType, Record<string | symbol, any>>()
14
+
15
+ /**
16
+ * Gets the constructor from a prototype (for method decorators).
17
+ */
18
+ function getConstructor(prototype: any): ClassType | null {
19
+ if (!prototype || typeof prototype !== 'object') {
20
+ return null
21
+ }
22
+ // In legacy decorators, target is the prototype
23
+ // The constructor is typically available via prototype.constructor
24
+ const constructor = prototype.constructor
25
+ if (constructor && typeof constructor === 'function') {
26
+ return constructor as ClassType
27
+ }
28
+ return null
29
+ }
30
+
31
+ /**
32
+ * Creates a mock ClassDecoratorContext for legacy class decorators.
33
+ */
34
+ export function createClassContext(target: ClassType): ClassDecoratorContext {
35
+ // Get or create metadata storage for this class
36
+ if (!classMetadataMap.has(target)) {
37
+ classMetadataMap.set(target, {})
38
+ }
39
+ const metadata = classMetadataMap.get(target)!
40
+
41
+ return {
42
+ kind: 'class',
43
+ name: target.name,
44
+ metadata,
45
+ addInitializer() {
46
+ // Legacy decorators don't support initializers
47
+ },
48
+ } as ClassDecoratorContext
49
+ }
50
+
51
+ /**
52
+ * Creates a mock ClassMethodDecoratorContext for legacy method decorators.
53
+ *
54
+ * Note: Method decorators need to share metadata with the class context
55
+ * because endpoint metadata is stored at the class level.
56
+ */
57
+ export function createMethodContext(
58
+ target: any,
59
+ propertyKey: string | symbol,
60
+ descriptor: PropertyDescriptor,
61
+ ): ClassMethodDecoratorContext {
62
+ // For method decorators, target is the prototype
63
+ // We need to get the class constructor to access class-level metadata
64
+ const constructor = getConstructor(target)
65
+ if (!constructor) {
66
+ throw new Error(
67
+ '[Navios] Could not determine class constructor from method decorator target.',
68
+ )
69
+ }
70
+
71
+ // Get or create metadata storage for the class
72
+ // Method decorators share metadata with the class
73
+ if (!classMetadataMap.has(constructor)) {
74
+ classMetadataMap.set(constructor, {})
75
+ }
76
+ const metadata = classMetadataMap.get(constructor)!
77
+
78
+ return {
79
+ kind: 'method',
80
+ name: propertyKey,
81
+ metadata,
82
+ static: false, // We can't determine this from legacy decorators
83
+ private: false, // We can't determine this from legacy decorators
84
+ access: {
85
+ has: () => true,
86
+ get: () => descriptor.value,
87
+ set: () => {},
88
+ },
89
+ addInitializer() {
90
+ // Legacy decorators don't support initializers
91
+ },
92
+ } as ClassMethodDecoratorContext
93
+ }
@@ -0,0 +1,31 @@
1
+ import type { ClassType } from '@navios/di'
2
+
3
+ import type { ControllerOptions } from '../../decorators/controller.decorator.mjs'
4
+
5
+ import { Controller as OriginalController } from '../../decorators/controller.decorator.mjs'
6
+ import { createClassContext } from '../context-compat.mjs'
7
+
8
+ /**
9
+ * Legacy-compatible Controller decorator.
10
+ *
11
+ * Works with TypeScript experimental decorators (legacy API).
12
+ *
13
+ * @param options - Controller configuration options
14
+ * @returns A class decorator compatible with legacy decorator API
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * @Controller({ guards: [AuthGuard] })
19
+ * export class UserController {
20
+ * @Endpoint(getUserEndpoint)
21
+ * async getUser() { }
22
+ * }
23
+ * ```
24
+ */
25
+ export function Controller(options: ControllerOptions = {}) {
26
+ return function (target: ClassType) {
27
+ const context = createClassContext(target)
28
+ const originalDecorator = OriginalController(options)
29
+ return originalDecorator(target, context)
30
+ }
31
+ }
@@ -0,0 +1,99 @@
1
+ import type {
2
+ BaseEndpointConfig,
3
+ EndpointFunctionArgs,
4
+ HttpMethod,
5
+ } from '@navios/builder'
6
+ import type { z, ZodType } from 'zod/v4'
7
+
8
+ import { Endpoint as OriginalEndpoint } from '../../decorators/endpoint.decorator.mjs'
9
+ import { createMethodContext } from '../context-compat.mjs'
10
+
11
+ /**
12
+ * Type helper to constrain a PropertyDescriptor's value to match an endpoint signature.
13
+ * Note: In legacy decorators, type constraints are checked when the decorator is applied,
14
+ * but may not be preserved perfectly when decorators are stacked.
15
+ */
16
+ type EndpointMethodDescriptor<
17
+ Url extends string,
18
+ QuerySchema,
19
+ RequestSchema,
20
+ ResponseSchema extends ZodType,
21
+ > = TypedPropertyDescriptor<
22
+ (
23
+ params: QuerySchema extends ZodType
24
+ ? RequestSchema extends ZodType
25
+ ? EndpointFunctionArgs<Url, QuerySchema, RequestSchema, true>
26
+ : EndpointFunctionArgs<Url, QuerySchema, undefined, true>
27
+ : RequestSchema extends ZodType
28
+ ? EndpointFunctionArgs<Url, undefined, RequestSchema, true>
29
+ : EndpointFunctionArgs<Url, undefined, undefined, true>,
30
+ ) => Promise<z.input<ResponseSchema>>
31
+ >
32
+
33
+ /**
34
+ * Legacy-compatible Endpoint decorator.
35
+ *
36
+ * Works with TypeScript experimental decorators (legacy API).
37
+ * Provides type safety by ensuring method signatures match the endpoint configuration.
38
+ *
39
+ * @param endpoint - The endpoint declaration from @navios/builder
40
+ * @returns A method decorator compatible with legacy decorator API
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * @Controller()
45
+ * export class UserController {
46
+ * @Endpoint(getUserEndpoint)
47
+ * async getUser(request: EndpointParams<typeof getUserEndpoint>): EndpointResult<typeof getUserEndpoint> {
48
+ * return { id: '1', name: 'John' }
49
+ * }
50
+ * }
51
+ * ```
52
+ */
53
+ export function Endpoint<
54
+ Method extends HttpMethod = HttpMethod,
55
+ Url extends string = string,
56
+ QuerySchema = undefined,
57
+ ResponseSchema extends ZodType = ZodType,
58
+ RequestSchema = ZodType,
59
+ >(endpoint: {
60
+ config: BaseEndpointConfig<
61
+ Method,
62
+ Url,
63
+ QuerySchema,
64
+ ResponseSchema,
65
+ RequestSchema
66
+ >
67
+ }) {
68
+ return function (
69
+ target: any,
70
+ propertyKey: string | symbol,
71
+ descriptor: EndpointMethodDescriptor<
72
+ Url,
73
+ QuerySchema,
74
+ RequestSchema,
75
+ ResponseSchema
76
+ >,
77
+ ): PropertyDescriptor | void {
78
+ if (!descriptor) {
79
+ throw new Error(
80
+ '[Navios] @Endpoint decorator requires a method descriptor. Make sure experimentalDecorators is enabled.',
81
+ )
82
+ }
83
+ // Type check the descriptor value matches expected signature
84
+ const typedDescriptor = descriptor as EndpointMethodDescriptor<
85
+ Url,
86
+ QuerySchema,
87
+ RequestSchema,
88
+ ResponseSchema
89
+ >
90
+ const context = createMethodContext(target, propertyKey, typedDescriptor)
91
+ const originalDecorator = OriginalEndpoint(endpoint)
92
+ // @ts-expect-error - we don't need to type the value
93
+ const result = originalDecorator(typedDescriptor.value, context)
94
+ if (result !== typedDescriptor.value) {
95
+ typedDescriptor.value = result
96
+ }
97
+ return typedDescriptor
98
+ }
99
+ }
@@ -0,0 +1,42 @@
1
+ import type { HttpHeader } from '../../interfaces/index.mjs'
2
+
3
+ import { Header as OriginalHeader } from '../../decorators/header.decorator.mjs'
4
+ import { createMethodContext } from '../context-compat.mjs'
5
+
6
+ /**
7
+ * Legacy-compatible Header decorator.
8
+ *
9
+ * Works with TypeScript experimental decorators (legacy API).
10
+ *
11
+ * @param name - The header name (e.g., 'Content-Type', 'Cache-Control')
12
+ * @param value - The header value (string, number, or array of strings)
13
+ * @returns A method decorator compatible with legacy decorator API
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * @Controller()
18
+ * export class UserController {
19
+ * @Endpoint(getUserEndpoint)
20
+ * @Header('Cache-Control', 'max-age=3600')
21
+ * async getUser() {
22
+ * return { id: '1', name: 'John' }
23
+ * }
24
+ * }
25
+ * ```
26
+ */
27
+ export function Header(name: HttpHeader, value: string | number | string[]) {
28
+ return function <T extends object>(
29
+ target: T,
30
+ propertyKey: string | symbol,
31
+ descriptor: PropertyDescriptor,
32
+ ) {
33
+ const context = createMethodContext(target, propertyKey, descriptor)
34
+ const originalDecorator = OriginalHeader(name, value)
35
+ const result = originalDecorator(descriptor.value, context)
36
+ if (result !== descriptor.value) {
37
+ descriptor.value = result
38
+ }
39
+ return descriptor
40
+ }
41
+ }
42
+
@@ -0,0 +1,38 @@
1
+ import { HttpCode as OriginalHttpCode } from '../../decorators/http-code.decorator.mjs'
2
+ import { createMethodContext } from '../context-compat.mjs'
3
+
4
+ /**
5
+ * Legacy-compatible HttpCode decorator.
6
+ *
7
+ * Works with TypeScript experimental decorators (legacy API).
8
+ *
9
+ * @param code - The HTTP status code to return (e.g., 201, 204, 202)
10
+ * @returns A method decorator compatible with legacy decorator API
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * @Controller()
15
+ * export class UserController {
16
+ * @Endpoint(createUserEndpoint)
17
+ * @HttpCode(201)
18
+ * async createUser() {
19
+ * return { id: '1', name: 'John' }
20
+ * }
21
+ * }
22
+ * ```
23
+ */
24
+ export function HttpCode(code: number) {
25
+ return function <T extends object>(
26
+ target: T,
27
+ propertyKey: string | symbol,
28
+ descriptor: PropertyDescriptor,
29
+ ) {
30
+ const context = createMethodContext(target, propertyKey, descriptor)
31
+ const originalDecorator = OriginalHttpCode(code)
32
+ const result = originalDecorator(descriptor.value, context)
33
+ if (result !== descriptor.value) {
34
+ descriptor.value = result
35
+ }
36
+ return descriptor
37
+ }
38
+ }
@@ -0,0 +1,9 @@
1
+ export * from './module.decorator.mjs'
2
+ export * from './controller.decorator.mjs'
3
+ export * from './endpoint.decorator.mjs'
4
+ export * from './use-guards.decorator.mjs'
5
+ export * from './header.decorator.mjs'
6
+ export * from './http-code.decorator.mjs'
7
+ export * from './multipart.decorator.mjs'
8
+ export * from './stream.decorator.mjs'
9
+
@@ -0,0 +1,37 @@
1
+ import type { ClassType } from '@navios/di'
2
+
3
+ import { Module as OriginalModule, type ModuleOptions } from '../../decorators/module.decorator.mjs'
4
+ import { createClassContext } from '../context-compat.mjs'
5
+
6
+ /**
7
+ * Legacy-compatible Module decorator.
8
+ *
9
+ * Works with TypeScript experimental decorators (legacy API).
10
+ *
11
+ * @param options - Module configuration options
12
+ * @returns A class decorator compatible with legacy decorator API
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * @Module({
17
+ * controllers: [UserController, AuthController],
18
+ * imports: [DatabaseModule],
19
+ * guards: [AuthGuard],
20
+ * })
21
+ * export class AppModule {}
22
+ * ```
23
+ */
24
+ export function Module(
25
+ options: ModuleOptions = {
26
+ controllers: [],
27
+ imports: [],
28
+ guards: [],
29
+ },
30
+ ) {
31
+ return function (target: ClassType) {
32
+ const context = createClassContext(target)
33
+ const originalDecorator = OriginalModule(options)
34
+ return originalDecorator(target, context)
35
+ }
36
+ }
37
+
@@ -0,0 +1,93 @@
1
+ import type {
2
+ BaseEndpointConfig,
3
+ EndpointFunctionArgs,
4
+ HttpMethod,
5
+ } from '@navios/builder'
6
+ import type { z, ZodObject, ZodType } from 'zod/v4'
7
+
8
+ import { Multipart as OriginalMultipart } from '../../decorators/multipart.decorator.mjs'
9
+ import { createMethodContext } from '../context-compat.mjs'
10
+
11
+ /**
12
+ * Type helper to constrain a PropertyDescriptor's value to match a multipart endpoint signature.
13
+ * Note: In legacy decorators, type constraints are checked when the decorator is applied,
14
+ * but may not be preserved perfectly when decorators are stacked.
15
+ */
16
+ type MultipartMethodDescriptor<
17
+ Url extends string,
18
+ QuerySchema,
19
+ RequestSchema,
20
+ ResponseSchema extends ZodType,
21
+ > = TypedPropertyDescriptor<
22
+ (
23
+ params: QuerySchema extends ZodObject
24
+ ? RequestSchema extends ZodType
25
+ ? EndpointFunctionArgs<Url, QuerySchema, RequestSchema>
26
+ : EndpointFunctionArgs<Url, QuerySchema, undefined>
27
+ : RequestSchema extends ZodType
28
+ ? EndpointFunctionArgs<Url, undefined, RequestSchema>
29
+ : EndpointFunctionArgs<Url, undefined, undefined>,
30
+ ) => Promise<z.input<ResponseSchema>>
31
+ >
32
+
33
+ /**
34
+ * Legacy-compatible Multipart decorator.
35
+ *
36
+ * Works with TypeScript experimental decorators (legacy API).
37
+ * Provides type safety by ensuring method signatures match the endpoint configuration.
38
+ *
39
+ * @param endpoint - The multipart endpoint declaration from @navios/builder
40
+ * @returns A method decorator compatible with legacy decorator API
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * @Controller()
45
+ * export class FileController {
46
+ * @Multipart(uploadFileEndpoint)
47
+ * async uploadFile(request: MultipartParams<typeof uploadFileEndpoint>): MultipartResult<typeof uploadFileEndpoint> {
48
+ * const { file } = request.data
49
+ * return { url: 'https://example.com/file.jpg' }
50
+ * }
51
+ * }
52
+ * ```
53
+ */
54
+ export function Multipart<
55
+ Method extends HttpMethod = HttpMethod,
56
+ Url extends string = string,
57
+ QuerySchema = undefined,
58
+ ResponseSchema extends ZodType = ZodType,
59
+ RequestSchema = ZodType,
60
+ >(endpoint: {
61
+ config: BaseEndpointConfig<
62
+ Method,
63
+ Url,
64
+ QuerySchema,
65
+ ResponseSchema,
66
+ RequestSchema
67
+ >
68
+ }) {
69
+ return function <T extends object>(
70
+ target: T,
71
+ propertyKey: string | symbol,
72
+ descriptor: MultipartMethodDescriptor<
73
+ Url,
74
+ QuerySchema,
75
+ RequestSchema,
76
+ ResponseSchema
77
+ >,
78
+ ): PropertyDescriptor | void {
79
+ if (!descriptor) {
80
+ throw new Error(
81
+ '[Navios] @Multipart decorator requires a method descriptor. Make sure experimentalDecorators is enabled.',
82
+ )
83
+ }
84
+ const context = createMethodContext(target, propertyKey, descriptor)
85
+ const originalDecorator = OriginalMultipart(endpoint)
86
+ // @ts-expect-error - we don't need to type the value
87
+ const result = originalDecorator(descriptor.value, context)
88
+ if (result !== descriptor.value) {
89
+ descriptor.value = result
90
+ }
91
+ return descriptor
92
+ }
93
+ }
@@ -0,0 +1,76 @@
1
+ import type {
2
+ BaseStreamConfig,
3
+ EndpointFunctionArgs,
4
+ HttpMethod,
5
+ } from '@navios/builder'
6
+ import type { ZodObject, ZodType } from 'zod/v4'
7
+
8
+ import { Stream as OriginalStream } from '../../decorators/stream.decorator.mjs'
9
+ import { createMethodContext } from '../context-compat.mjs'
10
+
11
+ /**
12
+ * Type helper to constrain a PropertyDescriptor's value to match a stream endpoint signature.
13
+ * Note: In legacy decorators, type constraints are checked when the decorator is applied,
14
+ * but may not be preserved perfectly when decorators are stacked.
15
+ */
16
+ type StreamMethodDescriptor<
17
+ Url extends string,
18
+ QuerySchema,
19
+ RequestSchema,
20
+ > = TypedPropertyDescriptor<
21
+ (
22
+ params: QuerySchema extends ZodObject
23
+ ? RequestSchema extends ZodType
24
+ ? EndpointFunctionArgs<Url, QuerySchema, RequestSchema>
25
+ : EndpointFunctionArgs<Url, QuerySchema, undefined>
26
+ : RequestSchema extends ZodType
27
+ ? EndpointFunctionArgs<Url, undefined, RequestSchema>
28
+ : EndpointFunctionArgs<Url, undefined, undefined>,
29
+ reply: any,
30
+ ) => Promise<void>
31
+ >
32
+
33
+ /**
34
+ * Legacy-compatible Stream decorator.
35
+ *
36
+ * Works with TypeScript experimental decorators (legacy API).
37
+ * Provides type safety by ensuring method signatures match the endpoint configuration.
38
+ *
39
+ * @param endpoint - The stream endpoint declaration from @navios/builder
40
+ * @returns A method decorator compatible with legacy decorator API
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * @Controller()
45
+ * export class FileController {
46
+ * @Stream(downloadFileEndpoint)
47
+ * async downloadFile(request: StreamParams<typeof downloadFileEndpoint>, reply: any) {
48
+ * const { fileId } = request.urlParams
49
+ * // Stream file data to reply
50
+ * }
51
+ * }
52
+ * ```
53
+ */
54
+ export function Stream<
55
+ Method extends HttpMethod = HttpMethod,
56
+ Url extends string = string,
57
+ QuerySchema = undefined,
58
+ RequestSchema = ZodType,
59
+ >(endpoint: {
60
+ config: BaseStreamConfig<Method, Url, QuerySchema, RequestSchema>
61
+ }) {
62
+ return function <T extends object>(
63
+ target: T,
64
+ propertyKey: string | symbol,
65
+ descriptor: StreamMethodDescriptor<Url, QuerySchema, RequestSchema>,
66
+ ) {
67
+ const context = createMethodContext(target, propertyKey, descriptor)
68
+ const originalDecorator = OriginalStream(endpoint)
69
+ // @ts-expect-error - we don't need to type the value
70
+ const result = originalDecorator(descriptor.value, context)
71
+ if (result !== descriptor.value) {
72
+ descriptor.value = result
73
+ }
74
+ return descriptor
75
+ }
76
+ }
@@ -0,0 +1,80 @@
1
+ import type {
2
+ ClassType,
3
+ ClassTypeWithInstance,
4
+ InjectionToken,
5
+ } from '@navios/di'
6
+
7
+ import type { CanActivate } from '../../interfaces/index.mjs'
8
+
9
+ import { UseGuards as OriginalUseGuards } from '../../decorators/use-guards.decorator.mjs'
10
+ import { createClassContext, createMethodContext } from '../context-compat.mjs'
11
+
12
+ /**
13
+ * Legacy-compatible UseGuards decorator.
14
+ *
15
+ * Works with TypeScript experimental decorators (legacy API).
16
+ * Can be applied to classes or methods.
17
+ *
18
+ * @param guards - Guard classes or injection tokens to apply
19
+ * @returns A class or method decorator compatible with legacy decorator API
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // Apply to a controller
24
+ * @Controller()
25
+ * @UseGuards(AuthGuard, RoleGuard)
26
+ * export class UserController { }
27
+ *
28
+ * // Apply to a specific endpoint
29
+ * @Controller()
30
+ * export class UserController {
31
+ * @Endpoint(getUserEndpoint)
32
+ * @UseGuards(AuthGuard)
33
+ * async getUser() { }
34
+ * }
35
+ * ```
36
+ */
37
+ export function UseGuards(
38
+ ...guards: (
39
+ | ClassTypeWithInstance<CanActivate>
40
+ | InjectionToken<CanActivate, undefined>
41
+ )[]
42
+ ) {
43
+ // Create the decorator function
44
+ // Note: TypeScript's legacy decorator system has strict type checking for decorators
45
+ // We use a flexible implementation that works for both class and method decorators
46
+ function decoratorImpl(
47
+ target: ClassType | Function,
48
+ propertyKey?: string | symbol,
49
+ descriptor?: PropertyDescriptor,
50
+ ): any {
51
+ // Determine if this is a class or method decorator
52
+ if (propertyKey !== undefined && descriptor !== undefined) {
53
+ // Method decorator
54
+ const context = createMethodContext(
55
+ target as Function,
56
+ propertyKey,
57
+ descriptor,
58
+ )
59
+ const originalDecorator = OriginalUseGuards(...guards)
60
+ const result = originalDecorator(descriptor.value, context)
61
+ if (result !== descriptor.value) {
62
+ descriptor.value = result
63
+ }
64
+ return descriptor
65
+ } else {
66
+ // Class decorator
67
+ const context = createClassContext(target as ClassType)
68
+ const originalDecorator = OriginalUseGuards(...guards)
69
+ return originalDecorator(target as ClassType, context)
70
+ }
71
+ }
72
+
73
+ // Return with 'any' type to work around TypeScript's strict decorator checking
74
+ // TypeScript's legacy decorator system cannot properly type-check decorators
75
+ // that work as both class and method decorators. The runtime behavior is correct.
76
+ // When used as a class decorator, it returns the class (preserving type at runtime)
77
+ // When used as a method decorator, it returns the PropertyDescriptor
78
+ // @ts-ignore - TypeScript limitation with dual-purpose legacy decorators
79
+ return decoratorImpl as any
80
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Legacy-compatible decorators for projects that cannot use Stage 3 decorators.
3
+ *
4
+ * These decorators use the TypeScript experimental decorator API and convert
5
+ * the arguments to Stage 3 format internally.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { Module, Controller, Endpoint } from '@navios/core/legacy-compat'
10
+ *
11
+ * @Module({
12
+ * controllers: [UserController],
13
+ * })
14
+ * export class AppModule {}
15
+ * ```
16
+ */
17
+
18
+ // Re-export types
19
+ export type {
20
+ ModuleOptions,
21
+ ControllerOptions,
22
+ EndpointParams,
23
+ EndpointResult,
24
+ MultipartParams,
25
+ MultipartResult,
26
+ StreamParams,
27
+ } from '../decorators/index.mjs'
28
+
29
+ // Export legacy-compatible decorators
30
+ export {
31
+ Module,
32
+ Controller,
33
+ Endpoint,
34
+ UseGuards,
35
+ Header,
36
+ HttpCode,
37
+ Multipart,
38
+ Stream,
39
+ } from './decorators/index.mjs'
40
+
@@ -7,6 +7,7 @@ import { Injectable } from '@navios/di'
7
7
  import type { LogLevel } from './log-levels.mjs'
8
8
  import type { LoggerService } from './logger-service.interface.mjs'
9
9
 
10
+ import { getRequestId } from '../stores/request-id.store.mjs'
10
11
  import { LoggerOutput } from './logger.tokens.mjs'
11
12
  import {
12
13
  clc,
@@ -312,6 +313,17 @@ export class ConsoleLogger implements LoggerService {
312
313
  return isLogLevelEnabled(level, logLevels)
313
314
  }
314
315
 
316
+ /**
317
+ * Gets the current request ID from the AsyncLocalStorage store.
318
+ * Only returns a value if the requestId option is enabled.
319
+ */
320
+ protected getCurrentRequestId(): string | undefined {
321
+ if (!this.options.requestId) {
322
+ return undefined
323
+ }
324
+ return getRequestId()
325
+ }
326
+
315
327
  protected getTimestamp(): string {
316
328
  return dateTimeFormatter.format(Date.now())
317
329
  }
@@ -324,6 +336,7 @@ export class ConsoleLogger implements LoggerService {
324
336
  writeStreamType?: 'stdout' | 'stderr',
325
337
  errorStack?: unknown,
326
338
  ) {
339
+ const resolvedRequestId = requestId ?? this.getCurrentRequestId()
327
340
  messages.forEach((message) => {
328
341
  if (this.options.json) {
329
342
  this.printAsJson(message, {
@@ -331,7 +344,7 @@ export class ConsoleLogger implements LoggerService {
331
344
  logLevel,
332
345
  writeStreamType,
333
346
  errorStack,
334
- requestId,
347
+ requestId: resolvedRequestId,
335
348
  })
336
349
  return
337
350
  }
@@ -346,7 +359,7 @@ export class ConsoleLogger implements LoggerService {
346
359
  formattedLogLevel,
347
360
  contextMessage,
348
361
  timestampDiff,
349
- requestId,
362
+ resolvedRequestId,
350
363
  )
351
364
 
352
365
  process[writeStreamType ?? 'stdout'].write(formattedMessage)