@duplojs/http 0.6.2 → 0.7.1
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/queryToString.cjs +2 -2
- package/dist/client/queryToString.mjs +2 -2
- package/dist/client/types/clientRequestParams.d.ts +9 -3
- 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 +28 -4
- 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/newType.d.ts +1 -1
- package/dist/core/clean/primitive.d.ts +1 -1
- 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 +34 -10
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.mjs +13 -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 +11 -4
- package/dist/plugins/codeGenerator/plugin.mjs +12 -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 +28 -0
- package/dist/plugins/codeGenerator/typescriptTransfomer.d.ts +4 -0
- package/dist/plugins/codeGenerator/typescriptTransfomer.mjs +24 -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 -6
- package/dist/plugins/openApiGenerator/routeToOpenApi.d.ts +10 -1
- package/dist/plugins/openApiGenerator/routeToOpenApi.mjs +16 -6
- 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
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createTransformer } from '@duplojs/data-parser-tools/toTypescript';
|
|
2
|
+
import { SDP } from '@duplojs/server-utils';
|
|
3
|
+
import { DP } from '@duplojs/utils';
|
|
4
|
+
import { factory } from 'typescript';
|
|
5
|
+
|
|
6
|
+
const fileTransformer = createTransformer(SDP.fileKind.has, (__, { success }) => success(factory.createTypeReferenceNode("File")));
|
|
7
|
+
const dateTransformer = createTransformer(DP.dateKind.has, (__, { success, addImport }) => {
|
|
8
|
+
addImport("@duplojs/utils/date", "TheDate");
|
|
9
|
+
addImport("@duplojs/utils/date", "SerializedTheDate");
|
|
10
|
+
return success(factory.createUnionTypeNode([
|
|
11
|
+
factory.createTypeReferenceNode(factory.createIdentifier("SerializedTheDate")),
|
|
12
|
+
factory.createTypeReferenceNode(factory.createIdentifier("TheDate")),
|
|
13
|
+
]));
|
|
14
|
+
});
|
|
15
|
+
const timeTransformer = createTransformer(DP.timeKind.has, (__, { success, addImport }) => {
|
|
16
|
+
addImport("@duplojs/utils/date", "TheTime");
|
|
17
|
+
addImport("@duplojs/utils/date", "SerializedTheTime");
|
|
18
|
+
return success(factory.createUnionTypeNode([
|
|
19
|
+
factory.createTypeReferenceNode(factory.createIdentifier("SerializedTheTime")),
|
|
20
|
+
factory.createTypeReferenceNode(factory.createIdentifier("TheTime")),
|
|
21
|
+
]));
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export { dateTransformer, fileTransformer, timeTransformer };
|
|
@@ -7,10 +7,13 @@ export declare function makeOpenApiRoute(routePath: RoutePath, openApiPage: stri
|
|
|
7
7
|
readonly hooks: readonly [];
|
|
8
8
|
readonly preflightSteps: readonly [];
|
|
9
9
|
readonly paths: readonly [`/${string}`];
|
|
10
|
+
readonly bodyController: null;
|
|
10
11
|
readonly steps: readonly [import("../../core/steps").HandlerStep<{
|
|
11
12
|
readonly responseContract: NoInfer<ResponseContract.Contract<"200", "swaggerUi", DP.DataParserString<{
|
|
12
13
|
readonly errorMessage?: string | undefined;
|
|
13
14
|
readonly identifier?: string | undefined;
|
|
15
|
+
readonly overrideJsonSchemaTransformer?: import("@duplojs/data-parser-tools/toJsonSchema").TransformerBuildFunction | undefined;
|
|
16
|
+
readonly overrideTypescriptTransformer?: import("@duplojs/data-parser-tools/toTypescript").TransformerBuildFunction | undefined;
|
|
14
17
|
readonly coerce: boolean;
|
|
15
18
|
readonly checkers: readonly [];
|
|
16
19
|
}>>>;
|
|
@@ -4,7 +4,7 @@ var routeToOpenApi = require('./routeToOpenApi.cjs');
|
|
|
4
4
|
var utils = require('@duplojs/utils');
|
|
5
5
|
var makeOpenApiPage = require('./makeOpenApiPage.cjs');
|
|
6
6
|
var makeOpenApiRoute = require('./makeOpenApiRoute.cjs');
|
|
7
|
-
var
|
|
7
|
+
var serverUtils = require('@duplojs/server-utils');
|
|
8
8
|
|
|
9
9
|
function openApiGeneratorPlugin(pluginParams) {
|
|
10
10
|
return () => ({
|
|
@@ -19,7 +19,7 @@ function openApiGeneratorPlugin(pluginParams) {
|
|
|
19
19
|
}
|
|
20
20
|
const contextToJsonSchemaFactory = new Map();
|
|
21
21
|
const resultSchemaContext = new Map();
|
|
22
|
-
const routes = hub.
|
|
22
|
+
const routes = utils.A.from(hub.routes);
|
|
23
23
|
const openApiRoutes = utils.pipe(routes, utils.A.filter((route) => route.definition.method !== "OPTIONS"), utils.A.flatMap((route) => routeToOpenApi.routeToOpenApi(route, {
|
|
24
24
|
defaultExtractContract: hub.defaultExtractContract,
|
|
25
25
|
resultSchemaContext,
|
|
@@ -77,7 +77,7 @@ function openApiGeneratorPlugin(pluginParams) {
|
|
|
77
77
|
};
|
|
78
78
|
const openApiDocumentString = JSON.stringify(openApiDocument, null, 2);
|
|
79
79
|
if (pluginParams.outputFile) {
|
|
80
|
-
await
|
|
80
|
+
utils.asserts(await serverUtils.SF.writeTextFile(pluginParams.outputFile, openApiDocumentString), utils.E.isRight);
|
|
81
81
|
}
|
|
82
82
|
if (pluginParams.routePath) {
|
|
83
83
|
const openApiPage = makeOpenApiPage.makeOpenApiPage({
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { routeToOpenApi } from './routeToOpenApi.mjs';
|
|
2
|
-
import { equal,
|
|
2
|
+
import { equal, A, pipe, O, G, P, justReturn, asserts, E } from '@duplojs/utils';
|
|
3
3
|
import { makeOpenApiPage } from './makeOpenApiPage.mjs';
|
|
4
4
|
import { makeOpenApiRoute } from './makeOpenApiRoute.mjs';
|
|
5
|
-
import {
|
|
5
|
+
import { SF } from '@duplojs/server-utils';
|
|
6
6
|
|
|
7
7
|
function openApiGeneratorPlugin(pluginParams) {
|
|
8
8
|
return () => ({
|
|
@@ -17,7 +17,7 @@ function openApiGeneratorPlugin(pluginParams) {
|
|
|
17
17
|
}
|
|
18
18
|
const contextToJsonSchemaFactory = new Map();
|
|
19
19
|
const resultSchemaContext = new Map();
|
|
20
|
-
const routes = hub.
|
|
20
|
+
const routes = A.from(hub.routes);
|
|
21
21
|
const openApiRoutes = pipe(routes, A.filter((route) => route.definition.method !== "OPTIONS"), A.flatMap((route) => routeToOpenApi(route, {
|
|
22
22
|
defaultExtractContract: hub.defaultExtractContract,
|
|
23
23
|
resultSchemaContext,
|
|
@@ -75,7 +75,7 @@ function openApiGeneratorPlugin(pluginParams) {
|
|
|
75
75
|
};
|
|
76
76
|
const openApiDocumentString = JSON.stringify(openApiDocument, null, 2);
|
|
77
77
|
if (pluginParams.outputFile) {
|
|
78
|
-
await
|
|
78
|
+
asserts(await SF.writeTextFile(pluginParams.outputFile, openApiDocumentString), E.isRight);
|
|
79
79
|
}
|
|
80
80
|
if (pluginParams.routePath) {
|
|
81
81
|
const openApiPage = makeOpenApiPage({
|
|
@@ -3,14 +3,16 @@
|
|
|
3
3
|
var aggregateStepContract = require('./aggregateStepContract.cjs');
|
|
4
4
|
var utils = require('@duplojs/utils');
|
|
5
5
|
var toJsonSchema = require('@duplojs/data-parser-tools/toJsonSchema');
|
|
6
|
+
require('../../core/request/index.cjs');
|
|
6
7
|
var metadata = require('./metadata.cjs');
|
|
8
|
+
var formData = require('../../core/request/bodyController/formData.cjs');
|
|
7
9
|
|
|
8
10
|
function factoryJsonSchema(params) {
|
|
9
11
|
const identifier = params.schema.definition.identifier
|
|
10
12
|
?? `NotIdentified${params.resultSchemaContext.size}`;
|
|
11
13
|
const renderResult = toJsonSchema.render(params.schema, {
|
|
12
14
|
identifier,
|
|
13
|
-
mode:
|
|
15
|
+
mode: "in",
|
|
14
16
|
context: params.context,
|
|
15
17
|
version: "openApi31",
|
|
16
18
|
transformers: toJsonSchema.defaultTransformers,
|
|
@@ -32,6 +34,7 @@ const methodMapper = {
|
|
|
32
34
|
TRACE: "trace",
|
|
33
35
|
CONNECT: "connect",
|
|
34
36
|
OPTIONS: "options",
|
|
37
|
+
PATCH: "patch",
|
|
35
38
|
};
|
|
36
39
|
function routeToOpenApi(route, params) {
|
|
37
40
|
const isIgnore = utils.A.find(route.definition.metadata, metadata.IgnoreByOpenApiGeneratorMetadata.is);
|
|
@@ -54,18 +57,27 @@ function routeToOpenApi(route, params) {
|
|
|
54
57
|
schema: factoryJsonSchema({
|
|
55
58
|
context: params.contextToJsonSchemaFactory,
|
|
56
59
|
resultSchemaContext: params.resultSchemaContext,
|
|
57
|
-
mode: "in",
|
|
58
60
|
schema,
|
|
59
61
|
}),
|
|
60
62
|
}))));
|
|
61
|
-
const requestBody = utils.pipe(body, utils.when((value) => utils.O.countKeys(value) === 0, utils.justReturn(utils.DP.empty())), utils.whenNot(utils.DP.dataParserKind.has, utils.DP.object), utils.P.when(utils.DP.identifier(utils.DP.emptyKind), utils.justReturn(undefined)), utils.P.when(
|
|
63
|
+
const requestBody = utils.pipe(body, utils.when((value) => utils.O.countKeys(value) === 0, utils.justReturn(utils.DP.empty())), utils.whenNot(utils.DP.dataParserKind.has, utils.DP.object), utils.P.when(utils.DP.identifier(utils.DP.emptyKind), utils.justReturn(undefined)), utils.P.when(() => formData.FormDataBodyController.is(route.definition.bodyController), (objectSchema) => ({
|
|
64
|
+
required: true,
|
|
65
|
+
content: {
|
|
66
|
+
"multipart/form-data": {
|
|
67
|
+
schema: factoryJsonSchema({
|
|
68
|
+
context: params.contextToJsonSchemaFactory,
|
|
69
|
+
resultSchemaContext: params.resultSchemaContext,
|
|
70
|
+
schema: objectSchema,
|
|
71
|
+
}),
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
})), utils.P.when(utils.DP.identifier(utils.DP.objectKind), (objectSchema) => ({
|
|
62
75
|
required: true,
|
|
63
76
|
content: {
|
|
64
77
|
"application/json": {
|
|
65
78
|
schema: factoryJsonSchema({
|
|
66
79
|
context: params.contextToJsonSchemaFactory,
|
|
67
80
|
resultSchemaContext: params.resultSchemaContext,
|
|
68
|
-
mode: "in",
|
|
69
81
|
schema: objectSchema,
|
|
70
82
|
}),
|
|
71
83
|
},
|
|
@@ -77,7 +89,6 @@ function routeToOpenApi(route, params) {
|
|
|
77
89
|
schema: factoryJsonSchema({
|
|
78
90
|
context: params.contextToJsonSchemaFactory,
|
|
79
91
|
resultSchemaContext: params.resultSchemaContext,
|
|
80
|
-
mode: "in",
|
|
81
92
|
schema: primitiveSchema,
|
|
82
93
|
}),
|
|
83
94
|
},
|
|
@@ -88,7 +99,6 @@ function routeToOpenApi(route, params) {
|
|
|
88
99
|
? factoryJsonSchema({
|
|
89
100
|
context: params.contextToJsonSchemaFactory,
|
|
90
101
|
resultSchemaContext: params.resultSchemaContext,
|
|
91
|
-
mode: "in",
|
|
92
102
|
schema: body,
|
|
93
103
|
})
|
|
94
104
|
: undefined;
|
|
@@ -10,9 +10,18 @@ export interface RouteToOpenApiParams {
|
|
|
10
10
|
}
|
|
11
11
|
export declare function routeToOpenApi(route: Route, params: RouteToOpenApiParams): {
|
|
12
12
|
path: `/${string}`;
|
|
13
|
-
method: "options" | "get" | "post" | "put" | "delete" | "head" | "trace" | "connect";
|
|
13
|
+
method: "options" | "get" | "post" | "put" | "patch" | "delete" | "head" | "trace" | "connect";
|
|
14
14
|
parameters: EntrypointParameter[];
|
|
15
15
|
requestBody: {
|
|
16
|
+
required: true;
|
|
17
|
+
content: {
|
|
18
|
+
"multipart/form-data": {
|
|
19
|
+
schema: {
|
|
20
|
+
$ref: `#/components/schemas/${string}`;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
} | {
|
|
16
25
|
required: true;
|
|
17
26
|
content: {
|
|
18
27
|
"application/json": {
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { aggregateStepContract } from './aggregateStepContract.mjs';
|
|
2
2
|
import { O, A, pipe, DP, when, justReturn, whenNot, P, isType, S } from '@duplojs/utils';
|
|
3
3
|
import { render, defaultTransformers } from '@duplojs/data-parser-tools/toJsonSchema';
|
|
4
|
+
import '../../core/request/index.mjs';
|
|
4
5
|
import { IgnoreByOpenApiGeneratorMetadata } from './metadata.mjs';
|
|
6
|
+
import { FormDataBodyController } from '../../core/request/bodyController/formData.mjs';
|
|
5
7
|
|
|
6
8
|
function factoryJsonSchema(params) {
|
|
7
9
|
const identifier = params.schema.definition.identifier
|
|
8
10
|
?? `NotIdentified${params.resultSchemaContext.size}`;
|
|
9
11
|
const renderResult = render(params.schema, {
|
|
10
12
|
identifier,
|
|
11
|
-
mode:
|
|
13
|
+
mode: "in",
|
|
12
14
|
context: params.context,
|
|
13
15
|
version: "openApi31",
|
|
14
16
|
transformers: defaultTransformers,
|
|
@@ -30,6 +32,7 @@ const methodMapper = {
|
|
|
30
32
|
TRACE: "trace",
|
|
31
33
|
CONNECT: "connect",
|
|
32
34
|
OPTIONS: "options",
|
|
35
|
+
PATCH: "patch",
|
|
33
36
|
};
|
|
34
37
|
function routeToOpenApi(route, params) {
|
|
35
38
|
const isIgnore = A.find(route.definition.metadata, IgnoreByOpenApiGeneratorMetadata.is);
|
|
@@ -52,18 +55,27 @@ function routeToOpenApi(route, params) {
|
|
|
52
55
|
schema: factoryJsonSchema({
|
|
53
56
|
context: params.contextToJsonSchemaFactory,
|
|
54
57
|
resultSchemaContext: params.resultSchemaContext,
|
|
55
|
-
mode: "in",
|
|
56
58
|
schema,
|
|
57
59
|
}),
|
|
58
60
|
}))));
|
|
59
|
-
const requestBody = pipe(body, when((value) => O.countKeys(value) === 0, justReturn(DP.empty())), whenNot(DP.dataParserKind.has, DP.object), P.when(DP.identifier(DP.emptyKind), justReturn(undefined)), P.when(
|
|
61
|
+
const requestBody = pipe(body, when((value) => O.countKeys(value) === 0, justReturn(DP.empty())), whenNot(DP.dataParserKind.has, DP.object), P.when(DP.identifier(DP.emptyKind), justReturn(undefined)), P.when(() => FormDataBodyController.is(route.definition.bodyController), (objectSchema) => ({
|
|
62
|
+
required: true,
|
|
63
|
+
content: {
|
|
64
|
+
"multipart/form-data": {
|
|
65
|
+
schema: factoryJsonSchema({
|
|
66
|
+
context: params.contextToJsonSchemaFactory,
|
|
67
|
+
resultSchemaContext: params.resultSchemaContext,
|
|
68
|
+
schema: objectSchema,
|
|
69
|
+
}),
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
})), P.when(DP.identifier(DP.objectKind), (objectSchema) => ({
|
|
60
73
|
required: true,
|
|
61
74
|
content: {
|
|
62
75
|
"application/json": {
|
|
63
76
|
schema: factoryJsonSchema({
|
|
64
77
|
context: params.contextToJsonSchemaFactory,
|
|
65
78
|
resultSchemaContext: params.resultSchemaContext,
|
|
66
|
-
mode: "in",
|
|
67
79
|
schema: objectSchema,
|
|
68
80
|
}),
|
|
69
81
|
},
|
|
@@ -75,7 +87,6 @@ function routeToOpenApi(route, params) {
|
|
|
75
87
|
schema: factoryJsonSchema({
|
|
76
88
|
context: params.contextToJsonSchemaFactory,
|
|
77
89
|
resultSchemaContext: params.resultSchemaContext,
|
|
78
|
-
mode: "in",
|
|
79
90
|
schema: primitiveSchema,
|
|
80
91
|
}),
|
|
81
92
|
},
|
|
@@ -86,7 +97,6 @@ function routeToOpenApi(route, params) {
|
|
|
86
97
|
? factoryJsonSchema({
|
|
87
98
|
context: params.contextToJsonSchemaFactory,
|
|
88
99
|
resultSchemaContext: params.resultSchemaContext,
|
|
89
|
-
mode: "in",
|
|
90
100
|
schema: body,
|
|
91
101
|
})
|
|
92
102
|
: undefined;
|
|
@@ -10,12 +10,17 @@ export interface EntrypointContentBodyApplicationJson {
|
|
|
10
10
|
schema: JsonSchema;
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
+
export interface EntrypointContentBodyFormData {
|
|
14
|
+
"multipart/form-data": {
|
|
15
|
+
schema: JsonSchema;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
13
18
|
export interface EntrypointContentBodyTextPlain {
|
|
14
19
|
"text/plain": {
|
|
15
20
|
schema: JsonSchema;
|
|
16
21
|
};
|
|
17
22
|
}
|
|
18
|
-
export type EntrypointContentBody = EntrypointContentBodyApplicationJson | EntrypointContentBodyTextPlain;
|
|
23
|
+
export type EntrypointContentBody = (EntrypointContentBodyApplicationJson | EntrypointContentBodyTextPlain | EntrypointContentBodyFormData);
|
|
19
24
|
export interface EntrypointRequestBody {
|
|
20
25
|
required: true;
|
|
21
26
|
content: EntrypointContentBody;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type OpenApiMethod = "get" | "post" | "put" | "delete" | "head" | "trace" | "connect" | "options";
|
|
1
|
+
export type OpenApiMethod = "get" | "post" | "put" | "patch" | "delete" | "head" | "trace" | "connect" | "options";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@duplojs/http",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"author": "mathcovax",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -65,8 +65,9 @@
|
|
|
65
65
|
"README.md"
|
|
66
66
|
],
|
|
67
67
|
"peerDependencies": {
|
|
68
|
-
"@duplojs/data-parser-tools": ">=0.2.
|
|
69
|
-
"@duplojs/utils": ">=
|
|
68
|
+
"@duplojs/data-parser-tools": ">=0.2.8 <1.0.0",
|
|
69
|
+
"@duplojs/server-utils": ">=0.2.0 <1.0.0",
|
|
70
|
+
"@duplojs/utils": ">=1.5.6 <2.0.0"
|
|
70
71
|
},
|
|
71
72
|
"devDependencies": {
|
|
72
73
|
"@commitlint/cli": "19.8.1",
|
|
@@ -76,6 +77,7 @@
|
|
|
76
77
|
"@types/bun": "^1.3.3",
|
|
77
78
|
"@types/deno": "^2.5.0",
|
|
78
79
|
"@types/node": "24.3.0",
|
|
80
|
+
"@types/web": "^0.0.317",
|
|
79
81
|
"@vitest/coverage-istanbul": "3.2.4",
|
|
80
82
|
"eslint": "9.34.0",
|
|
81
83
|
"form-data": "^4.0.5",
|
|
@@ -98,8 +100,5 @@
|
|
|
98
100
|
"keywords": [],
|
|
99
101
|
"engines": {
|
|
100
102
|
"node": ">=22.15.1"
|
|
101
|
-
},
|
|
102
|
-
"dependencies": {
|
|
103
|
-
"@types/web": "^0.0.317"
|
|
104
103
|
}
|
|
105
104
|
}
|
package/dist/core/request.mjs
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { kindHeritage } from '@duplojs/utils';
|
|
2
|
-
import { createCoreLibKind } from './kind.mjs';
|
|
3
|
-
|
|
4
|
-
class Request extends kindHeritage("request", createCoreLibKind("request")) {
|
|
5
|
-
method;
|
|
6
|
-
headers;
|
|
7
|
-
url;
|
|
8
|
-
host;
|
|
9
|
-
origin;
|
|
10
|
-
path;
|
|
11
|
-
params;
|
|
12
|
-
query;
|
|
13
|
-
matchedPath;
|
|
14
|
-
body = undefined;
|
|
15
|
-
constructor({ method, headers, url, host, origin, path, params, query, matchedPath, ...rest }) {
|
|
16
|
-
super();
|
|
17
|
-
this.method = method;
|
|
18
|
-
this.headers = headers;
|
|
19
|
-
this.url = url;
|
|
20
|
-
this.host = host;
|
|
21
|
-
this.origin = origin;
|
|
22
|
-
this.path = path;
|
|
23
|
-
this.params = params;
|
|
24
|
-
this.query = query;
|
|
25
|
-
this.matchedPath = matchedPath;
|
|
26
|
-
for (const key in rest) {
|
|
27
|
-
this[key] = rest[key];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export { Request };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var utils = require('@duplojs/utils');
|
|
4
|
-
var kind = require('../kind.cjs');
|
|
5
|
-
|
|
6
|
-
class BodyParseUnknownError extends utils.kindHeritage("body-parse-unknown-error", kind.createInterfacesNodeLibKind("body-parse-unknown-error"), Error) {
|
|
7
|
-
contentType;
|
|
8
|
-
unknownError;
|
|
9
|
-
constructor(contentType, unknownError) {
|
|
10
|
-
super({}, [`Error when parsing body with '${contentType}' content-type.`]);
|
|
11
|
-
this.contentType = contentType;
|
|
12
|
-
this.unknownError = unknownError;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
exports.BodyParseUnknownError = BodyParseUnknownError;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
declare const BodyParseUnknownError_base: new (params: {
|
|
2
|
-
"@DuplojsHttpInterfacesNode/body-parse-unknown-error"?: unknown;
|
|
3
|
-
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"@DuplojsHttpInterfacesNode/body-parse-unknown-error", unknown>, unknown> & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"body-parse-unknown-error", unknown>, unknown>;
|
|
4
|
-
export declare class BodyParseUnknownError extends BodyParseUnknownError_base {
|
|
5
|
-
contentType: string;
|
|
6
|
-
unknownError: unknown;
|
|
7
|
-
constructor(contentType: string, unknownError: unknown);
|
|
8
|
-
}
|
|
9
|
-
export {};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { kindHeritage } from '@duplojs/utils';
|
|
2
|
-
import { createInterfacesNodeLibKind } from '../kind.mjs';
|
|
3
|
-
|
|
4
|
-
class BodyParseUnknownError extends kindHeritage("body-parse-unknown-error", createInterfacesNodeLibKind("body-parse-unknown-error"), Error) {
|
|
5
|
-
contentType;
|
|
6
|
-
unknownError;
|
|
7
|
-
constructor(contentType, unknownError) {
|
|
8
|
-
super({}, [`Error when parsing body with '${contentType}' content-type.`]);
|
|
9
|
-
this.contentType = contentType;
|
|
10
|
-
this.unknownError = unknownError;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export { BodyParseUnknownError };
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
declare const BodyParseWrongChunkReceived_base: new (params: {
|
|
2
|
-
"@DuplojsHttpInterfacesNode/body-parse-wrong-chunk-received"?: unknown;
|
|
3
|
-
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"@DuplojsHttpInterfacesNode/body-parse-wrong-chunk-received", unknown>, unknown> & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"body-parse-wrong-chunk-received", unknown>, unknown>;
|
|
4
|
-
export declare class BodyParseWrongChunkReceived extends BodyParseWrongChunkReceived_base {
|
|
5
|
-
wrongChunk: unknown;
|
|
6
|
-
constructor(wrongChunk: unknown);
|
|
7
|
-
}
|
|
8
|
-
export {};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { kindHeritage } from '@duplojs/utils';
|
|
2
|
-
import { createInterfacesNodeLibKind } from '../kind.mjs';
|
|
3
|
-
|
|
4
|
-
class BodyParseWrongChunkReceived extends kindHeritage("body-parse-wrong-chunk-received", createInterfacesNodeLibKind("body-parse-wrong-chunk-received"), Error) {
|
|
5
|
-
wrongChunk;
|
|
6
|
-
constructor(wrongChunk) {
|
|
7
|
-
super({}, ["Received chunk is not buffer or string."]);
|
|
8
|
-
this.wrongChunk = wrongChunk;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export { BodyParseWrongChunkReceived };
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
require('../../core/route/index.cjs');
|
|
4
|
-
var utils = require('@duplojs/utils');
|
|
5
|
-
require('./error/index.cjs');
|
|
6
|
-
require('../../core/response/index.cjs');
|
|
7
|
-
var hooks = require('../../core/route/hooks.cjs');
|
|
8
|
-
var predicted = require('../../core/response/predicted.cjs');
|
|
9
|
-
var hook = require('../../core/response/hook.cjs');
|
|
10
|
-
var bodySizeExceedsLimitError = require('./error/bodySizeExceedsLimitError.cjs');
|
|
11
|
-
var bodyParseWrongChunkReceived = require('./error/bodyParseWrongChunkReceived.cjs');
|
|
12
|
-
var bodyParseUnknownError = require('./error/bodyParseUnknownError.cjs');
|
|
13
|
-
|
|
14
|
-
function makeNodeHook(hub, serverParams) {
|
|
15
|
-
const informationHeaderKey = serverParams.informationHeaderKey;
|
|
16
|
-
const predictedHeaderKey = serverParams.predictedHeaderKey;
|
|
17
|
-
const fromHookHeaderKey = serverParams.fromHookHeaderKey;
|
|
18
|
-
const isDev = hub.config.environment === "DEV";
|
|
19
|
-
const maxBodySize = utils.stringToBytes(serverParams.maxBodySize);
|
|
20
|
-
return hooks.createHookRouteLifeCycle({
|
|
21
|
-
async parseBody({ request, exit }) {
|
|
22
|
-
const contentType = request.headers["content-type"] instanceof Array
|
|
23
|
-
? request.headers["content-type"].join(", ")
|
|
24
|
-
: request.headers["content-type"] ?? "";
|
|
25
|
-
const isText = contentType.includes("text/plain");
|
|
26
|
-
const isJson = contentType.includes("application/json");
|
|
27
|
-
if (!isText && !isJson) {
|
|
28
|
-
return exit();
|
|
29
|
-
}
|
|
30
|
-
const { request: rawRequest } = request.raw;
|
|
31
|
-
request.body = await new Promise((resolve, reject) => {
|
|
32
|
-
function errorCallback(error) {
|
|
33
|
-
if (error instanceof bodySizeExceedsLimitError.BodySizeExceedsLimitError
|
|
34
|
-
|| error instanceof bodyParseWrongChunkReceived.BodyParseWrongChunkReceived) {
|
|
35
|
-
reject(error);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
reject(new bodyParseUnknownError.BodyParseUnknownError(contentType, error));
|
|
39
|
-
}
|
|
40
|
-
let stringBody = "";
|
|
41
|
-
let byteLengthBody = 0;
|
|
42
|
-
rawRequest.on("error", errorCallback);
|
|
43
|
-
rawRequest.on("data", (chunk) => {
|
|
44
|
-
if (!(chunk instanceof Buffer) && typeof chunk !== "string") {
|
|
45
|
-
rawRequest.emit("error", new bodyParseWrongChunkReceived.BodyParseWrongChunkReceived(chunk));
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
byteLengthBody += chunk instanceof Buffer
|
|
49
|
-
? chunk.byteLength
|
|
50
|
-
: Buffer.byteLength(chunk);
|
|
51
|
-
if (byteLengthBody > maxBodySize) {
|
|
52
|
-
rawRequest.emit("error", new bodySizeExceedsLimitError.BodySizeExceedsLimitError(serverParams.maxBodySize));
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
stringBody += chunk.toString();
|
|
56
|
-
});
|
|
57
|
-
rawRequest.on("end", () => {
|
|
58
|
-
try {
|
|
59
|
-
resolve(isText
|
|
60
|
-
? stringBody
|
|
61
|
-
: JSON.parse(stringBody));
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
errorCallback(error);
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
return exit();
|
|
69
|
-
},
|
|
70
|
-
error({ error, response, exit }) {
|
|
71
|
-
const displayedError = isDev ? error : undefined;
|
|
72
|
-
if (error instanceof bodySizeExceedsLimitError.BodySizeExceedsLimitError) {
|
|
73
|
-
return response("400", "body-size-exceeds-limit-error", displayedError);
|
|
74
|
-
}
|
|
75
|
-
else if (error instanceof bodyParseWrongChunkReceived.BodyParseWrongChunkReceived) {
|
|
76
|
-
return response("400", "body-parse-wrong-chunk-received", displayedError);
|
|
77
|
-
}
|
|
78
|
-
else if (error instanceof bodyParseUnknownError.BodyParseUnknownError) {
|
|
79
|
-
return response("400", "body-parse-unknown-error", displayedError);
|
|
80
|
-
}
|
|
81
|
-
return exit();
|
|
82
|
-
},
|
|
83
|
-
beforeSendResponse({ request, currentResponse, exit }) {
|
|
84
|
-
if (!currentResponse.headers?.["content-type"]) {
|
|
85
|
-
const body = currentResponse.body;
|
|
86
|
-
if (typeof body === "string"
|
|
87
|
-
|| body instanceof Error) {
|
|
88
|
-
currentResponse.setHeader("content-type", "text/plain; charset=utf-8");
|
|
89
|
-
}
|
|
90
|
-
else if (typeof body === "object"
|
|
91
|
-
|| typeof body === "number"
|
|
92
|
-
|| typeof body === "boolean") {
|
|
93
|
-
currentResponse.setHeader("content-type", "application/json; charset=utf-8");
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
currentResponse.setHeader(informationHeaderKey, currentResponse.information);
|
|
97
|
-
if (currentResponse instanceof predicted.PredictedResponse) {
|
|
98
|
-
currentResponse.setHeader(predictedHeaderKey, "1");
|
|
99
|
-
}
|
|
100
|
-
else if (currentResponse instanceof hook.HookResponse) {
|
|
101
|
-
currentResponse.setHeader(fromHookHeaderKey, currentResponse.fromHook);
|
|
102
|
-
}
|
|
103
|
-
request.raw.response.writeHead(Number(currentResponse.code), currentResponse.headers);
|
|
104
|
-
return exit();
|
|
105
|
-
},
|
|
106
|
-
sendResponse({ request, currentResponse, exit }) {
|
|
107
|
-
const { response: rawResponse } = request.raw;
|
|
108
|
-
const body = currentResponse.body;
|
|
109
|
-
if (body instanceof Error) {
|
|
110
|
-
rawResponse.write(body.toString());
|
|
111
|
-
}
|
|
112
|
-
else if (typeof body === "object"
|
|
113
|
-
|| typeof body === "number"
|
|
114
|
-
|| typeof body === "boolean") {
|
|
115
|
-
rawResponse.write(JSON.stringify(body));
|
|
116
|
-
}
|
|
117
|
-
else if (typeof body === "string") {
|
|
118
|
-
rawResponse.write(body);
|
|
119
|
-
}
|
|
120
|
-
rawResponse.end();
|
|
121
|
-
return exit();
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
exports.makeNodeHook = makeNodeHook;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type HttpServerParams, type Hub } from "../../core/hub";
|
|
2
|
-
import { HookResponse } from "../../core/response";
|
|
3
|
-
export declare function makeNodeHook(hub: Hub, serverParams: HttpServerParams): {
|
|
4
|
-
parseBody({ request, exit }: import("../../core/route").RouteHookParams<import("../../core/request").Request>): Promise<import("../../core/route").RouteHookExit>;
|
|
5
|
-
error({ error, response, exit }: import("../../core/route").RouteHookErrorParams<import("../../core/request").Request>): import("../../core/route").RouteHookExit | HookResponse<"400", "body-size-exceeds-limit-error", unknown> | HookResponse<"400", "body-parse-wrong-chunk-received", unknown> | HookResponse<"400", "body-parse-unknown-error", unknown>;
|
|
6
|
-
beforeSendResponse({ request, currentResponse, exit }: import("../../core/route").RouteHookParamsAfter<import("../../core/request").Request>): import("../../core/route").RouteHookExit;
|
|
7
|
-
sendResponse({ request, currentResponse, exit }: import("../../core/route").RouteHookParamsAfter<import("../../core/request").Request>): import("../../core/route").RouteHookExit;
|
|
8
|
-
};
|