@effect/platform 0.70.7 → 0.71.1
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/README.md +22 -34
- package/dist/cjs/HttpApi.js +15 -6
- package/dist/cjs/HttpApi.js.map +1 -1
- package/dist/cjs/HttpApiBuilder.js +4 -4
- package/dist/cjs/HttpApiBuilder.js.map +1 -1
- package/dist/cjs/HttpApiClient.js.map +1 -1
- package/dist/cjs/HttpApiError.js +109 -1
- package/dist/cjs/HttpApiError.js.map +1 -1
- package/dist/cjs/HttpApiGroup.js.map +1 -1
- package/dist/cjs/HttpApiSchema.js +46 -2
- package/dist/cjs/HttpApiSchema.js.map +1 -1
- package/dist/cjs/HttpApp.js +6 -3
- package/dist/cjs/HttpApp.js.map +1 -1
- package/dist/cjs/OpenApi.js +19 -2
- package/dist/cjs/OpenApi.js.map +1 -1
- package/dist/dts/HttpApi.d.ts +13 -12
- package/dist/dts/HttpApi.d.ts.map +1 -1
- package/dist/dts/HttpApiBuilder.d.ts +9 -9
- package/dist/dts/HttpApiBuilder.d.ts.map +1 -1
- package/dist/dts/HttpApiClient.d.ts +3 -3
- package/dist/dts/HttpApiClient.d.ts.map +1 -1
- package/dist/dts/HttpApiError.d.ts +85 -0
- package/dist/dts/HttpApiError.d.ts.map +1 -1
- package/dist/dts/HttpApiGroup.d.ts +3 -2
- package/dist/dts/HttpApiGroup.d.ts.map +1 -1
- package/dist/dts/HttpApiSchema.d.ts +19 -1
- package/dist/dts/HttpApiSchema.d.ts.map +1 -1
- package/dist/dts/HttpApp.d.ts +8 -4
- package/dist/dts/HttpApp.d.ts.map +1 -1
- package/dist/dts/OpenApi.d.ts +8 -0
- package/dist/dts/OpenApi.d.ts.map +1 -1
- package/dist/esm/HttpApi.js +13 -5
- package/dist/esm/HttpApi.js.map +1 -1
- package/dist/esm/HttpApiBuilder.js +4 -4
- package/dist/esm/HttpApiBuilder.js.map +1 -1
- package/dist/esm/HttpApiClient.js.map +1 -1
- package/dist/esm/HttpApiError.js +96 -0
- package/dist/esm/HttpApiError.js.map +1 -1
- package/dist/esm/HttpApiGroup.js.map +1 -1
- package/dist/esm/HttpApiSchema.js +45 -2
- package/dist/esm/HttpApiSchema.js.map +1 -1
- package/dist/esm/HttpApp.js +6 -3
- package/dist/esm/HttpApp.js.map +1 -1
- package/dist/esm/OpenApi.js +16 -0
- package/dist/esm/OpenApi.js.map +1 -1
- package/package.json +2 -2
- package/src/HttpApi.ts +35 -19
- package/src/HttpApiBuilder.ts +22 -20
- package/src/HttpApiClient.ts +8 -6
- package/src/HttpApiError.ts +108 -0
- package/src/HttpApiGroup.ts +4 -3
- package/src/HttpApiSchema.ts +63 -5
- package/src/HttpApp.ts +18 -6
- package/src/OpenApi.ts +18 -1
package/src/HttpApiSchema.ts
CHANGED
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
4
|
import type { Brand } from "effect/Brand"
|
|
5
|
+
import * as Effect from "effect/Effect"
|
|
6
|
+
import * as Effectable from "effect/Effectable"
|
|
5
7
|
import type { LazyArg } from "effect/Function"
|
|
6
|
-
import { constVoid, dual } from "effect/Function"
|
|
8
|
+
import { constant, constVoid, dual } from "effect/Function"
|
|
7
9
|
import { globalValue } from "effect/GlobalValue"
|
|
10
|
+
import { hasProperty } from "effect/Predicate"
|
|
8
11
|
import * as Schema from "effect/Schema"
|
|
9
12
|
import * as AST from "effect/SchemaAST"
|
|
10
13
|
import * as Struct from "effect/Struct"
|
|
@@ -245,7 +248,7 @@ export const asEmpty: {
|
|
|
245
248
|
self: S,
|
|
246
249
|
options: {
|
|
247
250
|
readonly status: number
|
|
248
|
-
readonly decode
|
|
251
|
+
readonly decode: LazyArg<Schema.Schema.Type<S>>
|
|
249
252
|
}
|
|
250
253
|
): asEmpty<S>
|
|
251
254
|
} = dual(
|
|
@@ -254,14 +257,14 @@ export const asEmpty: {
|
|
|
254
257
|
self: S,
|
|
255
258
|
options: {
|
|
256
259
|
readonly status: number
|
|
257
|
-
readonly decode
|
|
260
|
+
readonly decode: LazyArg<Schema.Schema.Type<S>>
|
|
258
261
|
}
|
|
259
262
|
): asEmpty<S> =>
|
|
260
263
|
Schema.transform(
|
|
261
|
-
Schema.Void,
|
|
264
|
+
Schema.Void.annotations(self.ast.annotations),
|
|
262
265
|
Schema.typeSchema(self),
|
|
263
266
|
{
|
|
264
|
-
decode: options.decode
|
|
267
|
+
decode: options.decode,
|
|
265
268
|
encode: constVoid
|
|
266
269
|
}
|
|
267
270
|
).annotations(annotations({
|
|
@@ -482,3 +485,58 @@ export const deunionize = (
|
|
|
482
485
|
schemas.add(schema)
|
|
483
486
|
}
|
|
484
487
|
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* @since 1.0.0
|
|
491
|
+
* @category empty errors
|
|
492
|
+
*/
|
|
493
|
+
export interface EmptyErrorClass<Self, Tag> extends Schema.Schema<Self, void> {
|
|
494
|
+
new(_: void): { readonly _tag: Tag } & Effect.Effect<never, Self>
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* @since 1.0.0
|
|
499
|
+
* @category empty errors
|
|
500
|
+
*/
|
|
501
|
+
export const EmptyError = <Self>() =>
|
|
502
|
+
<const Tag extends string>(options: {
|
|
503
|
+
readonly tag: Tag
|
|
504
|
+
readonly status: number
|
|
505
|
+
}): EmptyErrorClass<Self, Tag> => {
|
|
506
|
+
const symbol = Symbol.for(`@effect/platform/HttpApiSchema/EmptyError/${options.tag}`)
|
|
507
|
+
class EmptyError extends Effectable.StructuralClass<never, Self> {
|
|
508
|
+
readonly _tag: Tag = options.tag
|
|
509
|
+
commit(): Effect.Effect<never, Self> {
|
|
510
|
+
return Effect.fail(this) as any
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
;(EmptyError as any).prototype[symbol] = symbol
|
|
514
|
+
Object.assign(EmptyError, {
|
|
515
|
+
[Schema.TypeId]: Schema.Void[Schema.TypeId],
|
|
516
|
+
pipe: Schema.Void.pipe,
|
|
517
|
+
annotations(this: any, annotations: any) {
|
|
518
|
+
return Schema.make(this.ast).annotations(annotations)
|
|
519
|
+
}
|
|
520
|
+
})
|
|
521
|
+
let transform: Schema.Schema.Any | undefined
|
|
522
|
+
Object.defineProperty(EmptyError, "ast", {
|
|
523
|
+
get() {
|
|
524
|
+
if (transform) {
|
|
525
|
+
return transform.ast
|
|
526
|
+
}
|
|
527
|
+
const self = this as any
|
|
528
|
+
transform = asEmpty(
|
|
529
|
+
Schema.declare((u) => hasProperty(u, symbol), {
|
|
530
|
+
identifier: options.tag,
|
|
531
|
+
title: options.tag
|
|
532
|
+
}),
|
|
533
|
+
{
|
|
534
|
+
status: options.status,
|
|
535
|
+
decode: constant(new self())
|
|
536
|
+
}
|
|
537
|
+
)
|
|
538
|
+
return transform.ast
|
|
539
|
+
}
|
|
540
|
+
})
|
|
541
|
+
return EmptyError as any
|
|
542
|
+
}
|
package/src/HttpApp.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import * as Context from "effect/Context"
|
|
5
5
|
import * as Effect from "effect/Effect"
|
|
6
6
|
import * as Exit from "effect/Exit"
|
|
7
|
-
import
|
|
7
|
+
import * as FiberRef from "effect/FiberRef"
|
|
8
8
|
import * as Layer from "effect/Layer"
|
|
9
9
|
import type * as Option from "effect/Option"
|
|
10
10
|
import * as Runtime from "effect/Runtime"
|
|
@@ -160,11 +160,20 @@ export const toWebHandlerRuntime = <R>(runtime: Runtime.Runtime<R>) => {
|
|
|
160
160
|
)
|
|
161
161
|
return Effect.void
|
|
162
162
|
}, middleware)
|
|
163
|
-
return (request: Request): Promise<Response> =>
|
|
163
|
+
return (request: Request, context?: Context.Context<never> | undefined): Promise<Response> =>
|
|
164
164
|
new Promise((resolve) => {
|
|
165
|
+
const contextMap = new Map<string, any>(
|
|
166
|
+
context ?
|
|
167
|
+
[
|
|
168
|
+
...runtime.context.unsafeMap,
|
|
169
|
+
...context.unsafeMap
|
|
170
|
+
] :
|
|
171
|
+
runtime.context.unsafeMap
|
|
172
|
+
)
|
|
165
173
|
const httpServerRequest = ServerRequest.fromWeb(request)
|
|
174
|
+
contextMap.set(ServerRequest.HttpServerRequest.key, httpServerRequest)
|
|
166
175
|
;(httpServerRequest as any)[resolveSymbol] = resolve
|
|
167
|
-
const fiber = run(Effect.
|
|
176
|
+
const fiber = run(Effect.locally(httpApp as any, FiberRef.currentContext, Context.unsafeMake(contextMap)))
|
|
168
177
|
request.signal?.addEventListener("abort", () => {
|
|
169
178
|
fiber.unsafeInterruptAsFork(ServerError.clientAbortFiberId)
|
|
170
179
|
}, { once: true })
|
|
@@ -179,7 +188,9 @@ export const toWebHandlerRuntime = <R>(runtime: Runtime.Runtime<R>) => {
|
|
|
179
188
|
export const toWebHandler: <E>(
|
|
180
189
|
self: Default<E, Scope.Scope>,
|
|
181
190
|
middleware?: HttpMiddleware | undefined
|
|
182
|
-
) => (request: Request) => Promise<Response> = toWebHandlerRuntime(
|
|
191
|
+
) => (request: Request, context?: Context.Context<never> | undefined) => Promise<Response> = toWebHandlerRuntime(
|
|
192
|
+
Runtime.defaultRuntime
|
|
193
|
+
)
|
|
183
194
|
|
|
184
195
|
/**
|
|
185
196
|
* @since 1.0.0
|
|
@@ -191,12 +202,13 @@ export const toWebHandlerLayer = <E, R, RE>(
|
|
|
191
202
|
middleware?: HttpMiddleware | undefined
|
|
192
203
|
): {
|
|
193
204
|
readonly close: () => Promise<void>
|
|
194
|
-
readonly handler: (request: Request) => Promise<Response>
|
|
205
|
+
readonly handler: (request: Request, context?: Context.Context<never> | undefined) => Promise<Response>
|
|
195
206
|
} => {
|
|
196
207
|
const scope = Effect.runSync(Scope.make())
|
|
197
208
|
const close = () => Effect.runPromise(Scope.close(scope, Exit.void))
|
|
198
209
|
const build = Effect.map(Layer.toRuntime(layer), (_) => toWebHandlerRuntime(_)(self, middleware))
|
|
199
210
|
const runner = Effect.runPromise(Scope.extend(build, scope))
|
|
200
|
-
const handler = (request: Request): Promise<Response> =>
|
|
211
|
+
const handler = (request: Request, context?: Context.Context<never> | undefined): Promise<Response> =>
|
|
212
|
+
runner.then((handler) => handler(request, context))
|
|
201
213
|
return { close, handler } as const
|
|
202
214
|
}
|
package/src/OpenApi.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
4
|
import * as Context from "effect/Context"
|
|
5
|
+
import { constFalse } from "effect/Function"
|
|
5
6
|
import { globalValue } from "effect/GlobalValue"
|
|
6
7
|
import * as Option from "effect/Option"
|
|
7
8
|
import type { ReadonlyRecord } from "effect/Record"
|
|
@@ -84,6 +85,14 @@ export class Deprecated extends Context.Tag("@effect/platform/OpenApi/Deprecated
|
|
|
84
85
|
*/
|
|
85
86
|
export class Override extends Context.Tag("@effect/platform/OpenApi/Override")<Override, Record<string, unknown>>() {}
|
|
86
87
|
|
|
88
|
+
/**
|
|
89
|
+
* @since 1.0.0
|
|
90
|
+
* @category annotations
|
|
91
|
+
*/
|
|
92
|
+
export class Exclude extends Context.Reference<Exclude>()("@effect/platform/OpenApi/Exclude", {
|
|
93
|
+
defaultValue: constFalse
|
|
94
|
+
}) {}
|
|
95
|
+
|
|
87
96
|
/**
|
|
88
97
|
* Transforms the generated OpenAPI specification
|
|
89
98
|
* @since 1.0.0
|
|
@@ -127,6 +136,7 @@ export const annotations: (
|
|
|
127
136
|
readonly servers?: ReadonlyArray<OpenAPISpecServer> | undefined
|
|
128
137
|
readonly format?: string | undefined
|
|
129
138
|
readonly override?: Record<string, unknown> | undefined
|
|
139
|
+
readonly exclude?: boolean | undefined
|
|
130
140
|
readonly transform?: ((openApiSpec: Record<string, any>) => Record<string, any>) | undefined
|
|
131
141
|
}
|
|
132
142
|
) => Context.Context<never> = contextPartial({
|
|
@@ -140,6 +150,7 @@ export const annotations: (
|
|
|
140
150
|
servers: Servers,
|
|
141
151
|
format: Format,
|
|
142
152
|
override: Override,
|
|
153
|
+
exclude: Exclude,
|
|
143
154
|
transform: Transform
|
|
144
155
|
})
|
|
145
156
|
|
|
@@ -213,6 +224,9 @@ export const fromApi = <A extends HttpApi.HttpApi.Any>(self: A): OpenAPISpec =>
|
|
|
213
224
|
})
|
|
214
225
|
HttpApi.reflect(api as any, {
|
|
215
226
|
onGroup({ group }) {
|
|
227
|
+
if (Context.get(group.annotations, Exclude)) {
|
|
228
|
+
return
|
|
229
|
+
}
|
|
216
230
|
let tag: Mutable<OpenAPISpecTag> = {
|
|
217
231
|
name: Context.getOrElse(group.annotations, Title, () => group.identifier)
|
|
218
232
|
}
|
|
@@ -230,7 +244,10 @@ export const fromApi = <A extends HttpApi.HttpApi.Any>(self: A): OpenAPISpec =>
|
|
|
230
244
|
})
|
|
231
245
|
spec.tags!.push(tag)
|
|
232
246
|
},
|
|
233
|
-
onEndpoint({ endpoint, errors, group, middleware, payloads, successes }) {
|
|
247
|
+
onEndpoint({ endpoint, errors, group, mergedAnnotations, middleware, payloads, successes }) {
|
|
248
|
+
if (Context.get(mergedAnnotations, Exclude)) {
|
|
249
|
+
return
|
|
250
|
+
}
|
|
234
251
|
const path = endpoint.path.replace(/:(\w+)[^/]*/g, "{$1}")
|
|
235
252
|
const method = endpoint.method.toLowerCase() as OpenAPISpecMethodName
|
|
236
253
|
let op: DeepMutable<OpenAPISpecOperation> = {
|