honestjs 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 (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +127 -0
  3. package/dist/application.d.ts +124 -0
  4. package/dist/constants/index.d.ts +1 -0
  5. package/dist/constants/version.constants.d.ts +5 -0
  6. package/dist/decorators/controller.decorator.d.ts +9 -0
  7. package/dist/decorators/http-method.decorator.d.ts +43 -0
  8. package/dist/decorators/index.d.ts +10 -0
  9. package/dist/decorators/module.decorator.d.ts +8 -0
  10. package/dist/decorators/parameter.decorator.d.ts +41 -0
  11. package/dist/decorators/service.decorator.d.ts +6 -0
  12. package/dist/decorators/use-component.decorator.d.ts +10 -0
  13. package/dist/decorators/use-filters.decorator.d.ts +8 -0
  14. package/dist/decorators/use-guards.decorator.d.ts +9 -0
  15. package/dist/decorators/use-middleware.decorator.d.ts +9 -0
  16. package/dist/decorators/use-pipes.decorator.d.ts +9 -0
  17. package/dist/di/contrainer.d.ts +23 -0
  18. package/dist/di/index.d.ts +1 -0
  19. package/dist/handlers/error.handler.d.ts +31 -0
  20. package/dist/handlers/index.d.ts +2 -0
  21. package/dist/handlers/not-found.handler.d.ts +14 -0
  22. package/dist/helpers/create-error-response.helper.d.ts +25 -0
  23. package/dist/helpers/create-http-method-decorator.helper.d.ts +16 -0
  24. package/dist/helpers/create-param-decorator.helper.d.ts +16 -0
  25. package/dist/helpers/index.d.ts +3 -0
  26. package/dist/index.d.ts +19 -0
  27. package/dist/index.js +1 -0
  28. package/dist/interfaces/controller-options.interface.d.ts +17 -0
  29. package/dist/interfaces/di-container.interface.d.ts +24 -0
  30. package/dist/interfaces/error-response.interface.d.ts +13 -0
  31. package/dist/interfaces/filter.interface.d.ts +20 -0
  32. package/dist/interfaces/guard.interface.d.ts +21 -0
  33. package/dist/interfaces/honest-options.interface.d.ts +78 -0
  34. package/dist/interfaces/http-method-options.interface.d.ts +13 -0
  35. package/dist/interfaces/index.d.ts +14 -0
  36. package/dist/interfaces/middleware.interface.d.ts +22 -0
  37. package/dist/interfaces/module-options.interface.d.ts +18 -0
  38. package/dist/interfaces/parameter-metadata.interface.d.ts +27 -0
  39. package/dist/interfaces/pipe.interface.d.ts +37 -0
  40. package/dist/interfaces/plugin.interface.d.ts +31 -0
  41. package/dist/interfaces/route-definition.interface.d.ts +30 -0
  42. package/dist/interfaces/route-info.interface.d.ts +42 -0
  43. package/dist/managers/component.manager.d.ts +143 -0
  44. package/dist/managers/index.d.ts +2 -0
  45. package/dist/managers/route.manager.d.ts +109 -0
  46. package/dist/registries/index.d.ts +2 -0
  47. package/dist/registries/metadata.registry.d.ts +172 -0
  48. package/dist/registries/route.registry.d.ts +63 -0
  49. package/dist/types/constructor.type.d.ts +12 -0
  50. package/dist/types/index.d.ts +1 -0
  51. package/dist/utils/common.util.d.ts +116 -0
  52. package/dist/utils/index.d.ts +1 -0
  53. package/package.json +51 -0
@@ -0,0 +1,109 @@
1
+ import type { Hono } from 'hono';
2
+ import { VERSION_NEUTRAL } from '../constants';
3
+ import type { DiContainer } from '../interfaces';
4
+ import type { Constructor } from '../types';
5
+ /**
6
+ * Manager class for handling route registration in the Honest framework
7
+ * Responsible for:
8
+ * - Registering controller routes with the Hono application
9
+ * - Managing route versioning and prefixing
10
+ * - Applying middleware and guards to routes
11
+ * - Handling parameter transformation and validation
12
+ *
13
+ * Versioning features:
14
+ * - Global version setting can be overridden at controller or method level
15
+ * - Controllers can opt out of versioning by setting version to null
16
+ * - Routes can use VERSION_NEUTRAL to be accessible with and without version prefix
17
+ * - Routes can specify an array of versions to support multiple versions
18
+ *
19
+ * Path handling:
20
+ * - Global prefix can be overridden at controller level
21
+ * - Paths are automatically normalized
22
+ * - Final path structure: prefix/version/controller-path/method-path
23
+ */
24
+ export declare class RouteManager {
25
+ private hono;
26
+ private container;
27
+ private globalPrefix?;
28
+ private globalVersion?;
29
+ /**
30
+ * Creates a new RouteManager instance
31
+ * @param hono - The Hono application instance for route registration
32
+ * @param container - The dependency injection container for resolving controllers and dependencies
33
+ * @param options - Configuration options for the route manager
34
+ * @param options.prefix - Optional global prefix for all routes
35
+ * @param options.version - Optional global version or version array for all routes
36
+ */
37
+ constructor(hono: Hono, container: DiContainer, options?: {
38
+ prefix?: string;
39
+ version?: number | typeof VERSION_NEUTRAL | number[];
40
+ });
41
+ /**
42
+ * Applies global middleware to the application
43
+ */
44
+ private applyGlobalMiddleware;
45
+ /**
46
+ * Normalizes a path segment for route registration
47
+ * @param path - The path segment to normalize
48
+ * @returns The normalized path segment
49
+ */
50
+ private normalizePath;
51
+ /**
52
+ * Registers a wrapper handler with middleware for a route
53
+ * @param method - HTTP method
54
+ * @param path - Full path for the route
55
+ * @param handlerMiddleware - Middleware for the handler
56
+ * @param wrapperHandler - The wrapper handler function
57
+ */
58
+ private registerRouteHandler;
59
+ /**
60
+ * Builds a route path with the correct order: prefix, version, controller path, method path
61
+ * @param prefix - Global or controller-specific prefix
62
+ * @param version - Version string (e.g., '/v1') or empty string if no version
63
+ * @param controllerPath - Controller path
64
+ * @param methodPath - Method-specific path
65
+ * @returns Properly formatted full path
66
+ */
67
+ private buildRoutePath;
68
+ /**
69
+ * Formats a version number or VERSION_NEUTRAL into a path segment
70
+ * @param version - Version number or VERSION_NEUTRAL
71
+ * @returns Formatted version string (e.g., '/v1') or empty string if null
72
+ */
73
+ private formatVersionSegment;
74
+ /**
75
+ * Registers a controller and all its routes with the application
76
+ * Handles versioning, prefixing, and middleware application
77
+ *
78
+ * @param controllerClass - The controller class to register
79
+ * @throws {Error} If controller registration fails or if required dependencies cannot be resolved
80
+ *
81
+ * Route registration process:
82
+ * 1. Resolves controller instance and metadata
83
+ * 2. Processes controller-level options (prefix, version)
84
+ * 3. Registers each route with appropriate:
85
+ * - Path construction (prefix/version/controller-path/method-path)
86
+ * - Middleware application
87
+ * - Parameter processing
88
+ * - Guard validation
89
+ */
90
+ registerController(controllerClass: Constructor): Promise<void>;
91
+ /**
92
+ * Registers a specific route with the application
93
+ * Handles middleware setup, parameter processing, and response handling
94
+ *
95
+ * @param controllerInstance - Instance of the controller containing the route handler
96
+ * @param route - Route metadata including path and HTTP method
97
+ * @param parameterMetadata - Metadata for parameter processing
98
+ * @param contextIndices - Map of context parameter indices
99
+ * @param controllerClass - The controller class
100
+ * @param prefix - Route prefix
101
+ * @param versionSegment - Version segment of the path
102
+ * @param controllerSegment - Controller path segment
103
+ * @param methodSegment - Method-specific path segment
104
+ * @param method - HTTP method for the route
105
+ *
106
+ * @throws {Error} If route registration fails
107
+ */
108
+ private registerRoute;
109
+ }
@@ -0,0 +1,2 @@
1
+ export * from './metadata.registry';
2
+ export * from './route.registry';
@@ -0,0 +1,172 @@
1
+ import type { ControllerOptions, FilterType, GuardType, MiddlewareType, ModuleOptions, ParameterMetadata, PipeType, RouteDefinition } from '../interfaces';
2
+ import type { Constructor } from '../types';
3
+ /**
4
+ * Available component types that can be registered at different levels in the application
5
+ * Each type corresponds to a specific aspect of request processing
6
+ */
7
+ export type ComponentType = 'middleware' | 'guard' | 'pipe' | 'filter';
8
+ /**
9
+ * Union type of all possible component instances
10
+ * Represents any type of component that can be registered in the application
11
+ */
12
+ export type ComponentInstance = MiddlewareType | GuardType | PipeType | FilterType;
13
+ /**
14
+ * Maps component type identifiers to their specific instance types
15
+ * Used for type-safe component registration and retrieval
16
+ */
17
+ export interface ComponentTypeMap {
18
+ middleware: MiddlewareType;
19
+ guard: GuardType;
20
+ pipe: PipeType;
21
+ filter: FilterType;
22
+ }
23
+ /**
24
+ * Central registry for managing application metadata
25
+ * Stores and provides access to:
26
+ * - Route definitions and controller configurations
27
+ * - Service and module registrations
28
+ * - Parameter metadata and context indices
29
+ * - Component registrations at global, controller, and handler levels
30
+ */
31
+ export declare class MetadataRegistry {
32
+ /**
33
+ * Stores route definitions for each controller
34
+ * Maps controller classes to their route configurations
35
+ */
36
+ private static readonly routes;
37
+ /**
38
+ * Stores base paths for controllers
39
+ * Maps controller classes to their route prefixes
40
+ */
41
+ private static readonly controllers;
42
+ /**
43
+ * Stores configuration options for controllers
44
+ * Includes settings like versioning and prefix options
45
+ */
46
+ private static readonly controllerOptions;
47
+ /**
48
+ * Registry of service classes
49
+ * Used for dependency injection and lifecycle management
50
+ */
51
+ private static readonly services;
52
+ /**
53
+ * Stores configuration options for modules
54
+ * Includes imports, exports, providers, and controllers
55
+ */
56
+ private static readonly modules;
57
+ /**
58
+ * Stores parameter metadata for controller methods
59
+ * Used for parameter transformation and validation
60
+ */
61
+ private static readonly parameters;
62
+ /**
63
+ * Stores indices of context parameters in controller methods
64
+ * Used for optimizing context injection
65
+ */
66
+ private static readonly contextIndices;
67
+ /**
68
+ * Registry for global-level components
69
+ * Components registered here apply to all routes
70
+ */
71
+ private static readonly global;
72
+ /**
73
+ * Registry for controller-level components
74
+ * Components registered here apply to all routes in a specific controller
75
+ */
76
+ private static readonly controller;
77
+ /**
78
+ * Registry for handler-level components
79
+ * Components registered here apply to specific route handlers
80
+ */
81
+ private static readonly handler;
82
+ /**
83
+ * Gets all route definitions for a controller
84
+ * @param controller - The controller class to get routes for
85
+ * @returns Array of route definitions for the controller
86
+ */
87
+ static getRoutes(controller: Constructor): RouteDefinition[];
88
+ /**
89
+ * Set routes for a controller
90
+ */
91
+ static setRoutes(controller: Constructor, routes: RouteDefinition[]): void;
92
+ /**
93
+ * Add a route to a controller
94
+ */
95
+ static addRoute(controller: Constructor, route: RouteDefinition): void;
96
+ /**
97
+ * Get controller path
98
+ */
99
+ static getControllerPath(controller: Constructor): string;
100
+ /**
101
+ * Set controller path
102
+ */
103
+ static setControllerPath(controller: Constructor, path: string): void;
104
+ /**
105
+ * Get controller options
106
+ */
107
+ static getControllerOptions(controller: Constructor): ControllerOptions;
108
+ /**
109
+ * Set controller options
110
+ */
111
+ static setControllerOptions(controller: Constructor, options: ControllerOptions): void;
112
+ /**
113
+ * Check if class is a service
114
+ */
115
+ static isService(service: Constructor): boolean;
116
+ /**
117
+ * Add a service
118
+ */
119
+ static addService(service: Constructor): void;
120
+ /**
121
+ * Get all services
122
+ */
123
+ static getAllServices(): Set<Constructor>;
124
+ /**
125
+ * Get module options
126
+ */
127
+ static getModuleOptions(module: Constructor): ModuleOptions | undefined;
128
+ /**
129
+ * Set module options
130
+ */
131
+ static setModuleOptions(module: Constructor, options: ModuleOptions): void;
132
+ /**
133
+ * Get parameter metadata
134
+ */
135
+ static getParameters(controller: Constructor): Map<string | symbol, ParameterMetadata[]>;
136
+ /**
137
+ * Set parameter metadata
138
+ */
139
+ static setParameterMap(controller: Constructor, params: Map<string | symbol, ParameterMetadata[]>): void;
140
+ /**
141
+ * Get context indices
142
+ */
143
+ static getContextIndices(controller: Constructor): Map<string | symbol, number>;
144
+ /**
145
+ * Set context indices
146
+ */
147
+ static setContextIndices(controller: Constructor, indices: Map<string | symbol, number>): void;
148
+ /**
149
+ * Register a component at the global level
150
+ */
151
+ static registerGlobal<T extends ComponentType>(type: T, component: ComponentTypeMap[T]): void;
152
+ /**
153
+ * Get all global components of a specific type
154
+ */
155
+ static getGlobal<T extends ComponentType>(type: T): Set<ComponentTypeMap[T]>;
156
+ /**
157
+ * Register a component at the controller level
158
+ */
159
+ static registerController<T extends ComponentType>(type: T, controller: Constructor, component: ComponentTypeMap[T]): void;
160
+ /**
161
+ * Get all controller-level components of a specific type for a controller
162
+ */
163
+ static getController<T extends ComponentType>(type: T, controller: Constructor): ComponentTypeMap[T][];
164
+ /**
165
+ * Register a component at the handler level
166
+ */
167
+ static registerHandler<T extends ComponentType>(type: T, handlerKey: string, component: ComponentTypeMap[T]): void;
168
+ /**
169
+ * Get all handler-level components of a specific type for a handler
170
+ */
171
+ static getHandler<T extends ComponentType>(type: T, handlerKey: string): ComponentTypeMap[T][];
172
+ }
@@ -0,0 +1,63 @@
1
+ import type { RouteInfo } from '../interfaces';
2
+ /**
3
+ * Registry for managing and querying route information in the application
4
+ *
5
+ * Provides functionality to:
6
+ * - Register new routes with their metadata
7
+ * - Query routes by various criteria (controller, method, path)
8
+ * - Access route information for documentation and debugging
9
+ * - Manage route lifecycle (registration and cleanup)
10
+ *
11
+ * The registry maintains a read-only view of routes to prevent unintended modifications
12
+ */
13
+ export declare class RouteRegistry {
14
+ /**
15
+ * Internal storage for registered routes
16
+ * Maintains the complete list of routes in registration order
17
+ */
18
+ private static readonly routes;
19
+ /**
20
+ * Registers a new route in the application
21
+ * @param routeInfo - Complete route information including path, method, and handler details
22
+ * @throws {Error} If the route information is invalid or incomplete
23
+ */
24
+ static registerRoute(routeInfo: RouteInfo): void;
25
+ /**
26
+ * Retrieves all registered routes in the application
27
+ * @returns A read-only array of all route information
28
+ * Routes are returned in their registration order
29
+ */
30
+ static getRoutes(): ReadonlyArray<RouteInfo>;
31
+ /**
32
+ * Retrieves all routes registered for a specific controller
33
+ * @param controllerName - Name or symbol identifying the controller
34
+ * @returns A read-only array of routes belonging to the specified controller
35
+ * Returns an empty array if no routes are found for the controller
36
+ */
37
+ static getRoutesByController(controllerName: string | symbol): ReadonlyArray<RouteInfo>;
38
+ /**
39
+ * Retrieves all routes registered for a specific HTTP method
40
+ * @param method - HTTP method to filter by (case-insensitive)
41
+ * @returns A read-only array of routes handling the specified HTTP method
42
+ * Returns an empty array if no routes are found for the method
43
+ */
44
+ static getRoutesByMethod(method: string): ReadonlyArray<RouteInfo>;
45
+ /**
46
+ * Retrieves routes matching a specific path pattern
47
+ * @param pattern - Regular expression to match against route paths
48
+ * @returns A read-only array of routes whose paths match the pattern
49
+ * Returns an empty array if no matching routes are found
50
+ * @example
51
+ * ```ts
52
+ * // Find all routes containing 'users'
53
+ * const userRoutes = RouteRegistry.getRoutesByPath(/users/);
54
+ * ```
55
+ */
56
+ static getRoutesByPath(pattern: RegExp): ReadonlyArray<RouteInfo>;
57
+ /**
58
+ * Removes all registered routes from the registry
59
+ * Primarily used for testing and development purposes
60
+ * Use with caution in production environments
61
+ */
62
+ static clear(): void;
63
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Represents a class constructor type
3
+ * Used throughout the framework for type-safe dependency injection and component registration
4
+ *
5
+ * @template T - The type of instance that the constructor creates
6
+ * @example
7
+ * ```ts
8
+ * class MyService {}
9
+ * const myConstructor: Constructor<MyService> = MyService;
10
+ * ```
11
+ */
12
+ export type Constructor<T = any> = new (...args: any[]) => T;
@@ -0,0 +1 @@
1
+ export * from './constructor.type';
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Type guard that checks if a value is undefined
3
+ * @param obj - The value to check
4
+ * @returns True if the value is undefined, false otherwise
5
+ */
6
+ export declare const isUndefined: (obj: unknown) => obj is undefined;
7
+ /**
8
+ * Type guard that checks if a value is null or undefined
9
+ * @param val - The value to check
10
+ * @returns True if the value is null or undefined, false otherwise
11
+ */
12
+ export declare const isNil: (val: unknown) => val is null | undefined;
13
+ /**
14
+ * Type guard that checks if a value is an object (excluding null)
15
+ * @param val - The value to check
16
+ * @returns True if the value is a non-null object, false otherwise
17
+ */
18
+ export declare const isObject: (val: unknown) => val is Record<PropertyKey, unknown>;
19
+ /**
20
+ * Type guard that checks if a value is a plain object (not a class instance or array)
21
+ * Determines if an object is a simple key-value store created by object literals
22
+ *
23
+ * @param val - The value to check
24
+ * @returns True if the value is a plain object, false otherwise
25
+ * @example
26
+ * ```ts
27
+ * isPlainObject({}) // true
28
+ * isPlainObject(new Class()) // false
29
+ * isPlainObject([]) // false
30
+ * ```
31
+ */
32
+ export declare const isPlainObject: (val: unknown) => val is Record<string, unknown>;
33
+ /**
34
+ * Type guard that checks if a value is a function
35
+ * @param val - The value to check
36
+ * @returns True if the value is a function, false otherwise
37
+ */
38
+ export declare const isFunction: (val: unknown) => val is Function;
39
+ /**
40
+ * Type guard that checks if a value is a string
41
+ * @param val - The value to check
42
+ * @returns True if the value is a string, false otherwise
43
+ */
44
+ export declare const isString: (val: unknown) => val is string;
45
+ /**
46
+ * Type guard that checks if a value is a number
47
+ * @param val - The value to check
48
+ * @returns True if the value is a number, false otherwise
49
+ */
50
+ export declare const isNumber: (val: unknown) => val is number;
51
+ /**
52
+ * Checks if an array is empty
53
+ * @param array - The array to check
54
+ * @returns True if the array has no elements, false otherwise
55
+ */
56
+ export declare const isEmpty: (array: unknown[]) => boolean;
57
+ /**
58
+ * Type guard that checks if a value is a symbol
59
+ * @param val - The value to check
60
+ * @returns True if the value is a symbol, false otherwise
61
+ */
62
+ export declare const isSymbol: (val: unknown) => val is symbol;
63
+ /**
64
+ * Ensures a path starts with a leading slash
65
+ * @param path - The path to process
66
+ * @returns The path with a leading slash, or empty string if path is undefined
67
+ * @example
68
+ * ```ts
69
+ * addLeadingSlash('test') // '/test'
70
+ * addLeadingSlash('/test') // '/test'
71
+ * ```
72
+ */
73
+ export declare const addLeadingSlash: (path?: string) => string;
74
+ /**
75
+ * Normalizes a path by ensuring:
76
+ * - Starts with a single slash
77
+ * - No trailing slashes
78
+ * - No consecutive slashes
79
+ *
80
+ * @param path - The path to normalize
81
+ * @returns The normalized path
82
+ * @example
83
+ * ```ts
84
+ * normalizePath('//test//') // '/test'
85
+ * normalizePath('test/path//') // '/test/path'
86
+ * ```
87
+ */
88
+ export declare const normalizePath: (path?: string) => string;
89
+ /**
90
+ * Removes the trailing slash from a path
91
+ * @param path - The path to process
92
+ * @returns The path without a trailing slash
93
+ * @example
94
+ * ```ts
95
+ * stripEndSlash('/test/') // '/test'
96
+ * stripEndSlash('/test') // '/test'
97
+ * ```
98
+ */
99
+ export declare const stripEndSlash: (path: string) => string;
100
+ /**
101
+ * Checks if a value is a constructor function
102
+ * A constructor function must:
103
+ * - Be a function
104
+ * - Have a prototype
105
+ * - Have prototype properties beyond the default ones
106
+ *
107
+ * @param val - The value to check
108
+ * @returns True if the value is a constructor function, false otherwise
109
+ * @example
110
+ * ```ts
111
+ * class Test {}
112
+ * isConstructor(Test) // true
113
+ * isConstructor(() => {}) // false
114
+ * ```
115
+ */
116
+ export declare const isConstructor: (val: unknown) => boolean;
@@ -0,0 +1 @@
1
+ export * from './common.util';
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "honestjs",
3
+ "version": "0.1.0",
4
+ "author": "Orkhan Karimov <karimovok1@gmail.com> (https://github.com/kerimovok)",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/honestjs/honest.git"
8
+ },
9
+ "main": "dist/index.js",
10
+ "module": "dist/index.js",
11
+ "devDependencies": {
12
+ "@types/bun": "latest",
13
+ "prettier": "3.5.3"
14
+ },
15
+ "peerDependencies": {
16
+ "hono": "^4",
17
+ "typescript": "^5",
18
+ "reflect-metadata": "^0.2.2"
19
+ },
20
+ "description": "Nest.js inspired framework for Hono.js",
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "homepage": "https://github.com/honestjs/honest",
25
+ "keywords": [
26
+ "nodejs",
27
+ "bun",
28
+ "deno",
29
+ "javascript",
30
+ "typescript",
31
+ "node",
32
+ "framework",
33
+ "web-framework",
34
+ "hono",
35
+ "nest",
36
+ "honest"
37
+ ],
38
+ "license": "MIT",
39
+ "publishConfig": {
40
+ "registry": "https://registry.npmjs.org"
41
+ },
42
+ "scripts": {
43
+ "clean": "rm -rf dist",
44
+ "build": "bun run clean && bun build ./src/index.ts --outdir=dist --target=node --minify --external hono --external reflect-metadata && bun run build:types",
45
+ "build:types": "tsc --emitDeclarationOnly --declaration --outDir dist",
46
+ "format": "prettier --write .",
47
+ "format:check": "prettier --check ."
48
+ },
49
+ "type": "module",
50
+ "types": "dist/index.d.ts"
51
+ }