@duplojs/http 0.6.1 → 0.7.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.
- package/dist/client/getBody.cjs +1 -1
- package/dist/client/getBody.mjs +1 -1
- package/dist/client/hooks.d.ts +1 -25
- package/dist/client/httpClient.d.ts +29 -25
- package/dist/client/promiseRequest.cjs +3 -0
- package/dist/client/promiseRequest.d.ts +31 -39
- package/dist/client/promiseRequest.mjs +4 -1
- package/dist/client/types/clientResponse.d.ts +6 -6
- package/dist/client/types/hooks.d.ts +25 -0
- package/dist/client/types/index.cjs +2 -0
- package/dist/client/types/index.d.ts +2 -0
- package/dist/client/types/index.mjs +2 -0
- package/dist/client/types/promiseRequestParams.cjs +2 -0
- package/dist/client/types/promiseRequestParams.d.ts +9 -0
- package/dist/client/types/promiseRequestParams.mjs +1 -0
- package/dist/client/types/serverRoute.d.ts +19 -1
- package/dist/client/unexpectedResponseError.d.ts +1 -2
- package/dist/core/builders/preflight/route.cjs +1 -0
- package/dist/core/builders/preflight/route.d.ts +4 -2
- package/dist/core/builders/preflight/route.mjs +1 -0
- package/dist/core/builders/route/builder.cjs +1 -0
- package/dist/core/builders/route/builder.d.ts +4 -2
- package/dist/core/builders/route/builder.mjs +1 -0
- package/dist/core/clean/constraint.cjs +24 -0
- package/dist/core/clean/constraint.d.ts +8 -0
- package/dist/core/clean/constraint.mjs +22 -0
- package/dist/core/clean/constraintsSet.cjs +27 -0
- package/dist/core/clean/constraintsSet.d.ts +8 -0
- package/dist/core/clean/constraintsSet.mjs +25 -0
- package/dist/core/clean/entity.cjs +33 -0
- package/dist/core/clean/entity.d.ts +20 -0
- package/dist/core/clean/entity.mjs +31 -0
- package/dist/core/clean/index.cjs +8 -0
- package/dist/core/clean/index.d.ts +5 -0
- package/dist/core/clean/index.mjs +5 -0
- package/dist/core/clean/newType.cjs +15 -0
- package/dist/core/clean/newType.d.ts +8 -0
- package/dist/core/clean/newType.mjs +13 -0
- package/dist/core/clean/primitive.cjs +12 -0
- package/dist/core/clean/primitive.d.ts +8 -0
- package/dist/core/clean/primitive.mjs +10 -0
- package/dist/core/defaultHooks/index.cjs +50 -0
- package/dist/core/defaultHooks/index.d.ts +5 -0
- package/dist/core/defaultHooks/index.mjs +48 -0
- package/dist/{interfaces/node/error → core/errors}/bodyParseWrongChunkReceived.cjs +6 -4
- package/dist/core/errors/bodyParseWrongChunkReceived.d.ts +9 -0
- package/dist/core/errors/bodyParseWrongChunkReceived.mjs +14 -0
- package/dist/{interfaces/node/error → core/errors}/bodySizeExceedsLimitError.cjs +2 -2
- package/dist/{interfaces/node/error → core/errors}/bodySizeExceedsLimitError.d.ts +2 -2
- package/dist/{interfaces/node/error → core/errors}/bodySizeExceedsLimitError.mjs +2 -2
- package/dist/{interfaces/node/error → core/errors}/index.cjs +6 -4
- package/dist/{interfaces/node/error → core/errors}/index.d.ts +3 -2
- package/dist/{interfaces/node/error → core/errors}/index.mjs +3 -2
- package/dist/core/errors/parseJsonError.cjs +16 -0
- package/dist/core/errors/parseJsonError.d.ts +9 -0
- package/dist/core/errors/parseJsonError.mjs +14 -0
- package/dist/core/errors/wrongContentTypeError.cjs +16 -0
- package/dist/core/errors/wrongContentTypeError.d.ts +9 -0
- package/dist/core/errors/wrongContentTypeError.mjs +14 -0
- package/dist/core/functionsBuilders/route/create.d.ts +2 -2
- package/dist/core/functionsBuilders/route/default.cjs +0 -11
- package/dist/core/functionsBuilders/route/default.mjs +0 -11
- package/dist/core/functionsBuilders/route/hook.d.ts +2 -2
- package/dist/core/functionsBuilders/steps/create.d.ts +2 -2
- package/dist/core/functionsBuilders/steps/defaults/cutStep.cjs +15 -18
- package/dist/core/functionsBuilders/steps/defaults/cutStep.mjs +15 -18
- package/dist/core/functionsBuilders/steps/defaults/extractStep.cjs +43 -19
- package/dist/core/functionsBuilders/steps/defaults/extractStep.d.ts +2 -1
- package/dist/core/functionsBuilders/steps/defaults/extractStep.mjs +44 -20
- package/dist/core/functionsBuilders/steps/defaults/handlerStep.cjs +14 -8
- package/dist/core/functionsBuilders/steps/defaults/handlerStep.mjs +14 -8
- package/dist/core/hub/defaultBodyController.cjs +8 -0
- package/dist/core/hub/defaultBodyController.d.ts +1 -0
- package/dist/core/hub/defaultBodyController.mjs +6 -0
- package/dist/core/hub/hooks.cjs +3 -1
- package/dist/core/hub/hooks.d.ts +2 -3
- package/dist/core/hub/hooks.mjs +3 -1
- package/dist/core/hub/index.cjs +101 -127
- package/dist/core/hub/index.d.ts +33 -34
- package/dist/core/hub/index.mjs +100 -128
- package/dist/core/implementHttpServer.cjs +5 -5
- package/dist/core/implementHttpServer.d.ts +2 -1
- package/dist/core/implementHttpServer.mjs +5 -5
- package/dist/core/index.cjs +35 -10
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.mjs +14 -2
- package/dist/core/request/bodyController/base.cjs +36 -0
- package/dist/core/request/bodyController/base.d.ts +28 -0
- package/dist/core/request/bodyController/base.mjs +34 -0
- package/dist/core/request/bodyController/formData.cjs +28 -0
- package/dist/core/request/bodyController/formData.d.ts +22 -0
- package/dist/core/request/bodyController/formData.mjs +25 -0
- package/dist/core/request/bodyController/index.cjs +13 -0
- package/dist/core/request/bodyController/index.d.ts +3 -0
- package/dist/core/request/bodyController/index.mjs +3 -0
- package/dist/core/request/bodyController/text.cjs +14 -0
- package/dist/core/request/bodyController/text.d.ts +10 -0
- package/dist/core/request/bodyController/text.mjs +11 -0
- package/dist/core/{request.cjs → request/index.cjs} +21 -3
- package/dist/core/{request.d.ts → request/index.d.ts} +10 -3
- package/dist/core/request/index.mjs +50 -0
- package/dist/core/response/contract.d.ts +1 -1
- package/dist/core/route/hooks.d.ts +0 -2
- package/dist/core/route/index.d.ts +2 -1
- package/dist/core/router/index.cjs +27 -8
- package/dist/core/router/index.d.ts +2 -1
- package/dist/core/router/index.mjs +28 -10
- package/dist/core/router/notFoundBodyReaderImplementationError.cjs +16 -0
- package/dist/core/router/notFoundBodyReaderImplementationError.d.ts +11 -0
- package/dist/core/router/notFoundBodyReaderImplementationError.mjs +14 -0
- package/dist/core/router/types/buildedRouter.d.ts +3 -3
- package/dist/core/steps/extract.d.ts +3 -1
- package/dist/core/steps/types/steps.d.ts +1 -3
- package/dist/core/types/hosts.cjs +2 -0
- package/dist/core/types/hosts.d.ts +4 -0
- package/dist/core/types/hosts.mjs +1 -0
- package/dist/core/types/httpServerParams.cjs +2 -0
- package/dist/core/types/httpServerParams.d.ts +11 -0
- package/dist/core/types/httpServerParams.mjs +1 -0
- package/dist/core/types/index.cjs +2 -0
- package/dist/core/types/index.d.ts +2 -0
- package/dist/core/types/index.mjs +2 -0
- package/dist/interfaces/bun/types/request.cjs +1 -1
- package/dist/interfaces/bun/types/request.mjs +1 -1
- package/dist/interfaces/node/bodyReaders/formData/error.cjs +14 -0
- package/dist/interfaces/node/bodyReaders/formData/error.d.ts +8 -0
- package/dist/interfaces/node/bodyReaders/formData/error.mjs +12 -0
- package/dist/interfaces/node/bodyReaders/formData/index.cjs +94 -0
- package/dist/interfaces/node/bodyReaders/formData/index.d.ts +4 -0
- package/dist/interfaces/node/bodyReaders/formData/index.mjs +90 -0
- package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.cjs +175 -0
- package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.d.ts +21 -0
- package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.mjs +173 -0
- package/dist/interfaces/node/bodyReaders/index.cjs +9 -0
- package/dist/interfaces/node/bodyReaders/index.d.ts +2 -0
- package/dist/interfaces/node/bodyReaders/index.mjs +2 -0
- package/dist/interfaces/node/bodyReaders/text/index.cjs +41 -0
- package/dist/interfaces/node/bodyReaders/text/index.d.ts +3 -0
- package/dist/interfaces/node/bodyReaders/text/index.mjs +38 -0
- package/dist/interfaces/node/bodyReaders/text/readRequestText.cjs +37 -0
- package/dist/interfaces/node/bodyReaders/text/readRequestText.d.ts +6 -0
- package/dist/interfaces/node/bodyReaders/text/readRequestText.mjs +35 -0
- package/dist/interfaces/node/createHttpServer.cjs +13 -5
- package/dist/interfaces/node/createHttpServer.d.ts +13 -12
- package/dist/interfaces/node/createHttpServer.mjs +13 -5
- package/dist/interfaces/node/hooks/index.cjs +47 -0
- package/dist/interfaces/node/hooks/index.d.ts +5 -0
- package/dist/interfaces/node/hooks/index.mjs +45 -0
- package/dist/interfaces/node/index.cjs +13 -9
- package/dist/interfaces/node/index.d.ts +1 -1
- package/dist/interfaces/node/index.mjs +7 -5
- package/dist/interfaces/node/types/index.cjs +0 -1
- package/dist/interfaces/node/types/index.d.ts +0 -1
- package/dist/interfaces/node/types/index.mjs +0 -1
- package/dist/interfaces/node/types/request.cjs +1 -1
- package/dist/interfaces/node/types/request.mjs +1 -1
- package/dist/plugins/codeGenerator/index.cjs +2 -0
- package/dist/plugins/codeGenerator/index.mjs +1 -1
- package/dist/plugins/codeGenerator/plugin.cjs +8 -4
- package/dist/plugins/codeGenerator/plugin.mjs +9 -5
- package/dist/plugins/codeGenerator/routeToDataParser.cjs +24 -1
- package/dist/plugins/codeGenerator/routeToDataParser.d.ts +34 -0
- package/dist/plugins/codeGenerator/routeToDataParser.mjs +24 -3
- package/dist/plugins/codeGenerator/typescriptTransfomer.cjs +9 -0
- package/dist/plugins/codeGenerator/typescriptTransfomer.d.ts +1 -0
- package/dist/plugins/codeGenerator/typescriptTransfomer.mjs +7 -0
- package/dist/plugins/openApiGenerator/makeOpenApiRoute.d.ts +3 -0
- package/dist/plugins/openApiGenerator/plugin.cjs +3 -3
- package/dist/plugins/openApiGenerator/plugin.mjs +4 -4
- package/dist/plugins/openApiGenerator/routeToOpenApi.cjs +16 -1
- package/dist/plugins/openApiGenerator/routeToOpenApi.d.ts +10 -1
- package/dist/plugins/openApiGenerator/routeToOpenApi.mjs +16 -1
- package/dist/plugins/openApiGenerator/types/entrypoint.d.ts +6 -1
- package/dist/plugins/openApiGenerator/types/openApiMethod.d.ts +1 -1
- package/package.json +5 -6
- package/dist/core/request.mjs +0 -32
- package/dist/interfaces/node/error/bodyParseUnknownError.cjs +0 -16
- package/dist/interfaces/node/error/bodyParseUnknownError.d.ts +0 -9
- package/dist/interfaces/node/error/bodyParseUnknownError.mjs +0 -14
- package/dist/interfaces/node/error/bodyParseWrongChunkReceived.d.ts +0 -8
- package/dist/interfaces/node/error/bodyParseWrongChunkReceived.mjs +0 -12
- package/dist/interfaces/node/hooks.cjs +0 -126
- package/dist/interfaces/node/hooks.d.ts +0 -8
- package/dist/interfaces/node/hooks.mjs +0 -124
- package/dist/interfaces/node/types/host.d.ts +0 -4
- /package/dist/{interfaces/node/types/host.cjs → client/types/hooks.cjs} +0 -0
- /package/dist/{interfaces/node/types/host.mjs → client/types/hooks.mjs} +0 -0
|
@@ -6,8 +6,10 @@ var pathToRegExp = require('./pathToRegExp.cjs');
|
|
|
6
6
|
var index = require('../route/index.cjs');
|
|
7
7
|
var buildError = require('./buildError.cjs');
|
|
8
8
|
require('../functionsBuilders/route/index.cjs');
|
|
9
|
-
require('../functionsBuilders/steps/index.cjs');
|
|
10
9
|
var decodeUrl = require('./decodeUrl.cjs');
|
|
10
|
+
var text = require('../request/bodyController/text.cjs');
|
|
11
|
+
var notFoundBodyReaderImplementationError = require('./notFoundBodyReaderImplementationError.cjs');
|
|
12
|
+
require('../functionsBuilders/index.cjs');
|
|
11
13
|
require('./types/index.cjs');
|
|
12
14
|
var _default = require('../functionsBuilders/route/default.cjs');
|
|
13
15
|
var checkerStep = require('../functionsBuilders/steps/defaults/checkerStep.cjs');
|
|
@@ -18,18 +20,21 @@ var processStep = require('../functionsBuilders/steps/defaults/processStep.cjs')
|
|
|
18
20
|
var hooks = require('../hub/hooks.cjs');
|
|
19
21
|
var build = require('../functionsBuilders/route/build.cjs');
|
|
20
22
|
|
|
21
|
-
async function buildRouter(
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
async function buildRouter(hub) {
|
|
24
|
+
const { environment } = hub.config;
|
|
25
|
+
const { hooksRouteLifeCycle, routes, hooksHubLifeCycle, bodyReaderImplementations, } = hub;
|
|
26
|
+
const routeFunctionBuilders = [
|
|
27
|
+
...hub.routeFunctionBuilders,
|
|
28
|
+
_default.defaultRouteFunctionBuilder,
|
|
29
|
+
];
|
|
30
|
+
const stepFunctionBuilders = [
|
|
31
|
+
...hub.stepFunctionBuilders,
|
|
25
32
|
checkerStep.defaultCheckerStepFunctionBuilder,
|
|
26
33
|
cutStep.defaultCutStepFunctionBuilder,
|
|
27
34
|
handlerStep.defaultHandlerStepFunctionBuilder,
|
|
28
35
|
extractStep.defaultExtractStepFunctionBuilder,
|
|
29
36
|
processStep.defaultProcessStepFunctionBuilder,
|
|
30
|
-
]
|
|
31
|
-
const { environment } = hub.config;
|
|
32
|
-
const { hooksRouteLifeCycle, routeFunctionBuilders, routes, stepFunctionBuilders, hooksHubLifeCycle, } = hub.aggregates();
|
|
37
|
+
];
|
|
33
38
|
const hooksBeforeBuildRoute = utils.pipe(hooksHubLifeCycle, utils.A.map(({ beforeBuildRoute }) => beforeBuildRoute), utils.A.filter(utils.isType("function")));
|
|
34
39
|
const buildParams = {
|
|
35
40
|
environment,
|
|
@@ -44,14 +49,23 @@ async function buildRouter(inputHub) {
|
|
|
44
49
|
if (utils.E.isLeft(buildedRoute)) {
|
|
45
50
|
throw new buildError.RouterBuildError(route, utils.unwrap(buildedRoute));
|
|
46
51
|
}
|
|
52
|
+
const routeBodyController = route.definition.bodyController ?? hub.defaultBodyController;
|
|
53
|
+
const bodyReader = utils.pipe(bodyReaderImplementations, utils.A.reduce(utils.A.reduceFrom(null), ({ element, next, exit }) => utils.pipe(element, routeBodyController.tryToCreateReader, utils.E.whenIsRight(exit), utils.E.whenIsLeft(utils.justReturn(next(null))))));
|
|
54
|
+
if (!bodyReader) {
|
|
55
|
+
throw new notFoundBodyReaderImplementationError.NotFoundBodyReaderImplementationError(route, routeBodyController);
|
|
56
|
+
}
|
|
47
57
|
return nextWithObject(lastValue, {
|
|
48
58
|
[route.definition.method]: utils.A.concat(lastValue[route.definition.method] ?? [], utils.A.map(route.definition.paths, utils.O.to({
|
|
49
59
|
pattern: pathToRegExp.pathToRegExp,
|
|
50
60
|
buildedRoute: utils.justReturn(utils.unwrap(buildedRoute)),
|
|
51
61
|
matchedPath: utils.forward,
|
|
62
|
+
bodyReader: utils.justReturn(bodyReader),
|
|
52
63
|
}))),
|
|
53
64
|
});
|
|
54
65
|
});
|
|
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"));
|
|
55
69
|
const buildedNotfoundRoute = await utils.asyncPipe(index.createRoute({
|
|
56
70
|
method: "GET",
|
|
57
71
|
paths: ["/"],
|
|
@@ -59,6 +73,7 @@ async function buildRouter(inputHub) {
|
|
|
59
73
|
preflightSteps: [],
|
|
60
74
|
steps: [hub.notfoundHandler],
|
|
61
75
|
metadata: [],
|
|
76
|
+
bodyController: bodyControllerNotfoundRoute,
|
|
62
77
|
}), async (route) => {
|
|
63
78
|
const result = await build.buildRouteFunction(route, buildParams);
|
|
64
79
|
return utils.E.whenIsLeft(result, (element) => {
|
|
@@ -76,6 +91,7 @@ async function buildRouter(inputHub) {
|
|
|
76
91
|
...decodedUrl,
|
|
77
92
|
params: {},
|
|
78
93
|
matchedPath: null,
|
|
94
|
+
bodyReader: bodyReaderNotFoundRoute,
|
|
79
95
|
}));
|
|
80
96
|
}
|
|
81
97
|
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
@@ -90,6 +106,7 @@ async function buildRouter(inputHub) {
|
|
|
90
106
|
...decodedUrl,
|
|
91
107
|
params: result.groups ?? {},
|
|
92
108
|
matchedPath: routerElement.matchedPath,
|
|
109
|
+
bodyReader: routerElement.bodyReader,
|
|
93
110
|
}));
|
|
94
111
|
}
|
|
95
112
|
return buildedNotfoundRoute(new Request({
|
|
@@ -97,6 +114,7 @@ async function buildRouter(inputHub) {
|
|
|
97
114
|
...decodedUrl,
|
|
98
115
|
params: {},
|
|
99
116
|
matchedPath: null,
|
|
117
|
+
bodyReader: bodyReaderNotFoundRoute,
|
|
100
118
|
}));
|
|
101
119
|
},
|
|
102
120
|
hooksRouteLifeCycle,
|
|
@@ -112,4 +130,5 @@ exports.RouterBuildError = buildError.RouterBuildError;
|
|
|
112
130
|
exports.decodeUrl = decodeUrl.decodeUrl;
|
|
113
131
|
exports.regexQueryAnalyser = decodeUrl.regexQueryAnalyser;
|
|
114
132
|
exports.regexUrlAnalyser = decodeUrl.regexUrlAnalyser;
|
|
133
|
+
exports.NotFoundBodyReaderImplementationError = notFoundBodyReaderImplementationError.NotFoundBodyReaderImplementationError;
|
|
115
134
|
exports.buildRouter = buildRouter;
|
|
@@ -4,4 +4,5 @@ export * from "./types";
|
|
|
4
4
|
export * from "./pathToRegExp";
|
|
5
5
|
export * from "./buildError";
|
|
6
6
|
export * from "./decodeUrl";
|
|
7
|
-
export
|
|
7
|
+
export * from "./notFoundBodyReaderImplementationError";
|
|
8
|
+
export declare function buildRouter(hub: Hub): Promise<BuildedRouter>;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import '../hub/index.mjs';
|
|
2
|
-
import { pipe, A, isType, G, E, unwrap, O, forward,
|
|
2
|
+
import { pipe, A, isType, G, E, unwrap, justReturn, O, forward, asserts, asyncPipe } from '@duplojs/utils';
|
|
3
3
|
import { pathToRegExp } from './pathToRegExp.mjs';
|
|
4
4
|
import { createRoute } from '../route/index.mjs';
|
|
5
5
|
import { RouterBuildError } from './buildError.mjs';
|
|
6
6
|
import '../functionsBuilders/route/index.mjs';
|
|
7
|
-
import '../functionsBuilders/steps/index.mjs';
|
|
8
7
|
import { decodeUrl } from './decodeUrl.mjs';
|
|
9
8
|
export { regexQueryAnalyser, regexUrlAnalyser } from './decodeUrl.mjs';
|
|
9
|
+
import { controlBodyAsText, TextBodyController } from '../request/bodyController/text.mjs';
|
|
10
|
+
import { NotFoundBodyReaderImplementationError } from './notFoundBodyReaderImplementationError.mjs';
|
|
11
|
+
import '../functionsBuilders/index.mjs';
|
|
10
12
|
import './types/index.mjs';
|
|
11
13
|
import { defaultRouteFunctionBuilder } from '../functionsBuilders/route/default.mjs';
|
|
12
14
|
import { defaultCheckerStepFunctionBuilder } from '../functionsBuilders/steps/defaults/checkerStep.mjs';
|
|
@@ -17,18 +19,21 @@ import { defaultProcessStepFunctionBuilder } from '../functionsBuilders/steps/de
|
|
|
17
19
|
import { launchHookBeforeBuildRoute } from '../hub/hooks.mjs';
|
|
18
20
|
import { buildRouteFunction } from '../functionsBuilders/route/build.mjs';
|
|
19
21
|
|
|
20
|
-
async function buildRouter(
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
async function buildRouter(hub) {
|
|
23
|
+
const { environment } = hub.config;
|
|
24
|
+
const { hooksRouteLifeCycle, routes, hooksHubLifeCycle, bodyReaderImplementations, } = hub;
|
|
25
|
+
const routeFunctionBuilders = [
|
|
26
|
+
...hub.routeFunctionBuilders,
|
|
27
|
+
defaultRouteFunctionBuilder,
|
|
28
|
+
];
|
|
29
|
+
const stepFunctionBuilders = [
|
|
30
|
+
...hub.stepFunctionBuilders,
|
|
24
31
|
defaultCheckerStepFunctionBuilder,
|
|
25
32
|
defaultCutStepFunctionBuilder,
|
|
26
33
|
defaultHandlerStepFunctionBuilder,
|
|
27
34
|
defaultExtractStepFunctionBuilder,
|
|
28
35
|
defaultProcessStepFunctionBuilder,
|
|
29
|
-
]
|
|
30
|
-
const { environment } = hub.config;
|
|
31
|
-
const { hooksRouteLifeCycle, routeFunctionBuilders, routes, stepFunctionBuilders, hooksHubLifeCycle, } = hub.aggregates();
|
|
36
|
+
];
|
|
32
37
|
const hooksBeforeBuildRoute = pipe(hooksHubLifeCycle, A.map(({ beforeBuildRoute }) => beforeBuildRoute), A.filter(isType("function")));
|
|
33
38
|
const buildParams = {
|
|
34
39
|
environment,
|
|
@@ -43,14 +48,23 @@ async function buildRouter(inputHub) {
|
|
|
43
48
|
if (E.isLeft(buildedRoute)) {
|
|
44
49
|
throw new RouterBuildError(route, unwrap(buildedRoute));
|
|
45
50
|
}
|
|
51
|
+
const routeBodyController = route.definition.bodyController ?? hub.defaultBodyController;
|
|
52
|
+
const bodyReader = pipe(bodyReaderImplementations, A.reduce(A.reduceFrom(null), ({ element, next, exit }) => pipe(element, routeBodyController.tryToCreateReader, E.whenIsRight(exit), E.whenIsLeft(justReturn(next(null))))));
|
|
53
|
+
if (!bodyReader) {
|
|
54
|
+
throw new NotFoundBodyReaderImplementationError(route, routeBodyController);
|
|
55
|
+
}
|
|
46
56
|
return nextWithObject(lastValue, {
|
|
47
57
|
[route.definition.method]: A.concat(lastValue[route.definition.method] ?? [], A.map(route.definition.paths, O.to({
|
|
48
58
|
pattern: pathToRegExp,
|
|
49
59
|
buildedRoute: justReturn(unwrap(buildedRoute)),
|
|
50
60
|
matchedPath: forward,
|
|
61
|
+
bodyReader: justReturn(bodyReader),
|
|
51
62
|
}))),
|
|
52
63
|
});
|
|
53
64
|
});
|
|
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"));
|
|
54
68
|
const buildedNotfoundRoute = await asyncPipe(createRoute({
|
|
55
69
|
method: "GET",
|
|
56
70
|
paths: ["/"],
|
|
@@ -58,6 +72,7 @@ async function buildRouter(inputHub) {
|
|
|
58
72
|
preflightSteps: [],
|
|
59
73
|
steps: [hub.notfoundHandler],
|
|
60
74
|
metadata: [],
|
|
75
|
+
bodyController: bodyControllerNotfoundRoute,
|
|
61
76
|
}), async (route) => {
|
|
62
77
|
const result = await buildRouteFunction(route, buildParams);
|
|
63
78
|
return E.whenIsLeft(result, (element) => {
|
|
@@ -75,6 +90,7 @@ async function buildRouter(inputHub) {
|
|
|
75
90
|
...decodedUrl,
|
|
76
91
|
params: {},
|
|
77
92
|
matchedPath: null,
|
|
93
|
+
bodyReader: bodyReaderNotFoundRoute,
|
|
78
94
|
}));
|
|
79
95
|
}
|
|
80
96
|
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
@@ -89,6 +105,7 @@ async function buildRouter(inputHub) {
|
|
|
89
105
|
...decodedUrl,
|
|
90
106
|
params: result.groups ?? {},
|
|
91
107
|
matchedPath: routerElement.matchedPath,
|
|
108
|
+
bodyReader: routerElement.bodyReader,
|
|
92
109
|
}));
|
|
93
110
|
}
|
|
94
111
|
return buildedNotfoundRoute(new Request({
|
|
@@ -96,6 +113,7 @@ async function buildRouter(inputHub) {
|
|
|
96
113
|
...decodedUrl,
|
|
97
114
|
params: {},
|
|
98
115
|
matchedPath: null,
|
|
116
|
+
bodyReader: bodyReaderNotFoundRoute,
|
|
99
117
|
}));
|
|
100
118
|
},
|
|
101
119
|
hooksRouteLifeCycle,
|
|
@@ -106,4 +124,4 @@ async function buildRouter(inputHub) {
|
|
|
106
124
|
};
|
|
107
125
|
}
|
|
108
126
|
|
|
109
|
-
export { RouterBuildError, buildRouter, decodeUrl, pathToRegExp };
|
|
127
|
+
export { NotFoundBodyReaderImplementationError, RouterBuildError, buildRouter, decodeUrl, pathToRegExp };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var kind = require('../kind.cjs');
|
|
4
|
+
var utils = require('@duplojs/utils');
|
|
5
|
+
|
|
6
|
+
class NotFoundBodyReaderImplementationError extends utils.kindHeritage("not-found-body-reader-implementation-error", kind.createCoreLibKind("not-found-body-reader-implementation-error"), Error) {
|
|
7
|
+
route;
|
|
8
|
+
bodyController;
|
|
9
|
+
constructor(route, bodyController) {
|
|
10
|
+
super({}, ["Body reader implementation not found."]);
|
|
11
|
+
this.route = route;
|
|
12
|
+
this.bodyController = bodyController;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.NotFoundBodyReaderImplementationError = NotFoundBodyReaderImplementationError;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type BodyController } from "../request";
|
|
2
|
+
import { type Route } from "../route";
|
|
3
|
+
declare const NotFoundBodyReaderImplementationError_base: new (params: {
|
|
4
|
+
"@DuplojsHttpCore/not-found-body-reader-implementation-error"?: unknown;
|
|
5
|
+
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"@DuplojsHttpCore/not-found-body-reader-implementation-error", unknown>, unknown> & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"not-found-body-reader-implementation-error", unknown>, unknown>;
|
|
6
|
+
export declare class NotFoundBodyReaderImplementationError extends NotFoundBodyReaderImplementationError_base {
|
|
7
|
+
route: Route;
|
|
8
|
+
bodyController: BodyController;
|
|
9
|
+
constructor(route: Route, bodyController: BodyController);
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createCoreLibKind } from '../kind.mjs';
|
|
2
|
+
import { kindHeritage } from '@duplojs/utils';
|
|
3
|
+
|
|
4
|
+
class NotFoundBodyReaderImplementationError extends kindHeritage("not-found-body-reader-implementation-error", createCoreLibKind("not-found-body-reader-implementation-error"), Error) {
|
|
5
|
+
route;
|
|
6
|
+
bodyController;
|
|
7
|
+
constructor(route, bodyController) {
|
|
8
|
+
super({}, ["Body reader implementation not found."]);
|
|
9
|
+
this.route = route;
|
|
10
|
+
this.bodyController = bodyController;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { NotFoundBodyReaderImplementationError };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type createStepFunctionBuilder, type createRouteFunctionBuilder } from "../../functionsBuilders";
|
|
2
2
|
import { type HookHubLifeCycle } from "../../hub";
|
|
3
3
|
import { type RequestInitializationData } from "../../request";
|
|
4
|
-
import { type HookRouteLifeCycle, type Route
|
|
5
|
-
export type RouterInitializationData = Omit<RequestInitializationData, "matchedPath" | "params" | "path" | "query">;
|
|
4
|
+
import { type HookRouteLifeCycle, type Route } from "../../route";
|
|
5
|
+
export type RouterInitializationData = Omit<RequestInitializationData, "matchedPath" | "bodyReader" | "params" | "path" | "query">;
|
|
6
6
|
export interface BuildedRouter {
|
|
7
7
|
exec(initializationData: RouterInitializationData): Promise<void>;
|
|
8
|
-
readonly routes:
|
|
8
|
+
readonly routes: ReadonlySet<Route>;
|
|
9
9
|
readonly hooksRouteLifeCycle: readonly HookRouteLifeCycle[];
|
|
10
10
|
readonly routeFunctionBuilders: readonly ReturnType<typeof createRouteFunctionBuilder>[];
|
|
11
11
|
readonly stepFunctionBuilders: readonly ReturnType<typeof createStepFunctionBuilder>[];
|
|
@@ -6,7 +6,9 @@ import { type Metadata } from "../metadata";
|
|
|
6
6
|
export interface DisabledExtractKeysCustom {
|
|
7
7
|
}
|
|
8
8
|
export type DisabledExtractKeys = O.GetPropsWithValue<DisabledExtractKeysCustom, true>;
|
|
9
|
-
export type ExtractShape<GenericRequest extends Request = Request> = Partial<Record<Exclude<keyof GenericRequest, O.GetPropsWithValueExtends<GenericRequest, AnyFunction> | DisabledExtractKeys>, DP.DataParser | Record<string, DP.DataParser
|
|
9
|
+
export type ExtractShape<GenericRequest extends Request = Request> = Partial<Record<Exclude<keyof GenericRequest, O.GetPropsWithValueExtends<GenericRequest, AnyFunction> | DisabledExtractKeys | "body" | "bodyReader" | symbol>, DP.DataParser | Record<string, DP.DataParser>> & {
|
|
10
|
+
body: (DP.DataParser | Record<string, DP.DataParser>);
|
|
11
|
+
}>;
|
|
10
12
|
export interface ExtractStepDefinition {
|
|
11
13
|
readonly shape: ExtractShape;
|
|
12
14
|
readonly responseContract?: ResponseContract.Contract<ClientErrorResponseCode, string, DP.DataParserEmpty>;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { type Kind, type O } from "@duplojs/utils";
|
|
2
1
|
import { type CheckerStep } from "../checker";
|
|
3
2
|
import { type CutStep } from "../cut";
|
|
4
3
|
import { type ExtractStep } from "../extract";
|
|
5
4
|
import { type HandlerStep } from "../handler";
|
|
6
5
|
import { type PresetCheckerStep } from "../presetChecker";
|
|
7
6
|
import { type ProcessStep } from "../process";
|
|
8
|
-
import { type stepKind } from "../kind";
|
|
9
7
|
export interface StepsCustom {
|
|
10
8
|
}
|
|
11
|
-
export type Steps = (StepsCustom[
|
|
9
|
+
export type Steps = (StepsCustom[keyof StepsCustom] | CheckerStep | CutStep | ExtractStep | HandlerStep | PresetCheckerStep | ProcessStep);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type BytesInString } from "@duplojs/utils";
|
|
2
|
+
import { type Hosts } from "./hosts";
|
|
3
|
+
export interface HttpServerParams {
|
|
4
|
+
readonly host: Hosts;
|
|
5
|
+
readonly port: number;
|
|
6
|
+
readonly maxBodySize: BytesInString | number;
|
|
7
|
+
readonly informationHeaderKey: string;
|
|
8
|
+
readonly predictedHeaderKey: string;
|
|
9
|
+
readonly fromHookHeaderKey: string;
|
|
10
|
+
readonly uploadFolder: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import '../../../core/request.mjs';
|
|
1
|
+
import '../../../core/request/index.mjs';
|
|
2
2
|
import '../../../core/steps/index.mjs';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils = require('@duplojs/utils');
|
|
4
|
+
var kind = require('../../kind.cjs');
|
|
5
|
+
|
|
6
|
+
class BodyParseFormDataError extends utils.kindHeritage("body-parse-form-data-error", kind.createInterfacesNodeLibKind("body-parse-form-data-error"), Error) {
|
|
7
|
+
information;
|
|
8
|
+
constructor(information) {
|
|
9
|
+
super({}, [`Body parse form date error: ${information}`]);
|
|
10
|
+
this.information = information;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
exports.BodyParseFormDataError = BodyParseFormDataError;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare const BodyParseFormDataError_base: new (params: {
|
|
2
|
+
"@DuplojsHttpInterfacesNode/body-parse-form-data-error"?: unknown;
|
|
3
|
+
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"@DuplojsHttpInterfacesNode/body-parse-form-data-error", unknown>, unknown> & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"body-parse-form-data-error", unknown>, unknown>;
|
|
4
|
+
export declare class BodyParseFormDataError extends BodyParseFormDataError_base {
|
|
5
|
+
information: string;
|
|
6
|
+
constructor(information: string);
|
|
7
|
+
}
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { kindHeritage } from '@duplojs/utils';
|
|
2
|
+
import { createInterfacesNodeLibKind } from '../../kind.mjs';
|
|
3
|
+
|
|
4
|
+
class BodyParseFormDataError extends kindHeritage("body-parse-form-data-error", createInterfacesNodeLibKind("body-parse-form-data-error"), Error) {
|
|
5
|
+
information;
|
|
6
|
+
constructor(information) {
|
|
7
|
+
super({}, [`Body parse form date error: ${information}`]);
|
|
8
|
+
this.information = information;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { BodyParseFormDataError };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('../../../../core/request/index.cjs');
|
|
4
|
+
var serverUtils = require('@duplojs/server-utils');
|
|
5
|
+
var utils = require('@duplojs/utils');
|
|
6
|
+
var readRequestFormData = require('./readRequestFormData.cjs');
|
|
7
|
+
var node_fs = require('node:fs');
|
|
8
|
+
require('../../../../core/errors/index.cjs');
|
|
9
|
+
var error = require('./error.cjs');
|
|
10
|
+
var formData = require('../../../../core/request/bodyController/formData.cjs');
|
|
11
|
+
var wrongContentTypeError = require('../../../../core/errors/wrongContentTypeError.cjs');
|
|
12
|
+
|
|
13
|
+
function createFormDataBodyReaderImplementation(serverParams) {
|
|
14
|
+
const serverMaxBodySize = utils.stringToBytes(serverParams.maxBodySize);
|
|
15
|
+
function addValue(mapResult, fieldName, newValue) {
|
|
16
|
+
const value = mapResult.get(fieldName);
|
|
17
|
+
if (value === undefined) {
|
|
18
|
+
mapResult.set(fieldName, newValue);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
mapResult.set(fieldName, utils.A.push(utils.A.coalescing(value), newValue));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return formData.FormDataBodyController.createReaderImplementation(async (request, params) => {
|
|
25
|
+
if (!request.headers["content-type"]?.includes("multipart/form-data")) {
|
|
26
|
+
return utils.E.error(new wrongContentTypeError.WrongContentTypeError("multipart/form-data", utils.A.join(utils.A.coalescing(request.headers["content-type"] ?? ""), " ")));
|
|
27
|
+
}
|
|
28
|
+
const filesAttache = [];
|
|
29
|
+
request.filesAttache = filesAttache;
|
|
30
|
+
const result = await readRequestFormData.readRequestFormData(request.raw.request, new Map(), {
|
|
31
|
+
maxBodySize: params.bodyMaxSize ?? serverMaxBodySize,
|
|
32
|
+
fileMaxSize: params.fileMaxSize ?? Infinity,
|
|
33
|
+
maxFileQuantity: params.maxFileQuantity,
|
|
34
|
+
mimeType: params.mimeType,
|
|
35
|
+
maxBufferSize: params.maxBufferSize,
|
|
36
|
+
maxKeyLength: params.maxKeyLength,
|
|
37
|
+
}, (header) => {
|
|
38
|
+
const fieldName = header.name;
|
|
39
|
+
if (header.filename) {
|
|
40
|
+
const extension = utils.Path.getExtensionName(header.filename);
|
|
41
|
+
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
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
onReceiveChunk: (chunk) => new Promise((resolve, reject) => void currentFile.write(chunk, (result) => {
|
|
52
|
+
if (result instanceof Error) {
|
|
53
|
+
return void reject(result);
|
|
54
|
+
}
|
|
55
|
+
return void resolve();
|
|
56
|
+
})),
|
|
57
|
+
onEndPart: (valueAccumulator) => {
|
|
58
|
+
currentFile.end();
|
|
59
|
+
addValue(valueAccumulator, fieldName, serverUtils.SF.createFileInterface(currentFile.path.toString()));
|
|
60
|
+
return valueAccumulator;
|
|
61
|
+
},
|
|
62
|
+
onError: () => void currentFile.end(),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
let currentValue = "";
|
|
66
|
+
return {
|
|
67
|
+
onReceiveChunk: (chunk) => {
|
|
68
|
+
currentValue += chunk.toString("utf-8");
|
|
69
|
+
},
|
|
70
|
+
onEndPart: (valueAccumulator) => {
|
|
71
|
+
addValue(valueAccumulator, fieldName, currentValue);
|
|
72
|
+
return valueAccumulator;
|
|
73
|
+
},
|
|
74
|
+
onError: null,
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
if (utils.E.isLeft(result)) {
|
|
78
|
+
// mandatory in case of error to avoid monopolizing the client connection if a stream is not finished.
|
|
79
|
+
request.raw.response.setHeader("Connection", "close");
|
|
80
|
+
if (utils.E.hasInformation(result, "server-error")) {
|
|
81
|
+
throw utils.unwrap(result);
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
if (request.headers["content-type-options"]?.includes("advanced")) {
|
|
86
|
+
return utils.E.success(utils.TheFormData.fromEntries(result.entries(), params.maxIndexArray));
|
|
87
|
+
}
|
|
88
|
+
return utils.E.success(utils.O.fromEntries(result.entries()));
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
exports.readRequestFormData = readRequestFormData.readRequestFormData;
|
|
93
|
+
exports.BodyParseFormDataError = error.BodyParseFormDataError;
|
|
94
|
+
exports.createFormDataBodyReaderImplementation = createFormDataBodyReaderImplementation;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type HttpServerParams } from "../../../../core/types";
|
|
2
|
+
export * from "./error";
|
|
3
|
+
export * from "./readRequestFormData";
|
|
4
|
+
export declare function createFormDataBodyReaderImplementation(serverParams: HttpServerParams): import("../../../../core/request").BodyReaderImplementation<"formData", import("../../../../core/request").FormDataBodyReaderParams>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import '../../../../core/request/index.mjs';
|
|
2
|
+
import { SF } from '@duplojs/server-utils';
|
|
3
|
+
import { stringToBytes, A, E, Path, unwrap, TheFormData, O } from '@duplojs/utils';
|
|
4
|
+
import { readRequestFormData } from './readRequestFormData.mjs';
|
|
5
|
+
import { createWriteStream } from 'node:fs';
|
|
6
|
+
import '../../../../core/errors/index.mjs';
|
|
7
|
+
export { BodyParseFormDataError } from './error.mjs';
|
|
8
|
+
import { FormDataBodyController } from '../../../../core/request/bodyController/formData.mjs';
|
|
9
|
+
import { WrongContentTypeError } from '../../../../core/errors/wrongContentTypeError.mjs';
|
|
10
|
+
|
|
11
|
+
function createFormDataBodyReaderImplementation(serverParams) {
|
|
12
|
+
const serverMaxBodySize = stringToBytes(serverParams.maxBodySize);
|
|
13
|
+
function addValue(mapResult, fieldName, newValue) {
|
|
14
|
+
const value = mapResult.get(fieldName);
|
|
15
|
+
if (value === undefined) {
|
|
16
|
+
mapResult.set(fieldName, newValue);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
mapResult.set(fieldName, A.push(A.coalescing(value), newValue));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return FormDataBodyController.createReaderImplementation(async (request, params) => {
|
|
23
|
+
if (!request.headers["content-type"]?.includes("multipart/form-data")) {
|
|
24
|
+
return E.error(new WrongContentTypeError("multipart/form-data", A.join(A.coalescing(request.headers["content-type"] ?? ""), " ")));
|
|
25
|
+
}
|
|
26
|
+
const filesAttache = [];
|
|
27
|
+
request.filesAttache = filesAttache;
|
|
28
|
+
const result = await readRequestFormData(request.raw.request, new Map(), {
|
|
29
|
+
maxBodySize: params.bodyMaxSize ?? serverMaxBodySize,
|
|
30
|
+
fileMaxSize: params.fileMaxSize ?? Infinity,
|
|
31
|
+
maxFileQuantity: params.maxFileQuantity,
|
|
32
|
+
mimeType: params.mimeType,
|
|
33
|
+
maxBufferSize: params.maxBufferSize,
|
|
34
|
+
maxKeyLength: params.maxKeyLength,
|
|
35
|
+
}, (header) => {
|
|
36
|
+
const fieldName = header.name;
|
|
37
|
+
if (header.filename) {
|
|
38
|
+
const extension = Path.getExtensionName(header.filename);
|
|
39
|
+
const displayExtension = extension ? `.${extension}` : "";
|
|
40
|
+
const filePath = Path.resolveRelative([
|
|
41
|
+
serverParams.uploadFolder,
|
|
42
|
+
`${Math.random().toString(36).slice(2, 10)}-${Date.now()}${displayExtension}`,
|
|
43
|
+
]);
|
|
44
|
+
filesAttache.push(filePath);
|
|
45
|
+
const currentFile = createWriteStream(filePath, {
|
|
46
|
+
highWaterMark: request.raw.request.readableHighWaterMark,
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
onReceiveChunk: (chunk) => new Promise((resolve, reject) => void currentFile.write(chunk, (result) => {
|
|
50
|
+
if (result instanceof Error) {
|
|
51
|
+
return void reject(result);
|
|
52
|
+
}
|
|
53
|
+
return void resolve();
|
|
54
|
+
})),
|
|
55
|
+
onEndPart: (valueAccumulator) => {
|
|
56
|
+
currentFile.end();
|
|
57
|
+
addValue(valueAccumulator, fieldName, SF.createFileInterface(currentFile.path.toString()));
|
|
58
|
+
return valueAccumulator;
|
|
59
|
+
},
|
|
60
|
+
onError: () => void currentFile.end(),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
let currentValue = "";
|
|
64
|
+
return {
|
|
65
|
+
onReceiveChunk: (chunk) => {
|
|
66
|
+
currentValue += chunk.toString("utf-8");
|
|
67
|
+
},
|
|
68
|
+
onEndPart: (valueAccumulator) => {
|
|
69
|
+
addValue(valueAccumulator, fieldName, currentValue);
|
|
70
|
+
return valueAccumulator;
|
|
71
|
+
},
|
|
72
|
+
onError: null,
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
if (E.isLeft(result)) {
|
|
76
|
+
// mandatory in case of error to avoid monopolizing the client connection if a stream is not finished.
|
|
77
|
+
request.raw.response.setHeader("Connection", "close");
|
|
78
|
+
if (E.hasInformation(result, "server-error")) {
|
|
79
|
+
throw unwrap(result);
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
if (request.headers["content-type-options"]?.includes("advanced")) {
|
|
84
|
+
return E.success(TheFormData.fromEntries(result.entries(), params.maxIndexArray));
|
|
85
|
+
}
|
|
86
|
+
return E.success(O.fromEntries(result.entries()));
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { createFormDataBodyReaderImplementation, readRequestFormData };
|