@duplojs/http 0.2.0 → 0.5.0

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 (235) hide show
  1. package/dist/client/getBody.cjs +22 -0
  2. package/dist/client/getBody.d.ts +1 -0
  3. package/dist/client/getBody.mjs +20 -0
  4. package/dist/client/hooks.cjs +79 -0
  5. package/dist/client/hooks.d.ts +33 -0
  6. package/dist/client/hooks.mjs +70 -0
  7. package/dist/client/httpClient.cjs +153 -0
  8. package/dist/client/httpClient.d.ts +60 -0
  9. package/dist/client/httpClient.mjs +130 -0
  10. package/dist/client/index.cjs +33 -0
  11. package/dist/client/index.d.ts +9 -0
  12. package/dist/client/index.mjs +9 -0
  13. package/dist/client/insertParamsInPath.cjs +12 -0
  14. package/dist/client/insertParamsInPath.d.ts +2 -0
  15. package/dist/client/insertParamsInPath.mjs +10 -0
  16. package/dist/client/kind.cjs +9 -0
  17. package/dist/client/kind.d.ts +6 -0
  18. package/dist/client/kind.mjs +7 -0
  19. package/dist/client/promiseRequest.cjs +355 -0
  20. package/dist/client/promiseRequest.d.ts +98 -0
  21. package/dist/client/promiseRequest.mjs +332 -0
  22. package/dist/client/queryToString.cjs +25 -0
  23. package/dist/client/queryToString.d.ts +2 -0
  24. package/dist/client/queryToString.mjs +23 -0
  25. package/dist/client/types/ObjectCanBeEmpty.cjs +2 -0
  26. package/dist/client/types/ObjectCanBeEmpty.d.ts +4 -0
  27. package/dist/client/types/ObjectCanBeEmpty.mjs +1 -0
  28. package/dist/client/types/clientRequestParams.cjs +2 -0
  29. package/dist/client/types/clientRequestParams.d.ts +51 -0
  30. package/dist/client/types/clientRequestParams.mjs +1 -0
  31. package/dist/client/types/clientResponse.cjs +2 -0
  32. package/dist/client/types/clientResponse.d.ts +34 -0
  33. package/dist/client/types/clientResponse.mjs +1 -0
  34. package/dist/client/types/index.cjs +7 -0
  35. package/dist/client/types/index.d.ts +4 -0
  36. package/dist/client/types/index.mjs +4 -0
  37. package/dist/client/types/serverRoute.cjs +2 -0
  38. package/dist/client/types/serverRoute.d.ts +22 -0
  39. package/dist/client/types/serverRoute.mjs +1 -0
  40. package/dist/client/unexpectedResponseError.cjs +44 -0
  41. package/dist/client/unexpectedResponseError.d.ts +38 -0
  42. package/dist/client/unexpectedResponseError.mjs +39 -0
  43. package/dist/core/builders/preflight/builder.cjs +1 -0
  44. package/dist/core/builders/preflight/builder.d.ts +5 -1
  45. package/dist/core/builders/preflight/builder.mjs +1 -0
  46. package/dist/core/builders/preflight/process.cjs +2 -1
  47. package/dist/core/builders/preflight/process.d.ts +4 -2
  48. package/dist/core/builders/preflight/process.mjs +2 -1
  49. package/dist/core/builders/preflight/route.cjs +4 -0
  50. package/dist/core/builders/preflight/route.d.ts +9 -3
  51. package/dist/core/builders/preflight/route.mjs +4 -0
  52. package/dist/core/builders/process/builder.cjs +1 -0
  53. package/dist/core/builders/process/builder.d.ts +4 -1
  54. package/dist/core/builders/process/builder.mjs +1 -0
  55. package/dist/core/builders/process/checker.cjs +2 -1
  56. package/dist/core/builders/process/checker.d.ts +4 -2
  57. package/dist/core/builders/process/checker.mjs +2 -1
  58. package/dist/core/builders/process/cut.cjs +2 -1
  59. package/dist/core/builders/process/cut.d.ts +3 -1
  60. package/dist/core/builders/process/cut.mjs +2 -1
  61. package/dist/core/builders/process/extract.cjs +2 -1
  62. package/dist/core/builders/process/extract.d.ts +3 -1
  63. package/dist/core/builders/process/extract.mjs +2 -1
  64. package/dist/core/builders/process/index.cjs +1 -1
  65. package/dist/core/builders/process/index.d.ts +1 -1
  66. package/dist/core/builders/process/index.mjs +1 -1
  67. package/dist/core/builders/process/presetChecker.cjs +2 -1
  68. package/dist/core/builders/process/presetChecker.d.ts +3 -1
  69. package/dist/core/builders/process/presetChecker.mjs +2 -1
  70. package/dist/core/builders/process/process.cjs +2 -1
  71. package/dist/core/builders/process/process.d.ts +4 -2
  72. package/dist/core/builders/process/process.mjs +2 -1
  73. package/dist/core/builders/route/builder.cjs +1 -0
  74. package/dist/core/builders/route/builder.d.ts +4 -1
  75. package/dist/core/builders/route/builder.mjs +1 -0
  76. package/dist/core/builders/route/checker.cjs +2 -1
  77. package/dist/core/builders/route/checker.d.ts +4 -2
  78. package/dist/core/builders/route/checker.mjs +2 -1
  79. package/dist/core/builders/route/cut.cjs +2 -1
  80. package/dist/core/builders/route/cut.d.ts +3 -1
  81. package/dist/core/builders/route/cut.mjs +2 -1
  82. package/dist/core/builders/route/extract.cjs +2 -1
  83. package/dist/core/builders/route/extract.d.ts +3 -1
  84. package/dist/core/builders/route/extract.mjs +2 -1
  85. package/dist/core/builders/route/handler.cjs +9 -2
  86. package/dist/core/builders/route/handler.d.ts +3 -1
  87. package/dist/core/builders/route/handler.mjs +9 -2
  88. package/dist/core/builders/route/presetChecker.cjs +2 -1
  89. package/dist/core/builders/route/presetChecker.d.ts +3 -1
  90. package/dist/core/builders/route/presetChecker.mjs +2 -1
  91. package/dist/core/builders/route/process.cjs +2 -1
  92. package/dist/core/builders/route/process.d.ts +4 -2
  93. package/dist/core/builders/route/process.mjs +2 -1
  94. package/dist/core/functionsBuilders/route/default.cjs +10 -9
  95. package/dist/core/functionsBuilders/route/default.mjs +3 -2
  96. package/dist/core/functionsBuilders/route/hook.cjs +22 -22
  97. package/dist/core/functionsBuilders/route/hook.d.ts +2 -2
  98. package/dist/core/functionsBuilders/route/hook.mjs +2 -2
  99. package/dist/core/functionsBuilders/steps/create.d.ts +2 -2
  100. package/dist/core/functionsBuilders/steps/defaults/checkerStep.cjs +3 -2
  101. package/dist/core/functionsBuilders/steps/defaults/checkerStep.mjs +3 -2
  102. package/dist/core/functionsBuilders/steps/defaults/cutStep.cjs +3 -2
  103. package/dist/core/functionsBuilders/steps/defaults/cutStep.mjs +3 -2
  104. package/dist/core/functionsBuilders/steps/defaults/extractStep.cjs +6 -5
  105. package/dist/core/functionsBuilders/steps/defaults/extractStep.mjs +4 -3
  106. package/dist/core/functionsBuilders/steps/defaults/handlerStep.cjs +3 -2
  107. package/dist/core/functionsBuilders/steps/defaults/handlerStep.mjs +3 -2
  108. package/dist/core/functionsBuilders/steps/defaults/processStep.cjs +5 -4
  109. package/dist/core/functionsBuilders/steps/defaults/processStep.mjs +3 -2
  110. package/dist/core/hub/defaultNotfoundHandler.cjs +1 -0
  111. package/dist/core/hub/defaultNotfoundHandler.d.ts +2 -1
  112. package/dist/core/hub/defaultNotfoundHandler.mjs +1 -0
  113. package/dist/core/hub/index.cjs +2 -1
  114. package/dist/core/hub/index.mjs +2 -1
  115. package/dist/core/index.cjs +43 -34
  116. package/dist/core/index.d.ts +1 -0
  117. package/dist/core/index.mjs +8 -3
  118. package/dist/core/metadata/base.cjs +20 -0
  119. package/dist/core/metadata/base.d.ts +14 -0
  120. package/dist/core/metadata/base.mjs +17 -0
  121. package/dist/core/metadata/ignoreByRouteStore.cjs +7 -0
  122. package/dist/core/metadata/ignoreByRouteStore.d.ts +1 -0
  123. package/dist/core/metadata/ignoreByRouteStore.mjs +5 -0
  124. package/dist/core/metadata/index.cjs +10 -0
  125. package/dist/core/metadata/index.d.ts +2 -0
  126. package/dist/core/metadata/index.mjs +2 -0
  127. package/dist/core/process/index.d.ts +3 -1
  128. package/dist/core/response/base.cjs +40 -0
  129. package/dist/core/response/base.d.ts +21 -0
  130. package/dist/core/response/base.mjs +38 -0
  131. package/dist/core/response/contract.cjs +2 -2
  132. package/dist/core/response/contract.d.ts +120 -118
  133. package/dist/core/response/contract.mjs +2 -2
  134. package/dist/core/{route/hooks/response.cjs → response/hook.cjs} +4 -3
  135. package/dist/core/{route/hooks/response.d.ts → response/hook.d.ts} +2 -2
  136. package/dist/core/{route/hooks/response.mjs → response/hook.mjs} +3 -2
  137. package/dist/core/response/index.cjs +9 -38
  138. package/dist/core/response/index.d.ts +3 -20
  139. package/dist/core/response/index.mjs +3 -38
  140. package/dist/core/response/predicted.cjs +22 -0
  141. package/dist/core/response/predicted.d.ts +11 -0
  142. package/dist/core/response/predicted.mjs +20 -0
  143. package/dist/core/route/{hooks/index.cjs → hooks.cjs} +2 -3
  144. package/dist/core/route/{hooks/index.d.ts → hooks.d.ts} +4 -4
  145. package/dist/core/route/{hooks/index.mjs → hooks.mjs} +2 -2
  146. package/dist/core/route/index.cjs +4 -4
  147. package/dist/core/route/index.d.ts +2 -0
  148. package/dist/core/route/index.mjs +1 -1
  149. package/dist/core/router/index.cjs +1 -0
  150. package/dist/core/router/index.mjs +1 -0
  151. package/dist/core/steps/checker.d.ts +2 -0
  152. package/dist/core/steps/cut.d.ts +5 -3
  153. package/dist/core/steps/extract.d.ts +2 -0
  154. package/dist/core/steps/handler.d.ts +5 -3
  155. package/dist/core/steps/identifier.d.ts +2 -2
  156. package/dist/core/steps/presetChecker.d.ts +2 -0
  157. package/dist/core/steps/process.d.ts +2 -0
  158. package/dist/core/steps/types/stepFunctionParams.d.ts +2 -2
  159. package/dist/core/types/forbiddenBigintDataParser.cjs +2 -0
  160. package/dist/core/types/forbiddenBigintDataParser.d.ts +6 -0
  161. package/dist/core/types/forbiddenBigintDataParser.mjs +1 -0
  162. package/dist/core/types/index.cjs +1 -0
  163. package/dist/core/types/index.d.ts +1 -0
  164. package/dist/core/types/index.mjs +1 -0
  165. package/dist/interfaces/node/createHttpServer.cjs +1 -0
  166. package/dist/interfaces/node/createHttpServer.d.ts +2 -1
  167. package/dist/interfaces/node/createHttpServer.mjs +1 -0
  168. package/dist/interfaces/node/hooks.cjs +16 -13
  169. package/dist/interfaces/node/hooks.mjs +15 -12
  170. package/dist/plugins/codeGenerator/{stepsToDataParser.cjs → aggregateStepContract.cjs} +8 -5
  171. package/dist/plugins/codeGenerator/{stepsToDataParser.d.ts → aggregateStepContract.d.ts} +1 -1
  172. package/dist/plugins/codeGenerator/{stepsToDataParser.mjs → aggregateStepContract.mjs} +9 -6
  173. package/dist/plugins/codeGenerator/index.cjs +4 -5
  174. package/dist/plugins/codeGenerator/index.d.ts +2 -1
  175. package/dist/plugins/codeGenerator/index.mjs +3 -2
  176. package/dist/plugins/codeGenerator/metadata.cjs +8 -0
  177. package/dist/plugins/codeGenerator/metadata.d.ts +1 -0
  178. package/dist/plugins/codeGenerator/metadata.mjs +6 -0
  179. package/dist/plugins/codeGenerator/plugin.cjs +1 -1
  180. package/dist/plugins/codeGenerator/plugin.mjs +1 -1
  181. package/dist/plugins/codeGenerator/routeToDataParser.cjs +11 -57
  182. package/dist/plugins/codeGenerator/routeToDataParser.d.ts +2 -181
  183. package/dist/plugins/codeGenerator/routeToDataParser.mjs +13 -56
  184. package/dist/plugins/openApiGenerator/aggregateStepContract.cjs +65 -0
  185. package/dist/plugins/openApiGenerator/aggregateStepContract.d.ts +18 -0
  186. package/dist/plugins/openApiGenerator/aggregateStepContract.mjs +63 -0
  187. package/dist/plugins/openApiGenerator/index.cjs +19 -0
  188. package/dist/plugins/openApiGenerator/index.d.ts +8 -0
  189. package/dist/plugins/openApiGenerator/index.mjs +8 -0
  190. package/dist/plugins/openApiGenerator/makeOpenApiPage.cjs +30 -0
  191. package/dist/plugins/openApiGenerator/makeOpenApiPage.d.ts +7 -0
  192. package/dist/plugins/openApiGenerator/makeOpenApiPage.mjs +28 -0
  193. package/dist/plugins/openApiGenerator/makeOpenApiRoute.cjs +15 -0
  194. package/dist/plugins/openApiGenerator/makeOpenApiRoute.d.ts +20 -0
  195. package/dist/plugins/openApiGenerator/makeOpenApiRoute.mjs +13 -0
  196. package/dist/plugins/openApiGenerator/metadata.cjs +8 -0
  197. package/dist/plugins/openApiGenerator/metadata.d.ts +1 -0
  198. package/dist/plugins/openApiGenerator/metadata.mjs +6 -0
  199. package/dist/plugins/openApiGenerator/plugin.cjs +90 -0
  200. package/dist/plugins/openApiGenerator/plugin.d.ts +49 -0
  201. package/dist/plugins/openApiGenerator/plugin.mjs +88 -0
  202. package/dist/plugins/openApiGenerator/routeToOpenApi.cjs +168 -0
  203. package/dist/plugins/openApiGenerator/routeToOpenApi.d.ts +35 -0
  204. package/dist/plugins/openApiGenerator/routeToOpenApi.mjs +166 -0
  205. package/dist/plugins/openApiGenerator/types/endpointResponse.cjs +2 -0
  206. package/dist/plugins/openApiGenerator/types/endpointResponse.d.ts +19 -0
  207. package/dist/plugins/openApiGenerator/types/endpointResponse.mjs +1 -0
  208. package/dist/plugins/openApiGenerator/types/entrypoint.cjs +2 -0
  209. package/dist/plugins/openApiGenerator/types/entrypoint.d.ts +22 -0
  210. package/dist/plugins/openApiGenerator/types/entrypoint.mjs +1 -0
  211. package/dist/plugins/openApiGenerator/types/entrypointKey.cjs +2 -0
  212. package/dist/plugins/openApiGenerator/types/entrypointKey.d.ts +1 -0
  213. package/dist/plugins/openApiGenerator/types/entrypointKey.mjs +1 -0
  214. package/dist/plugins/openApiGenerator/types/index.cjs +11 -0
  215. package/dist/plugins/openApiGenerator/types/index.d.ts +8 -0
  216. package/dist/plugins/openApiGenerator/types/index.mjs +8 -0
  217. package/dist/plugins/openApiGenerator/types/openApiDocument.cjs +2 -0
  218. package/dist/plugins/openApiGenerator/types/openApiDocument.d.ts +31 -0
  219. package/dist/plugins/openApiGenerator/types/openApiDocument.mjs +1 -0
  220. package/dist/plugins/openApiGenerator/types/openApiMethod.cjs +2 -0
  221. package/dist/plugins/openApiGenerator/types/openApiMethod.d.ts +1 -0
  222. package/dist/plugins/openApiGenerator/types/openApiMethod.mjs +1 -0
  223. package/dist/plugins/openApiGenerator/types/openApiOperation.cjs +2 -0
  224. package/dist/plugins/openApiGenerator/types/openApiOperation.d.ts +8 -0
  225. package/dist/plugins/openApiGenerator/types/openApiOperation.mjs +1 -0
  226. package/dist/plugins/openApiGenerator/types/openApiPath.cjs +2 -0
  227. package/dist/plugins/openApiGenerator/types/openApiPath.d.ts +4 -0
  228. package/dist/plugins/openApiGenerator/types/openApiPath.mjs +1 -0
  229. package/dist/plugins/openApiGenerator/types/openApiSecuritySchema.cjs +2 -0
  230. package/dist/plugins/openApiGenerator/types/openApiSecuritySchema.d.ts +8 -0
  231. package/dist/plugins/openApiGenerator/types/openApiSecuritySchema.mjs +1 -0
  232. package/package.json +17 -4
  233. /package/dist/core/builders/process/{export.cjs → exports.cjs} +0 -0
  234. /package/dist/core/builders/process/{export.d.ts → exports.d.ts} +0 -0
  235. /package/dist/core/builders/process/{export.mjs → exports.mjs} +0 -0
@@ -0,0 +1,168 @@
1
+ 'use strict';
2
+
3
+ var aggregateStepContract = require('./aggregateStepContract.cjs');
4
+ var utils = require('@duplojs/utils');
5
+ var toJsonSchema = require('@duplojs/data-parser-tools/toJsonSchema');
6
+ var metadata = require('./metadata.cjs');
7
+
8
+ function factoryJsonSchema(params) {
9
+ const identifier = params.schema.definition.identifier
10
+ ?? `NotIdentified${params.resultSchemaContext.size}`;
11
+ const renderResult = toJsonSchema.render(params.schema, {
12
+ identifier,
13
+ mode: params.mode,
14
+ context: params.context,
15
+ version: "openApi31",
16
+ transformers: toJsonSchema.defaultTransformers,
17
+ });
18
+ params.resultSchemaContext.set(identifier, renderResult.components.schemas);
19
+ return utils.O.pick(renderResult, { $ref: true });
20
+ }
21
+ const parameterKeyMapper = {
22
+ query: "query",
23
+ params: "path",
24
+ headers: "header",
25
+ };
26
+ const methodMapper = {
27
+ GET: "get",
28
+ POST: "post",
29
+ PUT: "put",
30
+ DELETE: "delete",
31
+ HEAD: "head",
32
+ TRACE: "trace",
33
+ CONNECT: "connect",
34
+ OPTIONS: "options",
35
+ };
36
+ function routeToOpenApi(route, params) {
37
+ const isIgnore = utils.A.find(route.definition.metadata, metadata.IgnoreByOpenApiGeneratorMetadata.is);
38
+ if (isIgnore) {
39
+ return [];
40
+ }
41
+ const aggregateStepResult = aggregateStepContract.aggregateStepContract([
42
+ ...route.definition.preflightSteps,
43
+ ...route.definition.steps,
44
+ ], {
45
+ defaultExtractContract: params.defaultExtractContract,
46
+ });
47
+ const { body, ...restEntrypoint } = aggregateStepResult.entrypointContract;
48
+ const parameters = utils.pipe(restEntrypoint, utils.O.entries, utils.A.select(({ element: [key, value], select, skip }) => !utils.DP.dataParserKind.has(value) && utils.O.countKeys(value)
49
+ ? select(utils.O.entry(key, utils.O.entries(value)))
50
+ : skip()), utils.A.flatMap(([key, value]) => utils.A.map(value, ([name, schema]) => ({
51
+ name,
52
+ in: parameterKeyMapper[key],
53
+ required: !utils.DP.identifier(schema, utils.DP.optionalKind),
54
+ schema: factoryJsonSchema({
55
+ context: params.contextToJsonSchemaFactory,
56
+ resultSchemaContext: params.resultSchemaContext,
57
+ mode: "in",
58
+ schema,
59
+ }),
60
+ }))));
61
+ const requestBody = utils.pipe(body, utils.when((value) => utils.O.countKeys(value) === 0, utils.justReturn(utils.DP.empty())), utils.whenNot(utils.DP.dataParserKind.has, utils.DP.object), utils.P.when(utils.DP.identifier(utils.DP.emptyKind), utils.justReturn(undefined)), utils.P.when(utils.DP.identifier(utils.DP.objectKind), (objectSchema) => ({
62
+ required: true,
63
+ content: {
64
+ "application/json": {
65
+ schema: factoryJsonSchema({
66
+ context: params.contextToJsonSchemaFactory,
67
+ resultSchemaContext: params.resultSchemaContext,
68
+ mode: "in",
69
+ schema: objectSchema,
70
+ }),
71
+ },
72
+ },
73
+ })), utils.P.otherwise((primitiveSchema) => ({
74
+ required: true,
75
+ content: {
76
+ "text/plain": {
77
+ schema: factoryJsonSchema({
78
+ context: params.contextToJsonSchemaFactory,
79
+ resultSchemaContext: params.resultSchemaContext,
80
+ mode: "in",
81
+ schema: primitiveSchema,
82
+ }),
83
+ },
84
+ },
85
+ })));
86
+ const responses = utils.pipe(aggregateStepResult.endpointContract, utils.A.reduce(utils.A.reduceFrom({}), ({ lastValue, element: { information, body, code }, nextWithObject }) => {
87
+ const schemaResponse = !utils.DP.identifier(body, utils.DP.emptyKind)
88
+ ? factoryJsonSchema({
89
+ context: params.contextToJsonSchemaFactory,
90
+ resultSchemaContext: params.resultSchemaContext,
91
+ mode: "in",
92
+ schema: body,
93
+ })
94
+ : undefined;
95
+ const headerInformation = {
96
+ const: information,
97
+ type: "string",
98
+ };
99
+ const headerDescription = utils.P.match(lastValue[code])
100
+ .when(utils.isType("object"), (value) => {
101
+ if (utils.S.includes(value.headers.information.description, information)) {
102
+ return value.headers.information.description;
103
+ }
104
+ return utils.S.concat(value.headers.information.description, " | ", information);
105
+ })
106
+ .when(utils.isType("undefined"), utils.justReturn(information))
107
+ .exhaustive();
108
+ const headers = {
109
+ information: {
110
+ schema: lastValue[code]
111
+ ? {
112
+ anyOf: [
113
+ lastValue[code].headers.information.schema,
114
+ headerInformation,
115
+ ],
116
+ }
117
+ : headerInformation,
118
+ description: headerDescription,
119
+ },
120
+ };
121
+ const content = utils.pipe(body, utils.P.when(utils.DP.identifier(utils.DP.emptyKind), utils.justReturn(lastValue[code]?.content)), utils.P.otherwise((value) => {
122
+ if (utils.DP.identifier(value, utils.DP.stringKind) && lastValue[code]?.content?.["plain/text"]) {
123
+ return lastValue[code].content;
124
+ }
125
+ if (utils.DP.identifier(value, utils.DP.stringKind)) {
126
+ return {
127
+ ...lastValue[code]?.content,
128
+ "plain/text": {
129
+ schema: schemaResponse,
130
+ },
131
+ };
132
+ }
133
+ if (utils.DP.identifier(value, utils.DP.objectKind) && lastValue[code]?.content?.["application/json"]) {
134
+ return {
135
+ ...lastValue[code]?.content,
136
+ "application/json": {
137
+ schema: {
138
+ anyOf: [
139
+ lastValue[code].content["application/json"].schema,
140
+ schemaResponse,
141
+ ],
142
+ },
143
+ },
144
+ };
145
+ }
146
+ return {
147
+ "application/json": {
148
+ schema: schemaResponse,
149
+ },
150
+ };
151
+ }));
152
+ return nextWithObject(lastValue, {
153
+ [code]: {
154
+ headers,
155
+ content,
156
+ },
157
+ });
158
+ }));
159
+ return utils.A.map(route.definition.paths, (path) => ({
160
+ path,
161
+ method: methodMapper[route.definition.method],
162
+ parameters,
163
+ requestBody,
164
+ responses,
165
+ }));
166
+ }
167
+
168
+ exports.routeToOpenApi = routeToOpenApi;
@@ -0,0 +1,35 @@
1
+ import type { Route } from "../../core/route";
2
+ import type { ResponseCode, ResponseContract } from "../../core/response";
3
+ import { type MapContext, type JsonSchema } from "@duplojs/data-parser-tools/toJsonSchema";
4
+ import type { EndpointResponse, EntrypointParameter } from "./types";
5
+ export type ResultSchemaContext = Map<string, Record<string, JsonSchema>>;
6
+ export interface RouteToOpenApiParams {
7
+ readonly contextToJsonSchemaFactory: MapContext;
8
+ readonly resultSchemaContext: ResultSchemaContext;
9
+ readonly defaultExtractContract: ResponseContract.Contract;
10
+ }
11
+ export declare function routeToOpenApi(route: Route, params: RouteToOpenApiParams): {
12
+ path: `/${string}`;
13
+ method: "options" | "get" | "post" | "put" | "delete" | "head" | "trace" | "connect";
14
+ parameters: EntrypointParameter[];
15
+ requestBody: {
16
+ required: true;
17
+ content: {
18
+ "application/json": {
19
+ schema: {
20
+ $ref: `#/components/schemas/${string}`;
21
+ };
22
+ };
23
+ };
24
+ } | {
25
+ required: true;
26
+ content: {
27
+ "text/plain": {
28
+ schema: {
29
+ $ref: `#/components/schemas/${string}`;
30
+ };
31
+ };
32
+ };
33
+ } | undefined;
34
+ responses: Partial<Record<ResponseCode, EndpointResponse>>;
35
+ }[];
@@ -0,0 +1,166 @@
1
+ import { aggregateStepContract } from './aggregateStepContract.mjs';
2
+ import { O, A, pipe, DP, when, justReturn, whenNot, P, isType, S } from '@duplojs/utils';
3
+ import { render, defaultTransformers } from '@duplojs/data-parser-tools/toJsonSchema';
4
+ import { IgnoreByOpenApiGeneratorMetadata } from './metadata.mjs';
5
+
6
+ function factoryJsonSchema(params) {
7
+ const identifier = params.schema.definition.identifier
8
+ ?? `NotIdentified${params.resultSchemaContext.size}`;
9
+ const renderResult = render(params.schema, {
10
+ identifier,
11
+ mode: params.mode,
12
+ context: params.context,
13
+ version: "openApi31",
14
+ transformers: defaultTransformers,
15
+ });
16
+ params.resultSchemaContext.set(identifier, renderResult.components.schemas);
17
+ return O.pick(renderResult, { $ref: true });
18
+ }
19
+ const parameterKeyMapper = {
20
+ query: "query",
21
+ params: "path",
22
+ headers: "header",
23
+ };
24
+ const methodMapper = {
25
+ GET: "get",
26
+ POST: "post",
27
+ PUT: "put",
28
+ DELETE: "delete",
29
+ HEAD: "head",
30
+ TRACE: "trace",
31
+ CONNECT: "connect",
32
+ OPTIONS: "options",
33
+ };
34
+ function routeToOpenApi(route, params) {
35
+ const isIgnore = A.find(route.definition.metadata, IgnoreByOpenApiGeneratorMetadata.is);
36
+ if (isIgnore) {
37
+ return [];
38
+ }
39
+ const aggregateStepResult = aggregateStepContract([
40
+ ...route.definition.preflightSteps,
41
+ ...route.definition.steps,
42
+ ], {
43
+ defaultExtractContract: params.defaultExtractContract,
44
+ });
45
+ const { body, ...restEntrypoint } = aggregateStepResult.entrypointContract;
46
+ const parameters = pipe(restEntrypoint, O.entries, A.select(({ element: [key, value], select, skip }) => !DP.dataParserKind.has(value) && O.countKeys(value)
47
+ ? select(O.entry(key, O.entries(value)))
48
+ : skip()), A.flatMap(([key, value]) => A.map(value, ([name, schema]) => ({
49
+ name,
50
+ in: parameterKeyMapper[key],
51
+ required: !DP.identifier(schema, DP.optionalKind),
52
+ schema: factoryJsonSchema({
53
+ context: params.contextToJsonSchemaFactory,
54
+ resultSchemaContext: params.resultSchemaContext,
55
+ mode: "in",
56
+ schema,
57
+ }),
58
+ }))));
59
+ const requestBody = pipe(body, when((value) => O.countKeys(value) === 0, justReturn(DP.empty())), whenNot(DP.dataParserKind.has, DP.object), P.when(DP.identifier(DP.emptyKind), justReturn(undefined)), P.when(DP.identifier(DP.objectKind), (objectSchema) => ({
60
+ required: true,
61
+ content: {
62
+ "application/json": {
63
+ schema: factoryJsonSchema({
64
+ context: params.contextToJsonSchemaFactory,
65
+ resultSchemaContext: params.resultSchemaContext,
66
+ mode: "in",
67
+ schema: objectSchema,
68
+ }),
69
+ },
70
+ },
71
+ })), P.otherwise((primitiveSchema) => ({
72
+ required: true,
73
+ content: {
74
+ "text/plain": {
75
+ schema: factoryJsonSchema({
76
+ context: params.contextToJsonSchemaFactory,
77
+ resultSchemaContext: params.resultSchemaContext,
78
+ mode: "in",
79
+ schema: primitiveSchema,
80
+ }),
81
+ },
82
+ },
83
+ })));
84
+ const responses = pipe(aggregateStepResult.endpointContract, A.reduce(A.reduceFrom({}), ({ lastValue, element: { information, body, code }, nextWithObject }) => {
85
+ const schemaResponse = !DP.identifier(body, DP.emptyKind)
86
+ ? factoryJsonSchema({
87
+ context: params.contextToJsonSchemaFactory,
88
+ resultSchemaContext: params.resultSchemaContext,
89
+ mode: "in",
90
+ schema: body,
91
+ })
92
+ : undefined;
93
+ const headerInformation = {
94
+ const: information,
95
+ type: "string",
96
+ };
97
+ const headerDescription = P.match(lastValue[code])
98
+ .when(isType("object"), (value) => {
99
+ if (S.includes(value.headers.information.description, information)) {
100
+ return value.headers.information.description;
101
+ }
102
+ return S.concat(value.headers.information.description, " | ", information);
103
+ })
104
+ .when(isType("undefined"), justReturn(information))
105
+ .exhaustive();
106
+ const headers = {
107
+ information: {
108
+ schema: lastValue[code]
109
+ ? {
110
+ anyOf: [
111
+ lastValue[code].headers.information.schema,
112
+ headerInformation,
113
+ ],
114
+ }
115
+ : headerInformation,
116
+ description: headerDescription,
117
+ },
118
+ };
119
+ const content = pipe(body, P.when(DP.identifier(DP.emptyKind), justReturn(lastValue[code]?.content)), P.otherwise((value) => {
120
+ if (DP.identifier(value, DP.stringKind) && lastValue[code]?.content?.["plain/text"]) {
121
+ return lastValue[code].content;
122
+ }
123
+ if (DP.identifier(value, DP.stringKind)) {
124
+ return {
125
+ ...lastValue[code]?.content,
126
+ "plain/text": {
127
+ schema: schemaResponse,
128
+ },
129
+ };
130
+ }
131
+ if (DP.identifier(value, DP.objectKind) && lastValue[code]?.content?.["application/json"]) {
132
+ return {
133
+ ...lastValue[code]?.content,
134
+ "application/json": {
135
+ schema: {
136
+ anyOf: [
137
+ lastValue[code].content["application/json"].schema,
138
+ schemaResponse,
139
+ ],
140
+ },
141
+ },
142
+ };
143
+ }
144
+ return {
145
+ "application/json": {
146
+ schema: schemaResponse,
147
+ },
148
+ };
149
+ }));
150
+ return nextWithObject(lastValue, {
151
+ [code]: {
152
+ headers,
153
+ content,
154
+ },
155
+ });
156
+ }));
157
+ return A.map(route.definition.paths, (path) => ({
158
+ path,
159
+ method: methodMapper[route.definition.method],
160
+ parameters,
161
+ requestBody,
162
+ responses,
163
+ }));
164
+ }
165
+
166
+ export { routeToOpenApi };
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+
@@ -0,0 +1,19 @@
1
+ import type { JsonSchema, JsonSchemaLiteral, JsonSchemaString } from "@duplojs/data-parser-tools/toJsonSchema";
2
+ export interface EndpointResponseHeader {
3
+ information: {
4
+ schema: JsonSchemaLiteral;
5
+ description: string;
6
+ };
7
+ }
8
+ export interface EndpointResponseContent {
9
+ "application/json"?: {
10
+ schema: JsonSchema;
11
+ };
12
+ "plain/text"?: {
13
+ schema: JsonSchemaString;
14
+ };
15
+ }
16
+ export interface EndpointResponse {
17
+ headers: EndpointResponseHeader;
18
+ content?: EndpointResponseContent;
19
+ }
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+
@@ -0,0 +1,22 @@
1
+ import type { JsonSchema } from "@duplojs/data-parser-tools/toJsonSchema";
2
+ export interface EntrypointParameter {
3
+ name: string;
4
+ in: "path" | "query" | "header";
5
+ required: boolean;
6
+ schema: JsonSchema;
7
+ }
8
+ export interface EntrypointContentBodyApplicationJson {
9
+ "application/json": {
10
+ schema: JsonSchema;
11
+ };
12
+ }
13
+ export interface EntrypointContentBodyTextPlain {
14
+ "text/plain": {
15
+ schema: JsonSchema;
16
+ };
17
+ }
18
+ export type EntrypointContentBody = EntrypointContentBodyApplicationJson | EntrypointContentBodyTextPlain;
19
+ export interface EntrypointRequestBody {
20
+ required: true;
21
+ content: EntrypointContentBody;
22
+ }
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+
@@ -0,0 +1 @@
1
+ export type EntrypointKey = "query" | "body" | "params" | "headers";
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ require('./entrypointKey.cjs');
4
+ require('./openApiMethod.cjs');
5
+ require('./entrypoint.cjs');
6
+ require('./openApiSecuritySchema.cjs');
7
+ require('./endpointResponse.cjs');
8
+ require('./openApiOperation.cjs');
9
+ require('./openApiPath.cjs');
10
+ require('./openApiDocument.cjs');
11
+
@@ -0,0 +1,8 @@
1
+ export * from "./entrypointKey";
2
+ export * from "./openApiMethod";
3
+ export * from "./entrypoint";
4
+ export * from "./openApiSecuritySchema";
5
+ export * from "./endpointResponse";
6
+ export * from "./openApiOperation";
7
+ export * from "./openApiPath";
8
+ export * from "./openApiDocument";
@@ -0,0 +1,8 @@
1
+ import './entrypointKey.mjs';
2
+ import './openApiMethod.mjs';
3
+ import './entrypoint.mjs';
4
+ import './openApiSecuritySchema.mjs';
5
+ import './endpointResponse.mjs';
6
+ import './openApiOperation.mjs';
7
+ import './openApiPath.mjs';
8
+ import './openApiDocument.mjs';
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+
@@ -0,0 +1,31 @@
1
+ import type { JsonSchema } from "@duplojs/data-parser-tools/toJsonSchema";
2
+ import type { OpenApiSecuritySchema } from "./openApiSecuritySchema";
3
+ import type { OpenApiPath } from "./openApiPath";
4
+ export interface OpenApiDocument {
5
+ openapi: "3.1.0";
6
+ info: {
7
+ title: string;
8
+ version: string;
9
+ summary?: string;
10
+ contact?: {
11
+ name?: string;
12
+ email?: string;
13
+ url?: string;
14
+ };
15
+ license?: {
16
+ name: string;
17
+ url?: string;
18
+ identifier?: string;
19
+ };
20
+ };
21
+ servers?: {
22
+ url: string;
23
+ description?: string;
24
+ }[];
25
+ paths: OpenApiPath;
26
+ components: {
27
+ schemas: Record<string, JsonSchema>;
28
+ securitySchemes?: Record<string, OpenApiSecuritySchema>;
29
+ };
30
+ security?: Record<string, string[]>[];
31
+ }
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+
@@ -0,0 +1 @@
1
+ export type OpenApiMethod = "get" | "post" | "put" | "delete" | "head" | "trace" | "connect" | "options";
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+
@@ -0,0 +1,8 @@
1
+ import type { ResponseCode } from "../../../core/response";
2
+ import type { EntrypointParameter, EntrypointRequestBody } from "./entrypoint";
3
+ import type { EndpointResponse } from "./endpointResponse";
4
+ export interface OpenApiOperation {
5
+ parameters?: EntrypointParameter[];
6
+ requestBody?: EntrypointRequestBody;
7
+ responses: Partial<Record<ResponseCode, EndpointResponse>>;
8
+ }
@@ -0,0 +1,2 @@
1
+ 'use strict';
2
+
@@ -0,0 +1,4 @@
1
+ import type { RoutePath } from "../../../core/route";
2
+ import type { OpenApiMethod } from "./openApiMethod";
3
+ import type { OpenApiOperation } from "./openApiOperation";
4
+ export type OpenApiPath = Record<RoutePath, Partial<Record<OpenApiMethod, OpenApiOperation>> | undefined>;
@@ -0,0 +1,8 @@
1
+ export type SupportedBearerFormat = "JWT" | "JWS" | "JWE" | "Opaque";
2
+ export interface OpenApiSecuritySchema {
3
+ type: "http" | "apiKey";
4
+ scheme?: "bearer" | "basic";
5
+ bearerFormat?: SupportedBearerFormat;
6
+ name?: string;
7
+ in?: "header" | "query" | "cookie";
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duplojs/http",
3
- "version": "0.2.0",
3
+ "version": "0.5.0",
4
4
  "author": "mathcovax",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -14,7 +14,7 @@
14
14
  "test:tu:bench": "vitest bench",
15
15
  "test:tu:watch": "vitest --coverage --watch",
16
16
  "test:tu:update": "vitest --coverage --update",
17
- "test:types": "tsc -p tests/core/tsconfig.json && tsc -p tests/interfaces/node/tsconfig.json && tsc -p tests/interfaces/bun/tsconfig.json && tsc -p tests/interfaces/deno/tsconfig.json && tsc -p tests/plugins/codeGenerator/tsconfig.json",
17
+ "test:types": "tsc -p tests/core/tsconfig.json && tsc -p tests/client/tsconfig.json && tsc -p tests/interfaces/node/tsconfig.json && tsc -p tests/interfaces/bun/tsconfig.json && tsc -p tests/interfaces/deno/tsconfig.json && tsc -p tests/plugins/codeGenerator/tsconfig.json && tsc -p tests/plugins/openApiGenerator/tsconfig.json && npm -w integration run test:types",
18
18
  "test:lint": "eslint",
19
19
  "test:lint:fix": "eslint --fix",
20
20
  "prepare": "husky"
@@ -26,6 +26,11 @@
26
26
  "require": "./dist/core/index.cjs",
27
27
  "types": "./dist/core/index.d.ts"
28
28
  },
29
+ "./client": {
30
+ "import": "./dist/client/index.mjs",
31
+ "require": "./dist/client/index.cjs",
32
+ "types": "./dist/client/index.d.ts"
33
+ },
29
34
  "./node": {
30
35
  "import": "./dist/interfaces/node/index.mjs",
31
36
  "require": "./dist/interfaces/node/index.cjs",
@@ -45,6 +50,11 @@
45
50
  "import": "./dist/plugins/codeGenerator/index.mjs",
46
51
  "require": "./dist/plugins/codeGenerator/index.cjs",
47
52
  "types": "./dist/plugins/codeGenerator/index.d.ts"
53
+ },
54
+ "./openApiGenerator": {
55
+ "import": "./dist/plugins/openApiGenerator/index.mjs",
56
+ "require": "./dist/plugins/openApiGenerator/index.cjs",
57
+ "types": "./dist/plugins/openApiGenerator/index.d.ts"
48
58
  }
49
59
  },
50
60
  "files": [
@@ -52,8 +62,8 @@
52
62
  "README.md"
53
63
  ],
54
64
  "peerDependencies": {
55
- "@duplojs/data-parser-tools": ">=0.2.2 <1.0.0",
56
- "@duplojs/utils": ">=1.3.32 <2.0.0"
65
+ "@duplojs/data-parser-tools": ">=0.2.4 <1.0.0",
66
+ "@duplojs/utils": ">=1.4.40 <2.0.0"
57
67
  },
58
68
  "devDependencies": {
59
69
  "@commitlint/cli": "19.8.1",
@@ -84,5 +94,8 @@
84
94
  "keywords": [],
85
95
  "engines": {
86
96
  "node": ">=22.15.1"
97
+ },
98
+ "dependencies": {
99
+ "@types/web": "^0.0.317"
87
100
  }
88
101
  }