honest-node 1.0.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 (165) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +277 -0
  3. package/dist/app.d.ts +1 -0
  4. package/dist/app.js +36 -0
  5. package/dist/application/plugin-entries.d.ts +13 -0
  6. package/dist/application/plugin-entries.js +38 -0
  7. package/dist/application/startup-guide.d.ts +4 -0
  8. package/dist/application/startup-guide.js +53 -0
  9. package/dist/application-context.d.ts +13 -0
  10. package/dist/application-context.js +22 -0
  11. package/dist/application.d.ts +34 -0
  12. package/dist/application.js +224 -0
  13. package/dist/components/index.d.ts +1 -0
  14. package/dist/components/index.js +1 -0
  15. package/dist/components/layout.component.d.ts +31 -0
  16. package/dist/components/layout.component.js +94 -0
  17. package/dist/constants/index.d.ts +2 -0
  18. package/dist/constants/index.js +2 -0
  19. package/dist/constants/pipeline.constants.d.ts +6 -0
  20. package/dist/constants/pipeline.constants.js +6 -0
  21. package/dist/constants/version.constants.d.ts +5 -0
  22. package/dist/constants/version.constants.js +5 -0
  23. package/dist/decorators/controller.decorator.d.ts +9 -0
  24. package/dist/decorators/controller.decorator.js +16 -0
  25. package/dist/decorators/http-method.decorator.d.ts +43 -0
  26. package/dist/decorators/http-method.decorator.js +44 -0
  27. package/dist/decorators/index.d.ts +11 -0
  28. package/dist/decorators/index.js +11 -0
  29. package/dist/decorators/module.decorator.d.ts +8 -0
  30. package/dist/decorators/module.decorator.js +12 -0
  31. package/dist/decorators/mvc.decorator.d.ts +26 -0
  32. package/dist/decorators/mvc.decorator.js +36 -0
  33. package/dist/decorators/parameter.decorator.d.ts +41 -0
  34. package/dist/decorators/parameter.decorator.js +59 -0
  35. package/dist/decorators/service.decorator.d.ts +6 -0
  36. package/dist/decorators/service.decorator.js +11 -0
  37. package/dist/decorators/use-component.decorator.d.ts +10 -0
  38. package/dist/decorators/use-component.decorator.js +19 -0
  39. package/dist/decorators/use-filters.decorator.d.ts +8 -0
  40. package/dist/decorators/use-filters.decorator.js +17 -0
  41. package/dist/decorators/use-guards.decorator.d.ts +9 -0
  42. package/dist/decorators/use-guards.decorator.js +18 -0
  43. package/dist/decorators/use-middleware.decorator.d.ts +9 -0
  44. package/dist/decorators/use-middleware.decorator.js +18 -0
  45. package/dist/decorators/use-pipes.decorator.d.ts +9 -0
  46. package/dist/decorators/use-pipes.decorator.js +18 -0
  47. package/dist/di/container.d.ts +34 -0
  48. package/dist/di/container.js +114 -0
  49. package/dist/di/index.d.ts +1 -0
  50. package/dist/di/index.js +1 -0
  51. package/dist/errors/framework.error.d.ts +19 -0
  52. package/dist/errors/framework.error.js +23 -0
  53. package/dist/errors/index.d.ts +1 -0
  54. package/dist/errors/index.js +1 -0
  55. package/dist/handlers/error.handler.d.ts +28 -0
  56. package/dist/handlers/error.handler.js +17 -0
  57. package/dist/handlers/index.d.ts +2 -0
  58. package/dist/handlers/index.js +2 -0
  59. package/dist/handlers/not-found.handler.d.ts +14 -0
  60. package/dist/handlers/not-found.handler.js +17 -0
  61. package/dist/helpers/create-error-response.helper.d.ts +25 -0
  62. package/dist/helpers/create-error-response.helper.js +90 -0
  63. package/dist/helpers/create-http-method-decorator.helper.d.ts +16 -0
  64. package/dist/helpers/create-http-method-decorator.helper.js +30 -0
  65. package/dist/helpers/create-param-decorator.helper.d.ts +16 -0
  66. package/dist/helpers/create-param-decorator.helper.js +60 -0
  67. package/dist/helpers/index.d.ts +3 -0
  68. package/dist/helpers/index.js +3 -0
  69. package/dist/index.d.ts +16 -0
  70. package/dist/index.js +16 -0
  71. package/dist/interfaces/application-context.interface.d.ts +35 -0
  72. package/dist/interfaces/application-context.interface.js +1 -0
  73. package/dist/interfaces/controller-options.interface.d.ts +17 -0
  74. package/dist/interfaces/controller-options.interface.js +1 -0
  75. package/dist/interfaces/di-container.interface.d.ts +35 -0
  76. package/dist/interfaces/di-container.interface.js +1 -0
  77. package/dist/interfaces/error-response.interface.d.ts +13 -0
  78. package/dist/interfaces/error-response.interface.js +1 -0
  79. package/dist/interfaces/filter.interface.d.ts +20 -0
  80. package/dist/interfaces/filter.interface.js +1 -0
  81. package/dist/interfaces/guard.interface.d.ts +21 -0
  82. package/dist/interfaces/guard.interface.js +1 -0
  83. package/dist/interfaces/handler-invocation.interface.d.ts +10 -0
  84. package/dist/interfaces/handler-invocation.interface.js +1 -0
  85. package/dist/interfaces/honest-options.interface.d.ts +121 -0
  86. package/dist/interfaces/honest-options.interface.js +1 -0
  87. package/dist/interfaces/http-method-options.interface.d.ts +38 -0
  88. package/dist/interfaces/http-method-options.interface.js +1 -0
  89. package/dist/interfaces/index.d.ts +21 -0
  90. package/dist/interfaces/index.js +21 -0
  91. package/dist/interfaces/logger.interface.d.ts +23 -0
  92. package/dist/interfaces/logger.interface.js +1 -0
  93. package/dist/interfaces/metadata-repository.interface.d.ts +30 -0
  94. package/dist/interfaces/metadata-repository.interface.js +1 -0
  95. package/dist/interfaces/middleware.interface.d.ts +22 -0
  96. package/dist/interfaces/middleware.interface.js +1 -0
  97. package/dist/interfaces/module-options.interface.d.ts +18 -0
  98. package/dist/interfaces/module-options.interface.js +1 -0
  99. package/dist/interfaces/parameter-metadata.interface.d.ts +27 -0
  100. package/dist/interfaces/parameter-metadata.interface.js +1 -0
  101. package/dist/interfaces/parameter-resolution.interface.d.ts +14 -0
  102. package/dist/interfaces/parameter-resolution.interface.js +1 -0
  103. package/dist/interfaces/pipe.interface.d.ts +37 -0
  104. package/dist/interfaces/pipe.interface.js +1 -0
  105. package/dist/interfaces/pipeline-context.interface.d.ts +9 -0
  106. package/dist/interfaces/pipeline-context.interface.js +1 -0
  107. package/dist/interfaces/plugin.interface.d.ts +74 -0
  108. package/dist/interfaces/plugin.interface.js +1 -0
  109. package/dist/interfaces/route-definition.interface.d.ts +51 -0
  110. package/dist/interfaces/route-definition.interface.js +1 -0
  111. package/dist/interfaces/route-info.interface.d.ts +42 -0
  112. package/dist/interfaces/route-info.interface.js +1 -0
  113. package/dist/interfaces/service-registry.interface.d.ts +7 -0
  114. package/dist/interfaces/service-registry.interface.js +1 -0
  115. package/dist/loggers/console.logger.d.ts +7 -0
  116. package/dist/loggers/console.logger.js +21 -0
  117. package/dist/loggers/index.d.ts +2 -0
  118. package/dist/loggers/index.js +2 -0
  119. package/dist/loggers/noop.logger.d.ts +7 -0
  120. package/dist/loggers/noop.logger.js +8 -0
  121. package/dist/managers/component.manager.d.ts +48 -0
  122. package/dist/managers/component.manager.js +210 -0
  123. package/dist/managers/handler.invoker.d.ts +7 -0
  124. package/dist/managers/handler.invoker.js +37 -0
  125. package/dist/managers/index.d.ts +5 -0
  126. package/dist/managers/index.js +5 -0
  127. package/dist/managers/parameter.resolver.d.ts +13 -0
  128. package/dist/managers/parameter.resolver.js +58 -0
  129. package/dist/managers/pipeline.executor.d.ts +28 -0
  130. package/dist/managers/pipeline.executor.js +71 -0
  131. package/dist/managers/route.manager.d.ts +36 -0
  132. package/dist/managers/route.manager.js +149 -0
  133. package/dist/registries/index.d.ts +4 -0
  134. package/dist/registries/index.js +4 -0
  135. package/dist/registries/metadata.registry.d.ts +163 -0
  136. package/dist/registries/metadata.registry.js +250 -0
  137. package/dist/registries/metadata.repository.d.ts +30 -0
  138. package/dist/registries/metadata.repository.js +151 -0
  139. package/dist/registries/route.registry.d.ts +16 -0
  140. package/dist/registries/route.registry.js +46 -0
  141. package/dist/registries/service.registry.d.ts +8 -0
  142. package/dist/registries/service.registry.js +9 -0
  143. package/dist/testing/create-controller-test-application.d.ts +5 -0
  144. package/dist/testing/create-controller-test-application.js +11 -0
  145. package/dist/testing/create-service-test-container.d.ts +5 -0
  146. package/dist/testing/create-service-test-container.js +31 -0
  147. package/dist/testing/create-test-application.d.ts +5 -0
  148. package/dist/testing/create-test-application.js +20 -0
  149. package/dist/testing/create-testing-module.d.ts +6 -0
  150. package/dist/testing/create-testing-module.js +13 -0
  151. package/dist/testing/fixtures/application-test-fixtures.d.ts +17 -0
  152. package/dist/testing/fixtures/application-test-fixtures.js +230 -0
  153. package/dist/testing/index.d.ts +5 -0
  154. package/dist/testing/index.js +5 -0
  155. package/dist/testing/testing.interface.d.ts +96 -0
  156. package/dist/testing/testing.interface.js +1 -0
  157. package/dist/types/constructor.type.d.ts +12 -0
  158. package/dist/types/constructor.type.js +1 -0
  159. package/dist/types/index.d.ts +1 -0
  160. package/dist/types/index.js +1 -0
  161. package/dist/utils/common.util.d.ts +117 -0
  162. package/dist/utils/common.util.js +140 -0
  163. package/dist/utils/index.d.ts +1 -0
  164. package/dist/utils/index.js +1 -0
  165. package/package.json +42 -0
@@ -0,0 +1,230 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Body, Controller, Get, Module, Post } from '../../decorators';
14
+ import { createParamDecorator } from '../../helpers';
15
+ export function createTestController() {
16
+ let TestController = class TestController {
17
+ index() {
18
+ return { ok: true };
19
+ }
20
+ };
21
+ __decorate([
22
+ Get(),
23
+ __metadata("design:type", Function),
24
+ __metadata("design:paramtypes", []),
25
+ __metadata("design:returntype", void 0)
26
+ ], TestController.prototype, "index", null);
27
+ TestController = __decorate([
28
+ Controller('/health')
29
+ ], TestController);
30
+ return TestController;
31
+ }
32
+ export function createPayloadController() {
33
+ let PayloadController = class PayloadController {
34
+ async echo(a, b) {
35
+ return { a, b };
36
+ }
37
+ };
38
+ __decorate([
39
+ Post('echo'),
40
+ __param(0, Body('a')),
41
+ __param(1, Body('b')),
42
+ __metadata("design:type", Function),
43
+ __metadata("design:paramtypes", [String, String]),
44
+ __metadata("design:returntype", Promise)
45
+ ], PayloadController.prototype, "echo", null);
46
+ PayloadController = __decorate([
47
+ Controller('/payload')
48
+ ], PayloadController);
49
+ return PayloadController;
50
+ }
51
+ export function createRawResponseController() {
52
+ let RawResponseController = class RawResponseController {
53
+ raw() {
54
+ return new Response('raw-ok', {
55
+ status: 201,
56
+ headers: { 'x-honest': 'yes' }
57
+ });
58
+ }
59
+ };
60
+ __decorate([
61
+ Get(),
62
+ __metadata("design:type", Function),
63
+ __metadata("design:paramtypes", []),
64
+ __metadata("design:returntype", void 0)
65
+ ], RawResponseController.prototype, "raw", null);
66
+ RawResponseController = __decorate([
67
+ Controller('/raw')
68
+ ], RawResponseController);
69
+ return RawResponseController;
70
+ }
71
+ export function createOnlyAController() {
72
+ let OnlyAController = class OnlyAController {
73
+ index() {
74
+ return { app: 'a' };
75
+ }
76
+ };
77
+ __decorate([
78
+ Get(),
79
+ __metadata("design:type", Function),
80
+ __metadata("design:paramtypes", []),
81
+ __metadata("design:returntype", void 0)
82
+ ], OnlyAController.prototype, "index", null);
83
+ OnlyAController = __decorate([
84
+ Controller('/only-a')
85
+ ], OnlyAController);
86
+ return OnlyAController;
87
+ }
88
+ export function createOnlyBController() {
89
+ let OnlyBController = class OnlyBController {
90
+ index() {
91
+ return { app: 'b' };
92
+ }
93
+ };
94
+ __decorate([
95
+ Get(),
96
+ __metadata("design:type", Function),
97
+ __metadata("design:paramtypes", []),
98
+ __metadata("design:returntype", void 0)
99
+ ], OnlyBController.prototype, "index", null);
100
+ OnlyBController = __decorate([
101
+ Controller('/only-b')
102
+ ], OnlyBController);
103
+ return OnlyBController;
104
+ }
105
+ export function createUndecoratedController() {
106
+ class UndecoratedController {
107
+ hello() {
108
+ return 'hello';
109
+ }
110
+ }
111
+ return UndecoratedController;
112
+ }
113
+ export function createBrokenControllerModule() {
114
+ const UndecoratedController = createUndecoratedController();
115
+ let BrokenControllerModule = class BrokenControllerModule {
116
+ };
117
+ BrokenControllerModule = __decorate([
118
+ Module({ controllers: [UndecoratedController] })
119
+ ], BrokenControllerModule);
120
+ return BrokenControllerModule;
121
+ }
122
+ export function createEmptyModule() {
123
+ let EmptyModule = class EmptyModule {
124
+ };
125
+ EmptyModule = __decorate([
126
+ Module()
127
+ ], EmptyModule);
128
+ return EmptyModule;
129
+ }
130
+ export function createDuplicateRouteControllers() {
131
+ let DuplicateAController = class DuplicateAController {
132
+ index() {
133
+ return { ok: 'a' };
134
+ }
135
+ };
136
+ __decorate([
137
+ Get(),
138
+ __metadata("design:type", Function),
139
+ __metadata("design:paramtypes", []),
140
+ __metadata("design:returntype", void 0)
141
+ ], DuplicateAController.prototype, "index", null);
142
+ DuplicateAController = __decorate([
143
+ Controller('/dup')
144
+ ], DuplicateAController);
145
+ let DuplicateBController = class DuplicateBController {
146
+ index() {
147
+ return { ok: 'b' };
148
+ }
149
+ };
150
+ __decorate([
151
+ Get(),
152
+ __metadata("design:type", Function),
153
+ __metadata("design:paramtypes", []),
154
+ __metadata("design:returntype", void 0)
155
+ ], DuplicateBController.prototype, "index", null);
156
+ DuplicateBController = __decorate([
157
+ Controller('/dup')
158
+ ], DuplicateBController);
159
+ return { a: DuplicateAController, b: DuplicateBController };
160
+ }
161
+ export function createUnsafeParamController() {
162
+ const unsafeParam = createParamDecorator('unsafe');
163
+ let UnsafeParamController = class UnsafeParamController {
164
+ check(value) {
165
+ return { hasValue: value !== undefined };
166
+ }
167
+ };
168
+ __decorate([
169
+ Get(),
170
+ __param(0, unsafeParam()),
171
+ __metadata("design:type", Function),
172
+ __metadata("design:paramtypes", [Object]),
173
+ __metadata("design:returntype", void 0)
174
+ ], UnsafeParamController.prototype, "check", null);
175
+ UnsafeParamController = __decorate([
176
+ Controller('/unsafe')
177
+ ], UnsafeParamController);
178
+ return UnsafeParamController;
179
+ }
180
+ export function createDiagnosticsAController() {
181
+ let DiagnosticsAController = class DiagnosticsAController {
182
+ index() {
183
+ return { controller: 'a' };
184
+ }
185
+ };
186
+ __decorate([
187
+ Get(),
188
+ __metadata("design:type", Function),
189
+ __metadata("design:paramtypes", []),
190
+ __metadata("design:returntype", void 0)
191
+ ], DiagnosticsAController.prototype, "index", null);
192
+ DiagnosticsAController = __decorate([
193
+ Controller('/diag-a')
194
+ ], DiagnosticsAController);
195
+ return DiagnosticsAController;
196
+ }
197
+ export function createDiagnosticsBController() {
198
+ let DiagnosticsBController = class DiagnosticsBController {
199
+ index() {
200
+ return { controller: 'b' };
201
+ }
202
+ };
203
+ __decorate([
204
+ Get(),
205
+ __metadata("design:type", Function),
206
+ __metadata("design:paramtypes", []),
207
+ __metadata("design:returntype", void 0)
208
+ ], DiagnosticsBController.prototype, "index", null);
209
+ DiagnosticsBController = __decorate([
210
+ Controller('/diag-b')
211
+ ], DiagnosticsBController);
212
+ return DiagnosticsBController;
213
+ }
214
+ export function createRuntimeMetadataController() {
215
+ let RuntimeMetadataController = class RuntimeMetadataController {
216
+ index() {
217
+ throw new Error('runtime metadata baseline error');
218
+ }
219
+ };
220
+ __decorate([
221
+ Get(),
222
+ __metadata("design:type", Function),
223
+ __metadata("design:paramtypes", []),
224
+ __metadata("design:returntype", void 0)
225
+ ], RuntimeMetadataController.prototype, "index", null);
226
+ RuntimeMetadataController = __decorate([
227
+ Controller('/runtime-metadata')
228
+ ], RuntimeMetadataController);
229
+ return RuntimeMetadataController;
230
+ }
@@ -0,0 +1,5 @@
1
+ export * from './create-test-application';
2
+ export * from './create-controller-test-application';
3
+ export * from './create-service-test-container';
4
+ export * from './create-testing-module';
5
+ export * from './testing.interface';
@@ -0,0 +1,5 @@
1
+ export * from './create-test-application';
2
+ export * from './create-controller-test-application';
3
+ export * from './create-service-test-container';
4
+ export * from './create-testing-module';
5
+ export * from './testing.interface';
@@ -0,0 +1,96 @@
1
+ import type { Hono } from 'hono';
2
+ import type { Application } from '../application';
3
+ import type { DiContainer, HonestOptions, ILogger, ModuleOptions } from '../interfaces';
4
+ import type { Constructor } from '../types';
5
+ /**
6
+ * Options for creating a lightweight test module.
7
+ */
8
+ export interface TestModuleOptions extends ModuleOptions {
9
+ /**
10
+ * Optional class name to improve diagnostics in test output.
11
+ */
12
+ name?: string;
13
+ }
14
+ /**
15
+ * Options for creating a test application instance.
16
+ */
17
+ export interface CreateTestApplicationOptions extends TestModuleOptions {
18
+ /**
19
+ * Existing module class to bootstrap.
20
+ * If omitted, a module is created from controllers/services/imports.
21
+ */
22
+ module?: Constructor;
23
+ /**
24
+ * Honest application options passed to Application.create.
25
+ */
26
+ appOptions?: HonestOptions;
27
+ }
28
+ /**
29
+ * Options for creating a test application around a single controller.
30
+ */
31
+ export interface CreateControllerTestApplicationOptions extends Omit<TestModuleOptions, 'controllers'> {
32
+ /**
33
+ * Controller class to mount in the generated test module.
34
+ */
35
+ controller: Constructor;
36
+ /**
37
+ * Honest application options passed to Application.create.
38
+ */
39
+ appOptions?: HonestOptions;
40
+ }
41
+ /**
42
+ * Result object returned by createTestApplication.
43
+ */
44
+ export interface TestApplication {
45
+ /**
46
+ * Honest application instance.
47
+ */
48
+ app: Application;
49
+ /**
50
+ * Underlying Hono app.
51
+ */
52
+ hono: Hono;
53
+ /**
54
+ * Convenience request helper for tests.
55
+ * Relative paths are resolved against http://localhost.
56
+ */
57
+ request: (input: string | Request, init?: RequestInit) => Promise<Response>;
58
+ }
59
+ /**
60
+ * Override a service token with a pre-built test instance.
61
+ */
62
+ export interface ServiceTestOverride<T = unknown> {
63
+ provide: Constructor<T>;
64
+ useValue: T;
65
+ }
66
+ /**
67
+ * Options for creating a service-only test container.
68
+ */
69
+ export interface CreateServiceTestContainerOptions {
70
+ /**
71
+ * Optional service overrides registered before any resolve calls.
72
+ */
73
+ overrides?: ServiceTestOverride[];
74
+ /**
75
+ * Optional services to resolve immediately so tests can assert warm startup state.
76
+ */
77
+ preload?: Constructor[];
78
+ /**
79
+ * Optional logger used when debugDi is enabled.
80
+ */
81
+ logger?: ILogger;
82
+ /**
83
+ * Enable DI diagnostics while resolving services.
84
+ */
85
+ debugDi?: boolean;
86
+ }
87
+ /**
88
+ * Service-only test harness around the DI container.
89
+ */
90
+ export interface TestServiceContainer {
91
+ container: DiContainer;
92
+ get<T>(target: Constructor<T>): T;
93
+ register<T>(target: Constructor<T>, instance: T): void;
94
+ has<T>(target: Constructor<T>): boolean;
95
+ clear(): void;
96
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -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 {};
@@ -0,0 +1 @@
1
+ export * from './constructor.type';
@@ -0,0 +1 @@
1
+ export * from './constructor.type';
@@ -0,0 +1,117 @@
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 (callable with `new`).
102
+ * A constructor function must:
103
+ * - Be a function
104
+ * - Have a non-null prototype (excludes arrow functions, which have no prototype)
105
+ * - Have a prototype that is not a function (excludes rare edge cases)
106
+ * - Have at least the built-in 'constructor' on prototype (so empty classes are constructors)
107
+ *
108
+ * @param val - The value to check
109
+ * @returns True if the value is a constructor function, false otherwise
110
+ * @example
111
+ * ```ts
112
+ * class Test {}
113
+ * isConstructor(Test) // true
114
+ * isConstructor(() => {}) // false
115
+ * ```
116
+ */
117
+ export declare const isConstructor: (val: unknown) => boolean;
@@ -0,0 +1,140 @@
1
+ // Source: https://github.com/nestjs/nest/blob/master/packages/common/utils/shared.utils.ts
2
+ /**
3
+ * Type guard that checks if a value is undefined
4
+ * @param obj - The value to check
5
+ * @returns True if the value is undefined, false otherwise
6
+ */
7
+ export const isUndefined = (obj) => typeof obj === 'undefined';
8
+ /**
9
+ * Type guard that checks if a value is null or undefined
10
+ * @param val - The value to check
11
+ * @returns True if the value is null or undefined, false otherwise
12
+ */
13
+ export const isNil = (val) => val === null || typeof val === 'undefined';
14
+ /**
15
+ * Type guard that checks if a value is an object (excluding null)
16
+ * @param val - The value to check
17
+ * @returns True if the value is a non-null object, false otherwise
18
+ */
19
+ export const isObject = (val) => val !== null && typeof val === 'object';
20
+ /**
21
+ * Type guard that checks if a value is a plain object (not a class instance or array)
22
+ * Determines if an object is a simple key-value store created by object literals
23
+ *
24
+ * @param val - The value to check
25
+ * @returns True if the value is a plain object, false otherwise
26
+ * @example
27
+ * ```ts
28
+ * isPlainObject({}) // true
29
+ * isPlainObject(new Class()) // false
30
+ * isPlainObject([]) // false
31
+ * ```
32
+ */
33
+ export const isPlainObject = (val) => {
34
+ if (!isObject(val)) {
35
+ return false;
36
+ }
37
+ const proto = Object.getPrototypeOf(val);
38
+ if (proto === null) {
39
+ return true;
40
+ }
41
+ const ctor = Object.prototype.hasOwnProperty.call(proto, 'constructor') && proto.constructor;
42
+ return (typeof ctor === 'function' &&
43
+ ctor instanceof ctor &&
44
+ Function.prototype.toString.call(ctor) === Function.prototype.toString.call(Object));
45
+ };
46
+ /**
47
+ * Type guard that checks if a value is a function
48
+ * @param val - The value to check
49
+ * @returns True if the value is a function, false otherwise
50
+ */
51
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
52
+ export const isFunction = (val) => typeof val === 'function';
53
+ /**
54
+ * Type guard that checks if a value is a string
55
+ * @param val - The value to check
56
+ * @returns True if the value is a string, false otherwise
57
+ */
58
+ export const isString = (val) => typeof val === 'string';
59
+ /**
60
+ * Type guard that checks if a value is a number
61
+ * @param val - The value to check
62
+ * @returns True if the value is a number, false otherwise
63
+ */
64
+ export const isNumber = (val) => typeof val === 'number';
65
+ /**
66
+ * Checks if an array is empty
67
+ * @param array - The array to check
68
+ * @returns True if the array has no elements, false otherwise
69
+ */
70
+ export const isEmpty = (array) => array.length === 0;
71
+ /**
72
+ * Type guard that checks if a value is a symbol
73
+ * @param val - The value to check
74
+ * @returns True if the value is a symbol, false otherwise
75
+ */
76
+ export const isSymbol = (val) => typeof val === 'symbol';
77
+ /**
78
+ * Ensures a path starts with a leading slash
79
+ * @param path - The path to process
80
+ * @returns The path with a leading slash, or empty string if path is undefined
81
+ * @example
82
+ * ```ts
83
+ * addLeadingSlash('test') // '/test'
84
+ * addLeadingSlash('/test') // '/test'
85
+ * ```
86
+ */
87
+ export const addLeadingSlash = (path) => typeof path === 'string' ? (path.charAt(0) !== '/' ? '/' + path : path) : '';
88
+ /**
89
+ * Normalizes a path by ensuring:
90
+ * - Starts with a single slash
91
+ * - No trailing slashes
92
+ * - No consecutive slashes
93
+ *
94
+ * @param path - The path to normalize
95
+ * @returns The normalized path
96
+ * @example
97
+ * ```ts
98
+ * normalizePath('//test//') // '/test'
99
+ * normalizePath('test/path//') // '/test/path'
100
+ * ```
101
+ */
102
+ export const normalizePath = (path) => path
103
+ ? path.startsWith('/')
104
+ ? ('/' + path.replace(/\/+$/, '')).replace(/\/+/g, '/')
105
+ : '/' + path.replace(/\/+$/, '')
106
+ : '/';
107
+ /**
108
+ * Removes the trailing slash from a path
109
+ * @param path - The path to process
110
+ * @returns The path without a trailing slash
111
+ * @example
112
+ * ```ts
113
+ * stripEndSlash('/test/') // '/test'
114
+ * stripEndSlash('/test') // '/test'
115
+ * ```
116
+ */
117
+ export const stripEndSlash = (path) => (path.endsWith('/') ? path.slice(0, -1) : path);
118
+ /**
119
+ * Checks if a value is a constructor function (callable with `new`).
120
+ * A constructor function must:
121
+ * - Be a function
122
+ * - Have a non-null prototype (excludes arrow functions, which have no prototype)
123
+ * - Have a prototype that is not a function (excludes rare edge cases)
124
+ * - Have at least the built-in 'constructor' on prototype (so empty classes are constructors)
125
+ *
126
+ * @param val - The value to check
127
+ * @returns True if the value is a constructor function, false otherwise
128
+ * @example
129
+ * ```ts
130
+ * class Test {}
131
+ * isConstructor(Test) // true
132
+ * isConstructor(() => {}) // false
133
+ * ```
134
+ */
135
+ export const isConstructor = (val) => {
136
+ return (isFunction(val) &&
137
+ !isNil(val.prototype) &&
138
+ !isFunction(val.prototype) &&
139
+ Object.getOwnPropertyNames(val.prototype).length >= 1);
140
+ };
@@ -0,0 +1 @@
1
+ export * from './common.util';
@@ -0,0 +1 @@
1
+ export * from './common.util';
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "honest-node",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "engines": {
8
+ "node": ">=20.11.0",
9
+ "pnpm": ">=10.0.0"
10
+ },
11
+ "scripts": {
12
+ "clean": "rm -rf dist",
13
+ "test": "vitest run",
14
+ "test:watch": "vitest",
15
+ "test:coverage": "vitest run --coverage",
16
+ "format": "biome format --write package.json tsconfig.json src",
17
+ "build": "tsc -p tsconfig.json",
18
+ "build:preview": "tsc -p tsconfig.json --noEmit",
19
+ "lint": "biome lint src --ignore='**/*.test.ts'",
20
+ "lint:fix": "biome lint src --ignore='**/*.test.ts' --fix",
21
+ "check": "pnpm lint && pnpm test"
22
+ },
23
+ "keywords": [],
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "author": "",
28
+ "license": "ISC",
29
+ "packageManager": "pnpm@10.33.0",
30
+ "devDependencies": {
31
+ "@types/node": "^25.6.0",
32
+ "biome": "^0.3.3",
33
+ "lefthook": "^2.1.5",
34
+ "tsx": "^4.21.0",
35
+ "typescript": "^6.0.2",
36
+ "vitest": "^4.1.4"
37
+ },
38
+ "dependencies": {
39
+ "hono": "^4.12.12",
40
+ "reflect-metadata": "^0.2.2"
41
+ }
42
+ }