@duplojs/http 0.7.4 → 0.8.5
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/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.cjs +1 -0
- package/dist/core/request/bodyController/formData.d.ts +4 -2
- package/dist/core/request/bodyController/formData.mjs +1 -0
- 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 +34 -14
- package/dist/interfaces/node/bodyReaders/formData/index.mjs +35 -15
- package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.cjs +18 -12
- package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.d.ts +2 -1
- package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.mjs +18 -12
- 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,16 @@
|
|
|
1
|
+
export interface CacheControlDirectives {
|
|
2
|
+
maxAge?: number;
|
|
3
|
+
sMaxAge?: number;
|
|
4
|
+
public?: true;
|
|
5
|
+
private?: true | string[];
|
|
6
|
+
noCache?: true | string[];
|
|
7
|
+
noStore?: true;
|
|
8
|
+
noTransform?: true;
|
|
9
|
+
mustRevalidate?: true;
|
|
10
|
+
proxyRevalidate?: true;
|
|
11
|
+
immutable?: true;
|
|
12
|
+
staleWhileRevalidate?: number;
|
|
13
|
+
staleIfError?: number;
|
|
14
|
+
mustUnderstand?: true;
|
|
15
|
+
extensions?: Record<string, string>;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./cacheControlDirectives";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './cacheControlDirectives.mjs';
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require('../../core/steps/index.cjs');
|
|
4
4
|
var utils = require('@duplojs/utils');
|
|
5
|
+
require('../../core/response/index.cjs');
|
|
5
6
|
var metadata = require('./metadata.cjs');
|
|
6
7
|
var identifier = require('../../core/steps/identifier.cjs');
|
|
7
8
|
var process = require('../../core/steps/process.cjs');
|
|
@@ -10,6 +11,7 @@ var presetChecker = require('../../core/steps/presetChecker.cjs');
|
|
|
10
11
|
var checker = require('../../core/steps/checker.cjs');
|
|
11
12
|
var cut = require('../../core/steps/cut.cjs');
|
|
12
13
|
var handler = require('../../core/steps/handler.cjs');
|
|
14
|
+
var contract = require('../../core/response/contract.cjs');
|
|
13
15
|
|
|
14
16
|
function aggregateStepContract(steps, params) {
|
|
15
17
|
const filteredStep = utils.A.filter(steps, (step) => utils.A.find(step.definition.metadata, metadata.IgnoreByCodeGeneratorMetadata.is) === undefined);
|
|
@@ -55,11 +57,16 @@ function aggregateStepContract(steps, params) {
|
|
|
55
57
|
cut.cutStepKind,
|
|
56
58
|
handler.handlerStepKind,
|
|
57
59
|
]), ({ definition }) => definition.responseContract)
|
|
58
|
-
.exhaustive()), utils.A.map(({ code, information, body }) => utils.DP.object({
|
|
60
|
+
.exhaustive()), utils.A.map(utils.innerPipe(utils.P.when(contract.ResponseContract.contractKind.has, ({ code, information, body }) => utils.DP.object({
|
|
59
61
|
code: utils.DP.literal(code),
|
|
60
62
|
information: utils.DP.literal(information),
|
|
61
63
|
body,
|
|
62
|
-
})), utils.
|
|
64
|
+
})), utils.P.when(contract.ResponseContract.serverSentEventsContractKind.has, ({ code, information, body, events }) => utils.DP.object({
|
|
65
|
+
code: utils.DP.literal(code),
|
|
66
|
+
information: utils.DP.literal(information),
|
|
67
|
+
body,
|
|
68
|
+
events: utils.DP.object(events),
|
|
69
|
+
})), utils.P.exhaustive)), utils.A.concat(processContracts.endpointContract));
|
|
63
70
|
return {
|
|
64
71
|
entrypointContract,
|
|
65
72
|
endpointContract,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Steps } from "../../core/steps";
|
|
2
2
|
import { DP } from "@duplojs/utils";
|
|
3
3
|
import { type EntrypointKey } from "./types";
|
|
4
|
-
import {
|
|
4
|
+
import { ResponseContract } from "../../core/response";
|
|
5
5
|
type EntrypointReduceResult = Record<EntrypointKey, DP.DataParser | Record<string, DP.DataParser>>;
|
|
6
6
|
export interface StepsToDataParserParams {
|
|
7
7
|
readonly defaultExtractContract: ResponseContract.Contract;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import '../../core/steps/index.mjs';
|
|
2
|
-
import { A, pipe, O, DP, P, hasSomeKinds } from '@duplojs/utils';
|
|
2
|
+
import { A, pipe, O, DP, P, hasSomeKinds, innerPipe } from '@duplojs/utils';
|
|
3
|
+
import '../../core/response/index.mjs';
|
|
3
4
|
import { IgnoreByCodeGeneratorMetadata } from './metadata.mjs';
|
|
4
5
|
import { stepIdentifier } from '../../core/steps/identifier.mjs';
|
|
5
6
|
import { processStepKind } from '../../core/steps/process.mjs';
|
|
@@ -8,6 +9,7 @@ import { presetCheckerStepKind } from '../../core/steps/presetChecker.mjs';
|
|
|
8
9
|
import { checkerStepKind } from '../../core/steps/checker.mjs';
|
|
9
10
|
import { cutStepKind } from '../../core/steps/cut.mjs';
|
|
10
11
|
import { handlerStepKind } from '../../core/steps/handler.mjs';
|
|
12
|
+
import { ResponseContract } from '../../core/response/contract.mjs';
|
|
11
13
|
|
|
12
14
|
function aggregateStepContract(steps, params) {
|
|
13
15
|
const filteredStep = A.filter(steps, (step) => A.find(step.definition.metadata, IgnoreByCodeGeneratorMetadata.is) === undefined);
|
|
@@ -53,11 +55,16 @@ function aggregateStepContract(steps, params) {
|
|
|
53
55
|
cutStepKind,
|
|
54
56
|
handlerStepKind,
|
|
55
57
|
]), ({ definition }) => definition.responseContract)
|
|
56
|
-
.exhaustive()), A.map(({ code, information, body }) => DP.object({
|
|
58
|
+
.exhaustive()), A.map(innerPipe(P.when(ResponseContract.contractKind.has, ({ code, information, body }) => DP.object({
|
|
57
59
|
code: DP.literal(code),
|
|
58
60
|
information: DP.literal(information),
|
|
59
61
|
body,
|
|
60
|
-
})),
|
|
62
|
+
})), P.when(ResponseContract.serverSentEventsContractKind.has, ({ code, information, body, events }) => DP.object({
|
|
63
|
+
code: DP.literal(code),
|
|
64
|
+
information: DP.literal(information),
|
|
65
|
+
body,
|
|
66
|
+
events: DP.object(events),
|
|
67
|
+
})), P.exhaustive)), A.concat(processContracts.endpointContract));
|
|
61
68
|
return {
|
|
62
69
|
entrypointContract,
|
|
63
70
|
endpointContract,
|
|
@@ -4,7 +4,7 @@ var DataParserToTypescript = require('@duplojs/data-parser-tools/toTypescript');
|
|
|
4
4
|
var utils = require('@duplojs/utils');
|
|
5
5
|
var routeToDataParser = require('./routeToDataParser.cjs');
|
|
6
6
|
var serverUtils = require('@duplojs/server-utils');
|
|
7
|
-
var
|
|
7
|
+
var typescriptTransformer = require('./typescriptTransformer.cjs');
|
|
8
8
|
|
|
9
9
|
function _interopNamespaceDefault(e) {
|
|
10
10
|
var n = Object.create(null);
|
|
@@ -45,9 +45,9 @@ function codeGeneratorPlugin(pluginParams) {
|
|
|
45
45
|
identifier: "Routes",
|
|
46
46
|
mode: "in",
|
|
47
47
|
transformers: [
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
typescriptTransformer.fileTransformer,
|
|
49
|
+
typescriptTransformer.dateTransformer,
|
|
50
|
+
typescriptTransformer.timeTransformer,
|
|
51
51
|
...DataParserToTypescript__namespace.defaultTransformers,
|
|
52
52
|
],
|
|
53
53
|
});
|
|
@@ -2,7 +2,7 @@ import * as DataParserToTypescript from '@duplojs/data-parser-tools/toTypescript
|
|
|
2
2
|
import { equal, A, DP, asserts, E } from '@duplojs/utils';
|
|
3
3
|
import { routeToDataParser } from './routeToDataParser.mjs';
|
|
4
4
|
import { SF } from '@duplojs/server-utils';
|
|
5
|
-
import { fileTransformer, dateTransformer, timeTransformer } from './
|
|
5
|
+
import { fileTransformer, dateTransformer, timeTransformer } from './typescriptTransformer.mjs';
|
|
6
6
|
|
|
7
7
|
function codeGeneratorPlugin(pluginParams) {
|
|
8
8
|
return () => ({
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import { type Steps } from "../../core/steps";
|
|
2
2
|
import { DP } from "@duplojs/utils";
|
|
3
|
-
import type {
|
|
3
|
+
import type { ResponseContract } from "../../core/response";
|
|
4
4
|
import type { EntrypointKey } from "./types";
|
|
5
|
-
export interface EndpointRouteResult {
|
|
6
|
-
code: ResponseCode;
|
|
7
|
-
information: string;
|
|
8
|
-
body: DP.DataParser;
|
|
9
|
-
}
|
|
10
5
|
export type EntrypointReduceResult = Record<EntrypointKey, DP.DataParser | Record<string, DP.DataParser>>;
|
|
11
6
|
export interface AggregateStepsResult {
|
|
12
7
|
entrypointContract: EntrypointReduceResult;
|
|
13
|
-
endpointContract:
|
|
8
|
+
endpointContract: (ResponseContract.Contract | ResponseContract.ServerSentEventsContract)[];
|
|
14
9
|
}
|
|
15
10
|
export interface AggregateStepsParams {
|
|
16
11
|
readonly defaultExtractContract: ResponseContract.Contract;
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
var aggregateStepContract = require('./aggregateStepContract.cjs');
|
|
4
4
|
var utils = require('@duplojs/utils');
|
|
5
|
+
require('../../core/response/index.cjs');
|
|
5
6
|
var toJsonSchema = require('@duplojs/data-parser-tools/toJsonSchema');
|
|
6
7
|
require('../../core/request/index.cjs');
|
|
7
8
|
var metadata = require('./metadata.cjs');
|
|
8
9
|
var formData = require('../../core/request/bodyController/formData.cjs');
|
|
10
|
+
var contract = require('../../core/response/contract.cjs');
|
|
9
11
|
|
|
10
12
|
function factoryJsonSchema(params) {
|
|
11
13
|
const identifier = params.schema.definition.identifier
|
|
@@ -94,14 +96,8 @@ function routeToOpenApi(route, params) {
|
|
|
94
96
|
},
|
|
95
97
|
},
|
|
96
98
|
})));
|
|
97
|
-
const responses = utils.pipe(aggregateStepResult.endpointContract, utils.A.reduce(utils.A.reduceFrom({}), ({ lastValue, element:
|
|
98
|
-
const
|
|
99
|
-
? factoryJsonSchema({
|
|
100
|
-
context: params.contextToJsonSchemaFactory,
|
|
101
|
-
resultSchemaContext: params.resultSchemaContext,
|
|
102
|
-
schema: body,
|
|
103
|
-
})
|
|
104
|
-
: undefined;
|
|
99
|
+
const responses = utils.pipe(aggregateStepResult.endpointContract, utils.A.reduce(utils.A.reduceFrom({}), ({ lastValue, element: contract$1, nextWithObject, next }) => {
|
|
100
|
+
const { information, body, code } = contract$1;
|
|
105
101
|
const headerInformation = {
|
|
106
102
|
const: information,
|
|
107
103
|
type: "string",
|
|
@@ -128,6 +124,48 @@ function routeToOpenApi(route, params) {
|
|
|
128
124
|
description: headerDescription,
|
|
129
125
|
},
|
|
130
126
|
};
|
|
127
|
+
if (contract.ResponseContract.serverSentEventsContractKind.has(contract$1)) {
|
|
128
|
+
const eventNameList = utils.O.keys(contract$1.events);
|
|
129
|
+
const eventDataList = utils.O.values(contract$1.events);
|
|
130
|
+
if (!utils.A.minElements(eventNameList, 1) || !utils.A.minElements(eventDataList, 1)) {
|
|
131
|
+
return next(lastValue);
|
|
132
|
+
}
|
|
133
|
+
const schema = factoryJsonSchema({
|
|
134
|
+
context: params.contextToJsonSchemaFactory,
|
|
135
|
+
resultSchemaContext: params.resultSchemaContext,
|
|
136
|
+
schema: utils.DP.object({
|
|
137
|
+
event: utils.DP.literal(eventNameList),
|
|
138
|
+
data: utils.DP.union(eventDataList),
|
|
139
|
+
id: utils.DP.optional(utils.DP.string()),
|
|
140
|
+
retry: utils.DP.optional(utils.DP.number()),
|
|
141
|
+
}),
|
|
142
|
+
});
|
|
143
|
+
const lastContent = lastValue[code]?.content;
|
|
144
|
+
const content = {
|
|
145
|
+
...lastContent,
|
|
146
|
+
"text/event-stream": {
|
|
147
|
+
itemSchema: lastContent?.["text/event-stream"]
|
|
148
|
+
? {
|
|
149
|
+
anyOf: [
|
|
150
|
+
lastContent["text/event-stream"].itemSchema,
|
|
151
|
+
schema,
|
|
152
|
+
],
|
|
153
|
+
}
|
|
154
|
+
: schema,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
return nextWithObject(lastValue, {
|
|
158
|
+
[code]: {
|
|
159
|
+
headers,
|
|
160
|
+
content,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
const schemaResponse = factoryJsonSchema({
|
|
165
|
+
context: params.contextToJsonSchemaFactory,
|
|
166
|
+
resultSchemaContext: params.resultSchemaContext,
|
|
167
|
+
schema: body,
|
|
168
|
+
});
|
|
131
169
|
const content = utils.pipe(body, utils.P.when(utils.DP.identifier(utils.DP.emptyKind), utils.justReturn(lastValue[code]?.content)), utils.P.otherwise((value) => {
|
|
132
170
|
if (utils.DP.identifier(value, utils.DP.stringKind) && lastValue[code]?.content?.["plain/text"]) {
|
|
133
171
|
return lastValue[code].content;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Route } from "../../core/route";
|
|
2
|
-
import
|
|
2
|
+
import { ResponseContract } from "../../core/response";
|
|
3
3
|
import { type MapContext, type JsonSchema } from "@duplojs/data-parser-tools/toJsonSchema";
|
|
4
4
|
import type { EndpointResponse, EntrypointParameter } from "./types";
|
|
5
5
|
export type ResultSchemaContext = Map<string, Record<string, JsonSchema>>;
|
|
@@ -40,5 +40,5 @@ export declare function routeToOpenApi(route: Route, params: RouteToOpenApiParam
|
|
|
40
40
|
};
|
|
41
41
|
};
|
|
42
42
|
} | undefined;
|
|
43
|
-
responses: Partial<Record<
|
|
43
|
+
responses: Partial<Record<string, EndpointResponse>>;
|
|
44
44
|
}[];
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { aggregateStepContract } from './aggregateStepContract.mjs';
|
|
2
2
|
import { O, A, pipe, DP, when, justReturn, whenNot, P, isType, S } from '@duplojs/utils';
|
|
3
|
+
import '../../core/response/index.mjs';
|
|
3
4
|
import { render, defaultTransformers } from '@duplojs/data-parser-tools/toJsonSchema';
|
|
4
5
|
import '../../core/request/index.mjs';
|
|
5
6
|
import { IgnoreByOpenApiGeneratorMetadata } from './metadata.mjs';
|
|
6
7
|
import { FormDataBodyController } from '../../core/request/bodyController/formData.mjs';
|
|
8
|
+
import { ResponseContract } from '../../core/response/contract.mjs';
|
|
7
9
|
|
|
8
10
|
function factoryJsonSchema(params) {
|
|
9
11
|
const identifier = params.schema.definition.identifier
|
|
@@ -92,14 +94,8 @@ function routeToOpenApi(route, params) {
|
|
|
92
94
|
},
|
|
93
95
|
},
|
|
94
96
|
})));
|
|
95
|
-
const responses = pipe(aggregateStepResult.endpointContract, A.reduce(A.reduceFrom({}), ({ lastValue, element:
|
|
96
|
-
const
|
|
97
|
-
? factoryJsonSchema({
|
|
98
|
-
context: params.contextToJsonSchemaFactory,
|
|
99
|
-
resultSchemaContext: params.resultSchemaContext,
|
|
100
|
-
schema: body,
|
|
101
|
-
})
|
|
102
|
-
: undefined;
|
|
97
|
+
const responses = pipe(aggregateStepResult.endpointContract, A.reduce(A.reduceFrom({}), ({ lastValue, element: contract, nextWithObject, next }) => {
|
|
98
|
+
const { information, body, code } = contract;
|
|
103
99
|
const headerInformation = {
|
|
104
100
|
const: information,
|
|
105
101
|
type: "string",
|
|
@@ -126,6 +122,48 @@ function routeToOpenApi(route, params) {
|
|
|
126
122
|
description: headerDescription,
|
|
127
123
|
},
|
|
128
124
|
};
|
|
125
|
+
if (ResponseContract.serverSentEventsContractKind.has(contract)) {
|
|
126
|
+
const eventNameList = O.keys(contract.events);
|
|
127
|
+
const eventDataList = O.values(contract.events);
|
|
128
|
+
if (!A.minElements(eventNameList, 1) || !A.minElements(eventDataList, 1)) {
|
|
129
|
+
return next(lastValue);
|
|
130
|
+
}
|
|
131
|
+
const schema = factoryJsonSchema({
|
|
132
|
+
context: params.contextToJsonSchemaFactory,
|
|
133
|
+
resultSchemaContext: params.resultSchemaContext,
|
|
134
|
+
schema: DP.object({
|
|
135
|
+
event: DP.literal(eventNameList),
|
|
136
|
+
data: DP.union(eventDataList),
|
|
137
|
+
id: DP.optional(DP.string()),
|
|
138
|
+
retry: DP.optional(DP.number()),
|
|
139
|
+
}),
|
|
140
|
+
});
|
|
141
|
+
const lastContent = lastValue[code]?.content;
|
|
142
|
+
const content = {
|
|
143
|
+
...lastContent,
|
|
144
|
+
"text/event-stream": {
|
|
145
|
+
itemSchema: lastContent?.["text/event-stream"]
|
|
146
|
+
? {
|
|
147
|
+
anyOf: [
|
|
148
|
+
lastContent["text/event-stream"].itemSchema,
|
|
149
|
+
schema,
|
|
150
|
+
],
|
|
151
|
+
}
|
|
152
|
+
: schema,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
return nextWithObject(lastValue, {
|
|
156
|
+
[code]: {
|
|
157
|
+
headers,
|
|
158
|
+
content,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const schemaResponse = factoryJsonSchema({
|
|
163
|
+
context: params.contextToJsonSchemaFactory,
|
|
164
|
+
resultSchemaContext: params.resultSchemaContext,
|
|
165
|
+
schema: body,
|
|
166
|
+
});
|
|
129
167
|
const content = pipe(body, P.when(DP.identifier(DP.emptyKind), justReturn(lastValue[code]?.content)), P.otherwise((value) => {
|
|
130
168
|
if (DP.identifier(value, DP.stringKind) && lastValue[code]?.content?.["plain/text"]) {
|
|
131
169
|
return lastValue[code].content;
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
import type { JsonSchema
|
|
1
|
+
import type { JsonSchema } from "@duplojs/data-parser-tools/toJsonSchema";
|
|
2
2
|
export interface EndpointResponseHeader {
|
|
3
3
|
information: {
|
|
4
|
-
schema:
|
|
4
|
+
schema: JsonSchema;
|
|
5
5
|
description: string;
|
|
6
6
|
};
|
|
7
7
|
}
|
|
8
8
|
export interface EndpointResponseContent {
|
|
9
|
+
"text/event-stream"?: {
|
|
10
|
+
itemSchema: JsonSchema;
|
|
11
|
+
};
|
|
9
12
|
"application/json"?: {
|
|
10
13
|
schema: JsonSchema;
|
|
11
14
|
};
|
|
12
15
|
"plain/text"?: {
|
|
13
|
-
schema:
|
|
16
|
+
schema: JsonSchema;
|
|
14
17
|
};
|
|
15
18
|
}
|
|
16
19
|
export interface EndpointResponse {
|
|
20
|
+
description?: string;
|
|
17
21
|
headers: EndpointResponseHeader;
|
|
18
22
|
content?: EndpointResponseContent;
|
|
19
23
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var makeRouteFolder = require('./makeRouteFolder.cjs');
|
|
4
|
+
var makeRouteFile = require('./makeRouteFile.cjs');
|
|
5
|
+
var plugin = require('./plugin.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
exports.makeRouteFolder = makeRouteFolder.makeRouteFolder;
|
|
10
|
+
exports.MissingSelectedStaticFileError = makeRouteFile.MissingSelectedStaticFileError;
|
|
11
|
+
exports.SelectedStaticFileIsNotFileError = makeRouteFile.SelectedStaticFileIsNotFileError;
|
|
12
|
+
exports.makeRouteFile = makeRouteFile.makeRouteFile;
|
|
13
|
+
exports.StaticPluginError = plugin.StaticPluginError;
|
|
14
|
+
exports.staticPlugin = plugin.staticPlugin;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare module "@duplojs/utils" {
|
|
2
|
+
interface ReservedKindNamespace {
|
|
3
|
+
DuplojsStaticPlugin: true;
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
export declare const createStaticPluginKind: <GenericName extends string, GenericKindValue extends unknown = unknown>(name: GenericName & import("@duplojs/utils/string").ForbiddenString<GenericName, "@" | "/">) => import("@duplojs/utils").KindHandler<import("@duplojs/utils").KindDefinition<`@DuplojsStaticPlugin/${GenericName}`, GenericKindValue>>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var serverUtils = require('@duplojs/server-utils');
|
|
4
|
+
var utils = require('@duplojs/utils');
|
|
5
|
+
require('../../core/builders/index.cjs');
|
|
6
|
+
require('../../core/metadata/index.cjs');
|
|
7
|
+
require('../../core/response/index.cjs');
|
|
8
|
+
var hooks = require('../cacheController/hooks.cjs');
|
|
9
|
+
var kind = require('./kind.cjs');
|
|
10
|
+
var builder = require('../../core/builders/route/builder.cjs');
|
|
11
|
+
var ignoreByRouteStore = require('../../core/metadata/ignoreByRouteStore.cjs');
|
|
12
|
+
var contract = require('../../core/response/contract.cjs');
|
|
13
|
+
|
|
14
|
+
class MissingSelectedStaticFileError extends utils.kindHeritage("missing-selected-static-file", kind.createStaticPluginKind("missing-selected-static-file"), Error) {
|
|
15
|
+
source;
|
|
16
|
+
constructor(source) {
|
|
17
|
+
super({}, [`Missing selected static file: ${source.path}.`]);
|
|
18
|
+
this.source = source;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
class SelectedStaticFileIsNotFileError extends utils.kindHeritage("selected-static-file-is-not-file", kind.createStaticPluginKind("selected-static-file-is-not-file"), Error) {
|
|
22
|
+
source;
|
|
23
|
+
constructor(source) {
|
|
24
|
+
super({}, [`Selected static file is not file: ${source.path}.`]);
|
|
25
|
+
this.source = source;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function makeRouteFile(params) {
|
|
29
|
+
const localPath = utils.A.coalescing(params.path);
|
|
30
|
+
return builder.useRouteBuilder("GET", localPath, {
|
|
31
|
+
metadata: [ignoreByRouteStore.IgnoreByRouteStoreMetadata()],
|
|
32
|
+
hooks: [hooks.createCacheControllerHooks(params.cacheControlConfig)],
|
|
33
|
+
})
|
|
34
|
+
.handler([
|
|
35
|
+
contract.ResponseContract.ok("resource.found", serverUtils.SDP.file()),
|
|
36
|
+
contract.ResponseContract.notModified("resource.notModified"),
|
|
37
|
+
], async (__, { response, request }) => {
|
|
38
|
+
const sourceStatResult = await params.source.stat();
|
|
39
|
+
if (utils.E.isLeft(sourceStatResult)) {
|
|
40
|
+
throw new MissingSelectedStaticFileError(params.source);
|
|
41
|
+
}
|
|
42
|
+
const resourceStat = utils.unwrap(sourceStatResult);
|
|
43
|
+
if (!resourceStat.isFile) {
|
|
44
|
+
throw new SelectedStaticFileIsNotFileError(params.source);
|
|
45
|
+
}
|
|
46
|
+
if (request.headers["if-modified-since"]
|
|
47
|
+
&& typeof request.headers["if-modified-since"] === "string"
|
|
48
|
+
&& resourceStat.modifiedAt
|
|
49
|
+
&& new Date(request.headers["if-modified-since"]).getTime() >= resourceStat.modifiedAt.getTime()) {
|
|
50
|
+
return response("resource.notModified")
|
|
51
|
+
.setHeader("last-modified", resourceStat.modifiedAt.toISOString());
|
|
52
|
+
}
|
|
53
|
+
return resourceStat.modifiedAt
|
|
54
|
+
? response("resource.found", params.source)
|
|
55
|
+
.setHeader("last-modified", resourceStat.modifiedAt.toISOString())
|
|
56
|
+
: response("resource.found", params.source);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
exports.MissingSelectedStaticFileError = MissingSelectedStaticFileError;
|
|
61
|
+
exports.SelectedStaticFileIsNotFileError = SelectedStaticFileIsNotFileError;
|
|
62
|
+
exports.makeRouteFile = makeRouteFile;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { SDP, type SF } from "@duplojs/server-utils";
|
|
2
|
+
import { type AnyTuple } from "@duplojs/utils";
|
|
3
|
+
import { ResponseContract } from "../../core/response";
|
|
4
|
+
import type { RoutePath } from "../../core/route";
|
|
5
|
+
import { type CacheControlDirectives } from "../cacheController/types";
|
|
6
|
+
interface MakeRouteFileParams {
|
|
7
|
+
readonly source: SF.FileInterface;
|
|
8
|
+
readonly path: RoutePath | AnyTuple<RoutePath>;
|
|
9
|
+
readonly cacheControlConfig?: CacheControlDirectives;
|
|
10
|
+
}
|
|
11
|
+
declare const MissingSelectedStaticFileError_base: new (params: {
|
|
12
|
+
"@DuplojsStaticPlugin/missing-selected-static-file"?: unknown;
|
|
13
|
+
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"@DuplojsStaticPlugin/missing-selected-static-file", unknown>, unknown> & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"missing-selected-static-file", unknown>, unknown>;
|
|
14
|
+
export declare class MissingSelectedStaticFileError extends MissingSelectedStaticFileError_base {
|
|
15
|
+
source: SF.FileInterface;
|
|
16
|
+
constructor(source: SF.FileInterface);
|
|
17
|
+
}
|
|
18
|
+
declare const SelectedStaticFileIsNotFileError_base: new (params: {
|
|
19
|
+
"@DuplojsStaticPlugin/selected-static-file-is-not-file"?: unknown;
|
|
20
|
+
}, parentParams: readonly [message?: string | undefined, options?: ErrorOptions | undefined]) => Error & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"@DuplojsStaticPlugin/selected-static-file-is-not-file", unknown>, unknown> & import("@duplojs/utils").Kind<import("@duplojs/utils").KindDefinition<"selected-static-file-is-not-file", unknown>, unknown>;
|
|
21
|
+
export declare class SelectedStaticFileIsNotFileError extends SelectedStaticFileIsNotFileError_base {
|
|
22
|
+
source: SF.FileInterface;
|
|
23
|
+
constructor(source: SF.FileInterface);
|
|
24
|
+
}
|
|
25
|
+
export declare function makeRouteFile(params: MakeRouteFileParams): import("../../core/route").Route<{
|
|
26
|
+
readonly method: "GET";
|
|
27
|
+
readonly metadata: readonly [import("../../core/metadata").Metadata<"ignore-by-route-store", unknown>];
|
|
28
|
+
readonly hooks: readonly [{
|
|
29
|
+
readonly beforeSendResponse: ({ currentResponse, next }: import("../../core/route").RouteHookParamsAfter<import("../../core/request").Request>) => import("../../core/route").RouteHookNext;
|
|
30
|
+
}];
|
|
31
|
+
readonly paths: readonly [`/${string}`] | AnyTuple<`/${string}`>;
|
|
32
|
+
readonly preflightSteps: readonly [];
|
|
33
|
+
readonly bodyController: null;
|
|
34
|
+
readonly steps: readonly [import("../../core/steps").HandlerStep<{
|
|
35
|
+
readonly responseContract: [NoInfer<ResponseContract.Contract<"200", "resource.found", SDP.DataParserFile<{
|
|
36
|
+
readonly mimeType?: RegExp | undefined;
|
|
37
|
+
readonly errorMessage?: string | undefined;
|
|
38
|
+
readonly coerce: boolean;
|
|
39
|
+
readonly minSize?: number | undefined;
|
|
40
|
+
readonly maxSize?: number | undefined;
|
|
41
|
+
readonly checkExist: boolean;
|
|
42
|
+
readonly checkers: readonly [];
|
|
43
|
+
}>>>, NoInfer<ResponseContract.Contract<"304", "resource.notModified", import("@duplojs/utils/dataParser").DataParserEmpty<import("@duplojs/utils/dataParser").DataParserDefinitionEmpty>>>];
|
|
44
|
+
theFunction(floor: {}, param: import("../../core/steps").HandlerStepFunctionParams<import("../../core/request").Request, import("../../core/response").PredictedResponse<"200", "resource.found", SF.FileInterface> | import("../../core/response").PredictedResponse<"304", "resource.notModified", undefined>>): import("@duplojs/utils").MaybePromise<import("../../core/response").PredictedResponse<"200", "resource.found", SF.FileInterface> | import("../../core/response").PredictedResponse<"304", "resource.notModified", undefined>>;
|
|
45
|
+
readonly metadata: readonly [];
|
|
46
|
+
}>];
|
|
47
|
+
}>;
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { SDP } from '@duplojs/server-utils';
|
|
2
|
+
import { kindHeritage, A, E, unwrap } from '@duplojs/utils';
|
|
3
|
+
import '../../core/builders/index.mjs';
|
|
4
|
+
import '../../core/metadata/index.mjs';
|
|
5
|
+
import '../../core/response/index.mjs';
|
|
6
|
+
import { createCacheControllerHooks } from '../cacheController/hooks.mjs';
|
|
7
|
+
import { createStaticPluginKind } from './kind.mjs';
|
|
8
|
+
import { useRouteBuilder } from '../../core/builders/route/builder.mjs';
|
|
9
|
+
import { IgnoreByRouteStoreMetadata } from '../../core/metadata/ignoreByRouteStore.mjs';
|
|
10
|
+
import { ResponseContract } from '../../core/response/contract.mjs';
|
|
11
|
+
|
|
12
|
+
class MissingSelectedStaticFileError extends kindHeritage("missing-selected-static-file", createStaticPluginKind("missing-selected-static-file"), Error) {
|
|
13
|
+
source;
|
|
14
|
+
constructor(source) {
|
|
15
|
+
super({}, [`Missing selected static file: ${source.path}.`]);
|
|
16
|
+
this.source = source;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
class SelectedStaticFileIsNotFileError extends kindHeritage("selected-static-file-is-not-file", createStaticPluginKind("selected-static-file-is-not-file"), Error) {
|
|
20
|
+
source;
|
|
21
|
+
constructor(source) {
|
|
22
|
+
super({}, [`Selected static file is not file: ${source.path}.`]);
|
|
23
|
+
this.source = source;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function makeRouteFile(params) {
|
|
27
|
+
const localPath = A.coalescing(params.path);
|
|
28
|
+
return useRouteBuilder("GET", localPath, {
|
|
29
|
+
metadata: [IgnoreByRouteStoreMetadata()],
|
|
30
|
+
hooks: [createCacheControllerHooks(params.cacheControlConfig)],
|
|
31
|
+
})
|
|
32
|
+
.handler([
|
|
33
|
+
ResponseContract.ok("resource.found", SDP.file()),
|
|
34
|
+
ResponseContract.notModified("resource.notModified"),
|
|
35
|
+
], async (__, { response, request }) => {
|
|
36
|
+
const sourceStatResult = await params.source.stat();
|
|
37
|
+
if (E.isLeft(sourceStatResult)) {
|
|
38
|
+
throw new MissingSelectedStaticFileError(params.source);
|
|
39
|
+
}
|
|
40
|
+
const resourceStat = unwrap(sourceStatResult);
|
|
41
|
+
if (!resourceStat.isFile) {
|
|
42
|
+
throw new SelectedStaticFileIsNotFileError(params.source);
|
|
43
|
+
}
|
|
44
|
+
if (request.headers["if-modified-since"]
|
|
45
|
+
&& typeof request.headers["if-modified-since"] === "string"
|
|
46
|
+
&& resourceStat.modifiedAt
|
|
47
|
+
&& new Date(request.headers["if-modified-since"]).getTime() >= resourceStat.modifiedAt.getTime()) {
|
|
48
|
+
return response("resource.notModified")
|
|
49
|
+
.setHeader("last-modified", resourceStat.modifiedAt.toISOString());
|
|
50
|
+
}
|
|
51
|
+
return resourceStat.modifiedAt
|
|
52
|
+
? response("resource.found", params.source)
|
|
53
|
+
.setHeader("last-modified", resourceStat.modifiedAt.toISOString())
|
|
54
|
+
: response("resource.found", params.source);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { MissingSelectedStaticFileError, SelectedStaticFileIsNotFileError, makeRouteFile };
|