@effect-app/infra 0.133.0-next.3 → 0.133.0-next.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @effect-app/infra
2
2
 
3
+ ## 0.133.0-next.4
4
+
5
+ ### Minor Changes
6
+
7
+ - eb3bbc2: re-add basic routing
8
+
3
9
  ## 0.133.0-next.3
4
10
 
5
11
  ### Patch Changes
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.arrAsRouteDescriptionAny = arrAsRouteDescriptionAny;
7
+ exports.asRouteDescriptionAny = asRouteDescriptionAny;
8
+ exports.makeRouteDescriptor = makeRouteDescriptor;
9
+ function asRouteDescriptionAny(i) {
10
+ return i;
11
+ }
12
+ function arrAsRouteDescriptionAny(arr) {
13
+ return arr.map(asRouteDescriptionAny);
14
+ }
15
+ function makeRouteDescriptor(path, method, handler) {
16
+ return {
17
+ path,
18
+ handler,
19
+ method,
20
+ _tag: "Schema"
21
+ };
22
+ }
23
+ //# sourceMappingURL=routing.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.cjs","names":["asRouteDescriptionAny","i","arrAsRouteDescriptionAny","arr","map","makeRouteDescriptor","path","method","handler","_tag"],"sources":["../../../../_src/api/express/schema/routing.ts"],"sourcesContent":[null],"mappings":";;;;;;;;AAwCM,SAAUA,qBAAqBA,CAA+BC,CAAI;EACtE,OAAOA,CAAuB;AAChC;AAEM,SAAUC,wBAAwBA,CACtCC,GAAqB;EAErB,OAAOA,GAAG,CAACC,GAAG,CAACJ,qBAAqB,CAAC;AACvC;AAiCM,SAAUK,mBAAmBA,CAWjCC,IAAkB,EAClBC,MAAc,EACdC,OAUC;EAYD,OAAO;IAAEF,IAAI;IAAEE,OAAO;IAAED,MAAM;IAAEE,IAAI,EAAE;EAAQ,CAAE;AAClD"}
@@ -0,0 +1,236 @@
1
+ /* eslint-disable @typescript-eslint/ban-types */
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ import type { REST } from "@effect-app/prelude/schema"
4
+
5
+ export type Request<
6
+ M,
7
+ PathA,
8
+ CookieA,
9
+ QueryA,
10
+ BodyA,
11
+ HeaderA,
12
+ ReqA extends PathA & QueryA & BodyA,
13
+ PPath extends `/${string}`
14
+ > = REST.ReqRes<unknown, ReqA> & {
15
+ method: REST.Methods.Rest
16
+ path: PPath
17
+ Cookie?: REST.ReqRes<Record<string, string>, CookieA>
18
+ Path?: REST.ReqRes<Record<string, string>, PathA>
19
+ Body?: REST.ReqRes<unknown, BodyA>
20
+ Query?: REST.ReqRes<Record<string, string>, QueryA>
21
+ Headers?: REST.ReqRes<Record<string, string>, HeaderA>
22
+ Tag: Tag<M, M>
23
+ }
24
+
25
+ export interface RouteRequestHandler<
26
+ M,
27
+ PathA,
28
+ CookieA,
29
+ QueryA,
30
+ BodyA,
31
+ HeaderA,
32
+ ReqA extends PathA & QueryA & BodyA,
33
+ ResA,
34
+ PPath extends `/${string}`
35
+ > {
36
+ Request: Request<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, PPath>
37
+ Response?: REST.ReqRes<unknown, ResA> // | REST.ReqResSchemed<unknown, ResA>
38
+ ResponseOpenApi?: any
39
+ }
40
+
41
+ export function asRouteDescriptionAny<R extends RouteDescriptorAny>(i: R) {
42
+ return i as RouteDescriptorAny
43
+ }
44
+
45
+ export function arrAsRouteDescriptionAny<R extends RouteDescriptorAny>(
46
+ arr: ReadonlyArray<R>
47
+ ) {
48
+ return arr.map(asRouteDescriptionAny)
49
+ }
50
+
51
+ export interface RouteDescriptor<
52
+ M,
53
+ PathA,
54
+ CookieA,
55
+ QueryA,
56
+ BodyA,
57
+ HeaderA,
58
+ ReqA extends PathA & QueryA & BodyA,
59
+ ResA,
60
+ METHOD extends REST.Methods.Rest = REST.Methods.Rest
61
+ > {
62
+ _tag: "Schema"
63
+ path: `/${string}`
64
+ method: METHOD
65
+ handler: RouteRequestHandler<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, `/${string}`>
66
+ info?: {
67
+ tags: ReadonlyArray<string>
68
+ }
69
+ }
70
+
71
+ export type RouteDescriptorAny = RouteDescriptor<
72
+ any,
73
+ any,
74
+ any,
75
+ any,
76
+ any,
77
+ any,
78
+ any,
79
+ any
80
+ >
81
+
82
+ export function makeRouteDescriptor<
83
+ M,
84
+ PathA,
85
+ CookieA,
86
+ QueryA,
87
+ BodyA,
88
+ HeaderA,
89
+ ReqA extends PathA & QueryA & BodyA,
90
+ ResA = void,
91
+ METHOD extends REST.Methods.Rest = REST.Methods.Rest
92
+ >(
93
+ path: `/${string}`,
94
+ method: METHOD,
95
+ handler: RouteRequestHandler<
96
+ M,
97
+ PathA,
98
+ CookieA,
99
+ QueryA,
100
+ BodyA,
101
+ HeaderA,
102
+ ReqA,
103
+ ResA,
104
+ `/${string}`
105
+ >
106
+ ): RouteDescriptor<
107
+ M,
108
+ PathA,
109
+ CookieA,
110
+ QueryA,
111
+ BodyA,
112
+ HeaderA,
113
+ ReqA,
114
+ ResA,
115
+ METHOD
116
+ > {
117
+ return { path, handler, method, _tag: "Schema" }
118
+ }
119
+
120
+ // export function makeFromSchema<ResA>(
121
+ // e: RouteDescriptor<any, any, any, any, any, any, ResA, any>
122
+ // ) {
123
+ // const jsonSchema_ = OpenApi.for
124
+ // const jsonSchema = <E, A>(r: REST.ReqRes<E, A>) => jsonSchema_(r)
125
+ // const { Request: Req, Response: Res_, ResponseOpenApi } = e.handler
126
+ // const r = ResponseOpenApi ?? Res_
127
+ // const Res = r ? S.extractSchema(r) : S.Void
128
+ // // TODO EffectOption.fromNullable(Req.Headers).flatMapOpt(jsonSchema)
129
+ // // TODO: use the path vs body etc serialisation also in the Client.
130
+ // const makeReqQuerySchema = Effect(Option.fromNullable(Req.Query)).flatMap((_) =>
131
+ // _.match({
132
+ // onNone: () => Effect(Option.none),
133
+ // onSome: (_) => jsonSchema(_).map(Option.some)
134
+ // })
135
+ // )
136
+ // const makeReqHeadersSchema = Effect(Option.fromNullable(Req.Headers)).flatMap((_) =>
137
+ // _.match({
138
+ // onNone: () => Effect(Option.none),
139
+ // onSome: (_) => jsonSchema(_).map(Option.some)
140
+ // })
141
+ // )
142
+ // const makeReqCookieSchema = Effect(Option.fromNullable(Req.Cookie)).flatMap((_) =>
143
+ // _.match({
144
+ // onNone: () => Effect(Option.none),
145
+ // onSome: (_) => jsonSchema(_).map(Option.some)
146
+ // })
147
+ // )
148
+ // const makeReqPathSchema = Effect(Option.fromNullable(Req.Path)).flatMap((_) =>
149
+ // _.match({
150
+ // onNone: () => Effect(Option.none),
151
+ // onSome: (_) => jsonSchema(_).map(Option.some)
152
+ // })
153
+ // )
154
+ // const makeReqBodySchema = Effect(Option.fromNullable(Req.Body)).flatMap((_) =>
155
+ // _.match({
156
+ // onNone: () => Effect(Option.none),
157
+ // onSome: (_) => jsonSchema(_).map(Option.some)
158
+ // })
159
+ // )
160
+ // // const makeReqSchema = schema(Req)
161
+
162
+ // const makeResSchema = jsonSchema_(Res)
163
+
164
+ // function makeParameters(inn: ParameterLocation) {
165
+ // return (a: Option<JSONSchema | SubSchema>) => {
166
+ // return a
167
+ // .flatMap((o) => (isObjectSchema(o) ? Option(o) : Option.none))
168
+ // .map((x) => {
169
+ // // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
170
+ // return Object.keys(x.properties!).map((p) => {
171
+ // // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
172
+ // const schema = x.properties![p]
173
+ // const required = Boolean(x.required?.includes(p))
174
+ // return { name: p, in: inn, required, schema }
175
+ // })
176
+ // })
177
+ // .getOrElse(() => [])
178
+ // }
179
+ // }
180
+
181
+ // return Effect
182
+ // .all({
183
+ // req: jsonSchema(Req.Model),
184
+ // reqQuery: makeReqQuerySchema,
185
+ // reqHeaders: makeReqHeadersSchema,
186
+ // reqBody: makeReqBodySchema,
187
+ // reqPath: makeReqPathSchema,
188
+ // reqCookie: makeReqCookieSchema,
189
+ // res: makeResSchema
190
+ // })
191
+ // .map((_) => {
192
+ // // console.log("$$$ REQ", _.req)
193
+ // const isEmpty = !e.handler.Response || e.handler.Response === S.Void
194
+ // return {
195
+ // path: e.path,
196
+ // method: e.method.toLowerCase(),
197
+ // tags: e.info?.tags,
198
+ // description: _.req?.description,
199
+ // summary: _.req?.summary,
200
+ // operationId: _.req?.title,
201
+ // parameters: [
202
+ // ...makeParameters("path")(_.reqPath),
203
+ // ...makeParameters("query")(_.reqQuery),
204
+ // ...makeParameters("header")(_.reqHeaders),
205
+ // ...makeParameters("cookie")(_.reqCookie)
206
+ // ],
207
+ // requestBody: _
208
+ // .reqBody
209
+ // .map((schema) => ({
210
+ // content: { "application/json": { schema } }
211
+ // }))
212
+ // .value,
213
+ // responses: [
214
+ // isEmpty
215
+ // ? new Response(204, { description: "Empty" })
216
+ // : new Response(200, {
217
+ // description: "OK",
218
+ // content: { "application/json": { schema: _.res } }
219
+ // }),
220
+ // new Response(400, { description: "ValidationError" })
221
+ // ]
222
+ // .concat(
223
+ // e.path.includes(":") && isEmpty
224
+ // ? [new Response(404, { description: "NotFoundError" })]
225
+ // : []
226
+ // )
227
+ // }
228
+ // })
229
+ // }
230
+
231
+ // class Response {
232
+ // constructor(
233
+ // public readonly statusCode: number,
234
+ // public readonly type: any // string | JSONSchema | SubSchema
235
+ // ) {}
236
+ // }
@@ -0,0 +1,31 @@
1
+ import { Tag } from "effect/Context";
2
+ import type { REST } from "@effect-app/prelude/schema";
3
+ export type Request<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA extends PathA & QueryA & BodyA, PPath extends `/${string}`> = REST.ReqRes<unknown, ReqA> & {
4
+ method: REST.Methods.Rest;
5
+ path: PPath;
6
+ Cookie?: REST.ReqRes<Record<string, string>, CookieA>;
7
+ Path?: REST.ReqRes<Record<string, string>, PathA>;
8
+ Body?: REST.ReqRes<unknown, BodyA>;
9
+ Query?: REST.ReqRes<Record<string, string>, QueryA>;
10
+ Headers?: REST.ReqRes<Record<string, string>, HeaderA>;
11
+ Tag: Tag<M, M>;
12
+ };
13
+ export interface RouteRequestHandler<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA extends PathA & QueryA & BodyA, ResA, PPath extends `/${string}`> {
14
+ Request: Request<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, PPath>;
15
+ Response?: REST.ReqRes<unknown, ResA>;
16
+ ResponseOpenApi?: any;
17
+ }
18
+ export declare function asRouteDescriptionAny<R extends RouteDescriptorAny>(i: R): RouteDescriptorAny;
19
+ export declare function arrAsRouteDescriptionAny<R extends RouteDescriptorAny>(arr: ReadonlyArray<R>): RouteDescriptorAny[];
20
+ export interface RouteDescriptor<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA extends PathA & QueryA & BodyA, ResA, METHOD extends REST.Methods.Rest = REST.Methods.Rest> {
21
+ _tag: "Schema";
22
+ path: `/${string}`;
23
+ method: METHOD;
24
+ handler: RouteRequestHandler<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, `/${string}`>;
25
+ info?: {
26
+ tags: ReadonlyArray<string>;
27
+ };
28
+ }
29
+ export type RouteDescriptorAny = RouteDescriptor<any, any, any, any, any, any, any, any>;
30
+ export declare function makeRouteDescriptor<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA extends PathA & QueryA & BodyA, ResA = void, METHOD extends REST.Methods.Rest = REST.Methods.Rest>(path: `/${string}`, method: METHOD, handler: RouteRequestHandler<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, `/${string}`>): RouteDescriptor<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, METHOD>;
31
+ //# sourceMappingURL=routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../../../_src/api/express/schema/routing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export function asRouteDescriptionAny(i) {
2
+ return i;
3
+ }
4
+ export function arrAsRouteDescriptionAny(arr) {
5
+ return arr.map(asRouteDescriptionAny);
6
+ }
7
+ export function makeRouteDescriptor(path, method, handler) {
8
+ return { path, handler, method, _tag: "Schema" };
9
+ }
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL19zcmMvYXBpL2V4cHJlc3Mvc2NoZW1hL3JvdXRpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBd0NBLE1BQU0sVUFBVSxxQkFBcUIsQ0FBK0IsQ0FBSTtJQUN0RSxPQUFPLENBQXVCLENBQUE7QUFDaEMsQ0FBQztBQUVELE1BQU0sVUFBVSx3QkFBd0IsQ0FDdEMsR0FBcUI7SUFFckIsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUE7QUFDdkMsQ0FBQztBQWlDRCxNQUFNLFVBQVUsbUJBQW1CLENBV2pDLElBQWtCLEVBQ2xCLE1BQWMsRUFDZCxPQVVDO0lBWUQsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQTtBQUNsRCxDQUFDIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/infra",
3
- "version": "0.133.0-next.3",
3
+ "version": "0.133.0-next.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -20,9 +20,9 @@
20
20
  "pure-rand": "6.0.4",
21
21
  "redlock": "^4.2.0",
22
22
  "@effect-app/core": "0.97.0-next.0",
23
- "@effect-app/prelude": "0.107.0-next.3",
23
+ "@effect-app/schema": "0.150.0-next.1",
24
24
  "@effect-app/infra-adapters": "0.85.0-next.3",
25
- "@effect-app/schema": "0.150.0-next.1"
25
+ "@effect-app/prelude": "0.107.0-next.3"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@babel/cli": "^7.23.4",
@@ -143,6 +143,16 @@
143
143
  "default": "./_cjs/api/express/schema/jwt.cjs"
144
144
  }
145
145
  },
146
+ "./api/express/schema/routing": {
147
+ "import": {
148
+ "types": "./dist/api/express/schema/routing.d.ts",
149
+ "default": "./dist/api/express/schema/routing.js"
150
+ },
151
+ "require": {
152
+ "types": "./dist/api/express/schema/routing.d.ts",
153
+ "default": "./_cjs/api/express/schema/routing.cjs"
154
+ }
155
+ },
146
156
  "./api/reportError": {
147
157
  "import": {
148
158
  "types": "./dist/api/reportError.d.ts",
@@ -1,241 +0,0 @@
1
- /* eslint-disable @typescript-eslint/ban-types */
2
- /* eslint-disable @typescript-eslint/no-explicit-any */
3
- import * as S from "@effect-app/prelude/schema"
4
- import type { Methods } from "@effect-app/schema"
5
-
6
- import type { JSONSchema, ParameterLocation, SubSchema } from "@effect-app/infra-adapters/Openapi/atlas-plutus"
7
- import { isObjectSchema } from "@effect-app/infra-adapters/Openapi/atlas-plutus"
8
- import * as OpenApi from "@effect-app/infra-adapters/Openapi/index"
9
-
10
- export type Request<
11
- M,
12
- PathA,
13
- CookieA,
14
- QueryA,
15
- BodyA,
16
- HeaderA,
17
- ReqA extends PathA & QueryA & BodyA,
18
- PPath extends `/${string}`
19
- > = S.REST.ReqRes<unknown, ReqA> & {
20
- method: Methods.Rest
21
- path: PPath
22
- Cookie?: S.REST.ReqRes<Record<string, string>, CookieA>
23
- Path?: S.REST.ReqRes<Record<string, string>, PathA>
24
- Body?: S.REST.ReqRes<unknown, BodyA>
25
- Query?: S.REST.ReqRes<Record<string, string>, QueryA>
26
- Headers?: S.REST.ReqRes<Record<string, string>, HeaderA>
27
- Tag: Tag<M, M>
28
- }
29
-
30
- export interface RouteRequestHandler<
31
- M,
32
- PathA,
33
- CookieA,
34
- QueryA,
35
- BodyA,
36
- HeaderA,
37
- ReqA extends PathA & QueryA & BodyA,
38
- ResA,
39
- PPath extends `/${string}`
40
- > {
41
- Request: Request<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, PPath>
42
- Response?: S.REST.ReqRes<unknown, ResA> // | S.REST.ReqResSchemed<unknown, ResA>
43
- ResponseOpenApi?: any
44
- }
45
-
46
- export function asRouteDescriptionAny<R extends RouteDescriptorAny>(i: R) {
47
- return i as RouteDescriptorAny
48
- }
49
-
50
- export function arrAsRouteDescriptionAny<R extends RouteDescriptorAny>(
51
- arr: ReadonlyArray<R>
52
- ) {
53
- return arr.map(asRouteDescriptionAny)
54
- }
55
-
56
- export interface RouteDescriptor<
57
- M,
58
- PathA,
59
- CookieA,
60
- QueryA,
61
- BodyA,
62
- HeaderA,
63
- ReqA extends PathA & QueryA & BodyA,
64
- ResA,
65
- METHOD extends Methods.Rest = Methods.Rest
66
- > {
67
- _tag: "Schema"
68
- path: `/${string}`
69
- method: METHOD
70
- handler: RouteRequestHandler<M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, `/${string}`>
71
- info?: {
72
- tags: ReadonlyArray<string>
73
- }
74
- }
75
-
76
- export type RouteDescriptorAny = RouteDescriptor<
77
- any,
78
- any,
79
- any,
80
- any,
81
- any,
82
- any,
83
- any,
84
- any
85
- >
86
-
87
- export function makeRouteDescriptor<
88
- M,
89
- PathA,
90
- CookieA,
91
- QueryA,
92
- BodyA,
93
- HeaderA,
94
- ReqA extends PathA & QueryA & BodyA,
95
- ResA = void,
96
- METHOD extends Methods.Rest = Methods.Rest
97
- >(
98
- path: `/${string}`,
99
- method: METHOD,
100
- handler: RouteRequestHandler<
101
- M,
102
- PathA,
103
- CookieA,
104
- QueryA,
105
- BodyA,
106
- HeaderA,
107
- ReqA,
108
- ResA,
109
- `/${string}`
110
- >
111
- ): RouteDescriptor<
112
- M,
113
- PathA,
114
- CookieA,
115
- QueryA,
116
- BodyA,
117
- HeaderA,
118
- ReqA,
119
- ResA,
120
- METHOD
121
- > {
122
- return { path, handler, method, _tag: "Schema" }
123
- }
124
-
125
- export function makeFromSchema<ResA>(
126
- e: RouteDescriptor<any, any, any, any, any, any, ResA, any>
127
- ) {
128
- const jsonSchema_ = OpenApi.for
129
- const jsonSchema = <E, A>(r: S.REST.ReqRes<E, A>) => jsonSchema_(r)
130
- const { Request: Req, Response: Res_, ResponseOpenApi } = e.handler
131
- const r = ResponseOpenApi ?? Res_
132
- const Res = r ? S.extractSchema(r) : S.Void
133
- // TODO EffectOption.fromNullable(Req.Headers).flatMapOpt(jsonSchema)
134
- // TODO: use the path vs body etc serialisation also in the Client.
135
- const makeReqQuerySchema = Effect(Option.fromNullable(Req.Query)).flatMap((_) =>
136
- _.match({
137
- onNone: () => Effect(Option.none),
138
- onSome: (_) => jsonSchema(_).map(Option.some)
139
- })
140
- )
141
- const makeReqHeadersSchema = Effect(Option.fromNullable(Req.Headers)).flatMap((_) =>
142
- _.match({
143
- onNone: () => Effect(Option.none),
144
- onSome: (_) => jsonSchema(_).map(Option.some)
145
- })
146
- )
147
- const makeReqCookieSchema = Effect(Option.fromNullable(Req.Cookie)).flatMap((_) =>
148
- _.match({
149
- onNone: () => Effect(Option.none),
150
- onSome: (_) => jsonSchema(_).map(Option.some)
151
- })
152
- )
153
- const makeReqPathSchema = Effect(Option.fromNullable(Req.Path)).flatMap((_) =>
154
- _.match({
155
- onNone: () => Effect(Option.none),
156
- onSome: (_) => jsonSchema(_).map(Option.some)
157
- })
158
- )
159
- const makeReqBodySchema = Effect(Option.fromNullable(Req.Body)).flatMap((_) =>
160
- _.match({
161
- onNone: () => Effect(Option.none),
162
- onSome: (_) => jsonSchema(_).map(Option.some)
163
- })
164
- )
165
- // const makeReqSchema = schema(Req)
166
-
167
- const makeResSchema = jsonSchema_(Res)
168
-
169
- function makeParameters(inn: ParameterLocation) {
170
- return (a: Option<JSONSchema | SubSchema>) => {
171
- return a
172
- .flatMap((o) => (isObjectSchema(o) ? Option(o) : Option.none))
173
- .map((x) => {
174
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
175
- return Object.keys(x.properties!).map((p) => {
176
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
177
- const schema = x.properties![p]
178
- const required = Boolean(x.required?.includes(p))
179
- return { name: p, in: inn, required, schema }
180
- })
181
- })
182
- .getOrElse(() => [])
183
- }
184
- }
185
-
186
- return Effect
187
- .all({
188
- req: jsonSchema(Req.Model),
189
- reqQuery: makeReqQuerySchema,
190
- reqHeaders: makeReqHeadersSchema,
191
- reqBody: makeReqBodySchema,
192
- reqPath: makeReqPathSchema,
193
- reqCookie: makeReqCookieSchema,
194
- res: makeResSchema
195
- })
196
- .map((_) => {
197
- // console.log("$$$ REQ", _.req)
198
- const isEmpty = !e.handler.Response || e.handler.Response === S.Void
199
- return {
200
- path: e.path,
201
- method: e.method.toLowerCase(),
202
- tags: e.info?.tags,
203
- description: _.req?.description,
204
- summary: _.req?.summary,
205
- operationId: _.req?.title,
206
- parameters: [
207
- ...makeParameters("path")(_.reqPath),
208
- ...makeParameters("query")(_.reqQuery),
209
- ...makeParameters("header")(_.reqHeaders),
210
- ...makeParameters("cookie")(_.reqCookie)
211
- ],
212
- requestBody: _
213
- .reqBody
214
- .map((schema) => ({
215
- content: { "application/json": { schema } }
216
- }))
217
- .value,
218
- responses: [
219
- isEmpty
220
- ? new Response(204, { description: "Empty" })
221
- : new Response(200, {
222
- description: "OK",
223
- content: { "application/json": { schema: _.res } }
224
- }),
225
- new Response(400, { description: "ValidationError" })
226
- ]
227
- .concat(
228
- e.path.includes(":") && isEmpty
229
- ? [new Response(404, { description: "NotFoundError" })]
230
- : []
231
- )
232
- }
233
- })
234
- }
235
-
236
- class Response {
237
- constructor(
238
- public readonly statusCode: number,
239
- public readonly type: any // string | JSONSchema | SubSchema
240
- ) {}
241
- }