@duplojs/http 0.7.1 → 0.8.4

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 (154) hide show
  1. package/dist/client/getBody.cjs +3 -3
  2. package/dist/client/getBody.mjs +3 -3
  3. package/dist/client/hooks.cjs +45 -0
  4. package/dist/client/hooks.d.ts +6 -1
  5. package/dist/client/hooks.mjs +41 -1
  6. package/dist/client/httpClient.cjs +25 -1
  7. package/dist/client/httpClient.d.ts +8 -3
  8. package/dist/client/httpClient.mjs +25 -1
  9. package/dist/client/index.cjs +7 -0
  10. package/dist/client/index.d.ts +1 -0
  11. package/dist/client/index.mjs +2 -1
  12. package/dist/client/insertParamsInPath.cjs +1 -1
  13. package/dist/client/insertParamsInPath.mjs +1 -1
  14. package/dist/client/promiseRequest.cjs +83 -26
  15. package/dist/client/promiseRequest.d.ts +46 -29
  16. package/dist/client/promiseRequest.mjs +83 -26
  17. package/dist/client/queryToString.cjs +1 -1
  18. package/dist/client/queryToString.mjs +1 -1
  19. package/dist/client/serverSentEvents.cjs +231 -0
  20. package/dist/client/serverSentEvents.d.ts +2 -0
  21. package/dist/client/serverSentEvents.mjs +208 -0
  22. package/dist/client/types/clientRequestParams.d.ts +2 -0
  23. package/dist/client/types/clientResponse.d.ts +34 -3
  24. package/dist/client/types/hooks.d.ts +17 -7
  25. package/dist/client/types/promiseRequestParams.d.ts +1 -0
  26. package/dist/client/types/serverRoute.d.ts +2 -0
  27. package/dist/core/builders/route/handler.d.ts +5 -2
  28. package/dist/core/clean/entity.cjs +19 -28
  29. package/dist/core/clean/entity.d.ts +9 -9
  30. package/dist/core/clean/entity.mjs +20 -29
  31. package/dist/core/defaultHooks/index.cjs +8 -0
  32. package/dist/core/defaultHooks/index.d.ts +1 -1
  33. package/dist/core/defaultHooks/index.mjs +8 -0
  34. package/dist/core/functionsBuilders/route/default.cjs +9 -13
  35. package/dist/core/functionsBuilders/route/default.mjs +2 -6
  36. package/dist/core/functionsBuilders/steps/create.d.ts +2 -2
  37. package/dist/core/functionsBuilders/steps/defaults/cutStep.cjs +1 -1
  38. package/dist/core/functionsBuilders/steps/defaults/cutStep.mjs +1 -1
  39. package/dist/core/functionsBuilders/steps/defaults/handlerStep.cjs +37 -17
  40. package/dist/core/functionsBuilders/steps/defaults/handlerStep.mjs +37 -17
  41. package/dist/core/functionsBuilders/steps/defaults/processStep.cjs +3 -3
  42. package/dist/core/functionsBuilders/steps/defaults/processStep.mjs +3 -3
  43. package/dist/core/hub/defaultEmptyReaderImplementation.cjs +9 -0
  44. package/dist/core/hub/defaultEmptyReaderImplementation.d.ts +1 -0
  45. package/dist/core/hub/defaultEmptyReaderImplementation.mjs +7 -0
  46. package/dist/core/hub/defaultMalformedUrlHandler.cjs +14 -0
  47. package/dist/core/hub/defaultMalformedUrlHandler.d.ts +10 -0
  48. package/dist/core/hub/defaultMalformedUrlHandler.mjs +12 -0
  49. package/dist/core/hub/defaultNotfoundHandler.d.ts +1 -1
  50. package/dist/core/hub/index.cjs +14 -1
  51. package/dist/core/hub/index.d.ts +4 -0
  52. package/dist/core/hub/index.mjs +13 -2
  53. package/dist/core/implementHttpServer.cjs +7 -2
  54. package/dist/core/implementHttpServer.d.ts +7 -1
  55. package/dist/core/implementHttpServer.mjs +5 -0
  56. package/dist/core/index.cjs +18 -0
  57. package/dist/core/index.d.ts +1 -0
  58. package/dist/core/index.mjs +8 -2
  59. package/dist/core/request/bodyController/base.cjs +24 -6
  60. package/dist/core/request/bodyController/base.d.ts +9 -0
  61. package/dist/core/request/bodyController/base.mjs +25 -8
  62. package/dist/core/request/bodyController/empty.cjs +11 -0
  63. package/dist/core/request/bodyController/empty.d.ts +3 -0
  64. package/dist/core/request/bodyController/empty.mjs +8 -0
  65. package/dist/core/request/bodyController/formData.d.ts +2 -2
  66. package/dist/core/request/bodyController/index.cjs +4 -0
  67. package/dist/core/request/bodyController/index.d.ts +1 -0
  68. package/dist/core/request/bodyController/index.mjs +2 -1
  69. package/dist/core/request/index.cjs +5 -0
  70. package/dist/core/request/index.d.ts +1 -1
  71. package/dist/core/request/index.mjs +6 -1
  72. package/dist/core/response/contract.cjs +17 -4
  73. package/dist/core/response/contract.d.ts +19 -4
  74. package/dist/core/response/contract.mjs +17 -4
  75. package/dist/core/response/index.cjs +2 -0
  76. package/dist/core/response/index.d.ts +1 -0
  77. package/dist/core/response/index.mjs +1 -0
  78. package/dist/core/response/serverSentEventsPredicted.cjs +23 -0
  79. package/dist/core/response/serverSentEventsPredicted.d.ts +14 -0
  80. package/dist/core/response/serverSentEventsPredicted.mjs +21 -0
  81. package/dist/core/route/hooks.cjs +9 -0
  82. package/dist/core/route/hooks.d.ts +10 -9
  83. package/dist/core/route/hooks.mjs +9 -1
  84. package/dist/core/route/index.cjs +1 -0
  85. package/dist/core/route/index.mjs +1 -1
  86. package/dist/core/router/buildSystemRoute.cjs +33 -0
  87. package/dist/core/router/buildSystemRoute.d.ts +11 -0
  88. package/dist/core/router/buildSystemRoute.mjs +31 -0
  89. package/dist/core/router/decodeUrl.cjs +5 -4
  90. package/dist/core/router/decodeUrl.d.ts +1 -1
  91. package/dist/core/router/decodeUrl.mjs +5 -4
  92. package/dist/core/router/index.cjs +24 -23
  93. package/dist/core/router/index.d.ts +1 -0
  94. package/dist/core/router/index.mjs +25 -25
  95. package/dist/core/serverSentEvents.cjs +96 -0
  96. package/dist/core/serverSentEvents.d.ts +33 -0
  97. package/dist/core/serverSentEvents.mjs +96 -0
  98. package/dist/core/steps/cut.d.ts +2 -2
  99. package/dist/core/steps/handler.d.ts +10 -5
  100. package/dist/interfaces/node/bodyReaders/formData/index.cjs +33 -14
  101. package/dist/interfaces/node/bodyReaders/formData/index.mjs +34 -15
  102. package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.cjs +8 -11
  103. package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.mjs +8 -11
  104. package/dist/interfaces/node/createHttpServer.cjs +2 -3
  105. package/dist/interfaces/node/createHttpServer.mjs +2 -3
  106. package/dist/interfaces/node/hooks/index.cjs +61 -38
  107. package/dist/interfaces/node/hooks/index.d.ts +6 -4
  108. package/dist/interfaces/node/hooks/index.mjs +61 -38
  109. package/dist/interfaces/node/index.cjs +1 -1
  110. package/dist/interfaces/node/index.mjs +1 -1
  111. package/dist/plugins/cacheController/createResponseHeader.cjs +43 -0
  112. package/dist/plugins/cacheController/createResponseHeader.d.ts +2 -0
  113. package/dist/plugins/cacheController/createResponseHeader.mjs +41 -0
  114. package/dist/plugins/cacheController/hooks.cjs +23 -0
  115. package/dist/plugins/cacheController/hooks.d.ts +4 -0
  116. package/dist/plugins/cacheController/hooks.mjs +21 -0
  117. package/dist/plugins/cacheController/index.cjs +10 -0
  118. package/dist/plugins/cacheController/index.d.ts +3 -0
  119. package/dist/plugins/cacheController/index.mjs +3 -0
  120. package/dist/plugins/cacheController/types/cacheControlDirectives.cjs +2 -0
  121. package/dist/plugins/cacheController/types/cacheControlDirectives.d.ts +16 -0
  122. package/dist/plugins/cacheController/types/cacheControlDirectives.mjs +1 -0
  123. package/dist/plugins/cacheController/types/index.cjs +4 -0
  124. package/dist/plugins/cacheController/types/index.d.ts +1 -0
  125. package/dist/plugins/cacheController/types/index.mjs +1 -0
  126. package/dist/plugins/codeGenerator/aggregateStepContract.cjs +9 -2
  127. package/dist/plugins/codeGenerator/aggregateStepContract.d.ts +1 -1
  128. package/dist/plugins/codeGenerator/aggregateStepContract.mjs +10 -3
  129. package/dist/plugins/codeGenerator/plugin.cjs +4 -4
  130. package/dist/plugins/codeGenerator/plugin.mjs +1 -1
  131. package/dist/plugins/openApiGenerator/aggregateStepContract.d.ts +2 -7
  132. package/dist/plugins/openApiGenerator/routeToOpenApi.cjs +46 -8
  133. package/dist/plugins/openApiGenerator/routeToOpenApi.d.ts +2 -2
  134. package/dist/plugins/openApiGenerator/routeToOpenApi.mjs +46 -8
  135. package/dist/plugins/openApiGenerator/types/endpointResponse.d.ts +7 -3
  136. package/dist/plugins/static/index.cjs +14 -0
  137. package/dist/plugins/static/index.d.ts +3 -0
  138. package/dist/plugins/static/index.mjs +3 -0
  139. package/dist/plugins/static/kind.cjs +9 -0
  140. package/dist/plugins/static/kind.d.ts +6 -0
  141. package/dist/plugins/static/kind.mjs +7 -0
  142. package/dist/plugins/static/makeRouteFile.cjs +62 -0
  143. package/dist/plugins/static/makeRouteFile.d.ts +48 -0
  144. package/dist/plugins/static/makeRouteFile.mjs +58 -0
  145. package/dist/plugins/static/makeRouteFolder.cjs +67 -0
  146. package/dist/plugins/static/makeRouteFolder.d.ts +39 -0
  147. package/dist/plugins/static/makeRouteFolder.mjs +65 -0
  148. package/dist/plugins/static/plugin.cjs +53 -0
  149. package/dist/plugins/static/plugin.d.ts +26 -0
  150. package/dist/plugins/static/plugin.mjs +50 -0
  151. package/package.json +18 -7
  152. /package/dist/plugins/codeGenerator/{typescriptTransfomer.cjs → typescriptTransformer.cjs} +0 -0
  153. /package/dist/plugins/codeGenerator/{typescriptTransfomer.d.ts → typescriptTransformer.d.ts} +0 -0
  154. /package/dist/plugins/codeGenerator/{typescriptTransfomer.mjs → typescriptTransformer.mjs} +0 -0
@@ -0,0 +1,31 @@
1
+ import { asyncPipe, E, unwrap } from '@duplojs/utils';
2
+ import '../functionsBuilders/index.mjs';
3
+ import '../request/index.mjs';
4
+ import { createRoute } from '../route/index.mjs';
5
+ import { RouterBuildError } from './buildError.mjs';
6
+ import { defaultEmptyReaderImplementation } from '../hub/defaultEmptyReaderImplementation.mjs';
7
+ import { controlBodyAsEmpty } from '../request/bodyController/empty.mjs';
8
+ import { buildRouteFunction } from '../functionsBuilders/route/build.mjs';
9
+
10
+ async function buildSystemRoute(params) {
11
+ const bodyController = controlBodyAsEmpty();
12
+ const bodyReader = bodyController.createReaderOrThrow(defaultEmptyReaderImplementation);
13
+ const route = createRoute({
14
+ method: "GET",
15
+ paths: ["/"],
16
+ hooks: [],
17
+ preflightSteps: [],
18
+ steps: [params.handlerStep],
19
+ metadata: [],
20
+ bodyController,
21
+ });
22
+ const buildedRoute = await asyncPipe(buildRouteFunction(route, params.buildParams), E.whenIsLeft((element) => {
23
+ throw new RouterBuildError(route, element);
24
+ }), unwrap);
25
+ return {
26
+ bodyReader,
27
+ buildedRoute,
28
+ };
29
+ }
30
+
31
+ export { buildSystemRoute };
@@ -2,6 +2,7 @@
2
2
 
3
3
  const regexUrlAnalyser = /^(?<path>[^?]*)(?:\?(?<query>[^#]*))?(?:#(?<fragment>[^]*))?$/;
4
4
  const regexQueryAnalyser = /(?<key>[^=&]+)=(?<value>[^&]*)/g;
5
+ const invalidEntryRegex = /__proto__|constructor|prototype/;
5
6
  function decodeUrl(url) {
6
7
  try {
7
8
  const groups = regexUrlAnalyser.exec(url).groups;
@@ -17,6 +18,9 @@ function decodeUrl(url) {
17
18
  for (const result of queryString.matchAll(regexQueryAnalyser)) {
18
19
  const groups = result.groups;
19
20
  const key = decodeURIComponent(groups.key);
21
+ if (invalidEntryRegex.test(key)) {
22
+ continue;
23
+ }
20
24
  const value = decodeURIComponent(groups.value);
21
25
  const currentValue = query[key];
22
26
  if (typeof currentValue === "undefined") {
@@ -35,10 +39,7 @@ function decodeUrl(url) {
35
39
  };
36
40
  }
37
41
  catch {
38
- return {
39
- path: "/",
40
- query: {},
41
- };
42
+ return null;
42
43
  }
43
44
  }
44
45
 
@@ -4,4 +4,4 @@ export interface DecodedUrl {
4
4
  path: string;
5
5
  query: Record<string, string | string[]>;
6
6
  }
7
- export declare function decodeUrl(url: string): DecodedUrl;
7
+ export declare function decodeUrl(url: string): DecodedUrl | null;
@@ -1,5 +1,6 @@
1
1
  const regexUrlAnalyser = /^(?<path>[^?]*)(?:\?(?<query>[^#]*))?(?:#(?<fragment>[^]*))?$/;
2
2
  const regexQueryAnalyser = /(?<key>[^=&]+)=(?<value>[^&]*)/g;
3
+ const invalidEntryRegex = /__proto__|constructor|prototype/;
3
4
  function decodeUrl(url) {
4
5
  try {
5
6
  const groups = regexUrlAnalyser.exec(url).groups;
@@ -15,6 +16,9 @@ function decodeUrl(url) {
15
16
  for (const result of queryString.matchAll(regexQueryAnalyser)) {
16
17
  const groups = result.groups;
17
18
  const key = decodeURIComponent(groups.key);
19
+ if (invalidEntryRegex.test(key)) {
20
+ continue;
21
+ }
18
22
  const value = decodeURIComponent(groups.value);
19
23
  const currentValue = query[key];
20
24
  if (typeof currentValue === "undefined") {
@@ -33,10 +37,7 @@ function decodeUrl(url) {
33
37
  };
34
38
  }
35
39
  catch {
36
- return {
37
- path: "/",
38
- query: {},
39
- };
40
+ return null;
40
41
  }
41
42
  }
42
43
 
@@ -3,13 +3,12 @@
3
3
  require('../hub/index.cjs');
4
4
  var utils = require('@duplojs/utils');
5
5
  var pathToRegExp = require('./pathToRegExp.cjs');
6
- var index = require('../route/index.cjs');
7
6
  var buildError = require('./buildError.cjs');
8
7
  require('../functionsBuilders/route/index.cjs');
9
8
  var decodeUrl = require('./decodeUrl.cjs');
10
- var text = require('../request/bodyController/text.cjs');
11
9
  var notFoundBodyReaderImplementationError = require('./notFoundBodyReaderImplementationError.cjs');
12
10
  require('../functionsBuilders/index.cjs');
11
+ var buildSystemRoute = require('./buildSystemRoute.cjs');
13
12
  require('./types/index.cjs');
14
13
  var _default = require('../functionsBuilders/route/default.cjs');
15
14
  var checkerStep = require('../functionsBuilders/steps/defaults/checkerStep.cjs');
@@ -63,35 +62,36 @@ async function buildRouter(hub) {
63
62
  }))),
64
63
  });
65
64
  });
66
- const bodyControllerNotfoundRoute = text.controlBodyAsText();
67
- const bodyReaderNotFoundRoute = utils.unwrap(bodyControllerNotfoundRoute.tryToCreateReader(text.TextBodyController.createReaderImplementation(() => Promise.resolve(utils.E.error(new Error("Inaccessible body in not found route."))))));
68
- utils.asserts(bodyReaderNotFoundRoute, utils.isType("object"));
69
- const buildedNotfoundRoute = await utils.asyncPipe(index.createRoute({
70
- method: "GET",
71
- paths: ["/"],
72
- hooks: [],
73
- preflightSteps: [],
74
- steps: [hub.notfoundHandler],
75
- metadata: [],
76
- bodyController: bodyControllerNotfoundRoute,
77
- }), async (route) => {
78
- const result = await build.buildRouteFunction(route, buildParams);
79
- return utils.E.whenIsLeft(result, (element) => {
80
- throw new buildError.RouterBuildError(route, element);
81
- });
82
- }, utils.unwrap);
65
+ const defaultNotfoundRoute = await buildSystemRoute.buildSystemRoute({
66
+ handlerStep: hub.notfoundHandler,
67
+ buildParams,
68
+ });
69
+ const defaultMalformedUrlRoute = await buildSystemRoute.buildSystemRoute({
70
+ handlerStep: hub.malformedUrlHandler,
71
+ buildParams,
72
+ });
83
73
  const Request = hub.classRequest;
84
74
  return {
85
75
  exec: (initializationData) => {
86
76
  const routerElements = groupedRoute[initializationData.method];
87
77
  const decodedUrl = decodeUrl.decodeUrl(initializationData.url);
78
+ if (!decodedUrl) {
79
+ return defaultMalformedUrlRoute.buildedRoute(new Request({
80
+ ...initializationData,
81
+ params: {},
82
+ path: "",
83
+ query: {},
84
+ matchedPath: null,
85
+ bodyReader: defaultMalformedUrlRoute.bodyReader,
86
+ }));
87
+ }
88
88
  if (!routerElements) {
89
- return buildedNotfoundRoute(new Request({
89
+ return defaultNotfoundRoute.buildedRoute(new Request({
90
90
  ...initializationData,
91
91
  ...decodedUrl,
92
92
  params: {},
93
93
  matchedPath: null,
94
- bodyReader: bodyReaderNotFoundRoute,
94
+ bodyReader: defaultNotfoundRoute.bodyReader,
95
95
  }));
96
96
  }
97
97
  // eslint-disable-next-line @typescript-eslint/prefer-for-of
@@ -109,12 +109,12 @@ async function buildRouter(hub) {
109
109
  bodyReader: routerElement.bodyReader,
110
110
  }));
111
111
  }
112
- return buildedNotfoundRoute(new Request({
112
+ return defaultNotfoundRoute.buildedRoute(new Request({
113
113
  ...initializationData,
114
114
  ...decodedUrl,
115
115
  params: {},
116
116
  matchedPath: null,
117
- bodyReader: bodyReaderNotFoundRoute,
117
+ bodyReader: defaultNotfoundRoute.bodyReader,
118
118
  }));
119
119
  },
120
120
  hooksRouteLifeCycle,
@@ -131,4 +131,5 @@ exports.decodeUrl = decodeUrl.decodeUrl;
131
131
  exports.regexQueryAnalyser = decodeUrl.regexQueryAnalyser;
132
132
  exports.regexUrlAnalyser = decodeUrl.regexUrlAnalyser;
133
133
  exports.NotFoundBodyReaderImplementationError = notFoundBodyReaderImplementationError.NotFoundBodyReaderImplementationError;
134
+ exports.buildSystemRoute = buildSystemRoute.buildSystemRoute;
134
135
  exports.buildRouter = buildRouter;
@@ -5,4 +5,5 @@ export * from "./pathToRegExp";
5
5
  export * from "./buildError";
6
6
  export * from "./decodeUrl";
7
7
  export * from "./notFoundBodyReaderImplementationError";
8
+ export * from "./buildSystemRoute";
8
9
  export declare function buildRouter(hub: Hub): Promise<BuildedRouter>;
@@ -1,14 +1,13 @@
1
1
  import '../hub/index.mjs';
2
- import { pipe, A, isType, G, E, unwrap, justReturn, O, forward, asserts, asyncPipe } from '@duplojs/utils';
2
+ import { pipe, A, isType, G, E, unwrap, justReturn, O, forward } from '@duplojs/utils';
3
3
  import { pathToRegExp } from './pathToRegExp.mjs';
4
- import { createRoute } from '../route/index.mjs';
5
4
  import { RouterBuildError } from './buildError.mjs';
6
5
  import '../functionsBuilders/route/index.mjs';
7
6
  import { decodeUrl } from './decodeUrl.mjs';
8
7
  export { regexQueryAnalyser, regexUrlAnalyser } from './decodeUrl.mjs';
9
- import { controlBodyAsText, TextBodyController } from '../request/bodyController/text.mjs';
10
8
  import { NotFoundBodyReaderImplementationError } from './notFoundBodyReaderImplementationError.mjs';
11
9
  import '../functionsBuilders/index.mjs';
10
+ import { buildSystemRoute } from './buildSystemRoute.mjs';
12
11
  import './types/index.mjs';
13
12
  import { defaultRouteFunctionBuilder } from '../functionsBuilders/route/default.mjs';
14
13
  import { defaultCheckerStepFunctionBuilder } from '../functionsBuilders/steps/defaults/checkerStep.mjs';
@@ -62,35 +61,36 @@ async function buildRouter(hub) {
62
61
  }))),
63
62
  });
64
63
  });
65
- const bodyControllerNotfoundRoute = controlBodyAsText();
66
- const bodyReaderNotFoundRoute = unwrap(bodyControllerNotfoundRoute.tryToCreateReader(TextBodyController.createReaderImplementation(() => Promise.resolve(E.error(new Error("Inaccessible body in not found route."))))));
67
- asserts(bodyReaderNotFoundRoute, isType("object"));
68
- const buildedNotfoundRoute = await asyncPipe(createRoute({
69
- method: "GET",
70
- paths: ["/"],
71
- hooks: [],
72
- preflightSteps: [],
73
- steps: [hub.notfoundHandler],
74
- metadata: [],
75
- bodyController: bodyControllerNotfoundRoute,
76
- }), async (route) => {
77
- const result = await buildRouteFunction(route, buildParams);
78
- return E.whenIsLeft(result, (element) => {
79
- throw new RouterBuildError(route, element);
80
- });
81
- }, unwrap);
64
+ const defaultNotfoundRoute = await buildSystemRoute({
65
+ handlerStep: hub.notfoundHandler,
66
+ buildParams,
67
+ });
68
+ const defaultMalformedUrlRoute = await buildSystemRoute({
69
+ handlerStep: hub.malformedUrlHandler,
70
+ buildParams,
71
+ });
82
72
  const Request = hub.classRequest;
83
73
  return {
84
74
  exec: (initializationData) => {
85
75
  const routerElements = groupedRoute[initializationData.method];
86
76
  const decodedUrl = decodeUrl(initializationData.url);
77
+ if (!decodedUrl) {
78
+ return defaultMalformedUrlRoute.buildedRoute(new Request({
79
+ ...initializationData,
80
+ params: {},
81
+ path: "",
82
+ query: {},
83
+ matchedPath: null,
84
+ bodyReader: defaultMalformedUrlRoute.bodyReader,
85
+ }));
86
+ }
87
87
  if (!routerElements) {
88
- return buildedNotfoundRoute(new Request({
88
+ return defaultNotfoundRoute.buildedRoute(new Request({
89
89
  ...initializationData,
90
90
  ...decodedUrl,
91
91
  params: {},
92
92
  matchedPath: null,
93
- bodyReader: bodyReaderNotFoundRoute,
93
+ bodyReader: defaultNotfoundRoute.bodyReader,
94
94
  }));
95
95
  }
96
96
  // eslint-disable-next-line @typescript-eslint/prefer-for-of
@@ -108,12 +108,12 @@ async function buildRouter(hub) {
108
108
  bodyReader: routerElement.bodyReader,
109
109
  }));
110
110
  }
111
- return buildedNotfoundRoute(new Request({
111
+ return defaultNotfoundRoute.buildedRoute(new Request({
112
112
  ...initializationData,
113
113
  ...decodedUrl,
114
114
  params: {},
115
115
  matchedPath: null,
116
- bodyReader: bodyReaderNotFoundRoute,
116
+ bodyReader: defaultNotfoundRoute.bodyReader,
117
117
  }));
118
118
  },
119
119
  hooksRouteLifeCycle,
@@ -124,4 +124,4 @@ async function buildRouter(hub) {
124
124
  };
125
125
  }
126
126
 
127
- export { NotFoundBodyReaderImplementationError, RouterBuildError, buildRouter, decodeUrl, pathToRegExp };
127
+ export { NotFoundBodyReaderImplementationError, RouterBuildError, buildRouter, buildSystemRoute, decodeUrl, pathToRegExp };
@@ -0,0 +1,96 @@
1
+ 'use strict';
2
+
3
+ var utils = require('@duplojs/utils');
4
+
5
+ /* eslint-disable @typescript-eslint/prefer-for-of */
6
+ exports.ServerSentEvents = void 0;
7
+ (function (ServerSentEvents) {
8
+ const regexServerSentEventSplitStringData = /\r\n|\r|\n/;
9
+ const nullIdRegexp = /\0|\n|\r/;
10
+ function init(response, initParams) {
11
+ const abortSubscribers = [];
12
+ let isAbort = false;
13
+ const handler = {
14
+ async start(send, close) {
15
+ if (isAbort) {
16
+ return;
17
+ }
18
+ let isClose = false;
19
+ const closeSubscribers = [];
20
+ const errorSubscribers = [];
21
+ const params = {
22
+ send: (event, data, params) => {
23
+ if (isClose) {
24
+ return Promise.resolve();
25
+ }
26
+ else if (isAbort) {
27
+ return Promise.resolve();
28
+ }
29
+ let content = `event: ${event || "message"}\n`;
30
+ if (typeof data === "string") {
31
+ const splitData = data.split(regexServerSentEventSplitStringData);
32
+ for (let index = 0; index < splitData.length; index++) {
33
+ content += `data: ${splitData[index]}\n`;
34
+ }
35
+ }
36
+ else if (data !== undefined) {
37
+ content += `content-type: application/json\ndata: ${JSON.stringify(data)}\n`;
38
+ }
39
+ if (typeof params?.id === "string" && !nullIdRegexp.test(params.id)) {
40
+ content += `id: ${params.id}\n`;
41
+ }
42
+ if (params?.retry !== undefined) {
43
+ content += `retry: ${utils.stringToMillisecond(params.retry)}\n`;
44
+ }
45
+ content += "\n";
46
+ return send(content);
47
+ },
48
+ abort: handler.abort,
49
+ isAbort: () => isAbort,
50
+ onAbort: (theFunction) => void abortSubscribers.push(theFunction),
51
+ close: () => {
52
+ if (isClose === true) {
53
+ return;
54
+ }
55
+ isClose = true;
56
+ close();
57
+ for (let index = 0; index < closeSubscribers.length; index++) {
58
+ closeSubscribers[index]();
59
+ }
60
+ },
61
+ isClose: () => isClose,
62
+ onClose: (theFunction) => void closeSubscribers.push(theFunction),
63
+ error: (error) => {
64
+ for (let index = 0; index < errorSubscribers.length; index++) {
65
+ errorSubscribers[index](error);
66
+ }
67
+ },
68
+ onError: (theFunction) => void errorSubscribers.push(theFunction),
69
+ lastId: initParams.lastId && !nullIdRegexp.test(initParams.lastId)
70
+ ? initParams.lastId
71
+ : null,
72
+ };
73
+ try {
74
+ await response.startSendingEvents(params);
75
+ }
76
+ catch (error) {
77
+ params.error(error);
78
+ }
79
+ finally {
80
+ params.close();
81
+ }
82
+ },
83
+ abort() {
84
+ if (isAbort === true) {
85
+ return;
86
+ }
87
+ isAbort = true;
88
+ for (let index = 0; index < abortSubscribers.length; index++) {
89
+ abortSubscribers[index]();
90
+ }
91
+ },
92
+ };
93
+ return handler;
94
+ }
95
+ ServerSentEvents.init = init;
96
+ })(exports.ServerSentEvents || (exports.ServerSentEvents = {}));
@@ -0,0 +1,33 @@
1
+ import { type MillisecondInString } from "@duplojs/utils";
2
+ import { type ServerSentEventsPredictedResponse } from "./response";
3
+ export declare namespace ServerSentEvents {
4
+ type DefinitionShape = [string, unknown];
5
+ interface SendParams {
6
+ id?: string;
7
+ retry?: number | MillisecondInString;
8
+ }
9
+ interface StartSendingParams<GenericEvents extends DefinitionShape = DefinitionShape> {
10
+ send(...args: GenericEvents extends any ? [
11
+ event: GenericEvents[0],
12
+ ...(GenericEvents[1] extends undefined ? [data?: GenericEvents[1]] : [data: GenericEvents[1]]),
13
+ params?: SendParams
14
+ ] : never): Promise<void>;
15
+ abort(): void;
16
+ onAbort(theFunction: () => void): void;
17
+ isAbort(): boolean;
18
+ close(): void;
19
+ onClose(theFunction: () => void): void;
20
+ isClose(): boolean;
21
+ error(error: unknown): void;
22
+ onError(theFunction: (error: unknown) => void): void;
23
+ readonly lastId: string | null;
24
+ }
25
+ interface Handler {
26
+ start(send: (value: string) => Promise<void>, close: () => void): Promise<void>;
27
+ abort(): void;
28
+ }
29
+ interface InitParams {
30
+ readonly lastId: string | null;
31
+ }
32
+ function init(response: ServerSentEventsPredictedResponse, initParams: InitParams): Handler;
33
+ }
@@ -0,0 +1,96 @@
1
+ import { stringToMillisecond } from '@duplojs/utils';
2
+
3
+ /* eslint-disable @typescript-eslint/prefer-for-of */
4
+ var ServerSentEvents;
5
+ (function (ServerSentEvents) {
6
+ const regexServerSentEventSplitStringData = /\r\n|\r|\n/;
7
+ const nullIdRegexp = /\0|\n|\r/;
8
+ function init(response, initParams) {
9
+ const abortSubscribers = [];
10
+ let isAbort = false;
11
+ const handler = {
12
+ async start(send, close) {
13
+ if (isAbort) {
14
+ return;
15
+ }
16
+ let isClose = false;
17
+ const closeSubscribers = [];
18
+ const errorSubscribers = [];
19
+ const params = {
20
+ send: (event, data, params) => {
21
+ if (isClose) {
22
+ return Promise.resolve();
23
+ }
24
+ else if (isAbort) {
25
+ return Promise.resolve();
26
+ }
27
+ let content = `event: ${event || "message"}\n`;
28
+ if (typeof data === "string") {
29
+ const splitData = data.split(regexServerSentEventSplitStringData);
30
+ for (let index = 0; index < splitData.length; index++) {
31
+ content += `data: ${splitData[index]}\n`;
32
+ }
33
+ }
34
+ else if (data !== undefined) {
35
+ content += `content-type: application/json\ndata: ${JSON.stringify(data)}\n`;
36
+ }
37
+ if (typeof params?.id === "string" && !nullIdRegexp.test(params.id)) {
38
+ content += `id: ${params.id}\n`;
39
+ }
40
+ if (params?.retry !== undefined) {
41
+ content += `retry: ${stringToMillisecond(params.retry)}\n`;
42
+ }
43
+ content += "\n";
44
+ return send(content);
45
+ },
46
+ abort: handler.abort,
47
+ isAbort: () => isAbort,
48
+ onAbort: (theFunction) => void abortSubscribers.push(theFunction),
49
+ close: () => {
50
+ if (isClose === true) {
51
+ return;
52
+ }
53
+ isClose = true;
54
+ close();
55
+ for (let index = 0; index < closeSubscribers.length; index++) {
56
+ closeSubscribers[index]();
57
+ }
58
+ },
59
+ isClose: () => isClose,
60
+ onClose: (theFunction) => void closeSubscribers.push(theFunction),
61
+ error: (error) => {
62
+ for (let index = 0; index < errorSubscribers.length; index++) {
63
+ errorSubscribers[index](error);
64
+ }
65
+ },
66
+ onError: (theFunction) => void errorSubscribers.push(theFunction),
67
+ lastId: initParams.lastId && !nullIdRegexp.test(initParams.lastId)
68
+ ? initParams.lastId
69
+ : null,
70
+ };
71
+ try {
72
+ await response.startSendingEvents(params);
73
+ }
74
+ catch (error) {
75
+ params.error(error);
76
+ }
77
+ finally {
78
+ params.close();
79
+ }
80
+ },
81
+ abort() {
82
+ if (isAbort === true) {
83
+ return;
84
+ }
85
+ isAbort = true;
86
+ for (let index = 0; index < abortSubscribers.length; index++) {
87
+ abortSubscribers[index]();
88
+ }
89
+ },
90
+ };
91
+ return handler;
92
+ }
93
+ ServerSentEvents.init = init;
94
+ })(ServerSentEvents || (ServerSentEvents = {}));
95
+
96
+ export { ServerSentEvents };
@@ -1,4 +1,4 @@
1
- import { type WrappedValue, type Kind, type MaybePromise, type NeverCoalescing } from "@duplojs/utils";
1
+ import { type WrappedValue, type Kind, type MaybePromise, type NeverCoalescing, type MaybeArray } from "@duplojs/utils";
2
2
  import { type StepKind } from "./kind";
3
3
  import { type Floor } from "../floor";
4
4
  import { type StepFunctionParams } from "./types";
@@ -13,7 +13,7 @@ export interface CutStepFunctionParams<GenericRequest extends Request = Request,
13
13
  }
14
14
  export interface CutStepDefinition {
15
15
  theFunction(floor: Floor, params: CutStepFunctionParams): MaybePromise<CutStepFunctionOutput | PredictedResponse>;
16
- readonly responseContract: ResponseContract.Contract | readonly ResponseContract.Contract[];
16
+ readonly responseContract: MaybeArray<ResponseContract.Contract>;
17
17
  readonly metadata: readonly Metadata[];
18
18
  }
19
19
  export declare const cutStepKind: import("@duplojs/utils").KindHandler<import("@duplojs/utils").KindDefinition<"@DuplojsHttpCore/cut-step", unknown>>;
@@ -1,15 +1,20 @@
1
- import { type MaybePromise, type Kind } from "@duplojs/utils";
1
+ import { type MaybePromise, type Kind, type MaybeArray } from "@duplojs/utils";
2
2
  import { type StepKind } from "./kind";
3
3
  import { type Floor } from "../floor";
4
- import { type PredictedResponse, type ResponseContract } from "../response";
4
+ import { type ServerSentEventsPredictedResponse, type PredictedResponse, type ResponseContract } from "../response";
5
5
  import { type Request } from "../request";
6
6
  import { type StepFunctionParams } from "./types";
7
7
  import { type Metadata } from "../metadata";
8
- export interface HandlerStepFunctionParams<GenericRequest extends Request = Request, GenericResponse extends PredictedResponse = PredictedResponse> extends StepFunctionParams<GenericRequest, GenericResponse> {
8
+ interface HandlerStepFunctionParamsServerSentEventsResponse<GenericResponse extends ServerSentEventsPredictedResponse> {
9
+ serverSentEventsResponse<GenericInformation extends GenericResponse["information"], GenericFilteredResponse extends Extract<GenericResponse, {
10
+ information: GenericInformation;
11
+ }>>(information: GenericInformation, startSendingEvents: GenericFilteredResponse["startSendingEvents"]): GenericFilteredResponse;
12
+ }
13
+ export interface HandlerStepFunctionParams<GenericRequest extends Request = Request, GenericResponse extends PredictedResponse | ServerSentEventsPredictedResponse = PredictedResponse | ServerSentEventsPredictedResponse> extends StepFunctionParams<GenericRequest, Extract<GenericResponse, PredictedResponse>>, HandlerStepFunctionParamsServerSentEventsResponse<Extract<GenericResponse, ServerSentEventsPredictedResponse>> {
9
14
  }
10
15
  export interface HandlerStepDefinition {
11
- theFunction(floor: Floor, params: HandlerStepFunctionParams): MaybePromise<PredictedResponse>;
12
- readonly responseContract: ResponseContract.Contract | readonly ResponseContract.Contract[];
16
+ theFunction(floor: Floor, params: HandlerStepFunctionParams): MaybePromise<PredictedResponse | ServerSentEventsPredictedResponse>;
17
+ readonly responseContract: MaybeArray<ResponseContract.Contract | ResponseContract.ServerSentEventsContract>;
13
18
  readonly metadata: readonly Metadata[];
14
19
  }
15
20
  export declare const handlerStepKind: import("@duplojs/utils").KindHandler<import("@duplojs/utils").KindDefinition<"@DuplojsHttpCore/handler-step", unknown>>;
@@ -4,14 +4,39 @@ require('../../../../core/request/index.cjs');
4
4
  var serverUtils = require('@duplojs/server-utils');
5
5
  var utils = require('@duplojs/utils');
6
6
  var readRequestFormData = require('./readRequestFormData.cjs');
7
- var node_fs = require('node:fs');
7
+ var node_crypto = require('node:crypto');
8
8
  require('../../../../core/errors/index.cjs');
9
+ var promises = require('node:fs/promises');
9
10
  var error = require('./error.cjs');
10
11
  var formData = require('../../../../core/request/bodyController/formData.cjs');
11
12
  var wrongContentTypeError = require('../../../../core/errors/wrongContentTypeError.cjs');
12
13
 
13
14
  function createFormDataBodyReaderImplementation(serverParams) {
14
15
  const serverMaxBodySize = utils.stringToBytes(serverParams.maxBodySize);
16
+ async function createUploadFile(extension, highWaterMark) {
17
+ let remainingAttempts = 5;
18
+ do {
19
+ const path = utils.Path.resolveRelative([
20
+ serverParams.uploadFolder,
21
+ `${node_crypto.randomUUID()}${extension}`,
22
+ ]);
23
+ try {
24
+ const handle = await promises.open(path, "wx");
25
+ return {
26
+ path,
27
+ writeStream: handle.createWriteStream({
28
+ highWaterMark,
29
+ autoClose: true,
30
+ }),
31
+ };
32
+ }
33
+ catch (error) {
34
+ if (error.code !== "EEXIST" || --remainingAttempts === 0) {
35
+ throw error;
36
+ }
37
+ }
38
+ } while (true);
39
+ }
15
40
  function addValue(mapResult, fieldName, newValue) {
16
41
  const value = mapResult.get(fieldName);
17
42
  if (value === undefined) {
@@ -34,32 +59,26 @@ function createFormDataBodyReaderImplementation(serverParams) {
34
59
  mimeType: params.mimeType,
35
60
  maxBufferSize: params.maxBufferSize,
36
61
  maxKeyLength: params.maxKeyLength,
37
- }, (header) => {
62
+ }, async (header) => {
38
63
  const fieldName = header.name;
39
64
  if (header.filename) {
40
65
  const extension = utils.Path.getExtensionName(header.filename);
41
66
  const displayExtension = extension ? `.${extension}` : "";
42
- const filePath = utils.Path.resolveRelative([
43
- serverParams.uploadFolder,
44
- `${Math.random().toString(36).slice(2, 10)}-${Date.now()}${displayExtension}`,
45
- ]);
46
- filesAttache.push(filePath);
47
- const currentFile = node_fs.createWriteStream(filePath, {
48
- highWaterMark: request.raw.request.readableHighWaterMark,
49
- });
67
+ const { path, writeStream } = await createUploadFile(displayExtension, request.raw.request.readableHighWaterMark);
68
+ filesAttache.push(path);
50
69
  return {
51
- onReceiveChunk: (chunk) => new Promise((resolve, reject) => void currentFile.write(chunk, (result) => {
70
+ onReceiveChunk: (chunk) => new Promise((resolve, reject) => void writeStream.write(chunk, (result) => {
52
71
  if (result instanceof Error) {
53
72
  return void reject(result);
54
73
  }
55
74
  return void resolve();
56
75
  })),
57
76
  onEndPart: (valueAccumulator) => {
58
- currentFile.end();
59
- addValue(valueAccumulator, fieldName, serverUtils.SF.createFileInterface(currentFile.path.toString()));
77
+ writeStream.end();
78
+ addValue(valueAccumulator, fieldName, serverUtils.SF.createFileInterface(path));
60
79
  return valueAccumulator;
61
80
  },
62
- onError: () => void currentFile.end(),
81
+ onError: () => void writeStream.end(),
63
82
  };
64
83
  }
65
84
  let currentValue = "";