@adonisjs/http-server 5.12.0 → 6.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 (171) hide show
  1. package/README.md +15 -38
  2. package/build/index.d.ts +16 -0
  3. package/build/index.js +16 -0
  4. package/build/src/cookies/client.d.ts +12 -0
  5. package/build/src/cookies/client.js +42 -0
  6. package/build/src/cookies/drivers/encrypted.d.ts +4 -0
  7. package/build/src/cookies/drivers/encrypted.js +16 -0
  8. package/build/src/cookies/drivers/plain.d.ts +3 -0
  9. package/build/src/cookies/drivers/plain.js +13 -0
  10. package/build/src/cookies/drivers/signed.d.ts +4 -0
  11. package/build/src/cookies/drivers/signed.js +16 -0
  12. package/build/src/cookies/parser.d.ts +9 -0
  13. package/build/src/cookies/parser.js +69 -0
  14. package/build/src/cookies/serializer.d.ts +11 -0
  15. package/build/src/cookies/serializer.js +39 -0
  16. package/build/src/debug.d.ts +3 -0
  17. package/build/src/debug.js +2 -0
  18. package/build/src/define_config.d.ts +2 -0
  19. package/build/src/define_config.js +40 -0
  20. package/build/src/define_middleware.d.ts +4 -0
  21. package/build/src/define_middleware.js +6 -0
  22. package/build/src/exceptions/abort_exception.d.ts +5 -0
  23. package/build/src/exceptions/abort_exception.js +6 -0
  24. package/build/src/exceptions/cannot_lookup_route.d.ts +5 -0
  25. package/build/src/exceptions/cannot_lookup_route.js +5 -0
  26. package/build/src/exceptions/http_exception.d.ts +6 -0
  27. package/build/src/exceptions/http_exception.js +20 -0
  28. package/build/src/exceptions/route_not_found.d.ts +5 -0
  29. package/build/src/exceptions/route_not_found.js +5 -0
  30. package/build/src/helpers.d.ts +6 -67
  31. package/build/src/helpers.js +13 -168
  32. package/build/src/http_context/local_storage.d.ts +9 -0
  33. package/build/src/http_context/local_storage.js +14 -0
  34. package/build/src/http_context/main.d.ts +20 -0
  35. package/build/src/http_context/main.js +49 -0
  36. package/build/src/middleware/store.d.ts +11 -0
  37. package/build/src/middleware/store.js +33 -0
  38. package/build/src/qs.d.ts +7 -0
  39. package/build/src/qs.js +13 -0
  40. package/build/src/redirect.d.ts +18 -0
  41. package/build/src/redirect.js +80 -0
  42. package/build/src/request.d.ts +81 -0
  43. package/build/src/request.js +315 -0
  44. package/build/src/response.d.ts +108 -0
  45. package/build/src/response.js +587 -0
  46. package/build/src/router/brisk.d.ts +18 -0
  47. package/build/src/router/brisk.js +35 -0
  48. package/build/src/router/executor.d.ts +4 -0
  49. package/build/src/router/executor.js +16 -0
  50. package/build/src/router/group.d.ts +19 -0
  51. package/build/src/router/group.js +117 -0
  52. package/build/src/router/lookup_store/main.d.ts +17 -0
  53. package/build/src/router/lookup_store/main.js +37 -0
  54. package/build/src/router/lookup_store/route_finder.d.ts +8 -0
  55. package/build/src/router/lookup_store/route_finder.js +28 -0
  56. package/build/src/router/lookup_store/url_builder.d.ts +16 -0
  57. package/build/src/router/lookup_store/url_builder.js +111 -0
  58. package/build/src/router/main.d.ts +36 -0
  59. package/build/src/router/main.js +161 -0
  60. package/build/src/router/matchers.d.ts +14 -0
  61. package/build/src/router/matchers.js +15 -0
  62. package/build/src/router/resource.d.ts +27 -0
  63. package/build/src/router/resource.js +124 -0
  64. package/build/src/router/route.d.ts +28 -0
  65. package/build/src/router/route.js +135 -0
  66. package/build/src/router/store.d.ts +12 -0
  67. package/build/src/router/store.js +87 -0
  68. package/build/src/server/factories/final_handler.d.ts +4 -0
  69. package/build/src/server/factories/final_handler.js +17 -0
  70. package/build/src/server/factories/middleware_handler.d.ts +5 -0
  71. package/build/src/server/factories/middleware_handler.js +5 -0
  72. package/build/src/server/factories/use_return_value.d.ts +2 -0
  73. package/build/src/server/factories/use_return_value.js +9 -0
  74. package/build/src/server/factories/write_response.d.ts +2 -0
  75. package/build/src/server/factories/write_response.js +12 -0
  76. package/build/src/server/main.d.ts +23 -0
  77. package/build/src/server/main.js +124 -0
  78. package/build/src/types/base.d.ts +5 -0
  79. package/build/src/types/base.js +1 -0
  80. package/build/src/types/main.d.ts +7 -0
  81. package/build/src/types/main.js +7 -0
  82. package/build/src/types/middleware.d.ts +14 -0
  83. package/build/src/types/middleware.js +1 -0
  84. package/build/src/types/qs.d.ts +15 -0
  85. package/build/src/types/qs.js +1 -0
  86. package/build/src/types/request.d.ts +7 -0
  87. package/build/src/types/request.js +1 -0
  88. package/build/src/types/response.d.ts +18 -0
  89. package/build/src/types/response.js +1 -0
  90. package/build/src/types/route.d.ts +74 -0
  91. package/build/src/types/route.js +1 -0
  92. package/build/src/types/server.d.ts +13 -0
  93. package/build/src/types/server.js +1 -0
  94. package/package.json +88 -86
  95. package/build/adonis-typings/container.d.ts +0 -24
  96. package/build/adonis-typings/container.js +0 -8
  97. package/build/adonis-typings/context.d.ts +0 -73
  98. package/build/adonis-typings/context.js +0 -8
  99. package/build/adonis-typings/cookie-client.d.ts +0 -34
  100. package/build/adonis-typings/cookie-client.js +0 -8
  101. package/build/adonis-typings/http-server.d.ts +0 -98
  102. package/build/adonis-typings/http-server.js +0 -8
  103. package/build/adonis-typings/index.d.ts +0 -16
  104. package/build/adonis-typings/index.js +0 -16
  105. package/build/adonis-typings/middleware.d.ts +0 -95
  106. package/build/adonis-typings/middleware.js +0 -8
  107. package/build/adonis-typings/request.d.ts +0 -556
  108. package/build/adonis-typings/request.js +0 -8
  109. package/build/adonis-typings/response.d.ts +0 -440
  110. package/build/adonis-typings/response.js +0 -8
  111. package/build/adonis-typings/route.d.ts +0 -559
  112. package/build/adonis-typings/route.js +0 -8
  113. package/build/exceptions.json +0 -110
  114. package/build/providers/HttpServerProvider.d.ts +0 -46
  115. package/build/providers/HttpServerProvider.js +0 -100
  116. package/build/src/Cookie/Client/index.d.ts +0 -39
  117. package/build/src/Cookie/Client/index.js +0 -108
  118. package/build/src/Cookie/Drivers/Encrypted.d.ts +0 -24
  119. package/build/src/Cookie/Drivers/Encrypted.js +0 -42
  120. package/build/src/Cookie/Drivers/Plain.d.ts +0 -23
  121. package/build/src/Cookie/Drivers/Plain.js +0 -40
  122. package/build/src/Cookie/Drivers/Signed.d.ts +0 -24
  123. package/build/src/Cookie/Drivers/Signed.js +0 -42
  124. package/build/src/Cookie/Parser/index.d.ts +0 -61
  125. package/build/src/Cookie/Parser/index.js +0 -174
  126. package/build/src/Cookie/Serializer/index.d.ts +0 -46
  127. package/build/src/Cookie/Serializer/index.js +0 -88
  128. package/build/src/Exceptions/HttpException.d.ts +0 -20
  129. package/build/src/Exceptions/HttpException.js +0 -36
  130. package/build/src/Exceptions/RouterException.d.ts +0 -36
  131. package/build/src/Exceptions/RouterException.js +0 -76
  132. package/build/src/HttpContext/LocalStorage/index.d.ts +0 -24
  133. package/build/src/HttpContext/LocalStorage/index.js +0 -28
  134. package/build/src/HttpContext/index.d.ts +0 -90
  135. package/build/src/HttpContext/index.js +0 -181
  136. package/build/src/MiddlewareStore/index.d.ts +0 -92
  137. package/build/src/MiddlewareStore/index.js +0 -133
  138. package/build/src/Redirect/index.d.ts +0 -71
  139. package/build/src/Redirect/index.js +0 -139
  140. package/build/src/Request/index.d.ts +0 -619
  141. package/build/src/Request/index.js +0 -862
  142. package/build/src/Response/index.d.ts +0 -414
  143. package/build/src/Response/index.js +0 -1010
  144. package/build/src/Router/BriskRoute.d.ts +0 -53
  145. package/build/src/Router/BriskRoute.js +0 -74
  146. package/build/src/Router/Group.d.ts +0 -101
  147. package/build/src/Router/Group.js +0 -165
  148. package/build/src/Router/LookupStore.d.ts +0 -122
  149. package/build/src/Router/LookupStore.js +0 -264
  150. package/build/src/Router/Matchers.d.ts +0 -31
  151. package/build/src/Router/Matchers.js +0 -43
  152. package/build/src/Router/Resource.d.ts +0 -95
  153. package/build/src/Router/Resource.js +0 -182
  154. package/build/src/Router/Route.d.ts +0 -138
  155. package/build/src/Router/Route.js +0 -204
  156. package/build/src/Router/Store.d.ts +0 -93
  157. package/build/src/Router/Store.js +0 -211
  158. package/build/src/Router/index.d.ts +0 -142
  159. package/build/src/Router/index.js +0 -333
  160. package/build/src/Server/ExceptionManager/index.d.ts +0 -49
  161. package/build/src/Server/ExceptionManager/index.js +0 -96
  162. package/build/src/Server/Hooks/index.d.ts +0 -43
  163. package/build/src/Server/Hooks/index.js +0 -77
  164. package/build/src/Server/PreCompiler/index.d.ts +0 -60
  165. package/build/src/Server/PreCompiler/index.js +0 -143
  166. package/build/src/Server/RequestHandler/index.d.ts +0 -39
  167. package/build/src/Server/RequestHandler/index.js +0 -87
  168. package/build/src/Server/index.d.ts +0 -90
  169. package/build/src/Server/index.js +0 -175
  170. package/build/standalone.d.ts +0 -14
  171. package/build/standalone.js +0 -23
@@ -0,0 +1,124 @@
1
+ import string from '@poppinss/utils/string';
2
+ import { Macroable } from '@poppinss/macroable';
3
+ import { RuntimeException } from '@poppinss/utils';
4
+ import { Route } from './route.js';
5
+ export class RouteResource extends Macroable {
6
+ #resource;
7
+ #controller;
8
+ #shallow = false;
9
+ #globalMatchers;
10
+ #app;
11
+ #middlewareStore;
12
+ #params = {};
13
+ #routesBaseName;
14
+ routes = [];
15
+ constructor(app, middlewareStore, options) {
16
+ super();
17
+ this.#validateResourceName(options.resource);
18
+ this.#app = app;
19
+ this.#shallow = options.shallow;
20
+ this.#middlewareStore = middlewareStore;
21
+ this.#controller = options.controller;
22
+ this.#globalMatchers = options.globalMatchers;
23
+ this.#resource = this.#normalizeResourceName(options.resource);
24
+ this.#routesBaseName = this.#getRoutesBaseName();
25
+ this.#buildRoutes();
26
+ }
27
+ #normalizeResourceName(resource) {
28
+ return resource.replace(/^\//, '').replace(/\/$/, '');
29
+ }
30
+ #validateResourceName(resource) {
31
+ if (!resource || resource === '/') {
32
+ throw new RuntimeException(`Invalid resource name "${resource}"`);
33
+ }
34
+ }
35
+ #getRoutesBaseName() {
36
+ return this.#resource
37
+ .split('.')
38
+ .map((token) => string.snakeCase(token))
39
+ .join('.');
40
+ }
41
+ #createRoute(pattern, methods, action) {
42
+ const route = new Route(this.#app, this.#middlewareStore, {
43
+ pattern,
44
+ methods,
45
+ handler: `${this.#controller}.${action}`,
46
+ globalMatchers: this.#globalMatchers,
47
+ });
48
+ route.as(`${this.#routesBaseName}.${action}`);
49
+ this.routes.push(route);
50
+ }
51
+ #getResourceId(resource) {
52
+ return `${string.snakeCase(string.singular(resource))}_id`;
53
+ }
54
+ #buildRoutes() {
55
+ const resources = this.#resource.split('.');
56
+ const mainResource = resources.pop();
57
+ this.#params[mainResource] = ':id';
58
+ const baseURI = `${resources
59
+ .map((resource) => {
60
+ const paramName = `:${this.#getResourceId(resource)}`;
61
+ this.#params[resource] = paramName;
62
+ return `${resource}/${paramName}`;
63
+ })
64
+ .join('/')}/${mainResource}`;
65
+ this.#createRoute(baseURI, ['GET', 'HEAD'], 'index');
66
+ this.#createRoute(`${baseURI}/create`, ['GET', 'HEAD'], 'create');
67
+ this.#createRoute(baseURI, ['POST'], 'store');
68
+ this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id`, ['GET', 'HEAD'], 'show');
69
+ this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id/edit`, ['GET', 'HEAD'], 'edit');
70
+ this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id`, ['PUT', 'PATCH'], 'update');
71
+ this.#createRoute(`${this.#shallow ? mainResource : baseURI}/:id`, ['DELETE'], 'destroy');
72
+ }
73
+ #filter(names, inverse) {
74
+ const actions = Array.isArray(names) ? names : [names];
75
+ return this.routes.filter((route) => {
76
+ const match = actions.find((name) => route.getName().endsWith(name));
77
+ return inverse ? !match : match;
78
+ });
79
+ }
80
+ only(names) {
81
+ this.#filter(names, true).forEach((route) => route.markAsDeleted());
82
+ return this;
83
+ }
84
+ except(names) {
85
+ this.#filter(names, false).forEach((route) => route.markAsDeleted());
86
+ return this;
87
+ }
88
+ apiOnly() {
89
+ return this.except(['create', 'edit']);
90
+ }
91
+ where(key, matcher) {
92
+ this.routes.forEach((route) => {
93
+ route.where(key, matcher);
94
+ });
95
+ return this;
96
+ }
97
+ tap(actions, callback) {
98
+ if (typeof actions === 'function') {
99
+ this.routes.forEach((route) => actions(route));
100
+ return this;
101
+ }
102
+ this.#filter(actions, false).forEach((route) => callback(route));
103
+ return this;
104
+ }
105
+ params(resources) {
106
+ Object.keys(resources).forEach((resource) => {
107
+ const param = resources[resource];
108
+ const existingParam = this.#params[resource];
109
+ this.#params[resource] = `:${param}`;
110
+ this.routes.forEach((route) => {
111
+ route.setPattern(route.getPattern().replace(`${resource}/${existingParam}`, `${resource}/:${param}`));
112
+ });
113
+ });
114
+ return this;
115
+ }
116
+ as(name) {
117
+ name = string.snakeCase(name);
118
+ this.routes.forEach((route) => {
119
+ route.as(route.getName().replace(this.#routesBaseName, name), false);
120
+ });
121
+ this.#routesBaseName = name;
122
+ return this;
123
+ }
124
+ }
@@ -0,0 +1,28 @@
1
+ import { Macroable } from '@poppinss/macroable';
2
+ import type { Application } from '@adonisjs/application';
3
+ import type { MiddlewareStore } from '../middleware/store.js';
4
+ import type { LazyImport, UnWrapLazyImport } from '../types/base.js';
5
+ import type { GetMiddlewareArgs, MiddlewareAsClass, MiddlewareFn } from '../types/middleware.js';
6
+ import type { RouteFn, RouteJSON, RouteMatcher, RouteMatchers, StoreRouteMiddleware } from '../types/route.js';
7
+ export declare class Route<NamedMiddleware extends Record<string, LazyImport<MiddlewareAsClass>> = any> extends Macroable {
8
+ #private;
9
+ constructor(app: Application<any, any, any>, middlewareStore: MiddlewareStore<NamedMiddleware>, options: {
10
+ pattern: string;
11
+ methods: string[];
12
+ handler: RouteFn | string;
13
+ globalMatchers: RouteMatchers;
14
+ });
15
+ where(param: string, matcher: RouteMatcher | string | RegExp): this;
16
+ prefix(prefix: string): this;
17
+ domain(domain: string, overwrite?: boolean): this;
18
+ middleware<Name extends keyof NamedMiddleware>(middleware: Name, ...args: GetMiddlewareArgs<UnWrapLazyImport<NamedMiddleware[Name]>>): this;
19
+ middleware(middleware: MiddlewareFn): this;
20
+ as(name: string, prepend?: boolean): this;
21
+ isDeleted(): boolean;
22
+ markAsDeleted(): void;
23
+ getName(): string | undefined;
24
+ getPattern(): string;
25
+ setPattern(pattern: string): this;
26
+ getMiddleware(): StoreRouteMiddleware[][];
27
+ toJSON(): RouteJSON;
28
+ }
@@ -0,0 +1,135 @@
1
+ import is from '@sindresorhus/is';
2
+ import Middleware from '@poppinss/middleware';
3
+ import { Macroable } from '@poppinss/macroable';
4
+ import { moduleExpression } from '@adonisjs/fold';
5
+ import { RuntimeException } from '@poppinss/utils';
6
+ import { execute } from './executor.js';
7
+ import { dropSlash } from '../helpers.js';
8
+ export class Route extends Macroable {
9
+ #pattern;
10
+ #methods;
11
+ #name;
12
+ #isDeleted = false;
13
+ #handler;
14
+ #globalMatchers;
15
+ #app;
16
+ #middlewareStore;
17
+ #routeDomain = 'root';
18
+ #matchers = {};
19
+ #prefixes = [];
20
+ #middleware = [];
21
+ constructor(app, middlewareStore, options) {
22
+ super();
23
+ this.#app = app;
24
+ this.#middlewareStore = middlewareStore;
25
+ this.#pattern = options.pattern;
26
+ this.#methods = options.methods;
27
+ this.#handler = this.#resolveRouteHandle(options.handler);
28
+ this.#globalMatchers = options.globalMatchers;
29
+ }
30
+ #resolveRouteHandle(handler) {
31
+ if (typeof handler === 'string') {
32
+ return {
33
+ name: handler,
34
+ ...moduleExpression(handler, this.#app.appRoot).toHandleMethod(),
35
+ };
36
+ }
37
+ return handler;
38
+ }
39
+ #getMatchers() {
40
+ return { ...this.#globalMatchers, ...this.#matchers };
41
+ }
42
+ #computePattern() {
43
+ const pattern = dropSlash(this.#pattern);
44
+ const prefix = this.#prefixes
45
+ .slice()
46
+ .reverse()
47
+ .map((one) => dropSlash(one))
48
+ .join('');
49
+ return prefix ? `${prefix}${pattern === '/' ? '' : pattern}` : pattern;
50
+ }
51
+ where(param, matcher) {
52
+ if (this.#matchers[param]) {
53
+ return this;
54
+ }
55
+ if (typeof matcher === 'string') {
56
+ this.#matchers[param] = { match: new RegExp(matcher) };
57
+ }
58
+ else if (is.regExp(matcher)) {
59
+ this.#matchers[param] = { match: matcher };
60
+ }
61
+ else {
62
+ this.#matchers[param] = matcher;
63
+ }
64
+ return this;
65
+ }
66
+ prefix(prefix) {
67
+ this.#prefixes.push(prefix);
68
+ return this;
69
+ }
70
+ domain(domain, overwrite = false) {
71
+ if (this.#routeDomain === 'root' || overwrite) {
72
+ this.#routeDomain = domain;
73
+ }
74
+ return this;
75
+ }
76
+ middleware(middleware, args) {
77
+ if (typeof middleware === 'string') {
78
+ this.#middleware.push([this.#middlewareStore.get(middleware, args)]);
79
+ return this;
80
+ }
81
+ if (typeof middleware === 'function') {
82
+ this.#middleware.push([middleware]);
83
+ }
84
+ return this;
85
+ }
86
+ as(name, prepend = false) {
87
+ if (prepend) {
88
+ if (!this.#name) {
89
+ throw new RuntimeException(`Routes inside a group must have names before calling "router.group.as"`);
90
+ }
91
+ this.#name = `${name}.${this.#name}`;
92
+ return this;
93
+ }
94
+ this.#name = name;
95
+ return this;
96
+ }
97
+ isDeleted() {
98
+ return this.#isDeleted;
99
+ }
100
+ markAsDeleted() {
101
+ this.#isDeleted = true;
102
+ }
103
+ getName() {
104
+ return this.#name;
105
+ }
106
+ getPattern() {
107
+ return this.#pattern;
108
+ }
109
+ setPattern(pattern) {
110
+ this.#pattern = pattern;
111
+ return this;
112
+ }
113
+ getMiddleware() {
114
+ return this.#middleware;
115
+ }
116
+ #getMiddlewareForStore() {
117
+ const middleware = new Middleware();
118
+ this.#middlewareStore.list().forEach((one) => middleware.add(one));
119
+ this.#middleware.flat().forEach((one) => middleware.add(one));
120
+ return middleware;
121
+ }
122
+ toJSON() {
123
+ return {
124
+ domain: this.#routeDomain,
125
+ pattern: this.#computePattern(),
126
+ matchers: this.#getMatchers(),
127
+ meta: {},
128
+ name: this.#name,
129
+ handler: this.#handler,
130
+ methods: this.#methods,
131
+ middleware: this.#getMiddlewareForStore(),
132
+ execute: execute,
133
+ };
134
+ }
135
+ }
@@ -0,0 +1,12 @@
1
+ import type { RouteJSON, MatchedRoute, StoreRoutesTree, MatchItRouteToken } from '../types/route.js';
2
+ export declare class RoutesStore {
3
+ #private;
4
+ usingDomains: boolean;
5
+ tree: StoreRoutesTree;
6
+ add(route: RouteJSON): this;
7
+ match(url: string, method: string, domain?: {
8
+ tokens: MatchItRouteToken[];
9
+ hostname: string;
10
+ }): null | MatchedRoute;
11
+ matchDomain(hostname?: string | null): MatchItRouteToken[];
12
+ }
@@ -0,0 +1,87 @@
1
+ import matchit from '@poppinss/matchit';
2
+ import lodash from '@poppinss/utils/lodash';
3
+ import { RuntimeException } from '@poppinss/utils';
4
+ export class RoutesStore {
5
+ usingDomains = false;
6
+ tree = { tokens: [], domains: {} };
7
+ #getDomainNode(domain) {
8
+ if (!this.tree.domains[domain]) {
9
+ this.tree.tokens.push(matchit.parse(domain));
10
+ this.tree.domains[domain] = {};
11
+ }
12
+ return this.tree.domains[domain];
13
+ }
14
+ #getMethodNode(domain, method) {
15
+ const domainNode = this.#getDomainNode(domain);
16
+ if (!domainNode[method]) {
17
+ domainNode[method] = { tokens: [], routes: {}, routeKeys: {} };
18
+ }
19
+ return domainNode[method];
20
+ }
21
+ #collectRouteParams(route, tokens) {
22
+ const collectedParams = new Set();
23
+ for (let token of tokens) {
24
+ if ([1, 3].includes(token.type)) {
25
+ if (collectedParams.has(token.val)) {
26
+ throw new RuntimeException(`Duplicate param "${token.val}" found in "${route.pattern}"`);
27
+ }
28
+ else {
29
+ collectedParams.add(token.val);
30
+ }
31
+ }
32
+ }
33
+ const params = [...collectedParams];
34
+ collectedParams.clear();
35
+ return params;
36
+ }
37
+ #registerRoute(domain, method, tokens, route) {
38
+ const methodRoutes = this.#getMethodNode(domain, method);
39
+ if (methodRoutes.routes[route.pattern]) {
40
+ throw new RuntimeException(`Duplicate route found. "${method}: ${route.pattern}" route already exists`);
41
+ }
42
+ methodRoutes.tokens.push(tokens);
43
+ methodRoutes.routes[route.pattern] = route;
44
+ methodRoutes.routeKeys[route.pattern] =
45
+ domain !== 'root' ? `${domain}-${method}-${route.pattern}` : `${method}-${route.pattern}`;
46
+ }
47
+ add(route) {
48
+ if (route.domain !== 'root') {
49
+ this.usingDomains = true;
50
+ }
51
+ const tokens = matchit.parse(route.pattern, route.matchers);
52
+ const routeNode = lodash.merge({ meta: {} }, lodash.pick(route, ['pattern', 'handler', 'meta', 'middleware', 'name', 'execute']));
53
+ routeNode.meta.params = this.#collectRouteParams(routeNode, tokens);
54
+ route.methods.forEach((method) => {
55
+ this.#registerRoute(route.domain, method, tokens, routeNode);
56
+ });
57
+ return this;
58
+ }
59
+ match(url, method, domain) {
60
+ const domainName = domain?.tokens[0]?.old || 'root';
61
+ const matchedDomain = this.tree.domains[domainName];
62
+ if (!matchedDomain) {
63
+ return null;
64
+ }
65
+ const matchedMethod = this.tree.domains[domainName][method];
66
+ if (!matchedMethod) {
67
+ return null;
68
+ }
69
+ const matchedRoute = matchit.match(url, matchedMethod.tokens);
70
+ if (!matchedRoute.length) {
71
+ return null;
72
+ }
73
+ const route = matchedMethod.routes[matchedRoute[0].old];
74
+ return {
75
+ route: route,
76
+ routeKey: matchedMethod.routeKeys[route.pattern],
77
+ params: matchit.exec(url, matchedRoute),
78
+ subdomains: domain?.hostname ? matchit.exec(domain.hostname, domain.tokens) : {},
79
+ };
80
+ }
81
+ matchDomain(hostname) {
82
+ if (!hostname || !this.usingDomains) {
83
+ return [];
84
+ }
85
+ return matchit.match(hostname, this.tree.tokens);
86
+ }
87
+ }
@@ -0,0 +1,4 @@
1
+ import type { ContainerResolver } from '@adonisjs/fold';
2
+ import type { Router } from '../../router/main.js';
3
+ import type { HttpContext } from '../../http_context/main.js';
4
+ export declare function finalHandler(router: Router, resolver: ContainerResolver<any>, ctx: HttpContext): () => any;
@@ -0,0 +1,17 @@
1
+ import { RouteNotFoundException } from '../../exceptions/route_not_found.js';
2
+ export function finalHandler(router, resolver, ctx) {
3
+ return function () {
4
+ const url = ctx.request.url();
5
+ const method = ctx.request.method();
6
+ const hostname = router.usingDomains ? ctx.request.hostname() : undefined;
7
+ const route = router.match(url, method, hostname);
8
+ if (route) {
9
+ ctx.params = route.params;
10
+ ctx.subdomains = route.subdomains;
11
+ ctx.route = route.route;
12
+ ctx.routeKey = route.routeKey;
13
+ return route.route.execute(route.route, resolver, ctx);
14
+ }
15
+ throw new RouteNotFoundException(`Cannot ${method}:${url}`);
16
+ };
17
+ }
@@ -0,0 +1,5 @@
1
+ import type { NextFn } from '@poppinss/middleware/types';
2
+ import type { ContainerResolver } from '@adonisjs/fold';
3
+ import type { HttpContext } from '../../http_context/main.js';
4
+ import { ParsedGlobalMiddleware } from '../../types/middleware.js';
5
+ export declare function middlewareHandler(resolver: ContainerResolver<any>, ctx: HttpContext): (fn: ParsedGlobalMiddleware, next: NextFn) => any;
@@ -0,0 +1,5 @@
1
+ export function middlewareHandler(resolver, ctx) {
2
+ return function (fn, next) {
3
+ return fn.handle(resolver, ctx, next);
4
+ };
5
+ }
@@ -0,0 +1,2 @@
1
+ import type { HttpContext } from '../../http_context/main.js';
2
+ export declare function useReturnValue(ctx: HttpContext): (value: any) => void;
@@ -0,0 +1,9 @@
1
+ export function useReturnValue(ctx) {
2
+ return function (value) {
3
+ if (value !== undefined &&
4
+ !ctx.response.hasLazyBody &&
5
+ value !== ctx.response) {
6
+ ctx.response.send(value);
7
+ }
8
+ };
9
+ }
@@ -0,0 +1,2 @@
1
+ import type { HttpContext } from '../../http_context/main.js';
2
+ export declare function writeResponse(ctx: HttpContext): () => void;
@@ -0,0 +1,12 @@
1
+ export function writeResponse(ctx) {
2
+ return function () {
3
+ try {
4
+ ctx.response.finish();
5
+ }
6
+ catch (error) {
7
+ ctx.logger.fatal({ err: error }, 'Response serialization failed');
8
+ ctx.response.internalServerError(error.message);
9
+ ctx.response.finish();
10
+ }
11
+ };
12
+ }
@@ -0,0 +1,23 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
3
+ import type { Encryption } from '@adonisjs/encryption';
4
+ import type { Application } from '@adonisjs/application';
5
+ import type { Server as HttpsServer } from 'node:https';
6
+ import type { ServerResponse, IncomingMessage, Server as HttpServer } from 'node:http';
7
+ import type { LazyImport } from '../types/base.js';
8
+ import type { MiddlewareAsClass } from '../types/middleware.js';
9
+ import type { ErrorHandlerAsAClass, ServerConfig } from '../types/server.js';
10
+ import { Router } from '../router/main.js';
11
+ export declare class Server<NamedMiddleware extends Record<string, LazyImport<MiddlewareAsClass>> = any> {
12
+ #private;
13
+ get usingAsyncLocalStorage(): boolean;
14
+ constructor(app: Application<any, any, any>, encryption: Encryption, config: ServerConfig);
15
+ use(serverMiddleware: LazyImport<MiddlewareAsClass>[], routerMiddleware: LazyImport<MiddlewareAsClass>[], namedMiddleware: NamedMiddleware): this;
16
+ errorHandler(handler: LazyImport<ErrorHandlerAsAClass>): this;
17
+ boot(): Promise<void>;
18
+ setNodeServer(server: HttpServer | HttpsServer): void;
19
+ close(): Promise<void>;
20
+ getNodeServer(): HttpServer<typeof IncomingMessage, typeof ServerResponse> | HttpsServer<typeof IncomingMessage, typeof ServerResponse> | undefined;
21
+ getRouter(): Router<any> | undefined;
22
+ handle(req: IncomingMessage, res: ServerResponse): Promise<any>;
23
+ }
@@ -0,0 +1,124 @@
1
+ import Middleware from '@poppinss/middleware';
2
+ import { RuntimeException } from '@poppinss/utils';
3
+ import { Qs } from '../qs.js';
4
+ import debug from '../debug.js';
5
+ import { Request } from '../request.js';
6
+ import { Response } from '../response.js';
7
+ import { Router } from '../router/main.js';
8
+ import { HttpContext } from '../http_context/main.js';
9
+ import { MiddlewareStore } from '../middleware/store.js';
10
+ import { finalHandler } from './factories/final_handler.js';
11
+ import { writeResponse } from './factories/write_response.js';
12
+ import { useReturnValue } from './factories/use_return_value.js';
13
+ import { asyncLocalStorage } from '../http_context/local_storage.js';
14
+ import { middlewareHandler } from './factories/middleware_handler.js';
15
+ export class Server {
16
+ #errorHandler;
17
+ #resolvedErrorHandler = {
18
+ handle(error, ctx) {
19
+ ctx.response.status(error.status || 500).send(error.message || 'Internal server error');
20
+ },
21
+ };
22
+ #app;
23
+ #encryption;
24
+ #config;
25
+ #qsParser;
26
+ #serverMiddlewareStack;
27
+ #router;
28
+ #underlyingHttpServer;
29
+ get usingAsyncLocalStorage() {
30
+ return asyncLocalStorage.isEnabled;
31
+ }
32
+ constructor(app, encryption, config) {
33
+ this.#app = app;
34
+ this.#encryption = encryption;
35
+ this.#config = config;
36
+ this.#qsParser = new Qs(this.#config.qs);
37
+ this.#createAsyncLocalStore();
38
+ debug('server config: %O', this.#config);
39
+ }
40
+ #createAsyncLocalStore() {
41
+ if (this.#config.useAsyncLocalStorage) {
42
+ debug('creating http context async local storage');
43
+ asyncLocalStorage.create();
44
+ }
45
+ else {
46
+ asyncLocalStorage.destroy();
47
+ }
48
+ }
49
+ #createRouter(middlewareStore) {
50
+ this.#router = new Router(this.#app, this.#encryption, middlewareStore, this.#qsParser);
51
+ }
52
+ #createServerMiddlewareStack(middlewareStore) {
53
+ this.#serverMiddlewareStack = new Middleware();
54
+ middlewareStore.list().forEach((middleware) => this.#serverMiddlewareStack.add(middleware));
55
+ this.#serverMiddlewareStack.freeze();
56
+ }
57
+ #createContext(req, res) {
58
+ const request = new Request(req, res, this.#encryption, this.#config, this.#qsParser);
59
+ const response = new Response(req, res, this.#encryption, this.#config, this.#router, this.#qsParser);
60
+ return new HttpContext(request, response, this.#app.logger.child({}));
61
+ }
62
+ use(serverMiddleware, routerMiddleware, namedMiddleware) {
63
+ this.#createRouter(new MiddlewareStore(routerMiddleware, namedMiddleware));
64
+ this.#createServerMiddlewareStack(new MiddlewareStore(serverMiddleware));
65
+ return this;
66
+ }
67
+ errorHandler(handler) {
68
+ this.#errorHandler = handler;
69
+ return this;
70
+ }
71
+ async boot() {
72
+ debug('booting HTTP server');
73
+ if (!this.#router) {
74
+ throw new RuntimeException('Cannot boot HTTP server. Register middleware using "server.use" first');
75
+ }
76
+ this.#router.commit();
77
+ if (this.#errorHandler) {
78
+ if (debug.enabled) {
79
+ debug('using custom error handler "%s"', this.#errorHandler);
80
+ }
81
+ const moduleExports = await this.#errorHandler();
82
+ this.#resolvedErrorHandler = await this.#app.container.make(moduleExports.default);
83
+ }
84
+ }
85
+ #handleRequest(ctx, resolver) {
86
+ return this.#serverMiddlewareStack.runner()
87
+ .finalHandler(finalHandler(this.#router, resolver, ctx))
88
+ .run(middlewareHandler(resolver, ctx))
89
+ .then(useReturnValue(ctx))
90
+ .catch((error) => this.#resolvedErrorHandler.handle(error, ctx))
91
+ .finally(writeResponse(ctx));
92
+ }
93
+ setNodeServer(server) {
94
+ this.#underlyingHttpServer = server;
95
+ }
96
+ close() {
97
+ return new Promise((resolve, reject) => {
98
+ if (!this.#underlyingHttpServer || !this.#underlyingHttpServer.listening) {
99
+ resolve();
100
+ return;
101
+ }
102
+ this.#underlyingHttpServer.close((error) => {
103
+ if (error) {
104
+ return reject(error);
105
+ }
106
+ resolve();
107
+ });
108
+ });
109
+ }
110
+ getNodeServer() {
111
+ return this.#underlyingHttpServer;
112
+ }
113
+ getRouter() {
114
+ return this.#router;
115
+ }
116
+ handle(req, res) {
117
+ const ctx = this.#createContext(req, res);
118
+ const resolver = this.#app.container.createResolver();
119
+ if (this.usingAsyncLocalStorage) {
120
+ return asyncLocalStorage.storage.run(ctx, () => this.#handleRequest(ctx, resolver));
121
+ }
122
+ return this.#handleRequest(ctx, resolver);
123
+ }
124
+ }
@@ -0,0 +1,5 @@
1
+ export type Constructor<T> = new (...args: any[]) => T;
2
+ export type LazyImport<DefaultExport> = () => Promise<{
3
+ default: DefaultExport;
4
+ }>;
5
+ export type UnWrapLazyImport<Fn extends LazyImport<any>> = Awaited<ReturnType<Fn>>['default'];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ export * from './base.js';
2
+ export * from './middleware.js';
3
+ export * from './qs.js';
4
+ export * from './request.js';
5
+ export * from './response.js';
6
+ export * from './route.js';
7
+ export * from './server.js';
@@ -0,0 +1,7 @@
1
+ export * from './base.js';
2
+ export * from './middleware.js';
3
+ export * from './qs.js';
4
+ export * from './request.js';
5
+ export * from './response.js';
6
+ export * from './route.js';
7
+ export * from './server.js';
@@ -0,0 +1,14 @@
1
+ import type { ContainerResolver } from '@adonisjs/fold';
2
+ import type { NextFn } from '@poppinss/middleware/types';
3
+ import type { Constructor } from './base.js';
4
+ import type { HttpContext } from '../http_context/main.js';
5
+ export type MiddlewareAsClass = Constructor<{
6
+ handle: (ctx: HttpContext, next: NextFn, args?: any) => any;
7
+ }>;
8
+ type HasUndefined<T> = T extends NonNullable<T> ? true : false;
9
+ export type GetMiddlewareArgs<Middleware extends MiddlewareAsClass> = HasUndefined<Parameters<InstanceType<Middleware>['handle']>[2]> extends true ? [Parameters<InstanceType<Middleware>['handle']>[2]] : [Parameters<InstanceType<Middleware>['handle']>[2]?];
10
+ export type MiddlewareFn = (ctx: HttpContext, next: NextFn) => any;
11
+ export type ParsedGlobalMiddleware = {
12
+ handle: (resolver: ContainerResolver<any>, ...args: [ctx: HttpContext, next: NextFn, params?: any]) => any;
13
+ };
14
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ export type QSParserConfig = {
2
+ parse: {
3
+ depth: number;
4
+ parameterLimit: number;
5
+ allowSparse: boolean;
6
+ arrayLimit: number;
7
+ comma: boolean;
8
+ };
9
+ stringify: {
10
+ encode: boolean;
11
+ encodeValuesOnly: boolean;
12
+ arrayFormat: 'indices' | 'brackets' | 'repeat' | 'comma';
13
+ skipNulls: boolean;
14
+ };
15
+ };
@@ -0,0 +1 @@
1
+ export {};