@effect/platform 0.62.4 → 0.63.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.
- package/HttpApi/package.json +6 -0
- package/HttpApiBuilder/package.json +6 -0
- package/HttpApiClient/package.json +6 -0
- package/HttpApiEndpoint/package.json +6 -0
- package/HttpApiError/package.json +6 -0
- package/HttpApiGroup/package.json +6 -0
- package/HttpApiSchema/package.json +6 -0
- package/HttpApiSecurity/package.json +6 -0
- package/HttpApiSwagger/package.json +6 -0
- package/OpenApi/package.json +6 -0
- package/README.md +863 -302
- package/dist/cjs/HttpApi.js +168 -0
- package/dist/cjs/HttpApi.js.map +1 -0
- package/dist/cjs/HttpApiBuilder.js +471 -0
- package/dist/cjs/HttpApiBuilder.js.map +1 -0
- package/dist/cjs/HttpApiClient.js +134 -0
- package/dist/cjs/HttpApiClient.js.map +1 -0
- package/dist/cjs/HttpApiEndpoint.js +181 -0
- package/dist/cjs/HttpApiEndpoint.js.map +1 -0
- package/dist/cjs/HttpApiError.js +69 -0
- package/dist/cjs/HttpApiError.js.map +1 -0
- package/dist/cjs/HttpApiGroup.js +151 -0
- package/dist/cjs/HttpApiGroup.js.map +1 -0
- package/dist/cjs/HttpApiSchema.js +241 -0
- package/dist/cjs/HttpApiSchema.js.map +1 -0
- package/dist/cjs/HttpApiSecurity.js +83 -0
- package/dist/cjs/HttpApiSecurity.js.map +1 -0
- package/dist/cjs/HttpApiSwagger.js +50 -0
- package/dist/cjs/HttpApiSwagger.js.map +1 -0
- package/dist/cjs/HttpMethod.js +1 -1
- package/dist/cjs/HttpMethod.js.map +1 -1
- package/dist/cjs/HttpRouter.js +6 -1
- package/dist/cjs/HttpRouter.js.map +1 -1
- package/dist/cjs/OpenApi.js +317 -0
- package/dist/cjs/OpenApi.js.map +1 -0
- package/dist/cjs/index.js +21 -1
- package/dist/cjs/internal/apiSwagger.js +2 -0
- package/dist/cjs/internal/apiSwagger.js.map +1 -0
- package/dist/cjs/internal/httpRouter.js +6 -1
- package/dist/cjs/internal/httpRouter.js.map +1 -1
- package/dist/cjs/internal/multipart.js +5 -1
- package/dist/cjs/internal/multipart.js.map +1 -1
- package/dist/dts/HttpApi.d.ts +156 -0
- package/dist/dts/HttpApi.d.ts.map +1 -0
- package/dist/dts/HttpApiBuilder.d.ts +296 -0
- package/dist/dts/HttpApiBuilder.d.ts.map +1 -0
- package/dist/dts/HttpApiClient.d.ts +31 -0
- package/dist/dts/HttpApiClient.d.ts.map +1 -0
- package/dist/dts/HttpApiEndpoint.d.ts +350 -0
- package/dist/dts/HttpApiEndpoint.d.ts.map +1 -0
- package/dist/dts/HttpApiError.d.ts +70 -0
- package/dist/dts/HttpApiError.d.ts.map +1 -0
- package/dist/dts/HttpApiGroup.d.ts +196 -0
- package/dist/dts/HttpApiGroup.d.ts.map +1 -0
- package/dist/dts/HttpApiSchema.d.ts +223 -0
- package/dist/dts/HttpApiSchema.d.ts.map +1 -0
- package/dist/dts/HttpApiSecurity.d.ts +122 -0
- package/dist/dts/HttpApiSecurity.d.ts.map +1 -0
- package/dist/dts/HttpApiSwagger.d.ts +10 -0
- package/dist/dts/HttpApiSwagger.d.ts.map +1 -0
- package/dist/dts/HttpMethod.d.ts +16 -0
- package/dist/dts/HttpMethod.d.ts.map +1 -1
- package/dist/dts/HttpRouter.d.ts +8 -0
- package/dist/dts/HttpRouter.d.ts.map +1 -1
- package/dist/dts/HttpServerResponse.d.ts +3 -3
- package/dist/dts/HttpServerResponse.d.ts.map +1 -1
- package/dist/dts/OpenApi.d.ts +348 -0
- package/dist/dts/OpenApi.d.ts.map +1 -0
- package/dist/dts/index.d.ts +40 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/apiSwagger.d.ts +2 -0
- package/dist/dts/internal/apiSwagger.d.ts.map +1 -0
- package/dist/dts/internal/httpRouter.d.ts.map +1 -1
- package/dist/esm/HttpApi.js +157 -0
- package/dist/esm/HttpApi.js.map +1 -0
- package/dist/esm/HttpApiBuilder.js +447 -0
- package/dist/esm/HttpApiBuilder.js.map +1 -0
- package/dist/esm/HttpApiClient.js +124 -0
- package/dist/esm/HttpApiClient.js.map +1 -0
- package/dist/esm/HttpApiEndpoint.js +169 -0
- package/dist/esm/HttpApiEndpoint.js.map +1 -0
- package/dist/esm/HttpApiError.js +59 -0
- package/dist/esm/HttpApiError.js.map +1 -0
- package/dist/esm/HttpApiGroup.js +140 -0
- package/dist/esm/HttpApiGroup.js.map +1 -0
- package/dist/esm/HttpApiSchema.js +217 -0
- package/dist/esm/HttpApiSchema.js.map +1 -0
- package/dist/esm/HttpApiSecurity.js +73 -0
- package/dist/esm/HttpApiSecurity.js.map +1 -0
- package/dist/esm/HttpApiSwagger.js +40 -0
- package/dist/esm/HttpApiSwagger.js.map +1 -0
- package/dist/esm/HttpMethod.js +1 -1
- package/dist/esm/HttpMethod.js.map +1 -1
- package/dist/esm/HttpRouter.js +5 -0
- package/dist/esm/HttpRouter.js.map +1 -1
- package/dist/esm/OpenApi.js +299 -0
- package/dist/esm/OpenApi.js.map +1 -0
- package/dist/esm/index.js +40 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/apiSwagger.js +2 -0
- package/dist/esm/internal/apiSwagger.js.map +1 -0
- package/dist/esm/internal/httpRouter.js +5 -0
- package/dist/esm/internal/httpRouter.js.map +1 -1
- package/dist/esm/internal/multipart.js +5 -1
- package/dist/esm/internal/multipart.js.map +1 -1
- package/package.json +83 -3
- package/src/HttpApi.ts +342 -0
- package/src/HttpApiBuilder.ts +869 -0
- package/src/HttpApiClient.ts +228 -0
- package/src/HttpApiEndpoint.ts +818 -0
- package/src/HttpApiError.ts +113 -0
- package/src/HttpApiGroup.ts +365 -0
- package/src/HttpApiSchema.ts +384 -0
- package/src/HttpApiSecurity.ts +169 -0
- package/src/HttpApiSwagger.ts +46 -0
- package/src/HttpMethod.ts +19 -1
- package/src/HttpRouter.ts +9 -0
- package/src/HttpServerResponse.ts +3 -3
- package/src/OpenApi.ts +665 -0
- package/src/index.ts +50 -0
- package/src/internal/apiSwagger.ts +7 -0
- package/src/internal/httpRouter.ts +9 -0
- package/src/internal/multipart.ts +5 -1
package/src/HttpApi.ts
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 1.0.0
|
|
3
|
+
*/
|
|
4
|
+
import * as AST from "@effect/schema/AST"
|
|
5
|
+
import type * as Schema from "@effect/schema/Schema"
|
|
6
|
+
import * as Chunk from "effect/Chunk"
|
|
7
|
+
import * as Context from "effect/Context"
|
|
8
|
+
import { dual } from "effect/Function"
|
|
9
|
+
import * as Option from "effect/Option"
|
|
10
|
+
import type { Pipeable } from "effect/Pipeable"
|
|
11
|
+
import { pipeArguments } from "effect/Pipeable"
|
|
12
|
+
import * as Predicate from "effect/Predicate"
|
|
13
|
+
import * as HttpApiEndpoint from "./HttpApiEndpoint.js"
|
|
14
|
+
import { HttpApiDecodeError } from "./HttpApiError.js"
|
|
15
|
+
import * as HttpApiGroup from "./HttpApiGroup.js"
|
|
16
|
+
import * as HttpApiSchema from "./HttpApiSchema.js"
|
|
17
|
+
import type { HttpMethod } from "./HttpMethod.js"
|
|
18
|
+
import type * as HttpRouter from "./HttpRouter.js"
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @since 1.0.0
|
|
22
|
+
* @category type ids
|
|
23
|
+
*/
|
|
24
|
+
export const TypeId: unique symbol = Symbol.for("@effect/platform/HttpApi")
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @since 1.0.0
|
|
28
|
+
* @category type ids
|
|
29
|
+
*/
|
|
30
|
+
export type TypeId = typeof TypeId
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @since 1.0.0
|
|
34
|
+
* @category guards
|
|
35
|
+
*/
|
|
36
|
+
export const isHttpApi = (u: unknown): u is HttpApi<any, any> => Predicate.hasProperty(u, TypeId)
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* An `HttpApi` represents a collection of `HttpApiGroup`s. You can use an `HttpApi` to
|
|
40
|
+
* represent your entire domain.
|
|
41
|
+
*
|
|
42
|
+
* @since 1.0.0
|
|
43
|
+
* @category models
|
|
44
|
+
*/
|
|
45
|
+
export interface HttpApi<
|
|
46
|
+
out Groups extends HttpApiGroup.HttpApiGroup.Any = never,
|
|
47
|
+
in out Error = never,
|
|
48
|
+
out ErrorR = never
|
|
49
|
+
> extends Pipeable {
|
|
50
|
+
new(_: never): {}
|
|
51
|
+
readonly [TypeId]: TypeId
|
|
52
|
+
readonly groups: Chunk.Chunk<Groups>
|
|
53
|
+
readonly errorSchema: Schema.Schema<Error, unknown, ErrorR>
|
|
54
|
+
readonly annotations: Context.Context<never>
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @since 1.0.0
|
|
59
|
+
* @category tags
|
|
60
|
+
*/
|
|
61
|
+
export const HttpApi: Context.Tag<HttpApi.Service, HttpApi.Any> = Context.GenericTag<HttpApi.Service, HttpApi.Any>(
|
|
62
|
+
"@effect/platform/HttpApi"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @since 1.0.0
|
|
67
|
+
* @category models
|
|
68
|
+
*/
|
|
69
|
+
export declare namespace HttpApi {
|
|
70
|
+
/**
|
|
71
|
+
* @since 1.0.0
|
|
72
|
+
* @category models
|
|
73
|
+
*/
|
|
74
|
+
export interface Service {
|
|
75
|
+
readonly _: unique symbol
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @since 1.0.0
|
|
80
|
+
* @category models
|
|
81
|
+
*/
|
|
82
|
+
export interface Any extends Pipeable {
|
|
83
|
+
new(_: never): {}
|
|
84
|
+
readonly [TypeId]: TypeId
|
|
85
|
+
readonly groups: Chunk.Chunk<HttpApiGroup.HttpApiGroup.Any>
|
|
86
|
+
readonly errorSchema: Schema.Schema.All
|
|
87
|
+
readonly annotations: Context.Context<never>
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @since 1.0.0
|
|
92
|
+
* @category models
|
|
93
|
+
*/
|
|
94
|
+
export type Context<A> = A extends HttpApi<infer _Groups, infer _ApiError, infer _ApiErrorR>
|
|
95
|
+
? _ApiErrorR | HttpApiGroup.HttpApiGroup.Context<_Groups>
|
|
96
|
+
: never
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const Proto = {
|
|
100
|
+
[TypeId]: TypeId,
|
|
101
|
+
pipe() {
|
|
102
|
+
return pipeArguments(this, arguments)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const makeProto = <Groups extends HttpApiGroup.HttpApiGroup.Any, Error, ErrorR>(options: {
|
|
107
|
+
readonly groups: Chunk.Chunk<Groups>
|
|
108
|
+
readonly errorSchema: Schema.Schema<Error, unknown, ErrorR>
|
|
109
|
+
readonly annotations: Context.Context<never>
|
|
110
|
+
}): HttpApi<Groups, Error, ErrorR> => {
|
|
111
|
+
function HttpApi() {}
|
|
112
|
+
Object.setPrototypeOf(HttpApi, Proto)
|
|
113
|
+
return Object.assign(HttpApi, options) as any
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* An empty `HttpApi`. You can use this to start building your `HttpApi`.
|
|
118
|
+
*
|
|
119
|
+
* You can add groups to this `HttpApi` using the `addGroup` function.
|
|
120
|
+
*
|
|
121
|
+
* @since 1.0.0
|
|
122
|
+
* @category constructors
|
|
123
|
+
*/
|
|
124
|
+
export const empty: HttpApi = makeProto({
|
|
125
|
+
groups: Chunk.empty(),
|
|
126
|
+
errorSchema: HttpApiDecodeError as any,
|
|
127
|
+
annotations: Context.empty()
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Add a `HttpApiGroup` to an `HttpApi`.
|
|
132
|
+
*
|
|
133
|
+
* @since 1.0.0
|
|
134
|
+
* @category constructors
|
|
135
|
+
*/
|
|
136
|
+
export const addGroup: {
|
|
137
|
+
<Group extends HttpApiGroup.HttpApiGroup.Any>(
|
|
138
|
+
group: Group
|
|
139
|
+
): <Groups extends HttpApiGroup.HttpApiGroup.Any, Error, ErrorR>(
|
|
140
|
+
self: HttpApi<Groups, Error, ErrorR>
|
|
141
|
+
) => HttpApi<Groups | Group, Error, ErrorR>
|
|
142
|
+
<Group extends HttpApiGroup.HttpApiGroup.Any>(
|
|
143
|
+
path: HttpRouter.PathInput,
|
|
144
|
+
group: Group
|
|
145
|
+
): <Groups extends HttpApiGroup.HttpApiGroup.Any, Error, ErrorR>(
|
|
146
|
+
self: HttpApi<Groups, Error, ErrorR>
|
|
147
|
+
) => HttpApi<Groups | Group, Error, ErrorR>
|
|
148
|
+
<Groups extends HttpApiGroup.HttpApiGroup.Any, Error, ErrorR, Group extends HttpApiGroup.HttpApiGroup.Any>(
|
|
149
|
+
self: HttpApi<Groups, Error, ErrorR>,
|
|
150
|
+
group: Group
|
|
151
|
+
): HttpApi<Groups | Group, Error, ErrorR>
|
|
152
|
+
<Groups extends HttpApiGroup.HttpApiGroup.Any, Error, ErrorR, Group extends HttpApiGroup.HttpApiGroup.Any>(
|
|
153
|
+
self: HttpApi<Groups, Error, ErrorR>,
|
|
154
|
+
path: HttpRouter.PathInput,
|
|
155
|
+
group: Group
|
|
156
|
+
): HttpApi<Groups | Group, Error, ErrorR>
|
|
157
|
+
} = dual(
|
|
158
|
+
(args) => isHttpApi(args[0]),
|
|
159
|
+
(
|
|
160
|
+
self: HttpApi.Any,
|
|
161
|
+
...args: [group: HttpApiGroup.HttpApiGroup.Any] | [path: HttpRouter.PathInput, group: HttpApiGroup.HttpApiGroup.Any]
|
|
162
|
+
): HttpApi.Any => {
|
|
163
|
+
const group = args.length === 1 ? args[0] : HttpApiGroup.prefix(args[1] as any, args[0])
|
|
164
|
+
return makeProto({
|
|
165
|
+
errorSchema: self.errorSchema as any,
|
|
166
|
+
annotations: self.annotations,
|
|
167
|
+
groups: Chunk.append(self.groups, group)
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
/**
|
|
172
|
+
* Add an error schema to an `HttpApi`, which is shared by all endpoints in the
|
|
173
|
+
* `HttpApi`.
|
|
174
|
+
*
|
|
175
|
+
* Useful for adding error types from middleware or other shared error types.
|
|
176
|
+
*
|
|
177
|
+
* @since 1.0.0
|
|
178
|
+
* @category errors
|
|
179
|
+
*/
|
|
180
|
+
export const addError: {
|
|
181
|
+
<A, I, R>(
|
|
182
|
+
schema: Schema.Schema<A, I, R>,
|
|
183
|
+
annotations?: {
|
|
184
|
+
readonly status?: number | undefined
|
|
185
|
+
}
|
|
186
|
+
): <Groups extends HttpApiGroup.HttpApiGroup.Any, Error, ErrorR>(
|
|
187
|
+
self: HttpApi<Groups, Error, ErrorR>
|
|
188
|
+
) => HttpApi<Groups, Error | A, ErrorR | R>
|
|
189
|
+
<Groups extends HttpApiGroup.HttpApiGroup.Any, Error, ErrorR, A, I, R>(
|
|
190
|
+
self: HttpApi<Groups, Error, ErrorR>,
|
|
191
|
+
schema: Schema.Schema<A, I, R>,
|
|
192
|
+
annotations?: {
|
|
193
|
+
readonly status?: number | undefined
|
|
194
|
+
}
|
|
195
|
+
): HttpApi<Groups, Error | A, ErrorR | R>
|
|
196
|
+
} = dual(
|
|
197
|
+
(args) => isHttpApi(args[0]),
|
|
198
|
+
<Groups extends HttpApiGroup.HttpApiGroup.Any, Error, ErrorR, A, I, R>(
|
|
199
|
+
self: HttpApi<Groups, Error, ErrorR>,
|
|
200
|
+
schema: Schema.Schema<A, I, R>,
|
|
201
|
+
annotations?: {
|
|
202
|
+
readonly status?: number | undefined
|
|
203
|
+
}
|
|
204
|
+
): HttpApi<Groups, Error | A, ErrorR | R> =>
|
|
205
|
+
makeProto({
|
|
206
|
+
groups: self.groups,
|
|
207
|
+
annotations: self.annotations,
|
|
208
|
+
errorSchema: HttpApiSchema.UnionUnify(
|
|
209
|
+
self.errorSchema,
|
|
210
|
+
schema.annotations(HttpApiSchema.annotations({
|
|
211
|
+
status: annotations?.status ?? HttpApiSchema.getStatusError(schema)
|
|
212
|
+
}))
|
|
213
|
+
)
|
|
214
|
+
})
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* @since 1.0.0
|
|
219
|
+
* @category annotations
|
|
220
|
+
*/
|
|
221
|
+
export const annotateMerge: {
|
|
222
|
+
<I>(context: Context.Context<I>): <A extends HttpApi.Any>(self: A) => A
|
|
223
|
+
<A extends HttpApi.Any, I>(self: A, context: Context.Context<I>): A
|
|
224
|
+
} = dual(
|
|
225
|
+
2,
|
|
226
|
+
<A extends HttpApi.Any, I>(self: A, context: Context.Context<I>): A =>
|
|
227
|
+
makeProto({
|
|
228
|
+
groups: self.groups,
|
|
229
|
+
errorSchema: self.errorSchema as any,
|
|
230
|
+
annotations: Context.merge(self.annotations, context)
|
|
231
|
+
}) as A
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* @since 1.0.0
|
|
236
|
+
* @category annotations
|
|
237
|
+
*/
|
|
238
|
+
export const annotate: {
|
|
239
|
+
<I, S>(tag: Context.Tag<I, S>, value: S): <A extends HttpApi.Any>(self: A) => A
|
|
240
|
+
<A extends HttpApi.Any, I, S>(self: A, tag: Context.Tag<I, S>, value: S): A
|
|
241
|
+
} = dual(
|
|
242
|
+
3,
|
|
243
|
+
<A extends HttpApi.Any, I, S>(self: A, tag: Context.Tag<I, S>, value: S): A =>
|
|
244
|
+
makeProto({
|
|
245
|
+
groups: self.groups,
|
|
246
|
+
errorSchema: self.errorSchema as any,
|
|
247
|
+
annotations: Context.add(self.annotations, tag, value)
|
|
248
|
+
}) as A
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Extract metadata from an `HttpApi`, which can be used to generate documentation
|
|
253
|
+
* or other tooling.
|
|
254
|
+
*
|
|
255
|
+
* See the `OpenApi` & `HttpApiClient` modules for examples of how to use this function.
|
|
256
|
+
*
|
|
257
|
+
* @since 1.0.0
|
|
258
|
+
* @category reflection
|
|
259
|
+
*/
|
|
260
|
+
export const reflect = <Groups extends HttpApiGroup.HttpApiGroup.Any, Error, ErrorR>(
|
|
261
|
+
self: HttpApi<Groups, Error, ErrorR>,
|
|
262
|
+
options: {
|
|
263
|
+
readonly onGroup: (options: {
|
|
264
|
+
readonly group: HttpApiGroup.HttpApiGroup<string, any>
|
|
265
|
+
readonly mergedAnnotations: Context.Context<never>
|
|
266
|
+
}) => void
|
|
267
|
+
readonly onEndpoint: (options: {
|
|
268
|
+
readonly group: HttpApiGroup.HttpApiGroup<string, any>
|
|
269
|
+
readonly endpoint: HttpApiEndpoint.HttpApiEndpoint<string, HttpMethod>
|
|
270
|
+
readonly mergedAnnotations: Context.Context<never>
|
|
271
|
+
readonly successAST: Option.Option<AST.AST>
|
|
272
|
+
readonly successStatus: number
|
|
273
|
+
readonly successEncoding: HttpApiSchema.Encoding
|
|
274
|
+
readonly errors: ReadonlyMap<number, Option.Option<AST.AST>>
|
|
275
|
+
}) => void
|
|
276
|
+
}
|
|
277
|
+
) => {
|
|
278
|
+
const apiErrors = extractErrors(self.errorSchema.ast, new Map())
|
|
279
|
+
|
|
280
|
+
const groups = self.groups as Iterable<HttpApiGroup.HttpApiGroup<string, any>>
|
|
281
|
+
for (const group of groups) {
|
|
282
|
+
const groupErrors = extractErrors(group.errorSchema.ast, apiErrors)
|
|
283
|
+
const groupAnnotations = Context.merge(self.annotations, group.annotations)
|
|
284
|
+
options.onGroup({
|
|
285
|
+
group,
|
|
286
|
+
mergedAnnotations: groupAnnotations
|
|
287
|
+
})
|
|
288
|
+
const endpoints = group.endpoints as Iterable<HttpApiEndpoint.HttpApiEndpoint<string, HttpMethod>>
|
|
289
|
+
for (const endpoint of endpoints) {
|
|
290
|
+
options.onEndpoint({
|
|
291
|
+
group,
|
|
292
|
+
endpoint,
|
|
293
|
+
mergedAnnotations: Context.merge(groupAnnotations, endpoint.annotations),
|
|
294
|
+
successAST: HttpApiEndpoint.schemaSuccess(endpoint).pipe(
|
|
295
|
+
Option.map((schema) => schema.ast)
|
|
296
|
+
),
|
|
297
|
+
successStatus: HttpApiSchema.getStatusSuccess(endpoint.successSchema),
|
|
298
|
+
successEncoding: HttpApiSchema.getEncoding(endpoint.successSchema.ast),
|
|
299
|
+
errors: extractErrors(endpoint.errorSchema.ast, groupErrors)
|
|
300
|
+
})
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// -------------------------------------------------------------------------------------
|
|
306
|
+
|
|
307
|
+
const extractErrors = (
|
|
308
|
+
ast: AST.AST,
|
|
309
|
+
inherited: ReadonlyMap<number, Option.Option<AST.AST>>
|
|
310
|
+
): ReadonlyMap<number, Option.Option<AST.AST>> => {
|
|
311
|
+
const topStatus = HttpApiSchema.getStatusErrorAST(ast)
|
|
312
|
+
const errors = new Map(inherited)
|
|
313
|
+
function process(ast: AST.AST) {
|
|
314
|
+
if (ast._tag === "NeverKeyword") {
|
|
315
|
+
return
|
|
316
|
+
}
|
|
317
|
+
const status = HttpApiSchema.getStatus(ast, topStatus)
|
|
318
|
+
const emptyDecodeable = HttpApiSchema.getEmptyDecodeable(ast)
|
|
319
|
+
const current = errors.get(status) ?? Option.none()
|
|
320
|
+
errors.set(
|
|
321
|
+
status,
|
|
322
|
+
current.pipe(
|
|
323
|
+
Option.map((current) =>
|
|
324
|
+
AST.Union.make(
|
|
325
|
+
current._tag === "Union" ? [...current.types, ast] : [current, ast]
|
|
326
|
+
)
|
|
327
|
+
),
|
|
328
|
+
Option.orElse(() =>
|
|
329
|
+
!emptyDecodeable && AST.encodedAST(ast)._tag === "VoidKeyword" ? Option.none() : Option.some(ast)
|
|
330
|
+
)
|
|
331
|
+
)
|
|
332
|
+
)
|
|
333
|
+
}
|
|
334
|
+
if (ast._tag === "Union") {
|
|
335
|
+
for (const type of ast.types) {
|
|
336
|
+
process(type)
|
|
337
|
+
}
|
|
338
|
+
} else {
|
|
339
|
+
process(ast)
|
|
340
|
+
}
|
|
341
|
+
return errors
|
|
342
|
+
}
|