@shivaedev/platform 0.15.0 → 0.16.0

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +83 -49
  3. package/dist/rpc/identity.d.ts +1 -0
  4. package/dist/rpc/identity.d.ts.map +1 -1
  5. package/dist/rpc/identity.js.map +1 -1
  6. package/dist/rpc/requireAdmin.d.ts +5 -0
  7. package/dist/rpc/requireAdmin.d.ts.map +1 -0
  8. package/dist/rpc/requireAdmin.js +14 -0
  9. package/dist/rpc/requireAdmin.js.map +1 -0
  10. package/dist/server/MigrationOptions.d.ts +11 -0
  11. package/dist/server/MigrationOptions.d.ts.map +1 -0
  12. package/dist/server/MigrationOptions.js +2 -0
  13. package/dist/server/MigrationOptions.js.map +1 -0
  14. package/dist/server/appHost.d.ts +5 -10
  15. package/dist/server/appHost.d.ts.map +1 -1
  16. package/dist/server/appHost.js.map +1 -1
  17. package/dist/server/appHostHttp.d.ts +7 -7
  18. package/dist/server/appHostHttp.d.ts.map +1 -1
  19. package/dist/server/appHostHttp.js +8 -7
  20. package/dist/server/appHostHttp.js.map +1 -1
  21. package/dist/server/better-auth/adapter.d.ts +1 -1
  22. package/dist/server/better-auth/adapter.d.ts.map +1 -1
  23. package/dist/server/databaseLayer.d.ts.map +1 -1
  24. package/dist/server/databaseLayer.js +18 -4
  25. package/dist/server/databaseLayer.js.map +1 -1
  26. package/dist/server/hostOptions.d.ts +1 -1
  27. package/dist/server/hostOptions.d.ts.map +1 -1
  28. package/dist/server/otlpHttpClient.js +1 -1
  29. package/dist/server/otlpHttpClient.js.map +1 -1
  30. package/dist/server/otlpTracing.js +2 -2
  31. package/dist/server/otlpTracing.js.map +1 -1
  32. package/dist/server/redactOtlpUrl.js +1 -1
  33. package/dist/server/redactOtlpUrl.js.map +1 -1
  34. package/dist/server/rpc-server/adapters/betterAuthSessions.d.ts +1 -1
  35. package/dist/server/rpc-server/adapters/betterAuthSessions.d.ts.map +1 -1
  36. package/dist/server/rpc-server/adapters/betterAuthSessions.js +1 -1
  37. package/dist/server/rpc-server/adapters/betterAuthSessions.js.map +1 -1
  38. package/dist/server/rpc-server/session.d.ts +3 -2
  39. package/dist/server/rpc-server/session.d.ts.map +1 -1
  40. package/dist/server/rpc-server/session.js +9 -5
  41. package/dist/server/rpc-server/session.js.map +1 -1
  42. package/dist/server/safeOtlpSerialization.js +2 -2
  43. package/dist/server/safeOtlpSerialization.js.map +1 -1
  44. package/dist/server/testing/makePlatformIt.d.ts +1 -1
  45. package/dist/server/testing/makePlatformIt.d.ts.map +1 -1
  46. package/dist/server/testing/makePlatformIt.js +1 -1
  47. package/dist/server/testing/makePlatformIt.js.map +1 -1
  48. package/dist/server/testing/types.d.ts +3 -3
  49. package/dist/server/testing/types.d.ts.map +1 -1
  50. package/dist/server/tracedGroup.d.ts +4 -0
  51. package/dist/server/tracedGroup.d.ts.map +1 -0
  52. package/dist/server/tracedGroup.js +13 -0
  53. package/dist/server/tracedGroup.js.map +1 -0
  54. package/package.json +15 -343
  55. package/src/rpc/identity.ts +1 -0
  56. package/src/rpc/requireAdmin.ts +14 -0
  57. package/src/server/MigrationOptions.ts +11 -0
  58. package/src/server/appHost.ts +4 -9
  59. package/src/server/appHostHttp.ts +11 -10
  60. package/src/server/better-auth/adapter.ts +1 -1
  61. package/src/server/databaseLayer.ts +22 -6
  62. package/src/server/hostOptions.ts +1 -1
  63. package/src/server/otlpHttpClient.ts +1 -1
  64. package/src/server/otlpTracing.ts +2 -2
  65. package/src/server/redactOtlpUrl.ts +1 -1
  66. package/src/server/rpc-server/adapters/betterAuthSessions.ts +2 -2
  67. package/src/server/rpc-server/session.ts +9 -6
  68. package/src/server/safeOtlpSerialization.ts +2 -2
  69. package/src/server/testing/makePlatformIt.ts +4 -4
  70. package/src/server/testing/types.ts +3 -3
  71. package/src/server/tracedGroup.ts +14 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.16.0 - 2026-10-18
4
+
5
+ ### Added
6
+
7
+ - Export `requireAdmin` from `rpc/requireAdmin.ts` to guard request-local users with typed `Unauthorized` and `Forbidden` failures. Session users carry the provider's optional role, and `withSessionUser` from `server/rpc-server/session.ts` shares the identity boundary between HTTP routes and RPC middleware.
8
+ - `appHost` and `appDatabase` accept `migrations.mode: "wait"` to poll the migration ledger before starting application services, with configurable `pollInterval` (one second by default) and `waitTimeout` (five minutes by default). Timeout preserves the schema check's native `MigrationError`, and interruption closes the waiting host's database pool.
9
+ - `server/MigrationOptions.ts` exports `MigrationOptions<R = never>`, the migration settings used by `AppDatabaseOptions.migrations`.
10
+
11
+ ### Fixed
12
+
13
+ - App hosts apply request tracing to every served RPC, wrapping authentication and handlers even when the shared group omits `RequestTracing`. Existing declarations run once at the outermost middleware boundary; failures log redacted payloads with request ids.
14
+
15
+ ### Breaking
16
+
17
+ - Every module's import path is now its path under `src/`. Server modules gain a `server/` prefix and keep their file names, for example `server/appHost.ts`, `server/rpc-server/boundary.ts`, `server/better-auth/rowAdapter.ts`, `server/runtime/makePlatform.ts` and `server/testing/makePlatformIt.ts`. `errors/rejected-field.ts` becomes `errors/rejectedField.ts`.
18
+
3
19
  ## 0.15.0 - 2026-10-18
4
20
 
5
21
  ### Added
package/README.md CHANGED
@@ -33,7 +33,7 @@ There are three parts to a native RPC boundary:
33
33
 
34
34
  An **Origin policy** is a function of the transport request's origin, headers and RPC name. A **session provider** returns `Option<Session>` or fails with `AuthUnavailable`; a session carries `user.id`. These are application inputs, not a second authentication framework.
35
35
 
36
- The optional modules solve different boundaries. `runtime/` carries Effect services into Promise callers, `node-http/` combines subscription cancellation sources, `better-auth/adapter.ts` connects Better Auth storage to Effect Prisma, and `testing/vitest.ts` composes the Prisma and tRPC test harnesses. Choose the modules that match the application rather than adopting every integration.
36
+ The optional modules solve different boundaries. `server/runtime/` carries Effect services into Promise callers, `server/node-http/` combines subscription cancellation sources, `server/better-auth/adapter.ts` connects Better Auth storage to Effect Prisma, and `server/testing/makePlatformIt.ts` composes the Prisma and tRPC test harnesses. Choose the modules that match the application rather than adopting every integration.
37
37
 
38
38
  ### Host the application
39
39
 
@@ -42,7 +42,7 @@ The optional modules solve different boundaries. `runtime/` carries Effect servi
42
42
  ```ts
43
43
  import { NodeRuntime } from "@effect/platform-node";
44
44
  import { Layer } from "effect";
45
- import { appHost } from "@shivaedev/platform/appHost.ts";
45
+ import { appHost } from "@shivaedev/platform/server/appHost.ts";
46
46
  import { Api, Handlers, Services, migrations, sessions } from "./app.ts";
47
47
 
48
48
  const Server = appHost({
@@ -67,12 +67,12 @@ The listener uses `HOST` or `127.0.0.1`, uses `PORT` or 3000, and reads `DATABAS
67
67
 
68
68
  RPC request bodies are limited to 1 MiB by default. Set `MAX_BODY_SIZE` to a byte count or override it with `config.maxBodySize`, a nonnegative safe integer. An oversized NDJSON body returns a 4xx before any RPC handler runs; real HTTP tests cover fixed-length and chunked requests, byte counting, and configuration precedence. This limit applies to the host's RPC route.
69
69
 
70
- For a native Node HTTP route, use `readBoundedBody` from `@shivaedev/platform/boundedBody.ts` with Effect's `HttpIncomingMessage.MaxBodySize`. It returns an `ArrayBuffer` without decoding the bytes. Oversized `content-length` headers are rejected before reading; chunked overflow drains the remaining body and preserves the connection for another request. `RequestBodyTooLarge` is a typed failure that implements Effect's `HttpServerRespondable` protocol with status 413; other read errors remain native `HttpServerError` failures. Consume the body once through this reader and decode the result in the application.
70
+ For a native Node HTTP route, use `readBoundedBody` from `@shivaedev/platform/server/boundedBody.ts` with Effect's `HttpIncomingMessage.MaxBodySize`. It returns an `ArrayBuffer` without decoding the bytes. Oversized `content-length` headers are rejected before reading; chunked overflow drains the remaining body and preserves the connection for another request. `RequestBodyTooLarge` is a typed failure that implements Effect's `HttpServerRespondable` protocol with status 413; other read errors remain native `HttpServerError` failures. Consume the body once through this reader and decode the result in the application.
71
71
 
72
72
  ```ts
73
73
  import { ByteSize, Effect } from "effect";
74
74
  import { HttpIncomingMessage, HttpRouter, HttpServerResponse } from "effect/http";
75
- import { readBoundedBody } from "@shivaedev/platform/boundedBody.ts";
75
+ import { readBoundedBody } from "@shivaedev/platform/server/boundedBody.ts";
76
76
 
77
77
  const routes = HttpRouter.add("POST", "/webhook", (request) =>
78
78
  readBoundedBody(request).pipe(
@@ -82,7 +82,7 @@ const routes = HttpRouter.add("POST", "/webhook", (request) =>
82
82
  );
83
83
  ```
84
84
 
85
- RPC uses the existing `localRpcGuard`: it requires a loopback peer and Host, same-origin or absent Origin, and the NDJSON content type. Session lookup uses transport headers. With a session policy, contracts declare `Authenticated`, `MaybeAuthenticated` and `RequestTracing` as needed; the host supplies their implementations. For `AuthenticatedUser`, merge `authenticatedUserLayer(sessions)` beside the handlers as shown below. Declared errors retain their Schema types. Applications still own resource authorization and use `rpcBoundary` when they need to map unexpected failures.
85
+ RPC uses the existing `localRpcGuard`: it requires a loopback peer and Host, same-origin or absent Origin, and the NDJSON content type. Session lookup uses transport headers. The host applies `RequestTracing` last to every served RPC, including loopback RPC, so it wraps authentication and handlers without a per-contract tracing declaration. Existing tracing declarations run once at that outermost boundary. With a session policy, contracts declare `Authenticated` and `MaybeAuthenticated` as needed; the host supplies their implementations. For `AuthenticatedUser`, merge `authenticatedUserLayer(sessions)` beside the handlers as shown below. Declared errors retain their Schema types. Applications still own resource authorization and use `rpcBoundary` when they need to map unexpected failures.
86
86
 
87
87
  For local tools, use `policy: "loopback"` with contracts that do not use session middleware to serve RPC without a session provider. The guard requires a loopback peer and Host, absent or same-origin Origin, and NDJSON content type. This policy does not use `TRUSTED_PROXY` or `config.trustedProxy`. Set `rpcPath` to choose another native RPC route; `/rpc` remains the default.
88
88
 
@@ -90,7 +90,7 @@ Omit `migrations` to host an app without a database. This form creates no SQL po
90
90
 
91
91
  `appHost` serves unauthenticated `GET /health`. It queries its SQL client on each request and returns `200` only when the query succeeds within two seconds; a missing SQL client, query failure or timeout returns `503`. Both responses have an empty body and `Cache-Control: no-store`. This route also works when the SQL client comes from the application’s `services` Layer. Use it for database readiness checks.
92
92
 
93
- Set `migrations.mode: "check"` on `appDatabase` or a database-backed `appHost` when a separate pre-deploy command owns migrations. Startup reads the ledger and fails with native `MigrationError` (`kind: "BadState"`) if any required migration ID or name is missing; it does not run migrations or create a ledger. Later ledger entries are allowed for rolling deployments. With `mode` omitted or `"migrate"`, startup applies pending migrations with a five-second lock timeout unless `migrations.lockTimeout` overrides it.
93
+ Set `migrations.mode: "check"` on `appDatabase` or a database-backed `appHost` when a separate pre-deploy command owns migrations. Startup reads the ledger and fails with native `MigrationError` (`kind: "BadState"`) if any required migration ID or name is missing; it does not run migrations or create a ledger. Later ledger entries are allowed for rolling deployments. Use `migrations.mode: "wait"` for services that can start before that pre-deploy command finishes. It re-reads the ledger every second until current, then starts the application. Set `migrations.pollInterval` and `migrations.waitTimeout` with Effect duration inputs to change the interval and five-minute timeout. Timeout fails with the same `MigrationError` as `"check"`; interruption stops polling and closes the pool. SQL failures fail immediately. With `mode` omitted or `"migrate"`, startup applies pending migrations with a five-second lock timeout unless `migrations.lockTimeout` overrides it.
94
94
 
95
95
  When construction itself touches the schema, use `appHost({ migrations, config, application })`. `application` is a native Effect that returns the HTTP host options (`group`, handler and service Layers, session policy, and optional HTTP config). The host first builds `appDatabase`, then evaluates this Effect in the host scope with SQL, Reactivity and `AppChanges` available. A failed migration or schema-current check prevents construction. Initialization requirements and errors stay in the returned Layer's types, and acquired resources close with the host scope.
96
96
 
@@ -129,7 +129,7 @@ The supported tracing variables and defaults are:
129
129
 
130
130
  Timeouts fail through the HTTP client's typed transport-error channel and use the same warning path as other transport failures. Effect retains its native retry policy; the request timeout applies to each attempt. The batch defaults follow Effect's `OtlpTracer.layer`. Its options cannot express a separate batch-operation deadline or a queue capacity, so `OTEL_BSP_EXPORT_TIMEOUT` controls shutdown only and `OTEL_BSP_MAX_QUEUE_SIZE` is unsupported. Other `OTEL_BSP_*` variables are unsupported.
131
131
 
132
- On Railway, enable the per-service tracing setting separately for the web service and worker, and leave both exporter endpoint variables unset in your app's configuration. Railway injects the `OTEL_*` variables, including `OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf`, only when the app sets no endpoint of its own. The framework exports through Effect's own `effect/observability` OTLP tracer; eBPF auto-instrumentation is outside this path. For a worker, provide `otlpTracing` from `@shivaedev/platform/otlpTracing.ts` to its application Layer. It batches ended Effect spans and flushes during scoped shutdown with a three-second bound by default. The first failed export logs a warning with the collector status and redacted response body, or the transport failure kind when no response arrives. Repeated failures stay quiet until a successful export. Collector connection failures and HTTP errors leave requests, jobs and shutdown successful. HTTP receiver tests cover the host and the starter's PostgreSQL word-count worker; they do not establish delivery in a deployed collector.
132
+ On Railway, enable the per-service tracing setting separately for the web service and worker, and leave both exporter endpoint variables unset in your app's configuration. Railway injects the `OTEL_*` variables, including `OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf`, only when the app sets no endpoint of its own. The framework exports through Effect's own `effect/observability` OTLP tracer; eBPF auto-instrumentation is outside this path. For a worker, provide `otlpTracing` from `@shivaedev/platform/server/otlpTracing.ts` to its application Layer. It batches ended Effect spans and flushes during scoped shutdown with a three-second bound by default. The first failed export logs a warning with the collector status and redacted response body, or the transport failure kind when no response arrives. Repeated failures stay quiet until a successful export. Collector connection failures and HTTP errors leave requests, jobs and shutdown successful. HTTP receiver tests cover the host and the starter's PostgreSQL word-count worker; they do not establish delivery in a deployed collector.
133
133
 
134
134
  Exported HTTP server spans use `{method} {route}` with `http.route` for matched RPC and router paths, including parameter templates; unmatched requests use the method alone. The production host continues incoming W3C `traceparent` context, including one sent by an edge proxy.
135
135
 
@@ -179,8 +179,8 @@ The middleware declaration makes `Identity` available to guarded handlers and ad
179
179
  Supply a provider and an explicit Origin policy as the host's `sessions` input. For a Better Auth provider, adapt its existing session lookup:
180
180
 
181
181
  ```ts
182
- import { betterAuthSessions } from "@shivaedev/platform/rpc-server/adapters/better-auth-sessions.ts";
183
- import { trustedOrigins } from "@shivaedev/platform/rpc-server/origin.ts";
182
+ import { betterAuthSessions } from "@shivaedev/platform/server/rpc-server/adapters/betterAuthSessions.ts";
183
+ import { trustedOrigins } from "@shivaedev/platform/server/rpc-server/origin.ts";
184
184
  import { auth } from "./auth.ts";
185
185
 
186
186
  export const sessions = {
@@ -202,7 +202,7 @@ import { Effect, Layer, Schema } from "effect";
202
202
  import { Rpc, RpcGroup } from "effect/rpc";
203
203
  import { SessionUser } from "@shivaedev/platform/rpc/identity.ts";
204
204
  import { AuthenticatedUser } from "@shivaedev/platform/rpc/middleware.ts";
205
- import { authenticatedUserLayer } from "@shivaedev/platform/rpc-server/session.ts";
205
+ import { authenticatedUserLayer } from "@shivaedev/platform/server/rpc-server/session.ts";
206
206
 
207
207
  export const Account = RpcGroup.make(
208
208
  Rpc.make("Whoami", {
@@ -217,9 +217,9 @@ export const AccountHandlers = Account.toLayer({
217
217
  export const AccountServer = Layer.merge(AccountHandlers, authenticatedUserLayer(sessions));
218
218
  ```
219
219
 
220
- Here `sessions` is the application's policy from the previous example, with a Better Auth lookup that returns all three user fields. Merge `authenticatedUserLayer(sessions)` alongside the handler Layer when using `appHost`; the host continues to supply its id-only and optional middleware. A missing session fails with typed `Unauthorized`; rejected origins fail with `Forbidden`, and provider failures remain `AuthUnavailable`. By default, the profile contains only id, name and email, without exposing the rest of the provider's user record. Handlers do not query the provider's user table.
220
+ Here `sessions` is the application's policy from the previous example, with a Better Auth lookup that returns all three user fields. Merge `authenticatedUserLayer(sessions)` alongside the handler Layer when using `appHost`; the host continues to supply its id-only and optional middleware. A missing session fails with typed `Unauthorized`; rejected origins fail with `Forbidden`, and provider failures remain `AuthUnavailable`. The profile contains id, name and email, plus an optional role when the provider supplies it, without exposing the rest of the provider's user record. Handlers do not query the provider's user table.
221
221
 
222
- The starter's `notes.whoami` query returns this profile, and its note handlers use `SessionUser.id` for ownership. Its PostgreSQL/HTTP test checks concurrent users, anonymous requests and sign-out revocation.
222
+ The starter's `notes.whoami` query returns id, name and email, and its note handlers use `SessionUser.id` for ownership. Its PostgreSQL/HTTP test checks concurrent users, anonymous requests and sign-out revocation.
223
223
 
224
224
  #### Reading provider account IDs
225
225
 
@@ -243,6 +243,40 @@ Use `authenticatedUserLayer(sessions)` as above. `SessionUserValue.providerAccou
243
243
 
244
244
  An account lookup failure follows the same `AuthUnavailable` path as a session lookup failure. The starter's social-session story uses real PostgreSQL, GitHub OAuth responses from a local provider fixture, and Platform's HTTP host: GitHub sign-in exposes its account ID through native RPC, email sign-up has no GitHub entry, sign-out rejects access, and an account lookup failure stays distinct from a missing session.
245
245
 
246
+ ### Requiring an admin
247
+
248
+ Enable Better Auth's `admin()` plugin in the application's auth options and migrate its schema. `authenticatedUserLayer(sessions)` carries the provider's optional `user.role` into the request-local `SessionUser`. The `requireAdmin` Effect from `@shivaedev/platform/rpc/requireAdmin.ts` returns that user when the comma-separated role list includes `admin`. It fails in the error channel with `Unauthorized` when no request user is available and `Forbidden` when the user has no admin role.
249
+
250
+ ```ts
251
+ import { Effect } from "effect";
252
+ import { requireAdmin } from "@shivaedev/platform/rpc/requireAdmin.ts";
253
+
254
+ const adminTools = Effect.map(requireAdmin, (user) => `Admin tools for ${user.email}`);
255
+ ```
256
+
257
+ An RPC handler uses this Effect with `AuthenticatedUser` and declares `Forbidden` and `Unauthorized` in its error schema. For an HTTP route, use the same request identity boundary:
258
+
259
+ ```ts
260
+ import { HttpRouter, HttpServerResponse } from "effect/http";
261
+ import { withSessionUser } from "@shivaedev/platform/server/rpc-server/session.ts";
262
+
263
+ const routes = HttpRouter.use((router) =>
264
+ router.add("GET", "/admin-tools", (request) =>
265
+ adminTools.pipe(
266
+ withSessionUser(sessions, request.headers, "admin-tools"),
267
+ Effect.map(HttpServerResponse.text),
268
+ Effect.catchTags({
269
+ Unauthorized: () => Effect.succeed(HttpServerResponse.empty({ status: 401 })),
270
+ Forbidden: () => Effect.succeed(HttpServerResponse.empty({ status: 403 })),
271
+ AuthUnavailable: () => Effect.succeed(HttpServerResponse.empty({ status: 503 })),
272
+ }),
273
+ ),
274
+ ),
275
+ );
276
+ ```
277
+
278
+ `withSessionUser(policy, headers, operation)` resolves the session through the existing transport-header and Origin policy path and provides `Identity` and `SessionUser` only around the supplied Effect. It is also the boundary used by `authenticatedUserLayer`. Both the guard and identity boundary use public provider data, without reading Better Auth's tables or internal services. Keep Better Auth's cookie cache disabled for database-backed role removal to take effect on the next request, as in the starter. The auth story kit proves admin access, HTTP 401/403 and typed RPC refusals, and role removal with a retained session against PostgreSQL and a loopback host.
279
+
246
280
  ### Transport headers and request ids
247
281
 
248
282
  Session resolution reads `HttpServerRequest`: the HTTP POST or WebSocket upgrade request. Credentials and Origin supplied inside an RPC message cannot replace those transport headers. An application-owned middleware can use `transportHeaders(rpcHeaders)` for the same source of headers.
@@ -278,7 +312,7 @@ export const GreetingHandlers = Greetings.toLayer({
278
312
 
279
313
  A missing session produces `Option.none()` here. The same policy still rejects forbidden origins and distinguishes provider failure from an anonymous caller. Signed-in authenticated requests annotate the user's id on logs as `userId` and spans as `user.id`.
280
314
 
281
- For an HTTP RPC server that serves only the local machine, wrap its HTTP effect with `localRpcGuard` from `@shivaedev/platform/rpc-server/local.ts`. Provide the native `HttpServerRequest` and `RpcSerialization` services around the returned effect, using the same serialization as the RPC server. No session provider is required.
315
+ For an HTTP RPC server that serves only the local machine, wrap its HTTP effect with `localRpcGuard` from `@shivaedev/platform/server/rpc-server/local.ts`. Provide the native `HttpServerRequest` and `RpcSerialization` services around the returned effect, using the same serialization as the RPC server. No session provider is required.
282
316
 
283
317
  By default, the guard returns HTTP 403 before running the effect unless the transport reports a loopback peer address, the Host is a loopback host, any Origin matches the HTTP Host, and the content type matches the serialization. An absent peer address is rejected. Real Node HTTP tests cover accepted local requests and rejected Origin, Host and content-type requests, including a DNS-rebinding Host on a loopback connection. The optional second argument, `localRpcGuard(effect, trustedProxy)`, enables the same address and range forwarding policy as `appHost`.
284
318
 
@@ -305,7 +339,7 @@ export const Rename = Rpc.make("Rename", {
305
339
  A handler fails with `new Conflict({ field: "name", message: "Name is taken" })`. Native RPC JSON decodes the rejection back to the error instance with its field. Taxonomy errors can be declared on an RPC with no authentication middleware. `rejectedField` reads either that instance or tagged JSON:
306
340
 
307
341
  ```ts
308
- import { rejectedField } from "@shivaedev/platform/errors/rejected-field.ts";
342
+ import { rejectedField } from "@shivaedev/platform/errors/rejectedField.ts";
309
343
  import { Conflict } from "@shivaedev/platform/errors/taxonomy.ts";
310
344
 
311
345
  const field = rejectedField(
@@ -324,7 +358,7 @@ At the handler edge, `rpcBoundary(schema, options)` keeps declared rejections an
324
358
  ```ts
325
359
  import { Schema } from "effect";
326
360
  import { Conflict, InternalServerError } from "@shivaedev/platform/errors/taxonomy.ts";
327
- import { rpcBoundary } from "@shivaedev/platform/rpc-server/boundary.ts";
361
+ import { rpcBoundary } from "@shivaedev/platform/server/rpc-server/boundary.ts";
328
362
 
329
363
  const Rejection = Schema.Union([Conflict, InternalServerError]);
330
364
  const expose = rpcBoundary(Rejection, {
@@ -345,8 +379,8 @@ Tracing logs declared failures with `RPC failure` and their tag, and defects wit
345
379
  Defects are also redacted in the cause that reaches the client, server span and error reporters. An `Error` keeps its error shape with redacted fields and cause. Extend the sensitive-key rule explicitly:
346
380
 
347
381
  ```ts
348
- import { isSensitiveKey } from "@shivaedev/platform/rpc-server/sensitive.ts";
349
- import { requestTracingLayer } from "@shivaedev/platform/rpc-server/tracing.ts";
382
+ import { isSensitiveKey } from "@shivaedev/platform/server/rpc-server/sensitive.ts";
383
+ import { requestTracingLayer } from "@shivaedev/platform/server/rpc-server/tracing.ts";
350
384
 
351
385
  export const Tracing = requestTracingLayer({
352
386
  sensitive: (key) => isSensitiveKey(key) || key === "email",
@@ -361,7 +395,7 @@ Build the application Layer once. `runWithServices` supplies an invocation's ove
361
395
 
362
396
  ```ts
363
397
  import { Context, Layer } from "effect";
364
- import { makePlatformRuntime } from "@shivaedev/platform/runtime/make.ts";
398
+ import { makePlatformRuntime } from "@shivaedev/platform/server/runtime/makePlatform.ts";
365
399
 
366
400
  class Greeting extends Context.Service<Greeting, string>()("app/Greeting") {}
367
401
 
@@ -387,7 +421,7 @@ A long-lived response can receive cancellation from a Web request, a procedure a
387
421
 
388
422
  ```ts
389
423
  import type { IncomingMessage } from "node:http";
390
- import { nodeSubscriptionSignal } from "@shivaedev/platform/node-http/subscription-signal.ts";
424
+ import { nodeSubscriptionSignal } from "@shivaedev/platform/server/node-http/subscriptionSignal.ts";
391
425
 
392
426
  export async function consumeSubscription(
393
427
  request: Request,
@@ -416,8 +450,8 @@ When Better Auth's rows belong to an Effect Prisma database, give its adapter th
416
450
 
417
451
  ```ts
418
452
  import { betterAuth } from "better-auth";
419
- import { effectPrismaAdapter } from "@shivaedev/platform/better-auth/adapter.ts";
420
- import { makePlatformRuntime } from "@shivaedev/platform/runtime/make.ts";
453
+ import { effectPrismaAdapter } from "@shivaedev/platform/server/better-auth/adapter.ts";
454
+ import { makePlatformRuntime } from "@shivaedev/platform/server/runtime/makePlatform.ts";
421
455
  import { Database, DatabaseLive } from "./database.ts";
422
456
 
423
457
  export const runtime = makePlatformRuntime(DatabaseLive);
@@ -439,7 +473,7 @@ Set up the application harness once in `test-support/`:
439
473
 
440
474
  ```ts
441
475
  import { Effect } from "effect";
442
- import { makePlatformIt } from "@shivaedev/platform/testing/vitest.ts";
476
+ import { makePlatformIt } from "@shivaedev/platform/server/testing/makePlatformIt.ts";
443
477
  import { adapter, Database, router, TestLive } from "./application.ts";
444
478
 
445
479
  export const it = makePlatformIt(Database)({
@@ -481,33 +515,33 @@ Import the module that defines the name; there is no package-root entry. Paths b
481
515
 
482
516
  | Module | Names and purpose |
483
517
  | --- | --- |
484
- | `otlpTracing.ts` | `otlpTracing`: scoped, opt-in Effect OTLP trace export configured through standard exporter variables; provide it to worker Layers. |
485
- | `boundedBody.ts` | `readBoundedBody`, `RequestBodyTooLarge`: bounded body bytes and a typed HTTP 413 failure. |
486
- | `appHost.ts` | `appHost({ group, handlers, services, migrations?, sessions?, policy?, rpcPath?, assets?, routes?, config? })` or `appHost({ application, migrations, config? })`, `appDatabase({ migrations, config? })`, `AppChanges`, `AppHostOptions`, `AppHttpHostOptions`, `AppLocalHostOptions`, `AppDatabaseOptions`: scoped HTTP and PostgreSQL composition with loopback defaults and optional proxy trust. |
518
+ | `server/otlpTracing.ts` | `otlpTracing`: scoped, opt-in Effect OTLP trace export configured through standard exporter variables; provide it to worker Layers. |
519
+ | `server/boundedBody.ts` | `readBoundedBody`, `RequestBodyTooLarge`: bounded body bytes and a typed HTTP 413 failure. |
520
+ | `server/appHost.ts` | `appHost({ group, handlers, services, migrations?, sessions?, policy?, rpcPath?, assets?, routes?, config? })` or `appHost({ application, migrations, config? })`, `appDatabase({ migrations, config? })`, `AppChanges`, `AppHostOptions`, `AppHttpHostOptions`, `AppLocalHostOptions`, `AppDatabaseOptions`: scoped HTTP and PostgreSQL composition with loopback defaults and optional proxy trust. |
487
521
  | `errors/taxonomy.ts` | `NotFound`, `Unauthorized`, `Forbidden`, `BadRequest`, `Conflict`, `PreconditionFailed`, `TooManyRequests`, `AuthUnavailable`, `InternalServerError`, `ServiceUnavailable`: Schema tagged error classes with a `message`; `BadRequest` and `Conflict` also accept an optional `field`. |
488
- | `errors/rejected-field.ts` | `rejectedField(unknown): Option<RejectedField>`; `RejectedField` is `{ field: string, message: string }`. |
522
+ | `errors/rejectedField.ts` | `rejectedField(unknown): Option<RejectedField>`; `RejectedField` is `{ field: string, message: string }`. |
489
523
  | `rpc/identity.ts` | `RequestId`: string service. `Identity`: `IdentityValue`, `{ id: string }`. `OptionalIdentity`: `Option<IdentityValue>`. `SessionUser`: `SessionUserValue`, `{ id, name, email, providerAccounts? }`; `ProviderAccountValue`: `{ providerId, accountId }`. |
490
524
  | `rpc/middleware.ts` | `RequestTracing`, `Authenticated`, `AuthenticatedUser`, `MaybeAuthenticated`: native RPC middleware declarations. |
491
- | `rpc-server/boundary.ts` | `rpcBoundary(schema, { unexpected, message? })`; `RpcBoundaryOptions<Error>`: declared failures pass through, unexpected failures become one declared rejection. |
492
- | `rpc-server/session.ts` | `authenticatedLayer(policy)`, `maybeAuthenticatedLayer(policy)`, `resolveSession(policy, headers, rpc)`; `SessionShape`, `SessionProvider<Session>`, `SessionPolicy<Session>`. `authenticatedUserLayer(policy)` requires `UserSessionShape` and implements `AuthenticatedUser`. |
493
- | `rpc-server/adapters/better-auth-sessions.ts` | `betterAuthSessions(getSession, getProviderAccounts?)`; `GetSession<Session>` returns `Promise<Session \| null>`, `GetProviderAccounts` returns provider/id pairs, and `SessionWithProviderAccounts<Session>` describes an enriched session. |
494
- | `rpc-server/origin.ts` | `trustedOrigins({ allow, missing })`, `originRequest(headers, rpc)`; `OriginPolicy`, `OriginRequest`, `TrustedOriginsOptions`. |
495
- | `rpc-server/local.ts` | `localRpcGuard(effect)`: HTTP RPC guard using native request and serialization services; `loopbackOnly(handler)`, `sameOrigin(request)`, `trustedProxyPeer(trustedProxy?)`, `trustedProxyRanges(trustedProxy?)`. |
496
- | `rpc-server/transport.ts` | `transportHeaders(rpcHeaders)`: Effect returning the headers used for a transport-level decision. |
497
- | `rpc-server/tracing.ts` | `requestTracingLayer({ header?, sensitive? })`; `RequestTracingOptions`. |
498
- | `rpc-server/redact.ts` | `redact(value, sensitive?)`: unknown diagnostic value. |
499
- | `rpc-server/redact-cause.ts` | `redactCause(cause, sensitive?)`, `redactDefect(defect, sensitive?)`, `redactingErrorReporter(reporter, sensitive?)`. |
500
- | `rpc-server/sensitive.ts` | `isSensitiveKey`, `redactText`, `REDACTED`; `SensitiveKey` is `(key: string) => boolean`. |
501
- | `runtime/make.ts` | `makePlatformRuntime(layer, { developmentCacheKey? })`. |
502
- | `runtime/types.ts` | `PlatformRuntime<Services, BuildError>`, `PlatformRuntimeOptions`, `PlatformRuntimeServices<Runtime>`, `PlatformRuntimeBuildError<Runtime>`. |
503
- | `node-http/subscription-signal.ts` | `nodeSubscriptionSignal({ nodeRequest?, request?, signals? })` returns `{ signal, dispose }`; `NodeSubscriptionSignalOptions`, `NodeSubscriptionSignal`. |
504
- | `better-auth/adapter.ts` | `effectPrismaAdapter(Database, runtime, { debugLogs?, modelName?, usePlural? })`; `EffectPrismaAdapterOptions`. |
505
- | `testing/vitest.ts` | `makePlatformIt(Database)({ adapter, createCaller, layer, extend? })`. |
506
- | `testing/types.ts` | `MakePlatformItOptions`, `PlatformHarness`, `PlatformIt`, `PlatformTest`, `PlatformTester`. |
525
+ | `server/rpc-server/boundary.ts` | `rpcBoundary(schema, { unexpected, message? })`; `RpcBoundaryOptions<Error>`: declared failures pass through, unexpected failures become one declared rejection. |
526
+ | `server/rpc-server/session.ts` | `authenticatedLayer(policy)`, `maybeAuthenticatedLayer(policy)`, `resolveSession(policy, headers, rpc)`; `SessionShape`, `SessionProvider<Session>`, `SessionPolicy<Session>`. `authenticatedUserLayer(policy)` requires `UserSessionShape` and implements `AuthenticatedUser`. |
527
+ | `server/rpc-server/adapters/betterAuthSessions.ts` | `betterAuthSessions(getSession, getProviderAccounts?)`; `GetSession<Session>` returns `Promise<Session \| null>`, `GetProviderAccounts` returns provider/id pairs, and `SessionWithProviderAccounts<Session>` describes an enriched session. |
528
+ | `server/rpc-server/origin.ts` | `trustedOrigins({ allow, missing })`, `originRequest(headers, rpc)`; `OriginPolicy`, `OriginRequest`, `TrustedOriginsOptions`. |
529
+ | `server/rpc-server/local.ts` | `localRpcGuard(effect)`: HTTP RPC guard using native request and serialization services; `loopbackOnly(handler)`, `sameOrigin(request)`, `trustedProxyPeer(trustedProxy?)`, `trustedProxyRanges(trustedProxy?)`. |
530
+ | `server/rpc-server/transportHeaders.ts` | `transportHeaders(rpcHeaders)`: Effect returning the headers used for a transport-level decision. |
531
+ | `server/rpc-server/tracing.ts` | `requestTracingLayer({ header?, sensitive? })`; `RequestTracingOptions`. |
532
+ | `server/rpc-server/redact.ts` | `redact(value, sensitive?)`: unknown diagnostic value. |
533
+ | `server/rpc-server/redactCause.ts` | `redactCause(cause, sensitive?)`, `redactDefect(defect, sensitive?)`, `redactingErrorReporter(reporter, sensitive?)`. |
534
+ | `server/rpc-server/sensitive.ts` | `isSensitiveKey`, `redactText`, `REDACTED`; `SensitiveKey` is `(key: string) => boolean`. |
535
+ | `server/runtime/makePlatform.ts` | `makePlatformRuntime(layer, { developmentCacheKey? })`. |
536
+ | `server/runtime/types.ts` | `PlatformRuntime<Services, BuildError>`, `PlatformRuntimeOptions`, `PlatformRuntimeServices<Runtime>`, `PlatformRuntimeBuildError<Runtime>`. |
537
+ | `server/node-http/subscriptionSignal.ts` | `nodeSubscriptionSignal({ nodeRequest?, request?, signals? })` returns `{ signal, dispose }`; `NodeSubscriptionSignalOptions`, `NodeSubscriptionSignal`. |
538
+ | `server/better-auth/adapter.ts` | `effectPrismaAdapter(Database, runtime, { debugLogs?, modelName?, usePlural? })`; `EffectPrismaAdapterOptions`. |
539
+ | `server/testing/makePlatformIt.ts` | `makePlatformIt(Database)({ adapter, createCaller, layer, extend? })`. |
540
+ | `server/testing/types.ts` | `MakePlatformItOptions`, `PlatformHarness`, `PlatformIt`, `PlatformTest`, `PlatformTester`. |
507
541
 
508
542
  `PlatformRuntime` exposes `runPromise(effect, { signal? })`, `runPromiseExit(effect, { signal? })`, `runWithServices(context, evaluate)`, `contextEffect`, `currentServices()` and `dispose()`. The harness exposes native Vitest methods plus `effectApp(name, body, options?)`; its tester also has `skip`, `skipIf`, `runIf`, `only`, `each` and `fails`.
509
543
 
510
- The exports also include the adapter's translation modules: `makeRowAdapter` and `RelationQuery` in `better-auth/row-adapter.ts`, `refineRelation` and `DynamicRelation` in `better-auth/relation.ts`, and `whereExpression`, `CleanedWhere`, `DynamicField` and `Expression` in `better-auth/where.ts`. Application storage setup uses `effectPrismaAdapter`.
544
+ The exports also include the adapter's translation modules: `makeRowAdapter` and `RelationQuery` in `server/better-auth/rowAdapter.ts`, `refineRelation` and `DynamicRelation` in `server/better-auth/relation.ts`, and `whereExpression`, `CleanedWhere`, `DynamicField` and `Expression` in `server/better-auth/where.ts`. Application storage setup uses `effectPrismaAdapter`.
511
545
 
512
546
  ### Install, setup and limits
513
547
 
@@ -515,21 +549,21 @@ The exports also include the adapter's translation modules: `makeRowAdapter` and
515
549
  pnpm add @shivaedev/platform effect@4.0.4
516
550
  ```
517
551
 
518
- Effect is the only required peer. The peer-free implementation lives in the shared `src/errors/` and `src/rpc/` folders and the `src/server/node-http/`, `src/server/rpc-server/` and `src/server/runtime/` folders; explicit exports retain the defining-module import paths listed above. The package-local `quality.fences.config.ts` prevents core from reaching optional peers listed in the manifest. The core errors, RPC declarations, server middleware, runtime and Node HTTP modules can be imported without the optional peers, including the Promise-based `betterAuthSessions` function. The runtime uses Node's `AsyncLocalStorage`; browser consumers import the shared `errors/` and `rpc/` modules.
552
+ Effect is the only required peer. The peer-free implementation lives in the shared `errors/` and `rpc/` folders and the `server/node-http/`, `server/rpc-server/` and `server/runtime/` folders; a module's import path is its path under `src/`. The package-local `quality.fences.config.ts` prevents core from reaching optional peers listed in the manifest. The core errors, RPC declarations, server middleware, runtime and Node HTTP modules can be imported without the optional peers, including the Promise-based `betterAuthSessions` function. The runtime uses Node's `AsyncLocalStorage`; browser consumers import the shared `errors/` and `rpc/` modules.
519
553
 
520
554
  Install the optional peers for the selected integration:
521
555
 
522
556
  | Integration | Additional peers |
523
557
  | --- | --- |
524
- | `boundedBody.ts` | `@effect/platform-node` |
525
- | `appHost.ts` | `@effect/platform-node`, `@effect/sql-pg` |
526
- | `better-auth/adapter.ts` | `better-auth`, `@shivaedev/effect-prisma`, `@prisma-next/sql-orm-client` |
527
- | `testing/vitest.ts` | `@effect/vitest`, `@shivaedev/effect-prisma`, `@shivaedev/effect-trpc`, `@trpc/server` |
558
+ | `server/boundedBody.ts` | `@effect/platform-node` |
559
+ | `server/appHost.ts` | `@effect/platform-node`, `@effect/sql-pg` |
560
+ | `server/better-auth/adapter.ts` | `better-auth`, `@shivaedev/effect-prisma`, `@prisma-next/sql-orm-client` |
561
+ | `server/testing/makePlatformIt.ts` | `@effect/vitest`, `@shivaedev/effect-prisma`, `@shivaedev/effect-trpc`, `@trpc/server` |
528
562
 
529
563
  - The package declares Node 24 or newer and uses the Effect version in its peer manifest.
530
564
  - Keep the auth provider's configuration, cookie settings and resource authorization in the application. The session adapter takes a session lookup and an optional provider-account lookup and returns a session result; it does not write provider refresh cookies into RPC responses.
531
565
  - Without an `HttpServerRequest`, `transportHeaders` falls back to the supplied RPC headers. An application using another transport must decide what headers it can trust.
532
- - Add tracing last on the native group, as in the example, so it wraps the authentication middleware too. Middleware outside that tracing boundary is responsible for its own diagnostics.
566
+ - `appHost` adds tracing last on its server-side copy of the group. When composing a native RPC server directly, add `RequestTracing` last on the group, as in the example, so it wraps authentication too. Middleware outside that tracing boundary is responsible for its own diagnostics.
533
567
  - Redaction recognizes common shapes. Keep secrets out of messages and extend the key predicate for application-specific sensitive fields.
534
568
  - A development cache key is ignored when `NODE_ENV` is `production`. The application owns runtime disposal.
535
569
  - The Better Auth storage adapter's default model mapping capitalizes the model name. Supply `modelName` for a generated schema with another naming convention. Native Better Auth joins (`advanced.database.joins`) are rejected; leave that option off so Better Auth reads related rows with separate queries.
@@ -19,6 +19,7 @@ export interface SessionUserValue extends IdentityValue {
19
19
  readonly email: string;
20
20
  readonly name: string;
21
21
  readonly providerAccounts?: readonly ProviderAccountValue[];
22
+ readonly role?: string | null | undefined;
22
23
  }
23
24
  declare const SessionUser_base: Context.ServiceClass<SessionUser, "@shivaedev/platform/rpc/SessionUser", SessionUserValue>;
24
25
  export declare class SessionUser extends SessionUser_base {
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rpc/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;;AAC9C,qBAAa,SAAU,SAAQ,cAAyE;CAAG;AAC3G,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACpB;;AACD,qBAAa,QAAS,SAAQ,aAA8E;CAAG;;AAC/G,qBAAa,gBAAiB,SAAQ,qBAA6G;CAAG;AACtJ,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AACD,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;CAC5D;;AACD,qBAAa,WAAY,SAAQ,gBAAuF;CAAG"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/rpc/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;;AAC9C,qBAAa,SAAU,SAAQ,cAAyE;CAAG;AAC3G,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACpB;;AACD,qBAAa,QAAS,SAAQ,aAA8E;CAAG;;AAC/G,qBAAa,gBAAiB,SAAQ,qBAA6G;CAAG;AACtJ,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AACD,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC1C;;AACD,qBAAa,WAAY,SAAQ,gBAAuF;CAAG"}
@@ -1 +1 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/rpc/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAC9C,MAAM,OAAO,SAAU,SAAQ,OAAO,CAAC,OAAO,EAAqB,CAAC,mCAAmC,CAAC;CAAG;AAI3G,MAAM,OAAO,QAAS,SAAQ,OAAO,CAAC,OAAO,EAA2B,CAAC,kCAAkC,CAAC;CAAG;AAC/G,MAAM,OAAO,gBAAiB,SAAQ,OAAO,CAAC,OAAO,EAAkD,CAAC,0CAA0C,CAAC;CAAG;AAUtJ,MAAM,OAAO,WAAY,SAAQ,OAAO,CAAC,OAAO,EAAiC,CAAC,qCAAqC,CAAC;CAAG"}
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/rpc/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAC9C,MAAM,OAAO,SAAU,SAAQ,OAAO,CAAC,OAAO,EAAqB,CAAC,mCAAmC,CAAC;CAAG;AAI3G,MAAM,OAAO,QAAS,SAAQ,OAAO,CAAC,OAAO,EAA2B,CAAC,kCAAkC,CAAC;CAAG;AAC/G,MAAM,OAAO,gBAAiB,SAAQ,OAAO,CAAC,OAAO,EAAkD,CAAC,0CAA0C,CAAC;CAAG;AAWtJ,MAAM,OAAO,WAAY,SAAQ,OAAO,CAAC,OAAO,EAAiC,CAAC,qCAAqC,CAAC;CAAG"}
@@ -0,0 +1,5 @@
1
+ import { Effect } from "effect";
2
+ import { Forbidden, Unauthorized } from "#errors/taxonomy.ts";
3
+ import { type SessionUserValue } from "./identity.ts";
4
+ export declare const requireAdmin: Effect.Effect<SessionUserValue, Unauthorized | Forbidden>;
5
+ //# sourceMappingURL=requireAdmin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requireAdmin.d.ts","sourceRoot":"","sources":["../../src/rpc/requireAdmin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEnE,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,YAAY,GAAG,SAAS,CASjF,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { Effect, Option } from "effect";
2
+ import { Forbidden, Unauthorized } from "#errors/taxonomy.ts";
3
+ import { SessionUser } from "./identity.js";
4
+ export const requireAdmin = Effect.gen(function* () {
5
+ const user = yield* Effect.serviceOption(SessionUser);
6
+ if (Option.isNone(user)) {
7
+ return yield* new Unauthorized({ message: "Authentication required" });
8
+ }
9
+ if (!user.value.role?.split(",").includes("admin")) {
10
+ return yield* new Forbidden({ message: "Administrator role required" });
11
+ }
12
+ return user.value;
13
+ });
14
+ //# sourceMappingURL=requireAdmin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requireAdmin.js","sourceRoot":"","sources":["../../src/rpc/requireAdmin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAyB,MAAM,eAAe,CAAC;AAEnE,MAAM,CAAC,MAAM,YAAY,GAA8D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC1G,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACtD,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC;AACnB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Duration } from "effect";
2
+ import type { Migrator } from "effect/sql";
3
+ export interface MigrationOptions<R = never> {
4
+ readonly loader: Migrator.Loader<R>;
5
+ readonly lockTimeout?: Duration.Input;
6
+ readonly mode?: "migrate" | "check" | "wait";
7
+ readonly pollInterval?: Duration.Input;
8
+ readonly table?: string;
9
+ readonly waitTimeout?: Duration.Input;
10
+ }
11
+ //# sourceMappingURL=MigrationOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrationOptions.d.ts","sourceRoot":"","sources":["../../src/server/MigrationOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,KAAK;IAC1C,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;CACtC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=MigrationOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrationOptions.js","sourceRoot":"","sources":["../../src/server/MigrationOptions.ts"],"names":[],"mappings":""}
@@ -1,10 +1,10 @@
1
- import { Context, type Duration, type Effect } from "effect";
1
+ import { Context, type Effect } from "effect";
2
2
  import type { Rpc } from "effect/rpc";
3
- import type { Migrator } from "effect/sql";
4
- import type { SessionPolicy, SessionShape } from "#rpc-server/session.ts";
5
3
  import { appHostHttp, deferredHost } from "#server/appHostHttp.ts";
6
4
  import { type DatabaseConfig } from "#server/databaseLayer.ts";
7
5
  import type { HostOptions, HostPolicy } from "#server/hostOptions.ts";
6
+ import type { MigrationOptions } from "#server/MigrationOptions.ts";
7
+ import type { SessionPolicy, SessionShape } from "#server/rpc-server/session.ts";
8
8
  declare const AppChanges_base: Context.ServiceClass<AppChanges, "@shivaedev/platform/AppChanges", {
9
9
  resync: Effect.Effect<void, never, never>;
10
10
  stream: (keys: readonly import("@shivaedev/effect-contract/keys.ts").Key[]) => import("effect/Stream").Stream<{
@@ -25,14 +25,9 @@ export declare class AppChanges extends AppChanges_base {
25
25
  }
26
26
  export interface AppDatabaseOptions<R = never> {
27
27
  readonly config?: DatabaseConfig;
28
- readonly migrations: {
29
- readonly loader: Migrator.Loader<R>;
30
- readonly mode?: "migrate" | "check";
31
- readonly table?: string;
32
- readonly lockTimeout?: Duration.Input;
33
- };
28
+ readonly migrations: MigrationOptions<R>;
34
29
  }
35
- export declare function appDatabase<R>(options: AppDatabaseOptions<R>): import("effect/Layer").Layer<AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient, import("effect/Config").ConfigError | Migrator.MigrationError | import("effect/sql/SqlError").SqlError, Exclude<Exclude<R, import("effect/Scope").Scope>, import("@effect/sql-pg/PgClient").PgClient | import("effect/sql/SqlClient").SqlClient>>;
30
+ export declare function appDatabase<R>(options: AppDatabaseOptions<R>): import("effect/Layer").Layer<AppChanges | import("@effect/sql-pg/PgClient").PgClient | import("effect/reactivity/Reactivity").Reactivity | import("effect/sql/SqlClient").SqlClient, import("effect/Config").ConfigError | import("effect/sql/Migrator").MigrationError | import("effect/sql/SqlError").SqlError, Exclude<Exclude<R, import("effect/Scope").Scope>, import("@effect/sql-pg/PgClient").PgClient | import("effect/sql/SqlClient").SqlClient>>;
36
31
  export type AppHostOptions<TRpcs extends Rpc.Any, THandlers, THandlerError, THandlerRequirements, TServices = never, TServiceError = never, TServiceRequirements = never, TMigrations = never, TSession extends SessionShape = SessionShape> = HostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> & {
37
32
  readonly migrations: AppDatabaseOptions<TMigrations>["migrations"];
38
33
  readonly policy?: undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"appHost.d.ts","sourceRoot":"","sources":["../../src/server/appHost.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"appHost.d.ts","sourceRoot":"","sources":["../../src/server/appHost.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"appHost.js","sourceRoot":"","sources":["../../src/server/appHost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA8B,MAAM,QAAQ,CAAC;AAK7D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAuB,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAG9E,MAAM,OAAO,UAAW,SAAQ,OAAO,CAAC,OAAO,EAAqD,CAAC,gCAAgC,CAAC;CAAG;AAWzI,MAAM,UAAU,WAAW,CAAI,OAA8B;IAC5D,OAAO,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAgGD,MAAM,UAAU,OAAO,CAatB,OAUsI;IAEtI,IAAI,aAAa,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,OAAO,CAAC,UAAU,KAAK,SAAS;QACtC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC;QACtB,CAAC,CAAC,YAAY,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC9H,CAAC"}
1
+ {"version":3,"file":"appHost.js","sourceRoot":"","sources":["../../src/server/appHost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAuB,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAK9E,MAAM,OAAO,UAAW,SAAQ,OAAO,CAAC,OAAO,EAAqD,CAAC,gCAAgC,CAAC;CAAG;AAMzI,MAAM,UAAU,WAAW,CAAI,OAA8B;IAC5D,OAAO,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAgGD,MAAM,UAAU,OAAO,CAatB,OAUsI;IAEtI,IAAI,aAAa,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,OAAO,CAAC,UAAU,KAAK,SAAS;QACtC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC;QACtB,CAAC,CAAC,YAAY,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC9H,CAAC"}