node-honest 0.0.7 → 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.
Files changed (163) hide show
  1. package/dist/index.cjs +2185 -0
  2. package/dist/index.d.cts +1539 -0
  3. package/dist/index.d.ts +1539 -16
  4. package/dist/index.js +2116 -15
  5. package/package.json +12 -9
  6. package/dist/application/plugin-entries.d.ts +0 -13
  7. package/dist/application/plugin-entries.js +0 -38
  8. package/dist/application/startup-guide.d.ts +0 -4
  9. package/dist/application/startup-guide.js +0 -53
  10. package/dist/application-context.d.ts +0 -13
  11. package/dist/application-context.js +0 -22
  12. package/dist/application.d.ts +0 -34
  13. package/dist/application.js +0 -224
  14. package/dist/components/index.d.ts +0 -1
  15. package/dist/components/index.js +0 -1
  16. package/dist/components/layout.component.d.ts +0 -31
  17. package/dist/components/layout.component.js +0 -94
  18. package/dist/constants/index.d.ts +0 -2
  19. package/dist/constants/index.js +0 -2
  20. package/dist/constants/pipeline.constants.d.ts +0 -6
  21. package/dist/constants/pipeline.constants.js +0 -6
  22. package/dist/constants/version.constants.d.ts +0 -5
  23. package/dist/constants/version.constants.js +0 -5
  24. package/dist/decorators/controller.decorator.d.ts +0 -9
  25. package/dist/decorators/controller.decorator.js +0 -16
  26. package/dist/decorators/http-method.decorator.d.ts +0 -43
  27. package/dist/decorators/http-method.decorator.js +0 -44
  28. package/dist/decorators/index.d.ts +0 -11
  29. package/dist/decorators/index.js +0 -11
  30. package/dist/decorators/module.decorator.d.ts +0 -8
  31. package/dist/decorators/module.decorator.js +0 -12
  32. package/dist/decorators/mvc.decorator.d.ts +0 -26
  33. package/dist/decorators/mvc.decorator.js +0 -36
  34. package/dist/decorators/parameter.decorator.d.ts +0 -41
  35. package/dist/decorators/parameter.decorator.js +0 -59
  36. package/dist/decorators/service.decorator.d.ts +0 -6
  37. package/dist/decorators/service.decorator.js +0 -11
  38. package/dist/decorators/use-component.decorator.d.ts +0 -10
  39. package/dist/decorators/use-component.decorator.js +0 -19
  40. package/dist/decorators/use-filters.decorator.d.ts +0 -8
  41. package/dist/decorators/use-filters.decorator.js +0 -17
  42. package/dist/decorators/use-guards.decorator.d.ts +0 -9
  43. package/dist/decorators/use-guards.decorator.js +0 -18
  44. package/dist/decorators/use-middleware.decorator.d.ts +0 -9
  45. package/dist/decorators/use-middleware.decorator.js +0 -18
  46. package/dist/decorators/use-pipes.decorator.d.ts +0 -9
  47. package/dist/decorators/use-pipes.decorator.js +0 -18
  48. package/dist/di/container.d.ts +0 -34
  49. package/dist/di/container.js +0 -114
  50. package/dist/di/index.d.ts +0 -1
  51. package/dist/di/index.js +0 -1
  52. package/dist/errors/framework.error.d.ts +0 -19
  53. package/dist/errors/framework.error.js +0 -23
  54. package/dist/errors/index.d.ts +0 -1
  55. package/dist/errors/index.js +0 -1
  56. package/dist/handlers/error.handler.d.ts +0 -28
  57. package/dist/handlers/error.handler.js +0 -17
  58. package/dist/handlers/index.d.ts +0 -2
  59. package/dist/handlers/index.js +0 -2
  60. package/dist/handlers/not-found.handler.d.ts +0 -14
  61. package/dist/handlers/not-found.handler.js +0 -17
  62. package/dist/helpers/create-error-response.helper.d.ts +0 -25
  63. package/dist/helpers/create-error-response.helper.js +0 -90
  64. package/dist/helpers/create-http-method-decorator.helper.d.ts +0 -16
  65. package/dist/helpers/create-http-method-decorator.helper.js +0 -30
  66. package/dist/helpers/create-param-decorator.helper.d.ts +0 -16
  67. package/dist/helpers/create-param-decorator.helper.js +0 -60
  68. package/dist/helpers/index.d.ts +0 -3
  69. package/dist/helpers/index.js +0 -3
  70. package/dist/interfaces/application-context.interface.d.ts +0 -35
  71. package/dist/interfaces/application-context.interface.js +0 -1
  72. package/dist/interfaces/controller-options.interface.d.ts +0 -17
  73. package/dist/interfaces/controller-options.interface.js +0 -1
  74. package/dist/interfaces/di-container.interface.d.ts +0 -35
  75. package/dist/interfaces/di-container.interface.js +0 -1
  76. package/dist/interfaces/error-response.interface.d.ts +0 -13
  77. package/dist/interfaces/error-response.interface.js +0 -1
  78. package/dist/interfaces/filter.interface.d.ts +0 -20
  79. package/dist/interfaces/filter.interface.js +0 -1
  80. package/dist/interfaces/guard.interface.d.ts +0 -21
  81. package/dist/interfaces/guard.interface.js +0 -1
  82. package/dist/interfaces/handler-invocation.interface.d.ts +0 -10
  83. package/dist/interfaces/handler-invocation.interface.js +0 -1
  84. package/dist/interfaces/honest-options.interface.d.ts +0 -121
  85. package/dist/interfaces/honest-options.interface.js +0 -1
  86. package/dist/interfaces/http-method-options.interface.d.ts +0 -38
  87. package/dist/interfaces/http-method-options.interface.js +0 -1
  88. package/dist/interfaces/index.d.ts +0 -21
  89. package/dist/interfaces/index.js +0 -21
  90. package/dist/interfaces/logger.interface.d.ts +0 -23
  91. package/dist/interfaces/logger.interface.js +0 -1
  92. package/dist/interfaces/metadata-repository.interface.d.ts +0 -30
  93. package/dist/interfaces/metadata-repository.interface.js +0 -1
  94. package/dist/interfaces/middleware.interface.d.ts +0 -22
  95. package/dist/interfaces/middleware.interface.js +0 -1
  96. package/dist/interfaces/module-options.interface.d.ts +0 -18
  97. package/dist/interfaces/module-options.interface.js +0 -1
  98. package/dist/interfaces/parameter-metadata.interface.d.ts +0 -27
  99. package/dist/interfaces/parameter-metadata.interface.js +0 -1
  100. package/dist/interfaces/parameter-resolution.interface.d.ts +0 -14
  101. package/dist/interfaces/parameter-resolution.interface.js +0 -1
  102. package/dist/interfaces/pipe.interface.d.ts +0 -37
  103. package/dist/interfaces/pipe.interface.js +0 -1
  104. package/dist/interfaces/pipeline-context.interface.d.ts +0 -9
  105. package/dist/interfaces/pipeline-context.interface.js +0 -1
  106. package/dist/interfaces/plugin.interface.d.ts +0 -74
  107. package/dist/interfaces/plugin.interface.js +0 -1
  108. package/dist/interfaces/route-definition.interface.d.ts +0 -51
  109. package/dist/interfaces/route-definition.interface.js +0 -1
  110. package/dist/interfaces/route-info.interface.d.ts +0 -42
  111. package/dist/interfaces/route-info.interface.js +0 -1
  112. package/dist/interfaces/service-registry.interface.d.ts +0 -7
  113. package/dist/interfaces/service-registry.interface.js +0 -1
  114. package/dist/loggers/console.logger.d.ts +0 -7
  115. package/dist/loggers/console.logger.js +0 -21
  116. package/dist/loggers/index.d.ts +0 -2
  117. package/dist/loggers/index.js +0 -2
  118. package/dist/loggers/noop.logger.d.ts +0 -7
  119. package/dist/loggers/noop.logger.js +0 -8
  120. package/dist/managers/component.manager.d.ts +0 -48
  121. package/dist/managers/component.manager.js +0 -209
  122. package/dist/managers/handler.invoker.d.ts +0 -7
  123. package/dist/managers/handler.invoker.js +0 -37
  124. package/dist/managers/index.d.ts +0 -5
  125. package/dist/managers/index.js +0 -5
  126. package/dist/managers/parameter.resolver.d.ts +0 -13
  127. package/dist/managers/parameter.resolver.js +0 -57
  128. package/dist/managers/pipeline.executor.d.ts +0 -28
  129. package/dist/managers/pipeline.executor.js +0 -68
  130. package/dist/managers/route.manager.d.ts +0 -36
  131. package/dist/managers/route.manager.js +0 -147
  132. package/dist/registries/index.d.ts +0 -4
  133. package/dist/registries/index.js +0 -4
  134. package/dist/registries/metadata.registry.d.ts +0 -163
  135. package/dist/registries/metadata.registry.js +0 -250
  136. package/dist/registries/metadata.repository.d.ts +0 -30
  137. package/dist/registries/metadata.repository.js +0 -151
  138. package/dist/registries/route.registry.d.ts +0 -16
  139. package/dist/registries/route.registry.js +0 -46
  140. package/dist/registries/service.registry.d.ts +0 -8
  141. package/dist/registries/service.registry.js +0 -9
  142. package/dist/testing/create-controller-test-application.d.ts +0 -5
  143. package/dist/testing/create-controller-test-application.js +0 -11
  144. package/dist/testing/create-service-test-container.d.ts +0 -5
  145. package/dist/testing/create-service-test-container.js +0 -31
  146. package/dist/testing/create-test-application.d.ts +0 -5
  147. package/dist/testing/create-test-application.js +0 -20
  148. package/dist/testing/create-testing-module.d.ts +0 -6
  149. package/dist/testing/create-testing-module.js +0 -13
  150. package/dist/testing/fixtures/application-test-fixtures.d.ts +0 -17
  151. package/dist/testing/fixtures/application-test-fixtures.js +0 -230
  152. package/dist/testing/index.d.ts +0 -5
  153. package/dist/testing/index.js +0 -5
  154. package/dist/testing/testing.interface.d.ts +0 -96
  155. package/dist/testing/testing.interface.js +0 -1
  156. package/dist/types/constructor.type.d.ts +0 -12
  157. package/dist/types/constructor.type.js +0 -1
  158. package/dist/types/index.d.ts +0 -1
  159. package/dist/types/index.js +0 -1
  160. package/dist/utils/common.util.d.ts +0 -117
  161. package/dist/utils/common.util.js +0 -140
  162. package/dist/utils/index.d.ts +0 -1
  163. package/dist/utils/index.js +0 -1
@@ -1,8 +0,0 @@
1
- /**
2
- * Logger implementation that intentionally does nothing.
3
- */
4
- export class NoopLogger {
5
- emit(_event) {
6
- // no-op
7
- }
8
- }
@@ -1,48 +0,0 @@
1
- import type { Context, Next } from 'hono';
2
- import type { ArgumentMetadata, DiContainer, FilterType, GuardType, ILogger, IMetadataRepository, IGuard, IPipe, MiddlewareType, PipeType } from '../interfaces';
3
- import { type ComponentType, type ComponentTypeMap } from '../registries';
4
- import type { Constructor } from '../types';
5
- /**
6
- * Manager class for handling all component types in the Honest framework.
7
- *
8
- * Each Application instance owns a ComponentManager, which holds per-app
9
- * global components and a reference to the DI container. Controller-level
10
- * and handler-level components remain in MetadataRegistry (static, set at
11
- * class-definition time by decorators).
12
- */
13
- export declare class ComponentManager {
14
- private readonly container;
15
- private readonly metadataRepository;
16
- private readonly logger;
17
- private readonly globalComponents;
18
- constructor(container: DiContainer, metadataRepository: IMetadataRepository, logger?: ILogger);
19
- /**
20
- * Configures global components from application options.
21
- */
22
- setupGlobalComponents(options: {
23
- components?: {
24
- middleware?: MiddlewareType[];
25
- guards?: GuardType[];
26
- pipes?: PipeType[];
27
- filters?: FilterType[];
28
- };
29
- }): void;
30
- registerGlobal<T extends ComponentType>(type: T, ...components: ComponentTypeMap[T][]): void;
31
- getGlobal<T extends ComponentType>(type: T): Set<ComponentTypeMap[T]>;
32
- /**
33
- * Gets all components of a specific type for a handler.
34
- * Merges: instance global → static controller → static handler.
35
- */
36
- getComponents<T extends ComponentType>(type: T, controller: Constructor, handlerName: string | symbol): ComponentTypeMap[T][];
37
- resolveMiddleware(middlewareItems: MiddlewareType[]): ((c: Context, next: Next) => Promise<Response | void>)[];
38
- getHandlerMiddleware(controller: Constructor, handlerName: string | symbol): ((c: Context, next: Next) => Promise<Response | void>)[];
39
- getGlobalMiddleware(): ((c: Context, next: Next) => Promise<Response | void>)[];
40
- resolveGuards(guardItems: GuardType[]): IGuard[];
41
- getHandlerGuards(controller: Constructor, handlerName: string | symbol): IGuard[];
42
- resolvePipes(pipeItems: PipeType[]): IPipe[];
43
- getHandlerPipes(controller: Constructor, handlerName: string | symbol): IPipe[];
44
- executePipes(value: unknown, metadata: ArgumentMetadata, pipes: ReadonlyArray<IPipe>): Promise<unknown>;
45
- handleException(exception: unknown, context: Context): Promise<Response | undefined>;
46
- private executeFilters;
47
- registerModule(moduleClass: Constructor, registered?: Set<Constructor>): Promise<Constructor[]>;
48
- }
@@ -1,209 +0,0 @@
1
- import { HONEST_PIPELINE_CONTROLLER_KEY, HONEST_PIPELINE_HANDLER_KEY } from '../constants';
2
- import { createErrorResponse } from '../helpers';
3
- import { NoopLogger } from '../loggers';
4
- import { isObject } from '../utils';
5
- /**
6
- * Manager class for handling all component types in the Honest framework.
7
- *
8
- * Each Application instance owns a ComponentManager, which holds per-app
9
- * global components and a reference to the DI container. Controller-level
10
- * and handler-level components remain in MetadataRegistry (static, set at
11
- * class-definition time by decorators).
12
- */
13
- export class ComponentManager {
14
- container;
15
- metadataRepository;
16
- logger;
17
- globalComponents = new Map([
18
- ['middleware', new Set()],
19
- ['guard', new Set()],
20
- ['pipe', new Set()],
21
- ['filter', new Set()]
22
- ]);
23
- constructor(container, metadataRepository, logger = new NoopLogger()) {
24
- this.container = container;
25
- this.metadataRepository = metadataRepository;
26
- this.logger = logger;
27
- }
28
- /**
29
- * Configures global components from application options.
30
- */
31
- setupGlobalComponents(options) {
32
- const components = options.components || {};
33
- if (components.middleware) {
34
- this.registerGlobal('middleware', ...components.middleware);
35
- }
36
- if (components.guards) {
37
- this.registerGlobal('guard', ...components.guards);
38
- }
39
- if (components.pipes) {
40
- this.registerGlobal('pipe', ...components.pipes);
41
- }
42
- if (components.filters) {
43
- this.registerGlobal('filter', ...components.filters);
44
- }
45
- }
46
- registerGlobal(type, ...components) {
47
- components.forEach((component) => {
48
- this.globalComponents.get(type).add(component);
49
- });
50
- }
51
- getGlobal(type) {
52
- return this.globalComponents.get(type);
53
- }
54
- /**
55
- * Gets all components of a specific type for a handler.
56
- * Merges: instance global → static controller → static handler.
57
- */
58
- getComponents(type, controller, handlerName) {
59
- const handlerComponents = this.metadataRepository.getHandlerComponents(type, controller, handlerName);
60
- const controllerComponents = this.metadataRepository.getControllerComponents(type, controller);
61
- const globalComponents = Array.from(this.globalComponents.get(type) || []);
62
- return [...globalComponents, ...controllerComponents, ...handlerComponents];
63
- }
64
- // -- Middleware --
65
- resolveMiddleware(middlewareItems) {
66
- return middlewareItems.map((middlewareItem) => {
67
- if (isObject(middlewareItem) && 'use' in middlewareItem) {
68
- return middlewareItem.use.bind(middlewareItem);
69
- }
70
- const middleware = this.container.resolve(middlewareItem);
71
- return middleware.use.bind(middleware);
72
- });
73
- }
74
- getHandlerMiddleware(controller, handlerName) {
75
- const controllerMiddleware = this.metadataRepository.getControllerComponents('middleware', controller);
76
- const handlerMiddleware = this.metadataRepository.getHandlerComponents('middleware', controller, handlerName);
77
- return this.resolveMiddleware([...controllerMiddleware, ...handlerMiddleware]);
78
- }
79
- getGlobalMiddleware() {
80
- const globalMiddleware = Array.from(this.globalComponents.get('middleware') || []);
81
- return this.resolveMiddleware(globalMiddleware);
82
- }
83
- // -- Guards --
84
- resolveGuards(guardItems) {
85
- return guardItems.map((guardItem) => {
86
- if (isObject(guardItem) && 'canActivate' in guardItem) {
87
- return guardItem;
88
- }
89
- return this.container.resolve(guardItem);
90
- });
91
- }
92
- getHandlerGuards(controller, handlerName) {
93
- const guardItems = this.getComponents('guard', controller, handlerName);
94
- return this.resolveGuards(guardItems);
95
- }
96
- // -- Pipes --
97
- resolvePipes(pipeItems) {
98
- return pipeItems.map((pipeItem) => {
99
- if (isObject(pipeItem) && 'transform' in pipeItem) {
100
- return pipeItem;
101
- }
102
- return this.container.resolve(pipeItem);
103
- });
104
- }
105
- getHandlerPipes(controller, handlerName) {
106
- const pipeItems = this.getComponents('pipe', controller, handlerName);
107
- return this.resolvePipes(pipeItems);
108
- }
109
- async executePipes(value, metadata, pipes) {
110
- let transformedValue = value;
111
- for (const pipe of pipes) {
112
- transformedValue = await pipe.transform(transformedValue, metadata);
113
- }
114
- return transformedValue;
115
- }
116
- // -- Filters --
117
- async handleException(exception, context) {
118
- const normalizedException = exception instanceof Error ? exception : new Error(String(exception));
119
- const controller = context.get(HONEST_PIPELINE_CONTROLLER_KEY);
120
- const handlerName = context.get(HONEST_PIPELINE_HANDLER_KEY);
121
- if (controller && handlerName) {
122
- const handlerFilters = this.metadataRepository.getHandlerComponents('filter', controller, handlerName);
123
- if (handlerFilters.length > 0) {
124
- const response = await this.executeFilters(handlerFilters, normalizedException, context);
125
- if (response)
126
- return response;
127
- }
128
- }
129
- if (controller) {
130
- const controllerFilters = this.metadataRepository.getControllerComponents('filter', controller);
131
- if (controllerFilters.length > 0) {
132
- const response = await this.executeFilters(controllerFilters, normalizedException, context);
133
- if (response)
134
- return response;
135
- }
136
- }
137
- const globalFilters = Array.from(this.globalComponents.get('filter') || []);
138
- if (globalFilters.length > 0) {
139
- const response = await this.executeFilters(globalFilters, normalizedException, context);
140
- if (response)
141
- return response;
142
- }
143
- const { response, status } = createErrorResponse(normalizedException, context);
144
- return context.json(response, status);
145
- }
146
- async executeFilters(filterItems, exception, context) {
147
- for (const filterItem of filterItems) {
148
- let filter;
149
- if (isObject(filterItem) && 'catch' in filterItem) {
150
- filter = filterItem;
151
- }
152
- else {
153
- filter = this.container.resolve(filterItem);
154
- }
155
- try {
156
- const result = await filter.catch(exception, context);
157
- if (result !== undefined) {
158
- return result;
159
- }
160
- }
161
- catch (filterError) {
162
- const filterName = filter.constructor?.name || 'UnknownFilter';
163
- this.logger.emit({
164
- level: 'error',
165
- category: 'errors',
166
- message: `Error in exception filter ${filterName}`,
167
- details: {
168
- error: filterError instanceof Error ? filterError.message : String(filterError)
169
- }
170
- });
171
- const { response, status } = createErrorResponse(filterError, context);
172
- return context.json(response, status);
173
- }
174
- }
175
- return undefined;
176
- }
177
- // -- Module registration --
178
- async registerModule(moduleClass, registered = new Set()) {
179
- if (registered.has(moduleClass)) {
180
- return [];
181
- }
182
- registered.add(moduleClass);
183
- const moduleOptions = this.metadataRepository.getModuleOptions(moduleClass);
184
- if (!moduleOptions) {
185
- this.logger.emit({
186
- level: 'error',
187
- category: 'startup',
188
- message: `Module ${moduleClass.name} is not properly decorated with @Module()`
189
- });
190
- throw new Error(`Module ${moduleClass.name} is not properly decorated with @Module()`);
191
- }
192
- const controllers = [];
193
- if (moduleOptions.imports && moduleOptions.imports.length > 0) {
194
- for (const importedModule of moduleOptions.imports) {
195
- const importedControllers = await this.registerModule(importedModule, registered);
196
- controllers.push(...importedControllers);
197
- }
198
- }
199
- if (moduleOptions.services && moduleOptions.services.length > 0) {
200
- for (const serviceClass of moduleOptions.services) {
201
- this.container.resolve(serviceClass);
202
- }
203
- }
204
- if (moduleOptions.controllers && moduleOptions.controllers.length > 0) {
205
- controllers.push(...moduleOptions.controllers);
206
- }
207
- return controllers;
208
- }
209
- }
@@ -1,7 +0,0 @@
1
- import type { HandlerInvocationInput } from '../interfaces';
2
- /**
3
- * Invokes route handlers and maps non-Response results to Hono responses.
4
- */
5
- export declare class HandlerInvoker {
6
- invoke({ handler, args, context, contextIndex }: HandlerInvocationInput): Promise<unknown>;
7
- }
@@ -1,37 +0,0 @@
1
- import { FrameworkError } from '../errors';
2
- import { isNil, isString } from '../utils';
3
- /**
4
- * Invokes route handlers and maps non-Response results to Hono responses.
5
- */
6
- export class HandlerInvoker {
7
- async invoke({ handler, args, context, contextIndex }) {
8
- const result = await handler(...args);
9
- if (contextIndex !== undefined) {
10
- return result;
11
- }
12
- if (result instanceof Response) {
13
- return result;
14
- }
15
- if (isNil(result)) {
16
- return context.json(null);
17
- }
18
- if (isString(result)) {
19
- return context.text(result);
20
- }
21
- try {
22
- return context.json(result);
23
- }
24
- catch (error) {
25
- throw new FrameworkError('Handler return value could not be serialized as JSON.', {
26
- status: 500,
27
- code: 'RESPONSE_SERIALIZATION_FAILED',
28
- category: 'pipeline',
29
- remediation: 'Return JSON-serializable values from handlers or map custom values in a filter before returning.',
30
- details: {
31
- handlerResultType: typeof result
32
- },
33
- cause: error
34
- });
35
- }
36
- }
37
- }
@@ -1,5 +0,0 @@
1
- export * from './component.manager';
2
- export * from './handler.invoker';
3
- export * from './parameter.resolver';
4
- export * from './pipeline.executor';
5
- export * from './route.manager';
@@ -1,5 +0,0 @@
1
- export * from './component.manager';
2
- export * from './handler.invoker';
3
- export * from './parameter.resolver';
4
- export * from './pipeline.executor';
5
- export * from './route.manager';
@@ -1,13 +0,0 @@
1
- import type { ParameterResolutionInput } from '../interfaces';
2
- import type { ILogger } from '../interfaces';
3
- import { ComponentManager } from './component.manager';
4
- /**
5
- * Resolves route handler arguments from parameter decorator metadata.
6
- */
7
- export declare class ParameterResolver {
8
- private readonly componentManager;
9
- private readonly logger;
10
- private readonly debugPipeline;
11
- constructor(componentManager: ComponentManager, logger?: ILogger, debugPipeline?: boolean);
12
- resolveArguments(input: ParameterResolutionInput): Promise<unknown[]>;
13
- }
@@ -1,57 +0,0 @@
1
- import { NoopLogger } from '../loggers';
2
- /**
3
- * Resolves route handler arguments from parameter decorator metadata.
4
- */
5
- export class ParameterResolver {
6
- componentManager;
7
- logger;
8
- debugPipeline;
9
- constructor(componentManager, logger = new NoopLogger(), debugPipeline = false) {
10
- this.componentManager = componentManager;
11
- this.logger = logger;
12
- this.debugPipeline = debugPipeline;
13
- }
14
- async resolveArguments(input) {
15
- const { controllerName, handlerName, handlerArity, handlerParams, handlerPipes, context } = input;
16
- const maxDecoratorIndex = handlerParams.length > 0 ? Math.max(...handlerParams.map((parameter) => parameter.index)) : -1;
17
- const args = new Array(Math.max(handlerArity, maxDecoratorIndex + 1));
18
- const decoratedIndices = new Set(handlerParams.map((parameter) => parameter.index));
19
- if (this.debugPipeline && maxDecoratorIndex >= 0) {
20
- const sparseIndices = [];
21
- for (let i = 0; i <= maxDecoratorIndex; i++) {
22
- if (!decoratedIndices.has(i)) {
23
- sparseIndices.push(i);
24
- }
25
- }
26
- const hasOutOfRangeDecoratorIndex = maxDecoratorIndex >= handlerArity;
27
- if (sparseIndices.length > 0 || hasOutOfRangeDecoratorIndex) {
28
- this.logger.emit({
29
- level: 'warn',
30
- category: 'pipeline',
31
- message: `Potential parameter binding mismatch at ${controllerName}.${String(handlerName)}`,
32
- details: {
33
- handlerArity,
34
- maxDecoratorIndex,
35
- sparseIndices,
36
- handlerParamCount: handlerParams.length
37
- }
38
- });
39
- }
40
- }
41
- for (const parameter of handlerParams) {
42
- if (typeof parameter.factory !== 'function') {
43
- throw new Error(`Invalid parameter decorator metadata for ${controllerName}.${String(handlerName)}`);
44
- }
45
- const rawValue = await parameter.factory(parameter.data, context);
46
- const transformedValue = await this.componentManager.executePipes(rawValue, {
47
- type: parameter.name,
48
- metatype: parameter.metatype,
49
- data: typeof parameter.data === 'string' || typeof parameter.data === 'undefined'
50
- ? parameter.data
51
- : String(parameter.data)
52
- }, handlerPipes);
53
- args[parameter.index] = transformedValue;
54
- }
55
- return args;
56
- }
57
- }
@@ -1,28 +0,0 @@
1
- import type { Context } from 'hono';
2
- import type { ILogger, ParameterMetadata } from '../interfaces';
3
- import type { IPipe } from '../interfaces';
4
- import { ComponentManager } from './component.manager';
5
- import { HandlerInvoker } from './handler.invoker';
6
- import { ParameterResolver } from './parameter.resolver';
7
- import type { Constructor } from '../types';
8
- export interface PipelineExecutionInput {
9
- controllerClass: Constructor;
10
- handlerName: string | symbol;
11
- handler: (...args: unknown[]) => Promise<unknown> | unknown;
12
- handlerParams: ReadonlyArray<ParameterMetadata>;
13
- handlerPipes: ReadonlyArray<IPipe>;
14
- contextIndex?: number;
15
- context: Context;
16
- }
17
- /**
18
- * Executes guard, parameter-resolution, and handler invocation stages.
19
- */
20
- export declare class PipelineExecutor {
21
- private readonly componentManager;
22
- private readonly parameterResolver;
23
- private readonly handlerInvoker;
24
- private readonly logger;
25
- private readonly debugPipeline;
26
- constructor(componentManager: ComponentManager, parameterResolver: ParameterResolver, handlerInvoker: HandlerInvoker, logger?: ILogger, debugPipeline?: boolean);
27
- execute(input: PipelineExecutionInput): Promise<unknown>;
28
- }
@@ -1,68 +0,0 @@
1
- import { HTTPException } from 'hono/http-exception';
2
- import { HONEST_PIPELINE_CONTROLLER_KEY, HONEST_PIPELINE_HANDLER_KEY } from '../constants';
3
- import { NoopLogger } from '../loggers';
4
- /**
5
- * Executes guard, parameter-resolution, and handler invocation stages.
6
- */
7
- export class PipelineExecutor {
8
- componentManager;
9
- parameterResolver;
10
- handlerInvoker;
11
- logger;
12
- debugPipeline;
13
- constructor(componentManager, parameterResolver, handlerInvoker, logger = new NoopLogger(), debugPipeline = false) {
14
- this.componentManager = componentManager;
15
- this.parameterResolver = parameterResolver;
16
- this.handlerInvoker = handlerInvoker;
17
- this.logger = logger;
18
- this.debugPipeline = debugPipeline;
19
- }
20
- async execute(input) {
21
- const { controllerClass, handlerName, handler, handlerParams, handlerPipes, contextIndex, context } = input;
22
- context.set(HONEST_PIPELINE_CONTROLLER_KEY, controllerClass);
23
- context.set(HONEST_PIPELINE_HANDLER_KEY, String(handlerName));
24
- const guards = this.componentManager.getHandlerGuards(controllerClass, handlerName);
25
- for (const guard of guards) {
26
- const canActivate = await guard.canActivate(context);
27
- if (!canActivate) {
28
- if (this.debugPipeline) {
29
- this.logger.emit({
30
- level: 'warn',
31
- category: 'pipeline',
32
- message: `Guard rejected request at ${controllerClass.name}.${String(handlerName)}`,
33
- details: { guard: guard.constructor?.name || 'UnknownGuard' }
34
- });
35
- }
36
- throw new HTTPException(403, {
37
- message: `Forbidden by ${guard.constructor?.name || 'UnknownGuard'} at ${controllerClass.name}.${String(handlerName)}`
38
- });
39
- }
40
- }
41
- const args = await this.parameterResolver.resolveArguments({
42
- controllerName: controllerClass.name,
43
- handlerName,
44
- handlerArity: handler.length,
45
- handlerParams,
46
- handlerPipes,
47
- context
48
- });
49
- if (this.debugPipeline) {
50
- this.logger.emit({
51
- level: 'debug',
52
- category: 'pipeline',
53
- message: `Resolved handler arguments for ${controllerClass.name}.${String(handlerName)}`,
54
- details: {
55
- guardCount: guards.length,
56
- parameterCount: handlerParams.length,
57
- pipeCount: handlerPipes.length
58
- }
59
- });
60
- }
61
- return this.handlerInvoker.invoke({
62
- handler,
63
- args,
64
- context,
65
- contextIndex
66
- });
67
- }
68
- }
@@ -1,36 +0,0 @@
1
- import type { Hono } from 'hono';
2
- import { VERSION_NEUTRAL } from '../constants';
3
- import type { DiContainer, ILogger, IMetadataRepository } from '../interfaces';
4
- import { ComponentManager } from './component.manager';
5
- import { RouteRegistry } from '../registries/route.registry';
6
- import type { Constructor } from '../types';
7
- /**
8
- * Manager class for handling route registration in the Honest framework.
9
- *
10
- * Receives all per-app dependencies (Hono, Container, RouteRegistry,
11
- * ComponentManager) via constructor — no static state.
12
- */
13
- export declare class RouteManager {
14
- private hono;
15
- private container;
16
- private routeRegistry;
17
- private componentManager;
18
- private parameterResolver;
19
- private pipelineExecutor;
20
- private metadataRepository;
21
- private logger;
22
- private globalPrefix?;
23
- private globalVersion?;
24
- constructor(hono: Hono, container: DiContainer, routeRegistry: RouteRegistry, componentManager: ComponentManager, metadataRepository: IMetadataRepository, logger?: ILogger, options?: {
25
- prefix?: string;
26
- version?: number | typeof VERSION_NEUTRAL | number[];
27
- debugPipeline?: boolean;
28
- });
29
- private applyGlobalMiddleware;
30
- private normalizePath;
31
- private registerRouteHandler;
32
- private buildRoutePath;
33
- private formatVersionSegment;
34
- registerController(controllerClass: Constructor): Promise<void>;
35
- private registerRoute;
36
- }