Skip to content

Commit

Permalink
add HttpRouter.currentRouterConfig fiber ref (#3454)
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart authored Aug 13, 2024
1 parent a9345f1 commit 5dcb401
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/old-pumas-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect/platform": patch
---

add HttpRouter.currentRouterConfig fiber ref
17 changes: 17 additions & 0 deletions packages/platform-node/test/HttpServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -741,4 +741,21 @@ describe("HttpServer", () => {
expect(yield* responseB.text).toEqual("b")
expect(yield* responseMountB.text).toEqual("mb")
}).pipe(Effect.provide(NodeHttpServer.layerTest)))

it.scoped("setRouterConfig", () =>
Effect.gen(function*() {
yield* HttpRouter.empty.pipe(
HttpRouter.get("/:param", HttpServerResponse.empty()),
HttpServer.serveEffect()
)
let res = yield* HttpClientRequest.get("/123456").pipe(Effect.scoped)
assert.strictEqual(res.status, 404)
res = yield* HttpClientRequest.get("/12345").pipe(Effect.scoped)
assert.strictEqual(res.status, 204)
}).pipe(
Effect.provide(NodeHttpServer.layerTest),
HttpRouter.withRouterConfig({
maxParamLength: 5
})
))
})
23 changes: 23 additions & 0 deletions packages/platform/src/HttpRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import type * as Cause from "effect/Cause"
import type * as Chunk from "effect/Chunk"
import type * as Context from "effect/Context"
import type * as Effect from "effect/Effect"
import type { FiberRef } from "effect/FiberRef"
import type { Inspectable } from "effect/Inspectable"
import type * as Layer from "effect/Layer"
import type * as Option from "effect/Option"
import type * as Scope from "effect/Scope"
import type { RouterConfig } from "find-my-way-ts"
import type * as Etag from "./Etag.js"
import type { FileSystem } from "./FileSystem.js"
import type * as App from "./HttpApp.js"
Expand Down Expand Up @@ -308,6 +310,27 @@ export const schemaPathParams: <A, I extends Readonly<Record<string, string | un
options?: ParseOptions | undefined
) => Effect.Effect<A, ParseResult.ParseError, R | RouteContext> = internal.schemaPathParams

/**
* @since 1.0.0
* @category router config
*/
export const currentRouterConfig: FiberRef<Partial<RouterConfig>> = internal.currentRouterConfig

/**
* @since 1.0.0
* @category router config
*/
export const withRouterConfig: {
(config: Partial<RouterConfig>): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
<A, E, R>(effect: Effect.Effect<A, E, R>, config: Partial<RouterConfig>): Effect.Effect<A, E, R>
} = internal.withRouterConfig

/**
* @since 1.0.0
* @category router config
*/
export const setRouterConfig: (config: Partial<RouterConfig>) => Layer.Layer<never> = internal.setRouterConfig

/**
* @since 1.0.0
* @category constructors
Expand Down
30 changes: 27 additions & 3 deletions packages/platform/src/internal/httpRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as Effect from "effect/Effect"
import * as Effectable from "effect/Effectable"
import * as FiberRef from "effect/FiberRef"
import { dual } from "effect/Function"
import { globalValue } from "effect/GlobalValue"
import * as Inspectable from "effect/Inspectable"
import * as Layer from "effect/Layer"
import * as Option from "effect/Option"
Expand Down Expand Up @@ -139,6 +140,26 @@ export const schemaPathParams = <A, I extends Readonly<Record<string, string | u
return Effect.flatMap(RouteContext, (_) => parse(_.params))
}

/** @internal */
export const currentRouterConfig = globalValue(
"@effect/platform/HttpRouter/currentRouterConfig",
() => FiberRef.unsafeMake<Partial<FindMyWay.RouterConfig>>({})
)

/** @internal */
export const withRouterConfig: {
(config: Partial<FindMyWay.RouterConfig>): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
<A, E, R>(effect: Effect.Effect<A, E, R>, config: Partial<FindMyWay.RouterConfig>): Effect.Effect<A, E, R>
} = dual(
2,
<A, E, R>(effect: Effect.Effect<A, E, R>, config: Partial<FindMyWay.RouterConfig>): Effect.Effect<A, E, R> =>
Effect.locally(effect, currentRouterConfig, config)
)

/** @internal */
export const setRouterConfig = (config: Partial<FindMyWay.RouterConfig>) =>
Layer.locallyScoped(currentRouterConfig, config)

class RouterImpl<E = never, R = never> extends Effectable.StructuralClass<
ServerResponse.HttpServerResponse,
E | Error.RouteNotFound,
Expand All @@ -157,7 +178,9 @@ class RouterImpl<E = never, R = never> extends Effectable.StructuralClass<
) {
super()
this[TypeId] = TypeId
this.httpApp = toHttpApp(this) as any
this.httpApp = FiberRef.get(currentRouterConfig).pipe(
Effect.flatMap((config) => this.httpApp = toHttpApp(this, config) as any)
) as any
}
private httpApp: Effect.Effect<
ServerResponse.HttpServerResponse,
Expand All @@ -183,9 +206,10 @@ class RouterImpl<E = never, R = never> extends Effectable.StructuralClass<
}

const toHttpApp = <E, R>(
self: Router.HttpRouter<E, R>
self: Router.HttpRouter<E, R>,
config: Partial<FindMyWay.RouterConfig>
): App.Default<E | Error.RouteNotFound, R> => {
const router = FindMyWay.make<Router.Route<E, R>>()
const router = FindMyWay.make<Router.Route<E, R>>(config)
const mounts = Chunk.toReadonlyArray(self.mounts).map(([path, app, options]) =>
[
path,
Expand Down

0 comments on commit 5dcb401

Please sign in to comment.