@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.
Files changed (154) hide show
  1. package/dist/client/getBody.cjs +3 -3
  2. package/dist/client/getBody.mjs +3 -3
  3. package/dist/client/hooks.cjs +45 -0
  4. package/dist/client/hooks.d.ts +6 -1
  5. package/dist/client/hooks.mjs +41 -1
  6. package/dist/client/httpClient.cjs +25 -1
  7. package/dist/client/httpClient.d.ts +8 -3
  8. package/dist/client/httpClient.mjs +25 -1
  9. package/dist/client/index.cjs +7 -0
  10. package/dist/client/index.d.ts +1 -0
  11. package/dist/client/index.mjs +2 -1
  12. package/dist/client/insertParamsInPath.cjs +1 -1
  13. package/dist/client/insertParamsInPath.mjs +1 -1
  14. package/dist/client/promiseRequest.cjs +83 -26
  15. package/dist/client/promiseRequest.d.ts +46 -29
  16. package/dist/client/promiseRequest.mjs +83 -26
  17. package/dist/client/queryToString.cjs +1 -1
  18. package/dist/client/queryToString.mjs +1 -1
  19. package/dist/client/serverSentEvents.cjs +231 -0
  20. package/dist/client/serverSentEvents.d.ts +2 -0
  21. package/dist/client/serverSentEvents.mjs +208 -0
  22. package/dist/client/types/clientRequestParams.d.ts +2 -0
  23. package/dist/client/types/clientResponse.d.ts +34 -3
  24. package/dist/client/types/hooks.d.ts +17 -7
  25. package/dist/client/types/promiseRequestParams.d.ts +1 -0
  26. package/dist/client/types/serverRoute.d.ts +2 -0
  27. package/dist/core/builders/route/handler.d.ts +5 -2
  28. package/dist/core/defaultHooks/index.cjs +8 -0
  29. package/dist/core/defaultHooks/index.d.ts +1 -1
  30. package/dist/core/defaultHooks/index.mjs +8 -0
  31. package/dist/core/functionsBuilders/route/default.cjs +9 -13
  32. package/dist/core/functionsBuilders/route/default.mjs +2 -6
  33. package/dist/core/functionsBuilders/steps/create.d.ts +2 -2
  34. package/dist/core/functionsBuilders/steps/defaults/cutStep.cjs +1 -1
  35. package/dist/core/functionsBuilders/steps/defaults/cutStep.mjs +1 -1
  36. package/dist/core/functionsBuilders/steps/defaults/handlerStep.cjs +37 -17
  37. package/dist/core/functionsBuilders/steps/defaults/handlerStep.mjs +37 -17
  38. package/dist/core/functionsBuilders/steps/defaults/processStep.cjs +3 -3
  39. package/dist/core/functionsBuilders/steps/defaults/processStep.mjs +3 -3
  40. package/dist/core/hub/defaultEmptyReaderImplementation.cjs +9 -0
  41. package/dist/core/hub/defaultEmptyReaderImplementation.d.ts +1 -0
  42. package/dist/core/hub/defaultEmptyReaderImplementation.mjs +7 -0
  43. package/dist/core/hub/defaultMalformedUrlHandler.cjs +14 -0
  44. package/dist/core/hub/defaultMalformedUrlHandler.d.ts +10 -0
  45. package/dist/core/hub/defaultMalformedUrlHandler.mjs +12 -0
  46. package/dist/core/hub/defaultNotfoundHandler.d.ts +1 -1
  47. package/dist/core/hub/index.cjs +14 -1
  48. package/dist/core/hub/index.d.ts +4 -0
  49. package/dist/core/hub/index.mjs +13 -2
  50. package/dist/core/implementHttpServer.cjs +7 -2
  51. package/dist/core/implementHttpServer.d.ts +7 -1
  52. package/dist/core/implementHttpServer.mjs +5 -0
  53. package/dist/core/index.cjs +18 -0
  54. package/dist/core/index.d.ts +1 -0
  55. package/dist/core/index.mjs +8 -2
  56. package/dist/core/request/bodyController/base.cjs +24 -6
  57. package/dist/core/request/bodyController/base.d.ts +9 -0
  58. package/dist/core/request/bodyController/base.mjs +25 -8
  59. package/dist/core/request/bodyController/empty.cjs +11 -0
  60. package/dist/core/request/bodyController/empty.d.ts +3 -0
  61. package/dist/core/request/bodyController/empty.mjs +8 -0
  62. package/dist/core/request/bodyController/formData.cjs +1 -0
  63. package/dist/core/request/bodyController/formData.d.ts +4 -2
  64. package/dist/core/request/bodyController/formData.mjs +1 -0
  65. package/dist/core/request/bodyController/index.cjs +4 -0
  66. package/dist/core/request/bodyController/index.d.ts +1 -0
  67. package/dist/core/request/bodyController/index.mjs +2 -1
  68. package/dist/core/request/index.cjs +5 -0
  69. package/dist/core/request/index.d.ts +1 -1
  70. package/dist/core/request/index.mjs +6 -1
  71. package/dist/core/response/contract.cjs +17 -4
  72. package/dist/core/response/contract.d.ts +19 -4
  73. package/dist/core/response/contract.mjs +17 -4
  74. package/dist/core/response/index.cjs +2 -0
  75. package/dist/core/response/index.d.ts +1 -0
  76. package/dist/core/response/index.mjs +1 -0
  77. package/dist/core/response/serverSentEventsPredicted.cjs +23 -0
  78. package/dist/core/response/serverSentEventsPredicted.d.ts +14 -0
  79. package/dist/core/response/serverSentEventsPredicted.mjs +21 -0
  80. package/dist/core/route/hooks.cjs +9 -0
  81. package/dist/core/route/hooks.d.ts +10 -9
  82. package/dist/core/route/hooks.mjs +9 -1
  83. package/dist/core/route/index.cjs +1 -0
  84. package/dist/core/route/index.mjs +1 -1
  85. package/dist/core/router/buildSystemRoute.cjs +33 -0
  86. package/dist/core/router/buildSystemRoute.d.ts +11 -0
  87. package/dist/core/router/buildSystemRoute.mjs +31 -0
  88. package/dist/core/router/decodeUrl.cjs +5 -4
  89. package/dist/core/router/decodeUrl.d.ts +1 -1
  90. package/dist/core/router/decodeUrl.mjs +5 -4
  91. package/dist/core/router/index.cjs +24 -23
  92. package/dist/core/router/index.d.ts +1 -0
  93. package/dist/core/router/index.mjs +25 -25
  94. package/dist/core/serverSentEvents.cjs +96 -0
  95. package/dist/core/serverSentEvents.d.ts +33 -0
  96. package/dist/core/serverSentEvents.mjs +96 -0
  97. package/dist/core/steps/cut.d.ts +2 -2
  98. package/dist/core/steps/handler.d.ts +10 -5
  99. package/dist/interfaces/node/bodyReaders/formData/index.cjs +34 -14
  100. package/dist/interfaces/node/bodyReaders/formData/index.mjs +35 -15
  101. package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.cjs +18 -12
  102. package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.d.ts +2 -1
  103. package/dist/interfaces/node/bodyReaders/formData/readRequestFormData.mjs +18 -12
  104. package/dist/interfaces/node/createHttpServer.cjs +2 -3
  105. package/dist/interfaces/node/createHttpServer.mjs +2 -3
  106. package/dist/interfaces/node/hooks/index.cjs +61 -38
  107. package/dist/interfaces/node/hooks/index.d.ts +6 -4
  108. package/dist/interfaces/node/hooks/index.mjs +61 -38
  109. package/dist/interfaces/node/index.cjs +1 -1
  110. package/dist/interfaces/node/index.mjs +1 -1
  111. package/dist/plugins/cacheController/createResponseHeader.cjs +43 -0
  112. package/dist/plugins/cacheController/createResponseHeader.d.ts +2 -0
  113. package/dist/plugins/cacheController/createResponseHeader.mjs +41 -0
  114. package/dist/plugins/cacheController/hooks.cjs +23 -0
  115. package/dist/plugins/cacheController/hooks.d.ts +4 -0
  116. package/dist/plugins/cacheController/hooks.mjs +21 -0
  117. package/dist/plugins/cacheController/index.cjs +10 -0
  118. package/dist/plugins/cacheController/index.d.ts +3 -0
  119. package/dist/plugins/cacheController/index.mjs +3 -0
  120. package/dist/plugins/cacheController/types/cacheControlDirectives.cjs +2 -0
  121. package/dist/plugins/cacheController/types/cacheControlDirectives.d.ts +16 -0
  122. package/dist/plugins/cacheController/types/cacheControlDirectives.mjs +1 -0
  123. package/dist/plugins/cacheController/types/index.cjs +4 -0
  124. package/dist/plugins/cacheController/types/index.d.ts +1 -0
  125. package/dist/plugins/cacheController/types/index.mjs +1 -0
  126. package/dist/plugins/codeGenerator/aggregateStepContract.cjs +9 -2
  127. package/dist/plugins/codeGenerator/aggregateStepContract.d.ts +1 -1
  128. package/dist/plugins/codeGenerator/aggregateStepContract.mjs +10 -3
  129. package/dist/plugins/codeGenerator/plugin.cjs +4 -4
  130. package/dist/plugins/codeGenerator/plugin.mjs +1 -1
  131. package/dist/plugins/openApiGenerator/aggregateStepContract.d.ts +2 -7
  132. package/dist/plugins/openApiGenerator/routeToOpenApi.cjs +46 -8
  133. package/dist/plugins/openApiGenerator/routeToOpenApi.d.ts +2 -2
  134. package/dist/plugins/openApiGenerator/routeToOpenApi.mjs +46 -8
  135. package/dist/plugins/openApiGenerator/types/endpointResponse.d.ts +7 -3
  136. package/dist/plugins/static/index.cjs +14 -0
  137. package/dist/plugins/static/index.d.ts +3 -0
  138. package/dist/plugins/static/index.mjs +3 -0
  139. package/dist/plugins/static/kind.cjs +9 -0
  140. package/dist/plugins/static/kind.d.ts +6 -0
  141. package/dist/plugins/static/kind.mjs +7 -0
  142. package/dist/plugins/static/makeRouteFile.cjs +62 -0
  143. package/dist/plugins/static/makeRouteFile.d.ts +48 -0
  144. package/dist/plugins/static/makeRouteFile.mjs +58 -0
  145. package/dist/plugins/static/makeRouteFolder.cjs +67 -0
  146. package/dist/plugins/static/makeRouteFolder.d.ts +39 -0
  147. package/dist/plugins/static/makeRouteFolder.mjs +65 -0
  148. package/dist/plugins/static/plugin.cjs +53 -0
  149. package/dist/plugins/static/plugin.d.ts +26 -0
  150. package/dist/plugins/static/plugin.mjs +50 -0
  151. package/package.json +18 -7
  152. /package/dist/plugins/codeGenerator/{typescriptTransfomer.cjs → typescriptTransformer.cjs} +0 -0
  153. /package/dist/plugins/codeGenerator/{typescriptTransfomer.d.ts → typescriptTransformer.d.ts} +0 -0
  154. /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,4 @@
1
+ 'use strict';
2
+
3
+ require('./cacheControlDirectives.cjs');
4
+
@@ -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.A.concat(processContracts.endpointContract));
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 { type ResponseContract } from "../../core/response";
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
- })), A.concat(processContracts.endpointContract));
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 typescriptTransfomer = require('./typescriptTransfomer.cjs');
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
- typescriptTransfomer.fileTransformer,
49
- typescriptTransfomer.dateTransformer,
50
- typescriptTransfomer.timeTransformer,
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 './typescriptTransfomer.mjs';
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 { ResponseCode, ResponseContract } from "../../core/response";
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: EndpointRouteResult[];
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: { information, body, code }, nextWithObject }) => {
98
- const schemaResponse = !utils.DP.identifier(body, utils.DP.emptyKind)
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 type { ResponseCode, ResponseContract } from "../../core/response";
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<ResponseCode, EndpointResponse>>;
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: { information, body, code }, nextWithObject }) => {
96
- const schemaResponse = !DP.identifier(body, DP.emptyKind)
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, JsonSchemaLiteral, JsonSchemaString } from "@duplojs/data-parser-tools/toJsonSchema";
1
+ import type { JsonSchema } from "@duplojs/data-parser-tools/toJsonSchema";
2
2
  export interface EndpointResponseHeader {
3
3
  information: {
4
- schema: JsonSchemaLiteral;
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: JsonSchemaString;
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,3 @@
1
+ export * from "./makeRouteFolder";
2
+ export * from "./makeRouteFile";
3
+ export * from "./plugin";
@@ -0,0 +1,3 @@
1
+ export { makeRouteFolder } from './makeRouteFolder.mjs';
2
+ export { MissingSelectedStaticFileError, SelectedStaticFileIsNotFileError, makeRouteFile } from './makeRouteFile.mjs';
3
+ export { StaticPluginError, staticPlugin } from './plugin.mjs';
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ var utils = require('@duplojs/utils');
4
+
5
+ const createStaticPluginKind = utils.createKindNamespace(
6
+ // @ts-expect-error reserved kind namespace
7
+ "DuplojsStaticPlugin");
8
+
9
+ exports.createStaticPluginKind = createStaticPluginKind;
@@ -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,7 @@
1
+ import { createKindNamespace } from '@duplojs/utils';
2
+
3
+ const createStaticPluginKind = createKindNamespace(
4
+ // @ts-expect-error reserved kind namespace
5
+ "DuplojsStaticPlugin");
6
+
7
+ export { createStaticPluginKind };
@@ -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 };