@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,208 @@
|
|
|
1
|
+
import { pipe, sleep } from '@duplojs/utils';
|
|
2
|
+
import * as GG from '@duplojs/utils/generator';
|
|
3
|
+
import * as SS from '@duplojs/utils/string';
|
|
4
|
+
import * as AA from '@duplojs/utils/array';
|
|
5
|
+
import { launchStartServerEventHook, launchErrorServerEventHook, launchBeforeRetryServerEventHook, launchReceiveEventServerEventHook, launchCloseServerEventHook } from './hooks.mjs';
|
|
6
|
+
|
|
7
|
+
const closeReason = Symbol("CloseReason");
|
|
8
|
+
const endMessageRegexp = /\n\n|\r\r|\r\n\r\n/;
|
|
9
|
+
const eventPayloadRegexp = /^(?<field>event|data|id|retry|content-type): ?(?<value>.*)$/gm;
|
|
10
|
+
const validRetryRegexp = /^[0-9]+$/;
|
|
11
|
+
const nullIdRegexp = /\0|\n|\r/;
|
|
12
|
+
function makeClientEventsResponse(response, fetchUrl, fetchInitParams) {
|
|
13
|
+
let reader = response.raw.body?.getReader();
|
|
14
|
+
let abortController = response.requestParams.abortController;
|
|
15
|
+
const createEventResponse = (eventsReaderGenerator) => {
|
|
16
|
+
let closeServerEvent = undefined;
|
|
17
|
+
let beforeRetryServerEvent = undefined;
|
|
18
|
+
let errorServerEvent = undefined;
|
|
19
|
+
let startServerEvent = undefined;
|
|
20
|
+
let receiveEventServerEvent = undefined;
|
|
21
|
+
const eventResponse = {
|
|
22
|
+
...response,
|
|
23
|
+
closeEventStream: () => void abortController.abort(closeReason),
|
|
24
|
+
onReceiveEvent: (eventName, callback) => {
|
|
25
|
+
receiveEventServerEvent ??= [];
|
|
26
|
+
receiveEventServerEvent.push((receiveEvent) => receiveEvent.event === eventName
|
|
27
|
+
? callback(receiveEvent, eventResponse)
|
|
28
|
+
: undefined);
|
|
29
|
+
return eventResponse;
|
|
30
|
+
},
|
|
31
|
+
onStreamEvent: (event, callback) => {
|
|
32
|
+
if (event === "receiveServerEvents") {
|
|
33
|
+
receiveEventServerEvent ??= [];
|
|
34
|
+
receiveEventServerEvent.push(callback);
|
|
35
|
+
}
|
|
36
|
+
else if (event === "beforeRetry") {
|
|
37
|
+
beforeRetryServerEvent ??= [];
|
|
38
|
+
beforeRetryServerEvent.push(callback);
|
|
39
|
+
}
|
|
40
|
+
else if (event === "close") {
|
|
41
|
+
closeServerEvent ??= [];
|
|
42
|
+
closeServerEvent.push(callback);
|
|
43
|
+
}
|
|
44
|
+
else if (event === "start") {
|
|
45
|
+
startServerEvent ??= [];
|
|
46
|
+
startServerEvent.push(callback);
|
|
47
|
+
}
|
|
48
|
+
else if (event === "error") {
|
|
49
|
+
errorServerEvent ??= [];
|
|
50
|
+
errorServerEvent.push(callback);
|
|
51
|
+
}
|
|
52
|
+
return eventResponse;
|
|
53
|
+
},
|
|
54
|
+
async consumeEventStream() {
|
|
55
|
+
for await (const __ of eventResponse) { }
|
|
56
|
+
},
|
|
57
|
+
[Symbol.asyncIterator]: async function* () {
|
|
58
|
+
await launchStartServerEventHook(response.requestParams.hooks.startServerEvent, startServerEvent ?? [], eventResponse).catch(console.error);
|
|
59
|
+
const onError = (error) => launchErrorServerEventHook(response.requestParams.hooks.errorServerEvent, errorServerEvent ?? [], error, eventResponse).catch(console.error);
|
|
60
|
+
const generator = eventsReaderGenerator(onError, () => launchBeforeRetryServerEventHook(response.requestParams.hooks.beforeRetryServerEvent, beforeRetryServerEvent ?? [], eventResponse).catch(console.error));
|
|
61
|
+
try {
|
|
62
|
+
for await (const event of generator) {
|
|
63
|
+
await launchReceiveEventServerEventHook(response.requestParams.hooks.receiveEventServerEvent, receiveEventServerEvent ?? [], event, eventResponse).catch(console.error);
|
|
64
|
+
yield event;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
await launchCloseServerEventHook(response.requestParams.hooks.closeServerEvent, closeServerEvent ?? [], eventResponse).catch(console.error);
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
return eventResponse;
|
|
73
|
+
};
|
|
74
|
+
if (!reader
|
|
75
|
+
|| response.code === "204"
|
|
76
|
+
|| !response.headers.get("content-type")?.includes("text/event-stream")) {
|
|
77
|
+
return createEventResponse(async function* () { });
|
|
78
|
+
}
|
|
79
|
+
return createEventResponse((emitError, emitBeforeRetry) => {
|
|
80
|
+
let lastId = response.requestParams.headers?.["last-event-id"];
|
|
81
|
+
let retry = 3000;
|
|
82
|
+
return pipe(GG.asyncLoop(async ({ next, exit }) => {
|
|
83
|
+
try {
|
|
84
|
+
if (abortController.signal.aborted) {
|
|
85
|
+
return exit();
|
|
86
|
+
}
|
|
87
|
+
else if (reader) {
|
|
88
|
+
const chunk = await reader.read();
|
|
89
|
+
if (chunk.done) {
|
|
90
|
+
reader = undefined;
|
|
91
|
+
}
|
|
92
|
+
return next(chunk);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
abortController = new AbortController();
|
|
96
|
+
await sleep(retry);
|
|
97
|
+
await emitBeforeRetry();
|
|
98
|
+
const fetchResponse = await fetch(fetchUrl, {
|
|
99
|
+
...fetchInitParams,
|
|
100
|
+
headers: {
|
|
101
|
+
...fetchInitParams.headers,
|
|
102
|
+
...(typeof lastId === "string"
|
|
103
|
+
? { "last-event-id": lastId }
|
|
104
|
+
: undefined),
|
|
105
|
+
},
|
|
106
|
+
signal: abortController.signal,
|
|
107
|
+
});
|
|
108
|
+
const fetchInformation = fetchResponse.headers.get(response.requestParams.informationHeaderKey);
|
|
109
|
+
if (fetchResponse.status !== 204
|
|
110
|
+
&& fetchResponse.headers.get("content-type")?.includes("text/event-stream")
|
|
111
|
+
&& fetchResponse.body
|
|
112
|
+
&& ((fetchInformation === null
|
|
113
|
+
&& response.information === undefined)
|
|
114
|
+
|| fetchInformation === response.information)) {
|
|
115
|
+
reader = fetchResponse.body.getReader();
|
|
116
|
+
return next();
|
|
117
|
+
}
|
|
118
|
+
return exit();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (error !== closeReason) {
|
|
123
|
+
await emitError(error);
|
|
124
|
+
}
|
|
125
|
+
reader = undefined;
|
|
126
|
+
return next();
|
|
127
|
+
}
|
|
128
|
+
}), async function* (chunkGenerator) {
|
|
129
|
+
const decoder = new TextDecoder("utf-8");
|
|
130
|
+
let buffer = "";
|
|
131
|
+
for await (const chunk of chunkGenerator) {
|
|
132
|
+
buffer += decoder.decode(chunk.value, { stream: true });
|
|
133
|
+
if (SS.test(buffer, endMessageRegexp)) {
|
|
134
|
+
const events = SS.split(buffer, endMessageRegexp);
|
|
135
|
+
buffer = AA.last(events);
|
|
136
|
+
const restEvents = AA.pop(events);
|
|
137
|
+
for (const event of restEvents) {
|
|
138
|
+
yield event;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (chunk.done) {
|
|
142
|
+
buffer = "";
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}, async function* (chunkStringGenerator) {
|
|
146
|
+
for await (const stringChunk of chunkStringGenerator) {
|
|
147
|
+
const eventContent = GG.reduce(SS.extractAll(stringChunk, eventPayloadRegexp), GG.reduceFrom({}), ({ lastValue, element, next }) => {
|
|
148
|
+
const { field, value } = element.namedGroups;
|
|
149
|
+
if (field === "data") {
|
|
150
|
+
return next({
|
|
151
|
+
...lastValue,
|
|
152
|
+
data: lastValue.data === undefined
|
|
153
|
+
? value
|
|
154
|
+
: `${lastValue.data}\n${value}`,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
else if (field === "retry") {
|
|
158
|
+
const retry = SS.test(value, validRetryRegexp)
|
|
159
|
+
? parseInt(value, 10)
|
|
160
|
+
: undefined;
|
|
161
|
+
return next({
|
|
162
|
+
...lastValue,
|
|
163
|
+
retry: typeof retry === "number" && !isNaN(retry)
|
|
164
|
+
? retry
|
|
165
|
+
: undefined,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
else if (field === "id") {
|
|
169
|
+
return next({
|
|
170
|
+
...lastValue,
|
|
171
|
+
id: !SS.test(value, nullIdRegexp)
|
|
172
|
+
? value
|
|
173
|
+
: undefined,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return next({
|
|
177
|
+
...lastValue,
|
|
178
|
+
[field]: value,
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
if (typeof eventContent.id === "string") {
|
|
182
|
+
lastId = eventContent.id;
|
|
183
|
+
}
|
|
184
|
+
if (typeof eventContent.retry === "number") {
|
|
185
|
+
retry = eventContent.retry;
|
|
186
|
+
}
|
|
187
|
+
if (eventContent.data === undefined) {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
yield {
|
|
192
|
+
event: eventContent.event || "message",
|
|
193
|
+
data: eventContent["content-type"]?.includes("application/json")
|
|
194
|
+
? JSON.parse(eventContent.data)
|
|
195
|
+
: eventContent.data,
|
|
196
|
+
id: eventContent.id,
|
|
197
|
+
retry: eventContent.retry,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
await emitError(error);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export { makeClientEventsResponse };
|
|
@@ -21,6 +21,7 @@ export interface ClientRequestParams<GenericHookParams extends Record<string, un
|
|
|
21
21
|
params?: ClientRequestParamsParams;
|
|
22
22
|
query?: ClientRequestParamsQuery;
|
|
23
23
|
body?: ClientRequestParamsBody;
|
|
24
|
+
abortController?: AbortController;
|
|
24
25
|
initParams?: ClientRequestInitParams;
|
|
25
26
|
hookParams?: GenericHookParams;
|
|
26
27
|
}
|
|
@@ -43,6 +44,7 @@ type MaybeParams<GenericParams extends object> = {
|
|
|
43
44
|
export type ServerRouteToClientRequestParams<GenericServerRoute extends ServerRoute = ServerRoute, GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = GenericServerRoute extends any ? SimplifyTopLevel<({
|
|
44
45
|
method: GenericServerRoute["method"];
|
|
45
46
|
path: GenericServerRoute["path"];
|
|
47
|
+
abortController?: AbortController;
|
|
46
48
|
initParams?: ClientRequestInitParams;
|
|
47
49
|
hookParams?: GenericHookParams;
|
|
48
50
|
} & MaybeParams<(IsEqual<GenericServerRoute["headers"], unknown> extends true ? {} : {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as SS from "@duplojs/utils/string";
|
|
2
2
|
import { type ServerRouteResponse, type ServerRoute } from "./serverRoute";
|
|
3
|
-
import { type IsEqual, type SimplifyTopLevel } from "@duplojs/utils";
|
|
3
|
+
import { type MaybePromise, type IsEqual, type SimplifyTopLevel, type NeverCoalescing } from "@duplojs/utils";
|
|
4
4
|
import { type PromiseRequestParams } from "./promiseRequestParams";
|
|
5
5
|
export type ClientResponseBody = unknown;
|
|
6
6
|
export interface ClientResponse<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> {
|
|
@@ -16,10 +16,34 @@ export interface ClientResponse<GenericHookParams extends Record<string, unknown
|
|
|
16
16
|
requestParams: PromiseRequestParams<GenericHookParams>;
|
|
17
17
|
predicted: boolean;
|
|
18
18
|
}
|
|
19
|
+
export interface ServerEvent {
|
|
20
|
+
data: unknown;
|
|
21
|
+
event: string;
|
|
22
|
+
id?: string;
|
|
23
|
+
retry?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface ClientEventsResponseHandler<GenericServerEvent extends ServerEvent = ServerEvent> extends AsyncIterable<GenericServerEvent, void> {
|
|
26
|
+
closeEventStream(): void;
|
|
27
|
+
onReceiveEvent<GenericEventName extends GenericServerEvent["event"]>(name: GenericEventName, callback: (event: NeverCoalescing<Extract<GenericServerEvent, {
|
|
28
|
+
event: GenericEventName;
|
|
29
|
+
}>, ServerEvent>, response: this) => MaybePromise<void>): this;
|
|
30
|
+
onStreamEvent(event: "close", callback: (response: this) => MaybePromise<void>): this;
|
|
31
|
+
onStreamEvent(event: "beforeRetry", callback: (response: this) => MaybePromise<void>): this;
|
|
32
|
+
onStreamEvent(event: "error", callback: (error: unknown, response: this) => MaybePromise<void>): this;
|
|
33
|
+
onStreamEvent(event: "start", callback: (response: this) => MaybePromise<void>): this;
|
|
34
|
+
onStreamEvent(event: "receiveServerEvents", callback: (event: GenericServerEvent, response: this) => MaybePromise<void>): this;
|
|
35
|
+
consumeEventStream(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
export interface ClientEventsResponse<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> extends ClientResponse<GenericHookParams>, ClientEventsResponseHandler {
|
|
38
|
+
}
|
|
39
|
+
export type AllClientResponse<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (ClientResponse<GenericHookParams> | ClientEventsResponse<GenericHookParams>);
|
|
19
40
|
export interface NotPredictedClientResponse<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> extends ClientResponse<GenericHookParams> {
|
|
20
41
|
predicted: false;
|
|
21
42
|
}
|
|
22
|
-
export
|
|
43
|
+
export interface NotPredictedClientEventsResponse<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> extends NotPredictedClientResponse<GenericHookParams>, ClientEventsResponseHandler {
|
|
44
|
+
}
|
|
45
|
+
export type AllNotPredictedClientResponse<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (NotPredictedClientResponse<GenericHookParams> | NotPredictedClientEventsResponse<GenericHookParams>);
|
|
46
|
+
export type ServerRouteToClientResponse<GenericServerRoute extends ServerRoute = ServerRoute, GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = GenericServerRoute extends any ? GenericServerRoute["responses"] extends infer InferredResponse ? InferredResponse extends ServerRouteResponse ? (SimplifyTopLevel<{
|
|
23
47
|
code: InferredResponse["code"];
|
|
24
48
|
information: InferredResponse["information"];
|
|
25
49
|
body: IsEqual<InferredResponse["body"], File> extends true ? undefined : InferredResponse["body"];
|
|
@@ -31,4 +55,11 @@ export type ServerRouteToClientResponse<GenericServerRoute extends ServerRoute =
|
|
|
31
55
|
raw: globalThis.Response;
|
|
32
56
|
requestParams: PromiseRequestParams<GenericHookParams>;
|
|
33
57
|
predicted: boolean;
|
|
34
|
-
}>
|
|
58
|
+
}> & (IsEqual<InferredResponse["events"], unknown> extends true ? unknown : InferredResponse["events"] extends object ? ClientEventsResponseHandler<{
|
|
59
|
+
[EventName in keyof InferredResponse["events"]]: EventName extends string ? {
|
|
60
|
+
event: EventName;
|
|
61
|
+
data: InferredResponse["events"][EventName];
|
|
62
|
+
id?: string;
|
|
63
|
+
retry?: number;
|
|
64
|
+
} : never;
|
|
65
|
+
}[keyof InferredResponse["events"]]> : unknown)) extends infer InferredResult extends ClientResponse ? InferredResult : never : never : never : never;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { type MaybePromise } from "@duplojs/utils";
|
|
2
|
-
import { type
|
|
2
|
+
import { type ClientEventsResponse, type ServerEvent, type AllClientResponse, type AllNotPredictedClientResponse } from "./clientResponse";
|
|
3
3
|
import { type PromiseRequestParams } from "./promiseRequestParams";
|
|
4
4
|
export type RequestHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (requestParams: PromiseRequestParams<GenericHookParams>) => MaybePromise<PromiseRequestParams<GenericHookParams>>;
|
|
5
|
-
export type ResponseHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response:
|
|
6
|
-
export type InformationHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response:
|
|
7
|
-
export type ResponseTypeHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response:
|
|
8
|
-
export type ExpectedResponseHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response:
|
|
9
|
-
export type CodeHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response:
|
|
10
|
-
export type NotPredictedResponseHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response:
|
|
5
|
+
export type ResponseHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response: AllClientResponse<GenericHookParams>) => MaybePromise<AllClientResponse<GenericHookParams>>;
|
|
6
|
+
export type InformationHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response: AllClientResponse<GenericHookParams>) => MaybePromise<void>;
|
|
7
|
+
export type ResponseTypeHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response: AllClientResponse<GenericHookParams>) => MaybePromise<void>;
|
|
8
|
+
export type ExpectedResponseHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response: AllClientResponse<GenericHookParams>) => MaybePromise<void>;
|
|
9
|
+
export type CodeHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response: AllClientResponse<GenericHookParams>) => MaybePromise<void>;
|
|
10
|
+
export type NotPredictedResponseHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response: AllNotPredictedClientResponse<GenericHookParams>) => MaybePromise<void>;
|
|
11
11
|
export type ErrorHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (error: unknown, requestParams: PromiseRequestParams<GenericHookParams>) => MaybePromise<void>;
|
|
12
|
+
export type CloseServerEventHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response: ClientEventsResponse<GenericHookParams>) => MaybePromise<void>;
|
|
13
|
+
export type BeforeRetryServerEventHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response: ClientEventsResponse<GenericHookParams>) => MaybePromise<void>;
|
|
14
|
+
export type ErrorServerEventHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (error: unknown, response: ClientEventsResponse<GenericHookParams>) => MaybePromise<void>;
|
|
15
|
+
export type StartServerEventHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (response: ClientEventsResponse<GenericHookParams>) => MaybePromise<void>;
|
|
16
|
+
export type ReceiveEventServerEventHook<GenericHookParams extends Record<string, unknown> = Record<string, unknown>> = (event: ServerEvent, response: ClientEventsResponse<GenericHookParams>) => MaybePromise<void>;
|
|
12
17
|
export interface Hooks {
|
|
13
18
|
request: RequestHook[];
|
|
14
19
|
response: ResponseHook[];
|
|
@@ -22,4 +27,9 @@ export interface Hooks {
|
|
|
22
27
|
expectedResponse: ExpectedResponseHook[];
|
|
23
28
|
notPredictedResponse: NotPredictedResponseHook[];
|
|
24
29
|
error: ErrorHook[];
|
|
30
|
+
closeServerEvent: CloseServerEventHook[];
|
|
31
|
+
beforeRetryServerEvent: BeforeRetryServerEventHook[];
|
|
32
|
+
errorServerEvent: ErrorServerEventHook[];
|
|
33
|
+
startServerEvent: StartServerEventHook[];
|
|
34
|
+
receiveEventServerEvent: ReceiveEventServerEventHook[];
|
|
25
35
|
}
|
|
@@ -12,10 +12,12 @@ export type ServerRouteQuery = Record<string, MaybeArray<ServerPrimitiveData | {
|
|
|
12
12
|
}>>;
|
|
13
13
|
export type ServerRouteBody = unknown;
|
|
14
14
|
export type ServerRouteResponseBody = unknown;
|
|
15
|
+
export type ServerRouteResponseEvents = Record<string, unknown>;
|
|
15
16
|
export interface ServerRouteResponse {
|
|
16
17
|
code: SS.Number;
|
|
17
18
|
information?: string;
|
|
18
19
|
body?: ServerRouteResponseBody;
|
|
20
|
+
events?: ServerRouteResponseEvents;
|
|
19
21
|
}
|
|
20
22
|
export interface ServerRoute {
|
|
21
23
|
path: string;
|
|
@@ -2,12 +2,15 @@ import { type Floor } from "../../floor";
|
|
|
2
2
|
import { type ResponseContract } from "../../response";
|
|
3
3
|
import { type Route, type RouteDefinition } from "../../route";
|
|
4
4
|
import { type HandlerStep, type HandlerStepFunctionParams } from "../../steps";
|
|
5
|
-
import { type MaybePromise, type
|
|
5
|
+
import { type MaybePromise, type O } from "@duplojs/utils";
|
|
6
6
|
import { type Request } from "../../request";
|
|
7
7
|
import { type Metadata } from "../../metadata";
|
|
8
8
|
declare module "./builder" {
|
|
9
9
|
interface RouteBuilder<GenericDefinition extends RouteDefinition = RouteDefinition, GenericFloor extends Floor = {}, GenericRequest extends Request = Request> {
|
|
10
|
-
handler<GenericResponseContract extends (ResponseContract.Contract |
|
|
10
|
+
handler<GenericResponseContract extends (ResponseContract.Contract | ResponseContract.ServerSentEventsContract | readonly [
|
|
11
|
+
(ResponseContract.Contract | ResponseContract.ServerSentEventsContract),
|
|
12
|
+
...(ResponseContract.Contract | ResponseContract.ServerSentEventsContract)[]
|
|
13
|
+
]), GenericResponse extends ResponseContract.Convert<GenericResponseContract extends readonly any[] ? GenericResponseContract[number] : GenericResponseContract>, const GenericMetadata extends readonly Metadata[] = readonly []>(responseContract: GenericResponseContract, theFunction: (floor: GenericFloor, param: HandlerStepFunctionParams<GenericRequest, GenericResponse>) => MaybePromise<GenericResponse>, ...metadata: GenericMetadata): Route<O.AssignObjects<GenericDefinition, {
|
|
11
14
|
readonly steps: readonly [
|
|
12
15
|
...GenericDefinition["steps"],
|
|
13
16
|
HandlerStep<{
|
|
@@ -1,33 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var utils = require('@duplojs/utils');
|
|
4
|
-
|
|
4
|
+
require('@duplojs/utils/clean');
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
utils.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
: dataParser, (dataParser) => typeof definition.inArray === "object"
|
|
16
|
-
&& typeof definition.inArray.max === "number"
|
|
17
|
-
? dataParser.addChecker(utils.DP.checkerArrayMax(definition.inArray.max))
|
|
18
|
-
: dataParser);
|
|
19
|
-
}
|
|
20
|
-
return dataParser;
|
|
21
|
-
}, (dataParser) => definition.nullable === true
|
|
22
|
-
? utils.DP.nullable(dataParser)
|
|
23
|
-
: dataParser)));
|
|
24
|
-
}
|
|
25
|
-
clean.createEntity.overrideHandler.setMethod("toExtractParser", (self, keys) => utils.pipe(self.propertiesDefinition, utils.O.entries, utils.A.filter(([key]) => keys === undefined || utils.A.includes(keys, key)), utils.A.map(([key, value]) => utils.O.entry(key, propertiesDefinitionToSchema(value, "toExtractParser"))), utils.O.fromEntries, utils.DPE.object));
|
|
26
|
-
clean.createEntity.overrideHandler.setMethod("toEndpointSchema", (self, keys, params) => utils.pipe(self.propertiesDefinition, utils.O.entries, utils.A.filter(([key]) => keys === undefined || utils.A.includes(keys, key)), utils.A.map(([key, value]) => utils.O.entry(key, propertiesDefinitionToSchema(value, "toEndpointSchema"))), utils.O.fromEntries, (shape) => typeof params?.addEntityName !== "undefined"
|
|
27
|
-
? {
|
|
28
|
-
...shape,
|
|
29
|
-
_entityName: typeof params.addEntityName === "string"
|
|
30
|
-
? utils.DP.literal(`${self.name}/${params.addEntityName}`)
|
|
31
|
-
: utils.DP.literal(self.name),
|
|
6
|
+
utils.C.createEntity.overrideHandler.setMethod("toExtractParser", (self, keys) => {
|
|
7
|
+
if (typeof keys === "string") {
|
|
8
|
+
return utils.C.entityPropertyDefinitionToDataParser(self.propertiesDefinition[keys], (newTypeHandler) => newTypeHandler.toExtractParser());
|
|
9
|
+
}
|
|
10
|
+
return utils.pipe(self.propertiesDefinition, utils.O.entries, utils.A.filter(([key]) => keys === undefined || utils.A.includes(keys, key)), utils.A.map(([key, value]) => utils.O.entry(key, utils.C.entityPropertyDefinitionToDataParser(value, (newTypeHandler) => newTypeHandler.toExtractParser()))), utils.O.fromEntries, utils.DPE.object);
|
|
11
|
+
});
|
|
12
|
+
utils.C.createEntity.overrideHandler.setMethod("toEndpointSchema", (self, keys, params) => {
|
|
13
|
+
if (typeof keys === "string") {
|
|
14
|
+
return utils.C.entityPropertyDefinitionToDataParser(self.propertiesDefinition[keys], (newTypeHandler) => newTypeHandler.toEndpointSchema());
|
|
32
15
|
}
|
|
33
|
-
|
|
16
|
+
return utils.pipe(self.propertiesDefinition, utils.O.entries, utils.A.filter(([key]) => keys === undefined || utils.A.includes(keys, key)), utils.A.map(([key, value]) => utils.O.entry(key, utils.C.entityPropertyDefinitionToDataParser(value, (newTypeHandler) => newTypeHandler.toEndpointSchema()))), utils.O.fromEntries, (shape) => typeof params?.addEntityName !== "undefined"
|
|
17
|
+
? {
|
|
18
|
+
...shape,
|
|
19
|
+
_entityName: typeof params.addEntityName === "string"
|
|
20
|
+
? utils.DP.literal(`${self.name}/${params.addEntityName}`)
|
|
21
|
+
: utils.DP.literal(self.name),
|
|
22
|
+
}
|
|
23
|
+
: shape, utils.DPE.object);
|
|
24
|
+
});
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { DP, DPE, type IsEqual, type SimplifyTopLevel, type IsExtends } from "@duplojs/utils";
|
|
2
|
-
import
|
|
1
|
+
import { DP, DPE, type IsEqual, type SimplifyTopLevel, type IsExtends, C, type MaybeArray } from "@duplojs/utils";
|
|
2
|
+
import "@duplojs/utils/clean";
|
|
3
3
|
interface ToEndpointSchemaParams {
|
|
4
4
|
addEntityName?: boolean | string;
|
|
5
5
|
}
|
|
6
6
|
declare module "@duplojs/utils/clean" {
|
|
7
|
-
interface EntityHandler<GenericName extends string = string, GenericPropertiesDefinition extends EntityPropertiesDefinition = EntityPropertiesDefinition> {
|
|
8
|
-
toExtractParser<GenericEntityProperties extends EntityProperties<GenericPropertiesDefinition>, const GenericKey extends keyof GenericEntityProperties = keyof GenericEntityProperties>(keys?: GenericKey
|
|
9
|
-
[Prop in GenericKey]: DP.Contract<GenericEntityProperties[Prop], unknown>;
|
|
10
|
-
}
|
|
11
|
-
toEndpointSchema<GenericEntityRawProperties extends EntityRawProperties<GenericPropertiesDefinition>, const GenericKey extends keyof GenericEntityRawProperties = keyof GenericEntityRawProperties, const GenericParams extends ToEndpointSchemaParams = {}>(keys?: GenericKey
|
|
12
|
-
[Prop in GenericKey]: DP.Contract<GenericEntityRawProperties[Prop], unknown>;
|
|
7
|
+
interface EntityHandler<GenericName extends string = string, GenericPropertiesDefinition extends C.EntityPropertiesDefinition = C.EntityPropertiesDefinition> {
|
|
8
|
+
toExtractParser<GenericEntityProperties extends C.EntityProperties<GenericPropertiesDefinition>, const GenericKey extends MaybeArray<keyof GenericEntityProperties> = readonly (keyof GenericEntityProperties)[]>(keys?: GenericKey): GenericKey extends readonly any[] ? ReturnType<typeof DPE.object<SimplifyTopLevel<{
|
|
9
|
+
[Prop in GenericKey[number]]: DP.Contract<GenericEntityProperties[Prop], unknown>;
|
|
10
|
+
}>>> : DP.Contract<GenericEntityProperties[Extract<GenericKey, string>], unknown>;
|
|
11
|
+
toEndpointSchema<GenericEntityRawProperties extends C.EntityRawProperties<GenericPropertiesDefinition>, const GenericKey extends MaybeArray<keyof GenericEntityRawProperties> = readonly (keyof GenericEntityRawProperties)[], const GenericParams extends (ToEndpointSchemaParams) = {}>(keys?: GenericKey, params?: (GenericParams | ToEndpointSchemaParams) & (GenericKey extends string ? never : unknown)): GenericKey extends readonly any[] ? ReturnType<typeof DPE.object<SimplifyTopLevel<{
|
|
12
|
+
[Prop in GenericKey[number]]: DP.Contract<GenericEntityRawProperties[Prop], unknown>;
|
|
13
13
|
} & (IsEqual<GenericParams["addEntityName"], true> extends true ? {
|
|
14
14
|
[Prop in "_entityName"]: DP.Contract<GenericName, unknown>;
|
|
15
15
|
} : {}) & (IsExtends<GenericParams["addEntityName"], string> extends true ? {
|
|
16
16
|
[Prop in "_entityName"]: DP.Contract<`${GenericName}/${GenericParams["addEntityName"]}`, unknown>;
|
|
17
|
-
} : {})
|
|
17
|
+
} : {})>>> : DP.Contract<GenericEntityRawProperties[Extract<GenericKey, string>], unknown>;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
export {};
|
|
@@ -1,31 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { C, pipe, O, A, DPE, DP } from '@duplojs/utils';
|
|
2
|
+
import '@duplojs/utils/clean';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
: dataParser, (dataParser) => typeof definition.inArray === "object"
|
|
14
|
-
&& typeof definition.inArray.max === "number"
|
|
15
|
-
? dataParser.addChecker(DP.checkerArrayMax(definition.inArray.max))
|
|
16
|
-
: dataParser);
|
|
17
|
-
}
|
|
18
|
-
return dataParser;
|
|
19
|
-
}, (dataParser) => definition.nullable === true
|
|
20
|
-
? DP.nullable(dataParser)
|
|
21
|
-
: dataParser)));
|
|
22
|
-
}
|
|
23
|
-
createEntity.overrideHandler.setMethod("toExtractParser", (self, keys) => pipe(self.propertiesDefinition, O.entries, A.filter(([key]) => keys === undefined || A.includes(keys, key)), A.map(([key, value]) => O.entry(key, propertiesDefinitionToSchema(value, "toExtractParser"))), O.fromEntries, DPE.object));
|
|
24
|
-
createEntity.overrideHandler.setMethod("toEndpointSchema", (self, keys, params) => pipe(self.propertiesDefinition, O.entries, A.filter(([key]) => keys === undefined || A.includes(keys, key)), A.map(([key, value]) => O.entry(key, propertiesDefinitionToSchema(value, "toEndpointSchema"))), O.fromEntries, (shape) => typeof params?.addEntityName !== "undefined"
|
|
25
|
-
? {
|
|
26
|
-
...shape,
|
|
27
|
-
_entityName: typeof params.addEntityName === "string"
|
|
28
|
-
? DP.literal(`${self.name}/${params.addEntityName}`)
|
|
29
|
-
: DP.literal(self.name),
|
|
4
|
+
C.createEntity.overrideHandler.setMethod("toExtractParser", (self, keys) => {
|
|
5
|
+
if (typeof keys === "string") {
|
|
6
|
+
return C.entityPropertyDefinitionToDataParser(self.propertiesDefinition[keys], (newTypeHandler) => newTypeHandler.toExtractParser());
|
|
7
|
+
}
|
|
8
|
+
return pipe(self.propertiesDefinition, O.entries, A.filter(([key]) => keys === undefined || A.includes(keys, key)), A.map(([key, value]) => O.entry(key, C.entityPropertyDefinitionToDataParser(value, (newTypeHandler) => newTypeHandler.toExtractParser()))), O.fromEntries, DPE.object);
|
|
9
|
+
});
|
|
10
|
+
C.createEntity.overrideHandler.setMethod("toEndpointSchema", (self, keys, params) => {
|
|
11
|
+
if (typeof keys === "string") {
|
|
12
|
+
return C.entityPropertyDefinitionToDataParser(self.propertiesDefinition[keys], (newTypeHandler) => newTypeHandler.toEndpointSchema());
|
|
30
13
|
}
|
|
31
|
-
|
|
14
|
+
return pipe(self.propertiesDefinition, O.entries, A.filter(([key]) => keys === undefined || A.includes(keys, key)), A.map(([key, value]) => O.entry(key, C.entityPropertyDefinitionToDataParser(value, (newTypeHandler) => newTypeHandler.toEndpointSchema()))), O.fromEntries, (shape) => typeof params?.addEntityName !== "undefined"
|
|
15
|
+
? {
|
|
16
|
+
...shape,
|
|
17
|
+
_entityName: typeof params.addEntityName === "string"
|
|
18
|
+
? DP.literal(`${self.name}/${params.addEntityName}`)
|
|
19
|
+
: DP.literal(self.name),
|
|
20
|
+
}
|
|
21
|
+
: shape, DPE.object);
|
|
22
|
+
});
|
|
@@ -5,6 +5,7 @@ require('../route/index.cjs');
|
|
|
5
5
|
var serverUtils = require('@duplojs/server-utils');
|
|
6
6
|
var hooks = require('../route/hooks.cjs');
|
|
7
7
|
var predicted = require('../response/predicted.cjs');
|
|
8
|
+
var serverSentEventsPredicted = require('../response/serverSentEventsPredicted.cjs');
|
|
8
9
|
var hook = require('../response/hook.cjs');
|
|
9
10
|
|
|
10
11
|
function initDefaultHook(hub, serverParams) {
|
|
@@ -39,6 +40,13 @@ function initDefaultHook(hub, serverParams) {
|
|
|
39
40
|
if (currentResponse instanceof predicted.PredictedResponse) {
|
|
40
41
|
currentResponse.setHeader(predictedHeaderKey, "1");
|
|
41
42
|
}
|
|
43
|
+
else if (currentResponse instanceof serverSentEventsPredicted.ServerSentEventsPredictedResponse) {
|
|
44
|
+
currentResponse.setHeader(predictedHeaderKey, "1");
|
|
45
|
+
currentResponse.setHeader("transfer-encoding", "chunked");
|
|
46
|
+
currentResponse.setHeader("content-type", "text/event-stream");
|
|
47
|
+
currentResponse.setHeader("cache-control", "no-cache");
|
|
48
|
+
currentResponse.setHeader("connection", "keep-alive");
|
|
49
|
+
}
|
|
42
50
|
else if (currentResponse instanceof hook.HookResponse) {
|
|
43
51
|
currentResponse.setHeader(fromHookHeaderKey, currentResponse.fromHook);
|
|
44
52
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Hub } from "../hub";
|
|
2
2
|
import { type HttpServerParams } from "../types";
|
|
3
3
|
export declare function initDefaultHook(hub: Hub, serverParams: HttpServerParams): {
|
|
4
|
-
beforeSendResponse({ currentResponse, next }: import("../route").RouteHookParamsAfter<import("..").Request>)
|
|
4
|
+
readonly beforeSendResponse: ({ currentResponse, next }: import("../route").RouteHookParamsAfter<import("..").Request>) => import("../route").RouteHookNext;
|
|
5
5
|
};
|
|
@@ -3,6 +3,7 @@ import '../route/index.mjs';
|
|
|
3
3
|
import { SF } from '@duplojs/server-utils';
|
|
4
4
|
import { createHookRouteLifeCycle } from '../route/hooks.mjs';
|
|
5
5
|
import { PredictedResponse } from '../response/predicted.mjs';
|
|
6
|
+
import { ServerSentEventsPredictedResponse } from '../response/serverSentEventsPredicted.mjs';
|
|
6
7
|
import { HookResponse } from '../response/hook.mjs';
|
|
7
8
|
|
|
8
9
|
function initDefaultHook(hub, serverParams) {
|
|
@@ -37,6 +38,13 @@ function initDefaultHook(hub, serverParams) {
|
|
|
37
38
|
if (currentResponse instanceof PredictedResponse) {
|
|
38
39
|
currentResponse.setHeader(predictedHeaderKey, "1");
|
|
39
40
|
}
|
|
41
|
+
else if (currentResponse instanceof ServerSentEventsPredictedResponse) {
|
|
42
|
+
currentResponse.setHeader(predictedHeaderKey, "1");
|
|
43
|
+
currentResponse.setHeader("transfer-encoding", "chunked");
|
|
44
|
+
currentResponse.setHeader("content-type", "text/event-stream");
|
|
45
|
+
currentResponse.setHeader("cache-control", "no-cache");
|
|
46
|
+
currentResponse.setHeader("connection", "keep-alive");
|
|
47
|
+
}
|
|
40
48
|
else if (currentResponse instanceof HookResponse) {
|
|
41
49
|
currentResponse.setHeader(fromHookHeaderKey, currentResponse.fromHook);
|
|
42
50
|
}
|
|
@@ -9,6 +9,7 @@ require('../steps/index.cjs');
|
|
|
9
9
|
var processStep = require('../steps/defaults/processStep.cjs');
|
|
10
10
|
var base = require('../../response/base.cjs');
|
|
11
11
|
var hook$1 = require('../../response/hook.cjs');
|
|
12
|
+
var hooks = require('../../route/hooks.cjs');
|
|
12
13
|
|
|
13
14
|
/* eslint-disable @typescript-eslint/prefer-for-of */
|
|
14
15
|
const defaultRouteFunctionBuilder = create.createRouteFunctionBuilder(index.routeKind.has, async (route, { success, buildStep, globalHooksRouteLifeCycle, }) => {
|
|
@@ -35,7 +36,7 @@ const defaultRouteFunctionBuilder = create.createRouteFunctionBuilder(index.rout
|
|
|
35
36
|
const hookOnConstructRequest = utils.pipe(allHooks, utils.A.map(({ onConstructRequest }) => onConstructRequest), utils.A.filter(utils.isType("function")), utils.forward);
|
|
36
37
|
const hookError = utils.pipe(allHooks, utils.A.map(({ error }) => error), utils.A.filter(utils.isType("function")), utils.forward);
|
|
37
38
|
const hookSendResponse = utils.pipe(allHooks, utils.A.map(({ sendResponse }) => sendResponse), utils.A.filter(utils.isType("function")), utils.forward);
|
|
38
|
-
const hooks = {
|
|
39
|
+
const hooks$1 = {
|
|
39
40
|
afterSendResponse: hook.buildHookAfter(hookAfterSendResponse),
|
|
40
41
|
beforeRouteExecution: hook.buildHookBefore(hookBeforeRouteExecution),
|
|
41
42
|
beforeSendResponse: hook.buildHookAfter(hookBeforeSendResponse),
|
|
@@ -56,7 +57,7 @@ const defaultRouteFunctionBuilder = create.createRouteFunctionBuilder(index.rout
|
|
|
56
57
|
};
|
|
57
58
|
async function routeExecution(request) {
|
|
58
59
|
try {
|
|
59
|
-
const beforeRouteExecutionResult = await hooks.beforeRouteExecution({
|
|
60
|
+
const beforeRouteExecutionResult = await hooks$1.beforeRouteExecution({
|
|
60
61
|
request,
|
|
61
62
|
exit: hook.exitHookFunction,
|
|
62
63
|
next: hook.nextHookFunction,
|
|
@@ -83,7 +84,7 @@ const defaultRouteFunctionBuilder = create.createRouteFunctionBuilder(index.rout
|
|
|
83
84
|
return new base.Response("500", "missing-response", undefined);
|
|
84
85
|
}
|
|
85
86
|
catch (error) {
|
|
86
|
-
const errorResult = await hooks.error({
|
|
87
|
+
const errorResult = await hooks$1.error({
|
|
87
88
|
request,
|
|
88
89
|
error,
|
|
89
90
|
exit: hook.exitHookFunction,
|
|
@@ -97,14 +98,9 @@ const defaultRouteFunctionBuilder = create.createRouteFunctionBuilder(index.rout
|
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
100
|
return success(async (request) => {
|
|
100
|
-
const currentRequest = await hooks.onConstructRequest({
|
|
101
|
+
const currentRequest = await hooks$1.onConstructRequest({
|
|
101
102
|
request,
|
|
102
|
-
addRequestProperties: (
|
|
103
|
-
for (const key in newProperties) {
|
|
104
|
-
request[key] = newProperties[key];
|
|
105
|
-
}
|
|
106
|
-
return request;
|
|
107
|
-
},
|
|
103
|
+
addRequestProperties: hooks.hookRouteLifeCycleAddRequestProperties(request),
|
|
108
104
|
});
|
|
109
105
|
const currentResponse = await routeExecution(currentRequest);
|
|
110
106
|
const afterHookParams = {
|
|
@@ -113,9 +109,9 @@ const defaultRouteFunctionBuilder = create.createRouteFunctionBuilder(index.rout
|
|
|
113
109
|
exit: hook.exitHookFunction,
|
|
114
110
|
next: hook.nextHookFunction,
|
|
115
111
|
};
|
|
116
|
-
await hooks.beforeSendResponse(afterHookParams);
|
|
117
|
-
await hooks.sendResponse(afterHookParams);
|
|
118
|
-
await hooks.afterSendResponse(afterHookParams);
|
|
112
|
+
await hooks$1.beforeSendResponse(afterHookParams);
|
|
113
|
+
await hooks$1.sendResponse(afterHookParams);
|
|
114
|
+
await hooks$1.afterSendResponse(afterHookParams);
|
|
119
115
|
});
|
|
120
116
|
});
|
|
121
117
|
|