(rsLive: Layer.Layer<DbService | UserStoreService>)
| 94 | // account seat-gate, and the createOrganization free-limit gate each provide it |
| 95 | // where they run.) |
| 96 | export const makeProtectedApiLive = (rsLive: Layer.Layer<DbService | UserStoreService>) => { |
| 97 | // The neutral `IdentityProvider`, built per request: it reads `UserStoreService` |
| 98 | // from `rsLive` and the WorkOS control plane (`WorkOSClient` + `ApiKeyService`, |
| 99 | // stateless config — no per-request I/O socket) for the org-resolution path. |
| 100 | // `orDie` because a WorkOS config error is unrecoverable. |
| 101 | const identityLive = workosIdentityLayer.pipe( |
| 102 | Layer.provide(rsLive), |
| 103 | Layer.provide(ApiKeyService.WorkOS.pipe(Layer.provide(CoreSharedServices))), |
| 104 | Layer.provide(CoreSharedServices), |
| 105 | // oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: a boot-time WorkOS misconfiguration is unrecoverable |
| 106 | Layer.orDie, |
| 107 | ); |
| 108 | // The per-request layer the combine rebuilds in the request fiber's scope: the |
| 109 | // postgres socket (`rsLive`) PLUS the identity layer that reads it. Combining it |
| 110 | // into the auth middleware collapses `requires: IdentityProvider | DbService | |
| 111 | // UserStoreService` to `never` (so `.layer` is a real Layer instead of the "Need |
| 112 | // to combine" sentinel) AND keeps the socket request-scoped. Exposed as a |
| 113 | // factory so tests can swap in a counting fake — see |
| 114 | // `apps/cloud/src/api.request-scope.node.test.ts`. |
| 115 | const requestScopedLive = rsLive.pipe(Layer.provideMerge(identityLive)); |
| 116 | const protectedMiddleware = ExecutionStackMiddleware.combine( |
| 117 | requestScopedMiddleware(requestScopedLive), |
| 118 | ).layer; |
| 119 | return ProtectedCloudApiLive.pipe( |
| 120 | Layer.provide(protectedMiddleware), |
| 121 | Layer.provideMerge(AutumnService.Default), |
| 122 | Layer.provideMerge(RouterConfigLive), |
| 123 | ); |
| 124 | }; |
| 125 | |
| 126 | export const ProtectedApiLive = makeProtectedApiLive(RequestScopedServicesLive); |
no test coverage detected