| /** | |
| * Declares middleware for schema-driven HTTP APIs. | |
| * | |
| * HTTP API middleware wraps endpoint execution on the server and, when the API | |
| * requires it, can also wrap requests made by generated clients. It is used for | |
| * cross-cutting behavior that belongs to the API contract, such as | |
| * authentication, authorization, logging, tracing, rate limiting, | |
| * request-scoped services, schema-error handling, and client request | |
| * decoration. This module defines the middleware service keys and helpers used | |
| * by `HttpApi` declarations. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| /** @effect-diagnostics floatingEffect:skip-file */ | |
| /** @effect-diagnostics classSelfMismatch:off */ | |
| import * as Context from "../../Context.js"; | |
| import * as Effect from "../../Effect.js"; | |
| import * as Layer from "../../Layer.js"; | |
| import { hasProperty } from "../../Predicate.js"; | |
| import { Scope } from "../../Scope.js"; | |
| import { HttpApiSchemaError } from "./HttpApiError.js"; | |
| const TypeId = "~effect/httpapi/HttpApiMiddleware"; | |
| const SecurityTypeId = "~effect/httpapi/HttpApiMiddleware/Security"; | |
| /** | |
| * Returns `true` when an HTTP API middleware service is security middleware. | |
| * | |
| * @category guards | |
| * @since 4.0.0 | |
| */ | |
| export const isSecurity = u => hasProperty(u, SecurityTypeId); | |
| /** | |
| * Creates a `Context.Service` class for an HTTP API middleware implementation. | |
| * | |
| * **When to use** | |
| * | |
| * Use when you need an HTTP API middleware service whose configuration declares | |
| * required services, provided services, typed error schemas, security schemes, | |
| * client errors, or a matching client middleware requirement. | |
| * | |
| * @category schemas | |
| * @since 4.0.0 | |
| */ | |
| export const Service = () => (id, options) => { | |
| const Err = globalThis.Error; | |
| const limit = Err.stackTraceLimit; | |
| Err.stackTraceLimit = 2; | |
| const creationError = new Err(); | |
| Err.stackTraceLimit = limit; | |
| class Service extends Context.Service()(id) {} | |
| const self = Service; | |
| Object.defineProperty(Service, "stack", { | |
| get() { | |
| return creationError.stack; | |
| } | |
| }); | |
| self[TypeId] = TypeId; | |
| self.error = getError(options?.error); | |
| self.requiredForClient = options?.requiredForClient ?? false; | |
| if (options?.security !== undefined) { | |
| if (Object.keys(options.security).length === 0) { | |
| throw new Error("HttpApiMiddleware.Service: security object must not be empty"); | |
| } | |
| self[SecurityTypeId] = SecurityTypeId; | |
| self.security = options.security; | |
| } | |
| return self; | |
| }; | |
| function getError(error) { | |
| if (error === undefined) return new Set(); | |
| return new Set(Array.isArray(error) ? error : [error]); | |
| } | |
| /** | |
| * Creates a middleware layer that transforms `HttpApiSchemaError` failures. | |
| * | |
| * **Details** | |
| * | |
| * The middleware catches schema errors produced while running an endpoint and uses | |
| * the supplied `transform` function to convert them into the middleware's declared | |
| * error schema. | |
| * | |
| * **Example** (Mapping schema errors to custom errors) | |
| * | |
| * ```ts | |
| * import { Effect, Schema } from "effect" | |
| * import { HttpApiMiddleware } from "effect/unstable/httpapi" | |
| * | |
| * export class CustomError extends Schema.TaggedErrorClass<CustomError>()("CustomError", {}) {} | |
| * | |
| * export class ErrorHandler extends HttpApiMiddleware.Service<ErrorHandler>()("api/ErrorHandler", { | |
| * error: CustomError | |
| * }) {} | |
| * | |
| * export const ErrorHandlerLayer = HttpApiMiddleware.layerSchemaErrorTransform( | |
| * ErrorHandler, | |
| * (schemaError) => | |
| * Effect.log("Got SchemaError", schemaError).pipe( | |
| * Effect.andThen(Effect.fail(new CustomError())) | |
| * ) | |
| * ) | |
| * ``` | |
| * | |
| * @category SchemaError transform | |
| * @since 4.0.0 | |
| */ | |
| export const layerSchemaErrorTransform = (service, transform) => Layer.succeed(service, (httpEffect, options) => Effect.catch(httpEffect, e => HttpApiSchemaError.is(e) ? transform(e, options) : Effect.fail(e))); | |
| /** | |
| * Provides a client-side middleware implementation for a middleware that is required by generated clients. | |
| * | |
| * **Details** | |
| * | |
| * The layer captures the surrounding services and makes the middleware available | |
| * through the `ForClient` service marker used by HTTP API clients. | |
| * | |
| * @category client | |
| * @since 4.0.0 | |
| */ | |
| export const layerClient = (tag, service) => Layer.effectContext(Effect.gen(function* () { | |
| const services = (yield* Effect.context()).pipe(Context.omit(Scope)); | |
| const middleware = Effect.isEffect(service) ? yield* service : service; | |
| return Context.makeUnsafe(new Map([[`${tag.key}/Client`, options => Effect.updateContext(middleware(options), requestContext => Context.merge(services, requestContext))]])); | |
| })); | |
| //# sourceMappingURL=HttpApiMiddleware.js.map |
Xet Storage Details
- Size:
- 4.58 kB
- Xet hash:
- 3528bc8e72963900454839c1f778a558ce5d263c4fd4d86cee8eb447355ce934
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.