@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.
- package/dist/client/getBody.cjs +3 -3
- package/dist/client/getBody.mjs +3 -3
- package/dist/client/hooks.cjs +45 -0
- package/dist/client/hooks.d.ts +6 -1
- package/dist/client/hooks.mjs +41 -1
- package/dist/client/httpClient.cjs +25 -1
- package/dist/client/httpClient.d.ts +8 -3
- package/dist/client/httpClient.mjs +25 -1
- package/dist/client/index.cjs +7 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.mjs +2 -1
- package/dist/client/insertParamsInPath.cjs +1 -1
- package/dist/client/insertParamsInPath.mjs +1 -1
- package/dist/client/promiseRequest.cjs +83 -26
- package/dist/client/promiseRequest.d.ts +46 -29
- package/dist/client/promiseRequest.mjs +83 -26
- package/dist/client/queryToString.cjs +1 -1
- package/dist/client/queryToString.mjs +1 -1
- package/dist/client/serverSentEvents.cjs +231 -0
- package/dist/client/serverSentEvents.d.ts +2 -0
- package/dist/client/serverSentEvents.mjs +208 -0
- package/dist/client/types/clientRequestParams.d.ts +2 -0
- package/dist/client/types/clientResponse.d.ts +34 -3
- package/dist/client/types/hooks.d.ts +17 -7
- package/dist/client/types/promiseRequestParams.d.ts +1 -0
- package/dist/client/types/serverRoute.d.ts +2 -0
- package/dist/core/builders/route/handler.d.ts +5 -2
- package/dist/core/clean/entity.cjs +19 -28
- package/dist/core/clean/entity.d.ts +9 -9
- package/dist/core/clean/entity.mjs +20 -29
- package/dist/core/defaultHooks/index.cjs +8 -0
- package/dist/core/defaultHooks/index.d.ts +1 -1
- package/dist/core/defaultHooks/index.mjs +8 -0
- package/dist/core/functionsBuilders/route/default.cjs +9 -13
- package/dist/core/functionsBuilders/route/default.mjs +2 -6
- package/dist/core/functionsBuilders/steps/create.d.ts +2 -2
- package/dist/core/functionsBuilders/steps/defaults/cutStep.cjs +1 -1
- package/dist/core/functionsBuilders/steps/defaults/cutStep.mjs +1 -1
- package/dist/core/functionsBuilders/steps/defaults/handlerStep.cjs +37 -17
- package/dist/core/functionsBuilders/steps/defaults/handlerStep.mjs +37 -17
- package/dist/core/functionsBuilders/steps/defaults/processStep.cjs +3 -3
- package/dist/core/functionsBuilders/steps/defaults/processStep.mjs +3 -3
- package/dist/core/hub/defaultEmptyReaderImplementation.cjs +9 -0
- package/dist/core/hub/defaultEmptyReaderImplementation.d.ts +1 -0
- package/dist/core/hub/defaultEmptyReaderImplementation.mjs +7 -0
- package/dist/core/hub/defaultMalformedUrlHandler.cjs +14 -0
- package/dist/core/hub/defaultMalformedUrlHandler.d.ts +10 -0
- package/dist/core/hub/defaultMalformedUrlHandler.mjs +12 -0
- package/dist/core/hub/defaultNotfoundHandler.d.ts +1 -1
- package/dist/core/hub/index.cjs +14 -1
- package/dist/core/hub/index.d.ts +4 -0
- package/dist/core/hub/index.mjs +13 -2
- package/dist/core/implementHttpServer.cjs +7 -2
- package/dist/core/implementHttpServer.d.ts +7 -1
- package/dist/core/implementHttpServer.mjs +5 -0
- package/dist/core/index.cjs +18 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.mjs +8 -2
- package/dist/core/request/bodyController/base.cjs +24 -6
- package/dist/core/request/bodyController/base.d.ts +9 -0
- package/dist/core/request/bodyController/base.mjs +25 -8
- package/dist/core/request/bodyController/empty.cjs +11 -0
- package/dist/core/request/bodyController/empty.d.ts +3 -0
- package/dist/core/request/bodyController/empty.mjs +8 -0
- package/dist/core/request/bodyController/formData.d.ts +2 -2
- package/dist/core/request/bodyController/index.cjs +4 -0
- package/dist/core/request/bodyController/index.d.ts +1 -0
- package/dist/core/request/bodyController/index.mjs +2 -1
- package/dist/core/request/index.cjs +5 -0
- package/dist/core/request/index.d.ts +1 -1
- package/dist/core/request/index.mjs +6 -1
- package/dist/core/response/contract.cjs +17 -4
- package/dist/core/response/contract.d.ts +19 -4
- package/dist/core/response/contract.mjs +17 -4
- package/dist/core/response/index.cjs +2 -0
- package/dist/core/response/index.d.ts +1 -0
- package/dist/core/response/index.mjs +1 -0
- package/dist/core/response/serverSentEventsPredicted.cjs +23 -0
- package/dist/core/response/serverSentEventsPredicted.d.ts +14 -0
- package/dist/core/response/serverSentEventsPredicted.mjs +21 -0
- package/dist/core/route/hooks.cjs +9 -0
- package/dist/core/route/hooks.d.ts +10 -9
- package/dist/core/route/hooks.mjs +9 -1
- package/dist/core/route/index.cjs +1 -0
- package/dist/core/route/index.mjs +1 -1
- package/dist/core/router/buildSystemRoute.cjs +33 -0
- package/dist/core/router/buildSystemRoute.d.ts +11 -0
- package/dist/core/router/buildSystemRoute.mjs +31 -0
- package/dist/core/router/decodeUrl.cjs +5 -4
- package/dist/core/router/decodeUrl.d.ts +1 -1
- package/dist/core/router/decodeUrl.mjs +5 -4
- package/dist/core/router/index.cjs +24 -23
- package/dist/core/router/index.d.ts +1 -0
- package/dist/core/router/index.mjs +25 -25
- package/dist/core/serverSentEvents.cjs +96 -0
- package/dist/core/serverSentEvents.d.ts +33 -0
- package/dist/core/serverSentEvents.mjs +96 -0
- package/dist/core/steps/cut.d.ts +2 -2
- package/dist/core/steps/handler.d.ts +10 -5
- package/dist/interfaces/node/bodyReaders/formData/index.cjs +33 -14
- package/dist/interfaces/node/bodyReaders/formData/index.mjs +34 -15
- package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.cjs +8 -11
- package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.mjs +8 -11
- package/dist/interfaces/node/createHttpServer.cjs +2 -3
- package/dist/interfaces/node/createHttpServer.mjs +2 -3
- package/dist/interfaces/node/hooks/index.cjs +61 -38
- package/dist/interfaces/node/hooks/index.d.ts +6 -4
- package/dist/interfaces/node/hooks/index.mjs +61 -38
- package/dist/interfaces/node/index.cjs +1 -1
- package/dist/interfaces/node/index.mjs +1 -1
- package/dist/plugins/cacheController/createResponseHeader.cjs +43 -0
- package/dist/plugins/cacheController/createResponseHeader.d.ts +2 -0
- package/dist/plugins/cacheController/createResponseHeader.mjs +41 -0
- package/dist/plugins/cacheController/hooks.cjs +23 -0
- package/dist/plugins/cacheController/hooks.d.ts +4 -0
- package/dist/plugins/cacheController/hooks.mjs +21 -0
- package/dist/plugins/cacheController/index.cjs +10 -0
- package/dist/plugins/cacheController/index.d.ts +3 -0
- package/dist/plugins/cacheController/index.mjs +3 -0
- package/dist/plugins/cacheController/types/cacheControlDirectives.cjs +2 -0
- package/dist/plugins/cacheController/types/cacheControlDirectives.d.ts +16 -0
- package/dist/plugins/cacheController/types/cacheControlDirectives.mjs +1 -0
- package/dist/plugins/cacheController/types/index.cjs +4 -0
- package/dist/plugins/cacheController/types/index.d.ts +1 -0
- package/dist/plugins/cacheController/types/index.mjs +1 -0
- package/dist/plugins/codeGenerator/aggregateStepContract.cjs +9 -2
- package/dist/plugins/codeGenerator/aggregateStepContract.d.ts +1 -1
- package/dist/plugins/codeGenerator/aggregateStepContract.mjs +10 -3
- package/dist/plugins/codeGenerator/plugin.cjs +4 -4
- package/dist/plugins/codeGenerator/plugin.mjs +1 -1
- package/dist/plugins/openApiGenerator/aggregateStepContract.d.ts +2 -7
- package/dist/plugins/openApiGenerator/routeToOpenApi.cjs +46 -8
- package/dist/plugins/openApiGenerator/routeToOpenApi.d.ts +2 -2
- package/dist/plugins/openApiGenerator/routeToOpenApi.mjs +46 -8
- package/dist/plugins/openApiGenerator/types/endpointResponse.d.ts +7 -3
- package/dist/plugins/static/index.cjs +14 -0
- package/dist/plugins/static/index.d.ts +3 -0
- package/dist/plugins/static/index.mjs +3 -0
- package/dist/plugins/static/kind.cjs +9 -0
- package/dist/plugins/static/kind.d.ts +6 -0
- package/dist/plugins/static/kind.mjs +7 -0
- package/dist/plugins/static/makeRouteFile.cjs +62 -0
- package/dist/plugins/static/makeRouteFile.d.ts +48 -0
- package/dist/plugins/static/makeRouteFile.mjs +58 -0
- package/dist/plugins/static/makeRouteFolder.cjs +67 -0
- package/dist/plugins/static/makeRouteFolder.d.ts +39 -0
- package/dist/plugins/static/makeRouteFolder.mjs +65 -0
- package/dist/plugins/static/plugin.cjs +53 -0
- package/dist/plugins/static/plugin.d.ts +26 -0
- package/dist/plugins/static/plugin.mjs +50 -0
- package/package.json +18 -7
- /package/dist/plugins/codeGenerator/{typescriptTransfomer.cjs → typescriptTransformer.cjs} +0 -0
- /package/dist/plugins/codeGenerator/{typescriptTransfomer.d.ts → typescriptTransformer.d.ts} +0 -0
- /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
|
|
|
@@ -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
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
|
89
|
+
return defaultNotfoundRoute.buildedRoute(new Request({
|
|
90
90
|
...initializationData,
|
|
91
91
|
...decodedUrl,
|
|
92
92
|
params: {},
|
|
93
93
|
matchedPath: null,
|
|
94
|
-
bodyReader:
|
|
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
|
|
112
|
+
return defaultNotfoundRoute.buildedRoute(new Request({
|
|
113
113
|
...initializationData,
|
|
114
114
|
...decodedUrl,
|
|
115
115
|
params: {},
|
|
116
116
|
matchedPath: null,
|
|
117
|
-
bodyReader:
|
|
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;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import '../hub/index.mjs';
|
|
2
|
-
import { pipe, A, isType, G, E, unwrap, justReturn, O, forward
|
|
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
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
|
88
|
+
return defaultNotfoundRoute.buildedRoute(new Request({
|
|
89
89
|
...initializationData,
|
|
90
90
|
...decodedUrl,
|
|
91
91
|
params: {},
|
|
92
92
|
matchedPath: null,
|
|
93
|
-
bodyReader:
|
|
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
|
|
111
|
+
return defaultNotfoundRoute.buildedRoute(new Request({
|
|
112
112
|
...initializationData,
|
|
113
113
|
...decodedUrl,
|
|
114
114
|
params: {},
|
|
115
115
|
matchedPath: null,
|
|
116
|
-
bodyReader:
|
|
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 };
|
package/dist/core/steps/cut.d.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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 |
|
|
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
|
|
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
|
|
43
|
-
|
|
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
|
|
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
|
-
|
|
59
|
-
addValue(valueAccumulator, fieldName, serverUtils.SF.createFileInterface(
|
|
77
|
+
writeStream.end();
|
|
78
|
+
addValue(valueAccumulator, fieldName, serverUtils.SF.createFileInterface(path));
|
|
60
79
|
return valueAccumulator;
|
|
61
80
|
},
|
|
62
|
-
onError: () => void
|
|
81
|
+
onError: () => void writeStream.end(),
|
|
63
82
|
};
|
|
64
83
|
}
|
|
65
84
|
let currentValue = "";
|