awilixify 2.2.1 → 3.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 (119) hide show
  1. package/README.md +15 -6
  2. package/dist/index.d.ts +19 -0
  3. package/dist/index.js +15 -0
  4. package/dist/lib/decorators/decorator-state.d.ts +15 -0
  5. package/dist/lib/decorators/decorator-state.js +72 -0
  6. package/dist/lib/decorators/decorator-state.types.d.ts +35 -0
  7. package/dist/lib/decorators/decorator-state.types.js +1 -0
  8. package/dist/lib/devtools/devtools.types.d.ts +63 -0
  9. package/dist/lib/devtools/devtools.types.js +1 -0
  10. package/dist/lib/devtools/helpers.d.ts +2 -0
  11. package/dist/lib/devtools/helpers.js +18 -0
  12. package/dist/lib/devtools/index.d.ts +4 -0
  13. package/dist/lib/devtools/index.js +3 -0
  14. package/dist/lib/di/common.types.d.ts +6 -0
  15. package/dist/lib/di/common.types.js +1 -0
  16. package/dist/lib/di/contexts/container-context-base.d.ts +63 -0
  17. package/dist/lib/di/contexts/container-context-base.js +232 -0
  18. package/dist/lib/di/contexts/di-context-async.d.ts +14 -0
  19. package/dist/lib/di/contexts/di-context-async.js +118 -0
  20. package/dist/lib/di/contexts/di-context-base.d.ts +19 -0
  21. package/dist/lib/di/contexts/di-context-base.js +33 -0
  22. package/dist/lib/di/contexts/di-context.d.ts +7 -0
  23. package/dist/lib/di/contexts/di-context.js +9 -0
  24. package/dist/lib/di/contexts/module-graph-ensurer.d.ts +32 -0
  25. package/dist/lib/di/contexts/module-graph-ensurer.js +50 -0
  26. package/dist/lib/di/errors.d.ts +69 -0
  27. package/dist/lib/di/errors.js +154 -0
  28. package/dist/lib/di/modules/module-def.types.d.ts +117 -0
  29. package/dist/lib/di/modules/module-def.types.js +1 -0
  30. package/dist/lib/di/modules/module-factories.d.ts +16 -0
  31. package/dist/lib/di/modules/module-factories.js +54 -0
  32. package/dist/lib/di/modules/module-overrides.d.ts +70 -0
  33. package/dist/lib/di/modules/module-overrides.js +3 -0
  34. package/dist/lib/di/modules/module-ref.types.d.ts +13 -0
  35. package/dist/lib/di/modules/module-ref.types.js +1 -0
  36. package/dist/lib/di/modules/module.types.d.ts +178 -0
  37. package/dist/lib/di/modules/module.types.js +1 -0
  38. package/dist/lib/di/modules/runtime-module.types.d.ts +32 -0
  39. package/dist/lib/di/modules/runtime-module.types.js +1 -0
  40. package/dist/lib/di/processors/controller-processor.d.ts +13 -0
  41. package/dist/lib/di/processors/controller-processor.js +76 -0
  42. package/dist/lib/di/processors/handler-processor.d.ts +19 -0
  43. package/dist/lib/di/processors/handler-processor.js +103 -0
  44. package/dist/lib/di/processors/initializer-processor.d.ts +20 -0
  45. package/dist/lib/di/processors/initializer-processor.js +95 -0
  46. package/dist/lib/di/processors/interceptor-processor.d.ts +21 -0
  47. package/dist/lib/di/processors/interceptor-processor.js +117 -0
  48. package/dist/lib/di/processors/keyed-feature-registrar.d.ts +19 -0
  49. package/dist/lib/di/processors/keyed-feature-registrar.js +112 -0
  50. package/dist/lib/di/processors/lifecycle-processor.d.ts +37 -0
  51. package/dist/lib/di/processors/lifecycle-processor.js +175 -0
  52. package/dist/lib/di/processors/overrides-processor.d.ts +24 -0
  53. package/dist/lib/di/processors/overrides-processor.js +69 -0
  54. package/dist/lib/di/providers/provider-dependency-sorter.d.ts +9 -0
  55. package/dist/lib/di/providers/provider-dependency-sorter.js +76 -0
  56. package/dist/lib/di/providers/provider-resolver.d.ts +35 -0
  57. package/dist/lib/di/providers/provider-resolver.js +168 -0
  58. package/dist/lib/di/providers/provider.types.d.ts +1 -0
  59. package/dist/lib/di/providers/provider.types.js +1 -0
  60. package/dist/lib/di/providers/types/controller.types.d.ts +9 -0
  61. package/dist/lib/di/providers/types/controller.types.js +1 -0
  62. package/dist/lib/di/providers/types/decorator-context.types.d.ts +9 -0
  63. package/dist/lib/di/providers/types/decorator-context.types.js +1 -0
  64. package/dist/lib/di/providers/types/handler.types.d.ts +9 -0
  65. package/dist/lib/di/providers/types/handler.types.js +1 -0
  66. package/dist/lib/di/providers/types/index.d.ts +7 -0
  67. package/dist/lib/di/providers/types/index.js +7 -0
  68. package/dist/lib/di/providers/types/initializer.types.d.ts +16 -0
  69. package/dist/lib/di/providers/types/initializer.types.js +3 -0
  70. package/dist/lib/di/providers/types/interceptor.types.d.ts +18 -0
  71. package/dist/lib/di/providers/types/interceptor.types.js +1 -0
  72. package/dist/lib/di/providers/types/middleware.types.d.ts +10 -0
  73. package/dist/lib/di/providers/types/middleware.types.js +1 -0
  74. package/dist/lib/di/providers/types/provider.types.d.ts +26 -0
  75. package/dist/lib/di/providers/types/provider.types.js +1 -0
  76. package/dist/lib/di/request-scope-context.d.ts +5 -0
  77. package/dist/lib/di/request-scope-context.js +28 -0
  78. package/dist/lib/di/type-guards.d.ts +35 -0
  79. package/dist/lib/di/type-guards.js +84 -0
  80. package/dist/lib/http/decorators.d.ts +33 -0
  81. package/dist/lib/http/decorators.js +151 -0
  82. package/dist/lib/http/exceptions.d.ts +58 -0
  83. package/dist/lib/http/exceptions.js +71 -0
  84. package/dist/lib/http/http-verbs.d.ts +12 -0
  85. package/dist/lib/http/http-verbs.js +11 -0
  86. package/dist/lib/http/index.d.ts +3 -0
  87. package/dist/lib/http/index.js +3 -0
  88. package/dist/lib/http/openapi-builder.d.ts +27 -0
  89. package/dist/lib/http/openapi-builder.js +83 -0
  90. package/dist/lib/mediator/contract.types.d.ts +159 -0
  91. package/dist/lib/mediator/contract.types.js +1 -0
  92. package/dist/lib/mediator/errors.d.ts +15 -0
  93. package/dist/lib/mediator/errors.js +33 -0
  94. package/dist/lib/mediator/global-middlewares.types.d.ts +13 -0
  95. package/dist/lib/mediator/global-middlewares.types.js +1 -0
  96. package/dist/lib/mediator/handler.types.d.ts +16 -0
  97. package/dist/lib/mediator/handler.types.js +1 -0
  98. package/dist/lib/mediator/mediator.d.ts +24 -0
  99. package/dist/lib/mediator/mediator.js +134 -0
  100. package/dist/lib/mediator/mediator.types.d.ts +64 -0
  101. package/dist/lib/mediator/mediator.types.js +1 -0
  102. package/dist/lib/mediator/middleware.types.d.ts +41 -0
  103. package/dist/lib/mediator/middleware.types.js +1 -0
  104. package/dist/lib/mediator/result.d.ts +18 -0
  105. package/dist/lib/mediator/result.js +24 -0
  106. package/dist/lib/react/errors.d.ts +12 -0
  107. package/dist/lib/react/errors.js +24 -0
  108. package/dist/lib/react/index.d.ts +4 -0
  109. package/dist/lib/react/index.js +4 -0
  110. package/dist/lib/react/react-component-processor.d.ts +10 -0
  111. package/dist/lib/react/react-component-processor.js +62 -0
  112. package/dist/lib/react/react-di-context.d.ts +16 -0
  113. package/dist/lib/react/react-di-context.js +52 -0
  114. package/dist/lib/react/react-module-factories.d.ts +6 -0
  115. package/dist/lib/react/react-module-factories.js +34 -0
  116. package/dist/lib/react/react-module.types.d.ts +169 -0
  117. package/dist/lib/react/react-module.types.js +1 -0
  118. package/dist/tsconfig.tsbuildinfo +1 -0
  119. package/package.json +33 -3
@@ -0,0 +1,151 @@
1
+ import { createDecoratorStateUpdater } from "../decorators/decorator-state.js";
2
+ import { HttpVerbs } from "./http-verbs.js";
3
+ const { update, token } = createDecoratorStateUpdater("http-decorator-state", {
4
+ method: () => ({
5
+ paths: [],
6
+ beforeMiddleware: [],
7
+ afterMiddleware: [],
8
+ verbs: [],
9
+ schema: {},
10
+ }),
11
+ root: () => ({
12
+ paths: [],
13
+ beforeMiddleware: [],
14
+ afterMiddleware: [],
15
+ }),
16
+ });
17
+ export const HTTP_DECORATOR_STATE_TOKEN = token;
18
+ function createRouteDecorator(httpVerb) {
19
+ return (path = "/") => (target, context) => {
20
+ update(context, {
21
+ method: (previous) => {
22
+ return {
23
+ ...previous,
24
+ verbs: uniq([...previous.verbs, httpVerb]),
25
+ paths: uniq([...previous.paths, path]),
26
+ };
27
+ },
28
+ });
29
+ return target;
30
+ };
31
+ }
32
+ export const GET = createRouteDecorator(HttpVerbs.GET);
33
+ export const POST = createRouteDecorator(HttpVerbs.POST);
34
+ export const PUT = createRouteDecorator(HttpVerbs.PUT);
35
+ export const DELETE = createRouteDecorator(HttpVerbs.DELETE);
36
+ export const PATCH = createRouteDecorator(HttpVerbs.PATCH);
37
+ export function controller(options) {
38
+ return (target, context) => {
39
+ if (!options)
40
+ return target;
41
+ update(context, {
42
+ root: (previous) => {
43
+ return {
44
+ ...previous,
45
+ paths: uniq([...previous.paths, ...normalizePaths(options)]),
46
+ };
47
+ },
48
+ });
49
+ return target;
50
+ };
51
+ }
52
+ export function before(middleware) {
53
+ return (target, context) => {
54
+ if (context.kind === "class") {
55
+ update(context, {
56
+ root: (previous) => {
57
+ return {
58
+ ...previous,
59
+ beforeMiddleware: appendMiddleware(previous.beforeMiddleware, middleware),
60
+ };
61
+ },
62
+ });
63
+ return target;
64
+ }
65
+ update(context, {
66
+ method: (previous) => {
67
+ return {
68
+ ...previous,
69
+ beforeMiddleware: appendMiddleware(previous.beforeMiddleware, middleware),
70
+ };
71
+ },
72
+ });
73
+ return target;
74
+ };
75
+ }
76
+ export function after(middleware) {
77
+ return (target, context) => {
78
+ if (context.kind === "class") {
79
+ update(context, {
80
+ root: (previous) => {
81
+ return {
82
+ ...previous,
83
+ afterMiddleware: appendMiddleware(previous.afterMiddleware, middleware),
84
+ };
85
+ },
86
+ });
87
+ return target;
88
+ }
89
+ update(context, {
90
+ method: (previous) => {
91
+ return {
92
+ ...previous,
93
+ afterMiddleware: appendMiddleware(previous.afterMiddleware, middleware),
94
+ };
95
+ },
96
+ });
97
+ return target;
98
+ };
99
+ }
100
+ export function schema(schema) {
101
+ return (target, context) => {
102
+ update(context, {
103
+ method: (previous) => {
104
+ return {
105
+ ...previous,
106
+ schema,
107
+ };
108
+ },
109
+ });
110
+ return target;
111
+ };
112
+ }
113
+ function uniq(items) {
114
+ const result = [];
115
+ for (const item of items) {
116
+ if (!result.includes(item))
117
+ result.push(item);
118
+ }
119
+ return result;
120
+ }
121
+ function normalizePaths(options) {
122
+ if (typeof options === "string")
123
+ return [options];
124
+ if (Array.isArray(options))
125
+ return options;
126
+ return Array.isArray(options.path) ? options.path : [options.path];
127
+ }
128
+ function appendMiddleware(target, incoming) {
129
+ return Array.isArray(incoming)
130
+ ? [...target, ...incoming]
131
+ : [...target, incoming];
132
+ }
133
+ export function rollUpHttpDecoratorState(root, method) {
134
+ return {
135
+ ...method,
136
+ paths: concatPaths(root.paths, method.paths),
137
+ beforeMiddleware: [...root.beforeMiddleware, ...method.beforeMiddleware],
138
+ afterMiddleware: [...method.afterMiddleware, ...root.afterMiddleware],
139
+ };
140
+ }
141
+ function concatPaths(rootPaths, methodPaths) {
142
+ if (rootPaths.length === 0)
143
+ return [...methodPaths];
144
+ const result = [];
145
+ rootPaths.forEach((rootPath) => {
146
+ methodPaths.forEach((methodPath) => {
147
+ result.push(rootPath + methodPath);
148
+ });
149
+ });
150
+ return result;
151
+ }
@@ -0,0 +1,58 @@
1
+ export declare enum HttpStatus {
2
+ OK = 200,
3
+ CREATED = 201,
4
+ BAD_REQUEST = 400,
5
+ UNAUTHORIZED = 401,
6
+ FORBIDDEN = 403,
7
+ NOT_FOUND = 404,
8
+ METHOD_NOT_ALLOWED = 405,
9
+ NOT_ACCEPTABLE = 406,
10
+ REQUEST_TIMEOUT = 408,
11
+ CONFLICT = 409,
12
+ GONE = 410,
13
+ PRECONDITION_FAILED = 412,
14
+ PAYLOAD_TOO_LARGE = 413,
15
+ UNSUPPORTED_MEDIA_TYPE = 415,
16
+ I_AM_A_TEAPOT = 418,
17
+ UNPROCESSABLE_ENTITY = 422,
18
+ INTERNAL_SERVER_ERROR = 500,
19
+ NOT_IMPLEMENTED = 501,
20
+ BAD_GATEWAY = 502,
21
+ SERVICE_UNAVAILABLE = 503,
22
+ GATEWAY_TIMEOUT = 504,
23
+ HTTP_VERSION_NOT_SUPPORTED = 505
24
+ }
25
+ export declare class HttpException<TMessage extends string, TStatus extends HttpStatus = HttpStatus> extends Error {
26
+ readonly message: TMessage;
27
+ readonly statusCode: TStatus;
28
+ readonly response?: (Record<string, any> | null) | undefined;
29
+ constructor(message: TMessage, statusCode: TStatus, response?: (Record<string, any> | null) | undefined);
30
+ getResponse(): {
31
+ message: TMessage;
32
+ statusCode: TStatus;
33
+ [key: string]: any;
34
+ };
35
+ getStatus(): TStatus;
36
+ }
37
+ export declare const httpException: {
38
+ badRequest: <M extends string = "Bad Request">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Bad Request" : M, HttpStatus.BAD_REQUEST>;
39
+ unauthorized: <M extends string = "Unauthorized">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Unauthorized" : M, HttpStatus.UNAUTHORIZED>;
40
+ forbidden: <M extends string = "Forbidden">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Forbidden" : M, HttpStatus.FORBIDDEN>;
41
+ notFound: <M extends string = "Not Found">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Not Found" : M, HttpStatus.NOT_FOUND>;
42
+ methodNotAllowed: <M extends string = "Method Not Allowed">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Method Not Allowed" : M, HttpStatus.METHOD_NOT_ALLOWED>;
43
+ notAcceptable: <M extends string = "Not Acceptable">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Not Acceptable" : M, HttpStatus.NOT_ACCEPTABLE>;
44
+ requestTimeout: <M extends string = "Request Timeout">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Request Timeout" : M, HttpStatus.REQUEST_TIMEOUT>;
45
+ conflict: <M extends string = "Conflict">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Conflict" : M, HttpStatus.CONFLICT>;
46
+ gone: <M extends string = "Gone">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Gone" : M, HttpStatus.GONE>;
47
+ preconditionFailed: <M extends string = "Precondition Failed">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Precondition Failed" : M, HttpStatus.PRECONDITION_FAILED>;
48
+ payloadTooLarge: <M extends string = "Payload Too Large">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Payload Too Large" : M, HttpStatus.PAYLOAD_TOO_LARGE>;
49
+ unsupportedMediaType: <M extends string = "Unsupported Media Type">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Unsupported Media Type" : M, HttpStatus.UNSUPPORTED_MEDIA_TYPE>;
50
+ imATeapot: <M extends string = "I'm a teapot">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "I'm a teapot" : M, HttpStatus.I_AM_A_TEAPOT>;
51
+ unprocessableEntity: <M extends string = "Unprocessable Entity">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Unprocessable Entity" : M, HttpStatus.UNPROCESSABLE_ENTITY>;
52
+ internalServerError: <M extends string = "Internal Server Error">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Internal Server Error" : M, HttpStatus.INTERNAL_SERVER_ERROR>;
53
+ notImplemented: <M extends string = "Not Implemented">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Not Implemented" : M, HttpStatus.NOT_IMPLEMENTED>;
54
+ badGateway: <M extends string = "Bad Gateway">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Bad Gateway" : M, HttpStatus.BAD_GATEWAY>;
55
+ serviceUnavailable: <M extends string = "Service Unavailable">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Service Unavailable" : M, HttpStatus.SERVICE_UNAVAILABLE>;
56
+ gatewayTimeout: <M extends string = "Gateway Timeout">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "Gateway Timeout" : M, HttpStatus.GATEWAY_TIMEOUT>;
57
+ httpVersionNotSupported: <M extends string = "HTTP Version Not Supported">(message?: M | undefined, response?: Record<string, any>) => HttpException<M extends undefined ? "HTTP Version Not Supported" : M, HttpStatus.HTTP_VERSION_NOT_SUPPORTED>;
58
+ };
@@ -0,0 +1,71 @@
1
+ export var HttpStatus;
2
+ (function (HttpStatus) {
3
+ HttpStatus[HttpStatus["OK"] = 200] = "OK";
4
+ HttpStatus[HttpStatus["CREATED"] = 201] = "CREATED";
5
+ HttpStatus[HttpStatus["BAD_REQUEST"] = 400] = "BAD_REQUEST";
6
+ HttpStatus[HttpStatus["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
7
+ HttpStatus[HttpStatus["FORBIDDEN"] = 403] = "FORBIDDEN";
8
+ HttpStatus[HttpStatus["NOT_FOUND"] = 404] = "NOT_FOUND";
9
+ HttpStatus[HttpStatus["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
10
+ HttpStatus[HttpStatus["NOT_ACCEPTABLE"] = 406] = "NOT_ACCEPTABLE";
11
+ HttpStatus[HttpStatus["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
12
+ HttpStatus[HttpStatus["CONFLICT"] = 409] = "CONFLICT";
13
+ HttpStatus[HttpStatus["GONE"] = 410] = "GONE";
14
+ HttpStatus[HttpStatus["PRECONDITION_FAILED"] = 412] = "PRECONDITION_FAILED";
15
+ HttpStatus[HttpStatus["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
16
+ HttpStatus[HttpStatus["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
17
+ HttpStatus[HttpStatus["I_AM_A_TEAPOT"] = 418] = "I_AM_A_TEAPOT";
18
+ HttpStatus[HttpStatus["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
19
+ HttpStatus[HttpStatus["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
20
+ HttpStatus[HttpStatus["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
21
+ HttpStatus[HttpStatus["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
22
+ HttpStatus[HttpStatus["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
23
+ HttpStatus[HttpStatus["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
24
+ HttpStatus[HttpStatus["HTTP_VERSION_NOT_SUPPORTED"] = 505] = "HTTP_VERSION_NOT_SUPPORTED";
25
+ })(HttpStatus || (HttpStatus = {}));
26
+ export class HttpException extends Error {
27
+ message;
28
+ statusCode;
29
+ response;
30
+ constructor(message, statusCode, response) {
31
+ super(message);
32
+ this.message = message;
33
+ this.statusCode = statusCode;
34
+ this.response = response;
35
+ this.name = this.constructor.name;
36
+ Error.captureStackTrace(this, this.constructor);
37
+ }
38
+ getResponse() {
39
+ return {
40
+ message: this.message,
41
+ statusCode: this.statusCode,
42
+ ...this.response,
43
+ };
44
+ }
45
+ getStatus() {
46
+ return this.statusCode;
47
+ }
48
+ }
49
+ const createFactory = (defaultMessage, status) => (message, response) => new HttpException((message ?? defaultMessage), status, response);
50
+ export const httpException = {
51
+ badRequest: createFactory("Bad Request", HttpStatus.BAD_REQUEST),
52
+ unauthorized: createFactory("Unauthorized", HttpStatus.UNAUTHORIZED),
53
+ forbidden: createFactory("Forbidden", HttpStatus.FORBIDDEN),
54
+ notFound: createFactory("Not Found", HttpStatus.NOT_FOUND),
55
+ methodNotAllowed: createFactory("Method Not Allowed", HttpStatus.METHOD_NOT_ALLOWED),
56
+ notAcceptable: createFactory("Not Acceptable", HttpStatus.NOT_ACCEPTABLE),
57
+ requestTimeout: createFactory("Request Timeout", HttpStatus.REQUEST_TIMEOUT),
58
+ conflict: createFactory("Conflict", HttpStatus.CONFLICT),
59
+ gone: createFactory("Gone", HttpStatus.GONE),
60
+ preconditionFailed: createFactory("Precondition Failed", HttpStatus.PRECONDITION_FAILED),
61
+ payloadTooLarge: createFactory("Payload Too Large", HttpStatus.PAYLOAD_TOO_LARGE),
62
+ unsupportedMediaType: createFactory("Unsupported Media Type", HttpStatus.UNSUPPORTED_MEDIA_TYPE),
63
+ imATeapot: createFactory("I'm a teapot", HttpStatus.I_AM_A_TEAPOT),
64
+ unprocessableEntity: createFactory("Unprocessable Entity", HttpStatus.UNPROCESSABLE_ENTITY),
65
+ internalServerError: createFactory("Internal Server Error", HttpStatus.INTERNAL_SERVER_ERROR),
66
+ notImplemented: createFactory("Not Implemented", HttpStatus.NOT_IMPLEMENTED),
67
+ badGateway: createFactory("Bad Gateway", HttpStatus.BAD_GATEWAY),
68
+ serviceUnavailable: createFactory("Service Unavailable", HttpStatus.SERVICE_UNAVAILABLE),
69
+ gatewayTimeout: createFactory("Gateway Timeout", HttpStatus.GATEWAY_TIMEOUT),
70
+ httpVersionNotSupported: createFactory("HTTP Version Not Supported", HttpStatus.HTTP_VERSION_NOT_SUPPORTED),
71
+ };
@@ -0,0 +1,12 @@
1
+ export type HttpVerb = "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "PATCH" | "*";
2
+ export declare const HttpVerbs: {
3
+ readonly GET: "GET";
4
+ readonly HEAD: "HEAD";
5
+ readonly POST: "POST";
6
+ readonly PUT: "PUT";
7
+ readonly DELETE: "DELETE";
8
+ readonly CONNECT: "CONNECT";
9
+ readonly OPTIONS: "OPTIONS";
10
+ readonly PATCH: "PATCH";
11
+ readonly ALL: "*";
12
+ };
@@ -0,0 +1,11 @@
1
+ export const HttpVerbs = {
2
+ GET: "GET",
3
+ HEAD: "HEAD",
4
+ POST: "POST",
5
+ PUT: "PUT",
6
+ DELETE: "DELETE",
7
+ CONNECT: "CONNECT",
8
+ OPTIONS: "OPTIONS",
9
+ PATCH: "PATCH",
10
+ ALL: "*",
11
+ };
@@ -0,0 +1,3 @@
1
+ export * from "./decorators.js";
2
+ export * from "./exceptions.js";
3
+ export * from "./openapi-builder.js";
@@ -0,0 +1,3 @@
1
+ export * from "./decorators.js";
2
+ export * from "./exceptions.js";
3
+ export * from "./openapi-builder.js";
@@ -0,0 +1,27 @@
1
+ export interface RouteRegistration {
2
+ method: string;
3
+ path: string;
4
+ schema: RouteSchema;
5
+ }
6
+ export interface RouteSchema {
7
+ body?: unknown;
8
+ querystring?: unknown;
9
+ params?: unknown;
10
+ headers?: unknown;
11
+ response?: unknown;
12
+ description?: string;
13
+ summary?: string;
14
+ tags?: string[];
15
+ operationId?: string;
16
+ deprecated?: boolean;
17
+ }
18
+ export declare function hasValidationSchema(schema: RouteSchema): boolean;
19
+ export declare class OpenAPIBuilder {
20
+ private routes;
21
+ registerRoute(method: string, path: string, schema: RouteSchema): void;
22
+ buildPaths(): Record<string, any>;
23
+ private buildOperation;
24
+ private buildParameters;
25
+ private buildRequestBody;
26
+ private buildResponses;
27
+ }
@@ -0,0 +1,83 @@
1
+ export function hasValidationSchema(schema) {
2
+ return !!(schema?.body ||
3
+ schema?.querystring ||
4
+ schema?.params ||
5
+ schema?.headers);
6
+ }
7
+ export class OpenAPIBuilder {
8
+ routes = [];
9
+ registerRoute(method, path, schema) {
10
+ this.routes.push({ method: method.toLowerCase(), path, schema });
11
+ }
12
+ buildPaths() {
13
+ return this.routes.reduce((paths, route) => {
14
+ paths[route.path] ??= {};
15
+ paths[route.path][route.method] = this.buildOperation(route.schema);
16
+ return paths;
17
+ }, {});
18
+ }
19
+ buildOperation(schema) {
20
+ const parameters = this.buildParameters(schema);
21
+ const requestBody = this.buildRequestBody(schema);
22
+ const responses = this.buildResponses(schema);
23
+ return {
24
+ ...(schema.summary && { summary: schema.summary }),
25
+ ...(schema.description && { description: schema.description }),
26
+ ...(schema.tags && { tags: schema.tags }),
27
+ ...(schema.operationId && { operationId: schema.operationId }),
28
+ ...(schema.deprecated && { deprecated: schema.deprecated }),
29
+ ...(parameters.length > 0 && { parameters }),
30
+ ...(requestBody && { requestBody }),
31
+ responses,
32
+ };
33
+ }
34
+ buildParameters(schema) {
35
+ const parameters = [];
36
+ const querySchema = schema.querystring;
37
+ if (querySchema?.properties) {
38
+ parameters.push(...Object.entries(querySchema.properties).map(([name, propSchema]) => ({
39
+ name,
40
+ in: "query",
41
+ required: querySchema.required?.includes(name) ?? false,
42
+ schema: propSchema,
43
+ })));
44
+ }
45
+ const paramsSchema = schema.params;
46
+ if (paramsSchema?.properties) {
47
+ parameters.push(...Object.entries(paramsSchema.properties).map(([name, propSchema]) => ({
48
+ name,
49
+ in: "path",
50
+ required: true,
51
+ schema: propSchema,
52
+ })));
53
+ }
54
+ return parameters;
55
+ }
56
+ buildRequestBody(schema) {
57
+ return schema.body
58
+ ? {
59
+ required: true,
60
+ content: {
61
+ "application/json": {
62
+ schema: schema.body,
63
+ },
64
+ },
65
+ }
66
+ : undefined;
67
+ }
68
+ buildResponses(schema) {
69
+ if (!schema.response)
70
+ return {};
71
+ return Object.entries(schema.response).reduce((acc, [statusCode, responseSchema]) => {
72
+ acc[statusCode] = {
73
+ description: statusCode === "200" ? "Successful response" : "Response",
74
+ content: {
75
+ "application/json": {
76
+ schema: responseSchema,
77
+ },
78
+ },
79
+ };
80
+ return acc;
81
+ }, {});
82
+ }
83
+ }
@@ -0,0 +1,159 @@
1
+ import type { EmptyObject } from "../di/common.types.js";
2
+ import type { Module, ModuleDefinition, ModuleImport } from "../di/modules/module.types.js";
3
+ import type { DefPreHandlerMap } from "../di/providers/provider.types.js";
4
+ import type { GlobalCommandPreHandlers, GlobalQueryPreHandlers, NormalizeGlobalPreHandlerMap } from "./global-middlewares.types.js";
5
+ import type { EmptyContext } from "./middleware.types.js";
6
+ type QueryContractModuleDef = {
7
+ queryPreHandlers?: DefPreHandlerMap;
8
+ imports?: readonly ModuleImport[];
9
+ };
10
+ type EmptyModuleDef = Record<never, never>;
11
+ type CommandContractModuleDef = {
12
+ commandPreHandlers?: DefPreHandlerMap;
13
+ imports?: readonly ModuleImport[];
14
+ };
15
+ type ContractScenario<TPreHandlerKey extends string> = {
16
+ name: string;
17
+ includePreHandlerKeys?: readonly TPreHandlerKey[];
18
+ excludePreHandlerKeys?: readonly TPreHandlerKey[];
19
+ };
20
+ type PreHandlerExportKey = "queryPreHandlerExports" | "commandPreHandlerExports";
21
+ type ExtractModuleDef<T> = T extends Module<infer TDef extends ModuleDefinition> ? TDef : T extends Record<string, unknown> ? T : never;
22
+ type ExtractExportedPreHandlerMap<TModuleDef, TExportKey extends PreHandlerExportKey> = TModuleDef extends {
23
+ [K in TExportKey]?: infer E;
24
+ } ? [NonNullable<E>] extends [DefPreHandlerMap] ? NonNullable<E> : EmptyObject : EmptyObject;
25
+ type ExtractPreHandlerMapFromImports<TImports extends readonly ModuleImport[] | undefined, TExportKey extends PreHandlerExportKey> = TImports extends readonly [
26
+ infer First,
27
+ ...infer Rest extends readonly ModuleImport[]
28
+ ] ? ExtractExportedPreHandlerMap<ExtractModuleDef<First>, TExportKey> & ExtractPreHandlerMapFromImports<Rest, TExportKey> : EmptyObject;
29
+ type ExtractMiddlewareContract<M> = M extends {
30
+ readonly contract: infer C;
31
+ } ? C : M extends new (...args: any[]) => infer I ? I extends {
32
+ readonly contract: infer C;
33
+ } ? C : never : M extends {
34
+ useClass: infer U;
35
+ } ? ExtractMiddlewareContract<U> : never;
36
+ type ExtractContextData<T> = T extends Result<infer Data, any> ? Data extends Record<string, unknown> ? Data : never : T extends Record<string, unknown> ? T : never;
37
+ type ExtractContextFromMiddleware<M> = ExtractMiddlewareContract<M> extends {
38
+ returnType: infer R;
39
+ } ? ExtractContextData<R> : never;
40
+ type ExtractErrorFromMiddleware<M> = ExtractMiddlewareContract<M> extends {
41
+ returnType: infer R;
42
+ } ? ExtractResultError<R> : never;
43
+ export type AnyContract = {
44
+ key: string;
45
+ payload: unknown;
46
+ response: unknown;
47
+ returnType?: unknown;
48
+ context?: Record<string, unknown>;
49
+ scenarios?: Record<string, unknown>;
50
+ };
51
+ export type QueryContract<K extends string, P, R, Scenarios extends ContractScenario<QueryPreHandlerKeys<M>> | never = never, M extends QueryContractModuleDef = EmptyModuleDef> = Contract<K, P, R> & WithScenario<QueryContractPreHandlerMap<M>, QueryPreHandlerKeys<M>, R, Scenarios> & {
52
+ returnType: QueryContractReturnType<M, R>;
53
+ context: ResolveQueryContractContext<M, Scenarios>;
54
+ };
55
+ export type CommandContract<K extends string, P, R, Scenarios extends ContractScenario<CommandPreHandlerKeys<M>> | never = never, M extends CommandContractModuleDef = EmptyModuleDef> = Contract<K, P, R> & {
56
+ returnType: CommandContractReturnType<M, R>;
57
+ context: ResolveCommandContractContext<M, Scenarios>;
58
+ } & WithScenario<CommandContractPreHandlerMap<M>, CommandPreHandlerKeys<M>, R, Scenarios>;
59
+ type QueryContractPreHandlerMap<M extends QueryContractModuleDef> = [
60
+ M
61
+ ] extends [never] ? NormalizeGlobalPreHandlerMap<GlobalQueryPreHandlers> : NonNullable<M["queryPreHandlers"]> & NormalizeGlobalPreHandlerMap<GlobalQueryPreHandlers> & ExtractPreHandlerMapFromImports<M["imports"], "queryPreHandlerExports">;
62
+ type CommandContractPreHandlerMap<M extends CommandContractModuleDef> = [
63
+ M
64
+ ] extends [never] ? NormalizeGlobalPreHandlerMap<GlobalCommandPreHandlers> : NonNullable<M["commandPreHandlers"]> & NormalizeGlobalPreHandlerMap<GlobalCommandPreHandlers> & ExtractPreHandlerMapFromImports<M["imports"], "commandPreHandlerExports">;
65
+ type QueryContractReturnType<M extends QueryContractModuleDef, R> = ResolveContractReturnTypeByModule<M, NormalizeGlobalPreHandlerMap<GlobalQueryPreHandlers>, QueryContractPreHandlerMap<M>, R>;
66
+ type CommandContractReturnType<M extends CommandContractModuleDef, R> = ResolveContractReturnTypeByModule<M, NormalizeGlobalPreHandlerMap<GlobalCommandPreHandlers>, CommandContractPreHandlerMap<M>, R>;
67
+ type QueryPreHandlerKeys<M extends QueryContractModuleDef> = [M] extends [never] ? Extract<keyof NormalizeGlobalPreHandlerMap<GlobalQueryPreHandlers>, string> : Extract<keyof NonNullable<M["queryPreHandlers"]>, string> | Extract<keyof NormalizeGlobalPreHandlerMap<GlobalQueryPreHandlers>, string> | Extract<keyof ExtractPreHandlerMapFromImports<M["imports"], "queryPreHandlerExports">, string>;
68
+ type CommandPreHandlerKeys<M extends CommandContractModuleDef> = [M] extends [
69
+ never
70
+ ] ? Extract<keyof NormalizeGlobalPreHandlerMap<GlobalCommandPreHandlers>, string> : Extract<keyof NonNullable<M["commandPreHandlers"]>, string> | Extract<keyof NormalizeGlobalPreHandlerMap<GlobalCommandPreHandlers>, string> | Extract<keyof ExtractPreHandlerMapFromImports<M["imports"], "commandPreHandlerExports">, string>;
71
+ type WithScenario<TPreHandlerMap, TPreHandlerKey extends string, R, Scenarios extends ContractScenario<TPreHandlerKey> | never> = [Scenarios] extends [never] ? Record<never, never> : {
72
+ scenarios: ResolveScenarioResponseMap<TPreHandlerMap, TPreHandlerKey, R, Scenarios>;
73
+ };
74
+ type ExtractIncludedPreHandlerMap<TMap, TAllKeys extends string, TScenario> = NormalizeScenarioWithDefaultInclude<TScenario, TAllKeys> extends {
75
+ includePreHandlerKeys: infer Include extends readonly any[];
76
+ } ? Pick<TMap, Extract<Include[number], TAllKeys>> : TMap;
77
+ type NormalizeScenarioWithDefaultInclude<TScenario, TAllKeys extends string> = TScenario extends {
78
+ includePreHandlerKeys: readonly any[];
79
+ } ? TScenario : TScenario & {
80
+ includePreHandlerKeys: readonly TAllKeys[];
81
+ };
82
+ type ExtractScenarioPreHandlerMap<TMap, TAllKeys extends string, TScenario> = ExtractIncludedPreHandlerMap<TMap, TAllKeys, TScenario> extends infer TIncluded ? TScenario extends {
83
+ excludePreHandlerKeys: infer Exclude extends readonly any[];
84
+ } ? Omit<TIncluded, Extract<Exclude[number], keyof TIncluded>> : TIncluded : EmptyContext;
85
+ type ResolveScenarioContext<TPreHandlerMap, TPreHandlerKey extends string, Scenarios extends ContractScenario<TPreHandlerKey>> = Scenarios extends ContractScenario<TPreHandlerKey> ? ResolveContextOrEmpty<ContextFromPreHandlerMap<ExtractScenarioPreHandlerMap<TPreHandlerMap, TPreHandlerKey, Scenarios>>> : never;
86
+ type ExtractPreHandlerErrorsFromMap<TMap> = [
87
+ Extract<keyof TMap, string>
88
+ ] extends [never] ? never : {
89
+ [K in Extract<keyof TMap, string>]: ExtractErrorFromMiddleware<TMap[K]>;
90
+ }[Extract<keyof TMap, string>];
91
+ type ResolveScenarioResponse<TPreHandlerMap, TPreHandlerKey extends string, R, Scenario extends ContractScenario<TPreHandlerKey>> = ResponseWithErrors<R, ExtractPreHandlerErrorsFromMap<ExtractScenarioPreHandlerMap<TPreHandlerMap, TPreHandlerKey, Scenario>>>;
92
+ type ResolveContractReturnType<TPreHandlerErrors, R> = MergeResponseWithPreHandlerErrors<R, TPreHandlerErrors>;
93
+ type ResolveContractReturnTypeByModule<M, TGlobalPreHandlerMap, TContractPreHandlerMap, R> = [keyof M] extends [never] ? ResolveContractReturnType<ExtractPreHandlerErrorsFromMap<TGlobalPreHandlerMap>, R> : ResolveContractReturnType<ExtractPreHandlerErrorsFromMap<TContractPreHandlerMap>, R>;
94
+ type ResolveScenarioResponseMap<TPreHandlerMap, TPreHandlerKey extends string, R, Scenarios extends ContractScenario<TPreHandlerKey>> = {
95
+ [Scenario in Scenarios as Scenario["name"]]: {
96
+ config: Omit<Scenario, "name">;
97
+ returnType: ResolveScenarioResponse<TPreHandlerMap, TPreHandlerKey, R, Scenario>;
98
+ };
99
+ };
100
+ type ContextFromMiddlewareOrEmpty<TMiddleware> = [
101
+ ExtractContextFromMiddleware<TMiddleware>
102
+ ] extends [never] ? EmptyContext : ExtractContextFromMiddleware<TMiddleware>;
103
+ type ResolveContextOrEmpty<TContext> = [TContext] extends [
104
+ Record<string, unknown>
105
+ ] ? TContext : EmptyContext;
106
+ type ContextFromPreHandlerMap<TMap> = Extract<keyof TMap, string> extends never ? EmptyContext : UnionToIntersection<{
107
+ [K in Extract<keyof TMap, string>]: ContextFromMiddlewareOrEmpty<TMap[K]>;
108
+ }[Extract<keyof TMap, string>]>;
109
+ type Contract<K extends string, P, R> = {
110
+ key: K;
111
+ payload: P;
112
+ response: R;
113
+ };
114
+ type ResolveQueryContractContext<M extends QueryContractModuleDef, Scenarios extends ContractScenario<QueryPreHandlerKeys<M>>> = [Scenarios] extends [never] ? ResolveContextOrEmpty<ContextFromPreHandlerMap<QueryContractPreHandlerMap<M>>> : ResolveScenarioContext<QueryContractPreHandlerMap<M>, QueryPreHandlerKeys<M>, Scenarios>;
115
+ type ResolveCommandContractContext<M extends CommandContractModuleDef, Scenarios extends ContractScenario<CommandPreHandlerKeys<M>>> = [Scenarios] extends [never] ? ResolveContextOrEmpty<ContextFromPreHandlerMap<CommandContractPreHandlerMap<M>>> : ResolveScenarioContext<CommandContractPreHandlerMap<M>, CommandPreHandlerKeys<M>, Scenarios>;
116
+ type ExtractResultSuccess<R> = R extends {
117
+ readonly ok: true;
118
+ readonly value: infer T;
119
+ } ? T : never;
120
+ type ExtractResultError<R> = R extends {
121
+ readonly ok: false;
122
+ readonly error: infer E;
123
+ } ? E : never;
124
+ type IsResult<R> = R extends {
125
+ readonly ok: true;
126
+ readonly value: any;
127
+ } | {
128
+ readonly ok: false;
129
+ readonly error: any;
130
+ } ? true : false;
131
+ type ResponseWithErrors<Response, Errors> = [Errors] extends [never] ? Response : IsResult<Response> extends true ? Result<ExtractResultSuccess<Response>, ExtractResultError<Response> | Errors> : Result<Response, Errors>;
132
+ type Result<Value, Err> = {
133
+ readonly ok: true;
134
+ readonly value: Value;
135
+ readonly error: undefined;
136
+ } | {
137
+ readonly ok: false;
138
+ readonly value: undefined;
139
+ readonly error: Err;
140
+ };
141
+ type MergeResponseWithPreHandlerErrors<TResponse, TPreHandlerError> = [
142
+ TPreHandlerError
143
+ ] extends [never] ? TResponse : [TResponse] extends [{
144
+ readonly ok: true;
145
+ readonly value: infer V;
146
+ }] ? Result<V, TPreHandlerError> : [TResponse] extends [{
147
+ readonly ok: false;
148
+ readonly error: infer E;
149
+ }] ? Result<never, E | TPreHandlerError> : [TResponse] extends [
150
+ {
151
+ readonly ok: true;
152
+ readonly value: infer V;
153
+ } | {
154
+ readonly ok: false;
155
+ readonly error: infer E;
156
+ }
157
+ ] ? Result<V, E | TPreHandlerError> : Result<TResponse, TPreHandlerError>;
158
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
159
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ export declare class HandlerAlreadyRegisteredError extends Error {
2
+ constructor(handlerKey: string);
3
+ }
4
+ export declare class HandlerNotRegisteredError extends Error {
5
+ constructor(handlerKey: string, moduleName: string);
6
+ }
7
+ export declare class InvalidMiddlewareReturnValueError extends Error {
8
+ constructor(middlewareKey: string, returnedType: string);
9
+ }
10
+ export declare class ContextKeyConflictError extends Error {
11
+ constructor(middlewareKey: string, conflictingKeys: string[]);
12
+ }
13
+ export declare class MiddlewareRequiredError extends Error {
14
+ constructor(middlewareKey: string, requiredKey: string);
15
+ }
@@ -0,0 +1,33 @@
1
+ export class HandlerAlreadyRegisteredError extends Error {
2
+ constructor(handlerKey) {
3
+ super(`Handler "${handlerKey}" already registered!`);
4
+ this.name = "HandlerAlreadyRegisteredError";
5
+ }
6
+ }
7
+ export class HandlerNotRegisteredError extends Error {
8
+ constructor(handlerKey, moduleName) {
9
+ super(`Handler key of ${handlerKey} is not registered in module: "${moduleName}"`);
10
+ this.name = "HandlerNotRegisteredError";
11
+ }
12
+ }
13
+ export class InvalidMiddlewareReturnValueError extends Error {
14
+ constructor(middlewareKey, returnedType) {
15
+ super(`Middleware "${middlewareKey}" returned invalid value of type "${returnedType}". ` +
16
+ `Middlewares must return a Result type or a plain object for context merging.`);
17
+ this.name = "InvalidMiddlewareReturnValueError";
18
+ }
19
+ }
20
+ export class ContextKeyConflictError extends Error {
21
+ constructor(middlewareKey, conflictingKeys) {
22
+ super(`Middleware "${middlewareKey}" tried to add context keys that already exist: ${conflictingKeys.join(", ")}. ` +
23
+ `Each middleware must add unique keys to the context.`);
24
+ this.name = "ContextKeyConflictError";
25
+ }
26
+ }
27
+ export class MiddlewareRequiredError extends Error {
28
+ constructor(middlewareKey, requiredKey) {
29
+ super(`Middleware "${middlewareKey}" requires "${requiredKey}" to run before it. ` +
30
+ `Ensure "${requiredKey}" is included and appears before "${middlewareKey}" in the execution order.`);
31
+ this.name = "MiddlewareRequiredError";
32
+ }
33
+ }
@@ -0,0 +1,13 @@
1
+ import type { EmptyObject } from "../di/common.types.js";
2
+ import type { DefPreHandlerMap } from "../di/providers/provider.types.js";
3
+ export interface GlobalQueryPreHandlers {
4
+ }
5
+ export interface GlobalCommandPreHandlers {
6
+ }
7
+ export type NormalizeGlobalPreHandlerMap<T> = [T] extends [DefPreHandlerMap] ? T : EmptyObject;
8
+ export type InferGlobalQueryPreHandlers<TModuleDef> = TModuleDef extends {
9
+ queryPreHandlerExports: infer TPreHandlers;
10
+ } ? NormalizeGlobalPreHandlerMap<TPreHandlers> : EmptyObject;
11
+ export type InferGlobalCommandPreHandlers<TModuleDef> = TModuleDef extends {
12
+ commandPreHandlerExports: infer TPreHandlers;
13
+ } ? NormalizeGlobalPreHandlerMap<TPreHandlers> : EmptyObject;
@@ -0,0 +1 @@
1
+ export {};