@shivaedev/platform 0.16.1 → 0.18.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 (72) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +133 -12
  3. package/dist/rpc/identity.d.ts +8 -2
  4. package/dist/rpc/identity.d.ts.map +1 -1
  5. package/dist/rpc/identity.js +2 -0
  6. package/dist/rpc/identity.js.map +1 -1
  7. package/dist/rpc/middleware.d.ts +4 -1
  8. package/dist/rpc/middleware.d.ts.map +1 -1
  9. package/dist/rpc/middleware.js +4 -0
  10. package/dist/rpc/middleware.js.map +1 -1
  11. package/dist/rpc/publicConfig.d.ts +3 -0
  12. package/dist/rpc/publicConfig.d.ts.map +1 -0
  13. package/dist/rpc/publicConfig.js +8 -0
  14. package/dist/rpc/publicConfig.js.map +1 -0
  15. package/dist/rpc/requireAdmin.d.ts +3 -3
  16. package/dist/rpc/requireAdmin.d.ts.map +1 -1
  17. package/dist/rpc/requireAdmin.js +5 -8
  18. package/dist/rpc/requireAdmin.js.map +1 -1
  19. package/dist/server/AppHostFactory.d.ts +15 -0
  20. package/dist/server/AppHostFactory.d.ts.map +1 -0
  21. package/dist/server/AppHostFactory.js +2 -0
  22. package/dist/server/AppHostFactory.js.map +1 -0
  23. package/dist/server/AppHostInput.d.ts +13 -0
  24. package/dist/server/AppHostInput.d.ts.map +1 -0
  25. package/dist/server/AppHostInput.js +2 -0
  26. package/dist/server/AppHostInput.js.map +1 -0
  27. package/dist/server/appHost.d.ts +8 -10
  28. package/dist/server/appHost.d.ts.map +1 -1
  29. package/dist/server/appHost.js +6 -6
  30. package/dist/server/appHost.js.map +1 -1
  31. package/dist/server/appHostHttp.d.ts +5 -2
  32. package/dist/server/appHostHttp.d.ts.map +1 -1
  33. package/dist/server/appHostHttp.js.map +1 -1
  34. package/dist/server/better-auth/mount.d.ts +61 -0
  35. package/dist/server/better-auth/mount.d.ts.map +1 -0
  36. package/dist/server/better-auth/mount.js +59 -0
  37. package/dist/server/better-auth/mount.js.map +1 -0
  38. package/dist/server/better-auth/testing.d.ts +50 -0
  39. package/dist/server/better-auth/testing.d.ts.map +1 -0
  40. package/dist/server/better-auth/testing.js +18 -0
  41. package/dist/server/better-auth/testing.js.map +1 -0
  42. package/dist/server/databaseLayer.d.ts +2 -1
  43. package/dist/server/databaseLayer.d.ts.map +1 -1
  44. package/dist/server/databaseLayer.js +2 -0
  45. package/dist/server/databaseLayer.js.map +1 -1
  46. package/dist/server/rpc-server/adapters/betterAuthSessions.d.ts +3 -1
  47. package/dist/server/rpc-server/adapters/betterAuthSessions.d.ts.map +1 -1
  48. package/dist/server/rpc-server/adapters/betterAuthSessions.js +13 -22
  49. package/dist/server/rpc-server/adapters/betterAuthSessions.js.map +1 -1
  50. package/dist/server/rpc-server/publicConfigLayer.d.ts +4 -0
  51. package/dist/server/rpc-server/publicConfigLayer.d.ts.map +1 -0
  52. package/dist/server/rpc-server/publicConfigLayer.js +8 -0
  53. package/dist/server/rpc-server/publicConfigLayer.js.map +1 -0
  54. package/dist/server/rpc-server/session.d.ts +6 -2
  55. package/dist/server/rpc-server/session.d.ts.map +1 -1
  56. package/dist/server/rpc-server/session.js +16 -6
  57. package/dist/server/rpc-server/session.js.map +1 -1
  58. package/package.json +10 -6
  59. package/src/rpc/identity.ts +8 -2
  60. package/src/rpc/middleware.ts +7 -1
  61. package/src/rpc/publicConfig.ts +9 -0
  62. package/src/rpc/requireAdmin.ts +6 -9
  63. package/src/server/AppHostFactory.ts +121 -0
  64. package/src/server/AppHostInput.ts +74 -0
  65. package/src/server/appHost.ts +43 -71
  66. package/src/server/appHostHttp.ts +4 -4
  67. package/src/server/better-auth/mount.ts +68 -0
  68. package/src/server/better-auth/testing.ts +21 -0
  69. package/src/server/databaseLayer.ts +4 -1
  70. package/src/server/rpc-server/adapters/betterAuthSessions.ts +19 -23
  71. package/src/server/rpc-server/publicConfigLayer.ts +11 -0
  72. package/src/server/rpc-server/session.ts +38 -6
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publicConfigLayer.js","sourceRoot":"","sources":["../../../src/server/rpc-server/publicConfigLayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAuB,MAAM,EAAE,MAAM,QAAQ,CAAC;AAG7D,MAAM,UAAU,iBAAiB,CAAO,WAAkD,EAAE,IAAmC;IAC9H,OAAO,WAAW,CAAC,OAAO,CACzB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACrF,OAAO,WAAW,CAAC,EAAE,CAAC,EAAE,2BAA2B,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACrF,CAAC,CAAC,CACF,CAAC;AACH,CAAC"}
@@ -1,8 +1,8 @@
1
1
  import { Effect, Layer, Option } from "effect";
2
2
  import type { Headers } from "effect/http";
3
3
  import { type AuthUnavailable, Forbidden, Unauthorized } from "#errors/taxonomy.ts";
4
- import { Identity, SessionUser, type SessionUserValue } from "#rpc/identity.ts";
5
- import { Authenticated, AuthenticatedUser, MaybeAuthenticated } from "#rpc/middleware.ts";
4
+ import { Identity, SessionUser, type SessionUserValue, type SessionUserWithProviderAccountsValue } from "#rpc/identity.ts";
5
+ import { Authenticated, AuthenticatedUser, AuthenticatedUserWithProviderAccounts, MaybeAuthenticated } from "#rpc/middleware.ts";
6
6
  import { type OriginPolicy } from "./origin.ts";
7
7
  export interface SessionShape {
8
8
  readonly user: {
@@ -24,4 +24,8 @@ export interface UserSessionShape extends SessionShape {
24
24
  }
25
25
  export declare function withSessionUser<TSession extends UserSessionShape>(policy: SessionPolicy<TSession>, headers: Headers.Headers, operation: string): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E | AuthUnavailable | Forbidden | Unauthorized, Exclude<Exclude<R, Identity>, SessionUser>>;
26
26
  export declare function authenticatedUserLayer<TSession extends UserSessionShape>(policy: SessionPolicy<TSession>): Layer.Layer<AuthenticatedUser>;
27
+ export interface ProviderAccountsSessionShape extends UserSessionShape {
28
+ readonly user: SessionUserWithProviderAccountsValue;
29
+ }
30
+ export declare function authenticatedUserWithProviderAccountsLayer<TSession extends ProviderAccountsSessionShape>(policy: SessionPolicy<TSession>): Layer.Layer<AuthenticatedUserWithProviderAccounts>;
27
31
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/server/rpc-server/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAoB,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,KAAK,YAAY,EAAiB,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE;QACd,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;KACpB,CAAC;CACF;AACD,MAAM,WAAW,eAAe,CAAC,QAAQ,SAAS,YAAY;IAC7D,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC;CACpG;AACD,MAAM,WAAW,aAAa,CAAC,QAAQ,SAAS,YAAY;IAC3D,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;CAC7C;AACD,eAAO,MAAM,cAAc,EAAE,CAAC,QAAQ,SAAS,YAAY,EAC1D,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAC/B,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,GAAG,EAAE,MAAM,KACP,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,SAAS,CAQrE,CAAC;AAIH,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAW7H;AACD,wBAAgB,uBAAuB,CAAC,QAAQ,SAAS,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAWvI;AACD,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACrD,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;CAChC;AACD,wBAAgB,eAAe,CAAC,QAAQ,SAAS,gBAAgB,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,IACtI,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,kHAsB/C;AACD,wBAAgB,sBAAsB,CAAC,QAAQ,SAAS,gBAAgB,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAEzI"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/server/rpc-server/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,KAAK,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EACN,QAAQ,EAER,WAAW,EACX,KAAK,gBAAgB,EAErB,KAAK,oCAAoC,EACzC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,qCAAqC,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACjI,OAAO,EAAE,KAAK,YAAY,EAAiB,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE;QACd,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;KACpB,CAAC;CACF;AACD,MAAM,WAAW,eAAe,CAAC,QAAQ,SAAS,YAAY;IAC7D,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAC,CAAC;CACpG;AACD,MAAM,WAAW,aAAa,CAAC,QAAQ,SAAS,YAAY;IAC3D,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;CAC7C;AACD,eAAO,MAAM,cAAc,EAAE,CAAC,QAAQ,SAAS,YAAY,EAC1D,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAC/B,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,GAAG,EAAE,MAAM,KACP,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,SAAS,CAQrE,CAAC;AAIH,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAW7H;AACD,wBAAgB,uBAAuB,CAAC,QAAQ,SAAS,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAWvI;AACD,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACrD,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;CAChC;AACD,wBAAgB,eAAe,CAAC,QAAQ,SAAS,gBAAgB,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,IACtI,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,kHAmB/C;AACD,wBAAgB,sBAAsB,CAAC,QAAQ,SAAS,gBAAgB,EAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAEzI;AAED,MAAM,WAAW,4BAA6B,SAAQ,gBAAgB;IACrE,QAAQ,CAAC,IAAI,EAAE,oCAAoC,CAAC;CACpD;AACD,wBAAgB,0CAA0C,CAAC,QAAQ,SAAS,4BAA4B,EACvG,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAC7B,KAAK,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAqBpD"}
@@ -1,7 +1,7 @@
1
1
  import { Effect, Layer, Option } from "effect";
2
2
  import { Forbidden, Unauthorized } from "#errors/taxonomy.ts";
3
- import { Identity, OptionalIdentity, SessionUser } from "#rpc/identity.ts";
4
- import { Authenticated, AuthenticatedUser, MaybeAuthenticated } from "#rpc/middleware.ts";
3
+ import { Identity, OptionalIdentity, SessionUser, SessionUserWithProviderAccounts, } from "#rpc/identity.ts";
4
+ import { Authenticated, AuthenticatedUser, AuthenticatedUserWithProviderAccounts, MaybeAuthenticated } from "#rpc/middleware.ts";
5
5
  import { originRequest } from "./origin.js";
6
6
  import { transportHeaders } from "./transportHeaders.js";
7
7
  export const resolveSession = Effect.fn("PlatformRpc.resolveSession")(function* (policy, headers, rpc) {
@@ -40,20 +40,30 @@ export function withSessionUser(policy, headers, operation) {
40
40
  if (Option.isNone(session)) {
41
41
  return yield* new Unauthorized({ message: "Authentication required" });
42
42
  }
43
- const { name, email, role, providerAccounts } = session.value.user;
43
+ const { name, email, role } = session.value.user;
44
44
  const id = yield* identified(session.value.user.id);
45
45
  return yield* effect.pipe(Effect.provideService(Identity, { id }), Effect.provideService(SessionUser, {
46
46
  email,
47
47
  id,
48
48
  name,
49
49
  ...(role === undefined ? {} : { role }),
50
- ...(providerAccounts === undefined
51
- ? {}
52
- : { providerAccounts: providerAccounts.map(({ accountId, providerId }) => ({ accountId, providerId })) }),
53
50
  }), Effect.annotateLogs({ userId: id }));
54
51
  });
55
52
  }
56
53
  export function authenticatedUserLayer(policy) {
57
54
  return Layer.succeed(AuthenticatedUser, (effect, { headers, rpc }) => effect.pipe(withSessionUser(policy, headers, rpc._tag)));
58
55
  }
56
+ export function authenticatedUserWithProviderAccountsLayer(policy) {
57
+ return Layer.succeed(AuthenticatedUserWithProviderAccounts, (effect, { headers, rpc }) => Effect.gen(function* () {
58
+ const session = yield* resolveSession(policy, headers, rpc._tag);
59
+ if (Option.isNone(session)) {
60
+ return yield* new Unauthorized({ message: "Authentication required" });
61
+ }
62
+ const { id, name, email, role, providerAccounts } = session.value.user;
63
+ const accounts = yield* Effect.cached(Effect.map(providerAccounts, (values) => values.map(({ accountId, providerId }) => ({ accountId, providerId }))));
64
+ const user = { email, id, name, ...(role === undefined ? {} : { role }) };
65
+ yield* identified(id);
66
+ return yield* effect.pipe(Effect.provideService(Identity, { id }), Effect.provideService(SessionUser, user), Effect.provideService(SessionUserWithProviderAccounts, { ...user, providerAccounts: accounts }), Effect.annotateLogs({ userId: id }));
67
+ }));
68
+ }
59
69
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/server/rpc-server/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/server/rpc-server/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,EAAwB,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EACN,QAAQ,EACR,gBAAgB,EAChB,WAAW,EAEX,+BAA+B,GAE/B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,qCAAqC,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACjI,OAAO,EAAqB,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAazD,MAAM,CAAC,MAAM,cAAc,GAIgD,MAAM,CAAC,EAAE,CAAC,4BAA4B,CAAC,CAAC,QAAQ,CAAC,EAE1H,MAA+B,EAAE,OAAwB,EAAE,GAAW;IACvE,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;QACnD,OAAO,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AACH,SAAS,UAAU,CAAC,EAAU;IAC7B,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AACtF,CAAC;AACD,MAAM,UAAU,kBAAkB,CAAgC,MAA+B;IAChG,OAAO,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAChE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACzG,CAAC,CAAC,CACF,CAAC;AACH,CAAC;AACD,MAAM,UAAU,uBAAuB,CAAgC,MAA+B;IACrG,OAAO,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CACrE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9H,CAAC,CAAC,CACF,CAAC;AACH,CAAC;AAID,MAAM,UAAU,eAAe,CAAoC,MAA+B,EAAE,OAAwB,EAAE,SAAiB;IAC9I,OAAO,CAAU,MAA8B,EAAE,EAAE,CAClD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAClE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;QACjD,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACxB,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,EACvC,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE;YAClC,KAAK;YACL,EAAE;YACF,IAAI;YACJ,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;SACvC,CAAC,EACF,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CACnC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AACD,MAAM,UAAU,sBAAsB,CAAoC,MAA+B;IACxG,OAAO,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChI,CAAC;AAKD,MAAM,UAAU,0CAA0C,CACzD,MAA+B;IAE/B,OAAO,KAAK,CAAC,OAAO,CAAC,qCAAqC,EAAE,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CACxF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;QACvE,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CACpC,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAChH,CAAC;QACF,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC1E,KAAK,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACtB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACxB,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,EACvC,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC,EACxC,MAAM,CAAC,cAAc,CAAC,+BAA+B,EAAE,EAAE,GAAG,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC,EAC/F,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CACnC,CAAC;IACH,CAAC,CAAC,CACF,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shivaedev/platform",
3
- "version": "0.16.1",
3
+ "version": "0.18.0",
4
4
  "description": "Opinionated Effect application infrastructure for ShivaeDev services",
5
5
  "homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/platform#readme",
6
6
  "bugs": {
@@ -41,7 +41,7 @@
41
41
  ],
42
42
  "dependencies": {
43
43
  "@shivaedev/effect-contract": "0.5.1",
44
- "@shivaedev/effect-sql": "0.5.2",
44
+ "@shivaedev/effect-sql": "0.6.0",
45
45
  "@shivaedev/types": "0.2.1"
46
46
  },
47
47
  "devDependencies": {
@@ -55,10 +55,10 @@
55
55
  "@prisma-next/sql-orm-client": "0.16.0",
56
56
  "@prisma-next/target-postgres": "0.16.0",
57
57
  "@shivaedev/effect-prisma": "0.10.0",
58
- "@shivaedev/effect-test-sql": "0.5.5",
58
+ "@shivaedev/effect-test-sql": "0.6.0",
59
59
  "@shivaedev/effect-trpc": "0.8.0",
60
- "@shivaedev/quality": "0.26.0",
61
- "@shivaedev/test-story": "0.8.0",
60
+ "@shivaedev/quality": "0.27.1",
61
+ "@shivaedev/test-story": "0.10.0",
62
62
  "@trpc/client": "11.19.0",
63
63
  "@trpc/server": "11.19.0",
64
64
  "@types/node": "24.19.2",
@@ -79,7 +79,8 @@
79
79
  "@shivaedev/effect-trpc": "0.8.0",
80
80
  "@trpc/server": "11.19.0",
81
81
  "better-auth": "1.7.7",
82
- "effect": "4.0.4"
82
+ "effect": "4.0.4",
83
+ "pg": "8.23.0"
83
84
  },
84
85
  "peerDependenciesMeta": {
85
86
  "@effect/platform-node": {
@@ -105,6 +106,9 @@
105
106
  },
106
107
  "better-auth": {
107
108
  "optional": true
109
+ },
110
+ "pg": {
111
+ "optional": true
108
112
  }
109
113
  },
110
114
  "engines": {
@@ -1,4 +1,5 @@
1
- import { Context, type Option } from "effect";
1
+ import { Context, type Effect, type Option } from "effect";
2
+ import type { AuthUnavailable, Unauthorized } from "#errors/taxonomy.ts";
2
3
  export class RequestId extends Context.Service<RequestId, string>()("@shivaedev/platform/rpc/RequestId") {}
3
4
  export interface IdentityValue {
4
5
  readonly id: string;
@@ -12,7 +13,12 @@ export interface ProviderAccountValue {
12
13
  export interface SessionUserValue extends IdentityValue {
13
14
  readonly email: string;
14
15
  readonly name: string;
15
- readonly providerAccounts?: readonly ProviderAccountValue[];
16
16
  readonly role?: string | null | undefined;
17
17
  }
18
18
  export class SessionUser extends Context.Service<SessionUser, SessionUserValue>()("@shivaedev/platform/rpc/SessionUser") {}
19
+ export interface SessionUserWithProviderAccountsValue extends SessionUserValue {
20
+ readonly providerAccounts: Effect.Effect<readonly ProviderAccountValue[], AuthUnavailable | Unauthorized>;
21
+ }
22
+ export class SessionUserWithProviderAccounts extends Context.Service<SessionUserWithProviderAccounts, SessionUserWithProviderAccountsValue>()(
23
+ "@shivaedev/platform/rpc/SessionUserWithProviderAccounts",
24
+ ) {}
@@ -1,7 +1,7 @@
1
1
  import { Schema } from "effect";
2
2
  import { RpcMiddleware } from "effect/rpc";
3
3
  import { AuthUnavailable, Forbidden, Unauthorized } from "#errors/taxonomy.ts";
4
- import type { Identity, OptionalIdentity, RequestId, SessionUser } from "./identity.ts";
4
+ import type { Identity, OptionalIdentity, RequestId, SessionUser, SessionUserWithProviderAccounts } from "./identity.ts";
5
5
  export class RequestTracing extends RpcMiddleware.Service<
6
6
  RequestTracing,
7
7
  {
@@ -30,3 +30,9 @@ export class AuthenticatedUser extends RpcMiddleware.Service<
30
30
  >()("@shivaedev/platform/rpc/AuthenticatedUser", {
31
31
  error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
32
32
  }) {}
33
+ export class AuthenticatedUserWithProviderAccounts extends RpcMiddleware.Service<
34
+ AuthenticatedUserWithProviderAccounts,
35
+ { provides: Identity | SessionUser | SessionUserWithProviderAccounts }
36
+ >()("@shivaedev/platform/rpc/AuthenticatedUserWithProviderAccounts", {
37
+ error: Schema.Union([Unauthorized, AuthUnavailable, Forbidden]),
38
+ }) {}
@@ -0,0 +1,9 @@
1
+ import type { Schema } from "effect";
2
+ import { contract } from "@shivaedev/effect-contract/contract.ts";
3
+ import { query } from "@shivaedev/effect-contract/operation.ts";
4
+
5
+ export function publicConfig<T, E>(schema: Schema.Codec<T, E>) {
6
+ return contract("platform.publicConfig", {
7
+ queries: [query("get", { reads: () => [], success: schema })],
8
+ });
9
+ }
@@ -1,14 +1,11 @@
1
- import { Effect, Option } from "effect";
2
- import { Forbidden, Unauthorized } from "#errors/taxonomy.ts";
1
+ import { Effect } from "effect";
2
+ import { Forbidden } from "#errors/taxonomy.ts";
3
3
  import { SessionUser, type SessionUserValue } from "./identity.ts";
4
4
 
5
- export const requireAdmin: Effect.Effect<SessionUserValue, Unauthorized | Forbidden> = Effect.gen(function* () {
6
- const user = yield* Effect.serviceOption(SessionUser);
7
- if (Option.isNone(user)) {
8
- return yield* new Unauthorized({ message: "Authentication required" });
9
- }
10
- if (!user.value.role?.split(",").includes("admin")) {
5
+ export const requireAdmin: Effect.Effect<SessionUserValue, Forbidden, SessionUser> = Effect.gen(function* () {
6
+ const user = yield* SessionUser;
7
+ if (!user.role?.split(",").includes("admin")) {
11
8
  return yield* new Forbidden({ message: "Administrator role required" });
12
9
  }
13
- return user.value;
10
+ return user;
14
11
  });
@@ -0,0 +1,121 @@
1
+ import type { Effect, Layer } from "effect";
2
+ import type { Rpc } from "effect/rpc";
3
+ import type { HostPreflight } from "#server/AppHostInput.ts";
4
+ import type { AppDatabaseOptions, AppHostOptions, AppHttpHostOptions, AppLocalHostOptions } from "#server/appHost.ts";
5
+ import type { appHostHttp, deferredHost } from "#server/appHostHttp.ts";
6
+ import type { SessionShape } from "#server/rpc-server/session.ts";
7
+
8
+ type PreflightHost<THost extends Layer.Any, TServices, TError, TRequirements> = Layer.Layer<
9
+ Layer.Success<THost> | TServices,
10
+ Layer.Error<THost> | TError,
11
+ Exclude<Layer.Services<THost>, TServices> | TRequirements
12
+ >;
13
+
14
+ export interface AppHostFactory {
15
+ <
16
+ TRpcs extends Rpc.Any,
17
+ THandlers,
18
+ THandlerError,
19
+ THandlerRequirements,
20
+ TServices = never,
21
+ TServiceError = never,
22
+ TServiceRequirements = never,
23
+ TMigrations = never,
24
+ TSession extends SessionShape = SessionShape,
25
+ TApplicationError = never,
26
+ TApplicationRequirements = never,
27
+ TPreflight = never,
28
+ TPreflightError = never,
29
+ TPreflightRequirements = never,
30
+ >(
31
+ options: HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> &
32
+ (
33
+ | (AppDatabaseOptions<TMigrations> & {
34
+ readonly application: Effect.Effect<
35
+ AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>,
36
+ TApplicationError,
37
+ TApplicationRequirements
38
+ >;
39
+ })
40
+ | AppHostOptions<
41
+ TRpcs,
42
+ THandlers,
43
+ THandlerError,
44
+ THandlerRequirements,
45
+ TServices,
46
+ TServiceError,
47
+ TServiceRequirements,
48
+ TMigrations,
49
+ TSession,
50
+ TPreflight,
51
+ TPreflightError,
52
+ TPreflightRequirements
53
+ >
54
+ | AppLocalHostOptions<
55
+ TRpcs,
56
+ THandlers,
57
+ THandlerError,
58
+ THandlerRequirements,
59
+ TServices,
60
+ TServiceError,
61
+ TServiceRequirements,
62
+ TMigrations,
63
+ TPreflight,
64
+ TPreflightError,
65
+ TPreflightRequirements
66
+ >
67
+ ),
68
+ ): PreflightHost<
69
+ ReturnType<
70
+ typeof deferredHost<
71
+ TRpcs,
72
+ THandlers,
73
+ THandlerError,
74
+ THandlerRequirements,
75
+ TServices,
76
+ TServiceError,
77
+ TServiceRequirements,
78
+ TMigrations,
79
+ TSession,
80
+ TApplicationError,
81
+ TApplicationRequirements
82
+ >
83
+ >,
84
+ NoInfer<TPreflight>,
85
+ NoInfer<TPreflightError>,
86
+ NoInfer<TPreflightRequirements>
87
+ >;
88
+
89
+ <
90
+ TRpcs extends Rpc.Any,
91
+ THandlers,
92
+ THandlerError,
93
+ THandlerRequirements,
94
+ TServices = never,
95
+ TServiceError = never,
96
+ TServiceRequirements = never,
97
+ TSession extends SessionShape = SessionShape,
98
+ TPreflight = never,
99
+ TPreflightError = never,
100
+ TPreflightRequirements = never,
101
+ >(
102
+ options: AppHttpHostOptions<
103
+ TRpcs,
104
+ THandlers,
105
+ THandlerError,
106
+ THandlerRequirements,
107
+ TServices,
108
+ TServiceError,
109
+ TServiceRequirements,
110
+ TSession,
111
+ TPreflight,
112
+ TPreflightError,
113
+ TPreflightRequirements
114
+ >,
115
+ ): PreflightHost<
116
+ ReturnType<typeof appHostHttp<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>>,
117
+ NoInfer<TPreflight>,
118
+ NoInfer<TPreflightError>,
119
+ NoInfer<TPreflightRequirements>
120
+ >;
121
+ }
@@ -0,0 +1,74 @@
1
+ import type { Effect, Layer } from "effect";
2
+ import type { Rpc } from "effect/rpc";
3
+ import type { AppDatabaseOptions, AppHostOptions, AppHttpHostOptions, AppLocalHostOptions } from "#server/appHost.ts";
4
+ import type { SessionShape } from "#server/rpc-server/session.ts";
5
+
6
+ export type HostPreflight<TServices = never, TError = never, TRequirements = never> =
7
+ | { readonly preflight: Layer.Layer<TServices, TError, TRequirements> }
8
+ | ([TServices | TError | TRequirements] extends [never] ? { readonly preflight?: never } : never);
9
+
10
+ export type AppHostInput<
11
+ TRpcs extends Rpc.Any,
12
+ THandlers,
13
+ THandlerError,
14
+ THandlerRequirements,
15
+ TServices = never,
16
+ TServiceError = never,
17
+ TServiceRequirements = never,
18
+ TMigrations = never,
19
+ TSession extends SessionShape = SessionShape,
20
+ TApplicationError = never,
21
+ TApplicationRequirements = never,
22
+ TPreflight = never,
23
+ TPreflightError = never,
24
+ TPreflightRequirements = never,
25
+ > = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> &
26
+ (
27
+ | (AppDatabaseOptions<TMigrations> & {
28
+ readonly application: Effect.Effect<
29
+ AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>,
30
+ TApplicationError,
31
+ TApplicationRequirements
32
+ >;
33
+ })
34
+ | AppHostOptions<
35
+ TRpcs,
36
+ THandlers,
37
+ THandlerError,
38
+ THandlerRequirements,
39
+ TServices,
40
+ TServiceError,
41
+ TServiceRequirements,
42
+ TMigrations,
43
+ TSession,
44
+ TPreflight,
45
+ TPreflightError,
46
+ TPreflightRequirements
47
+ >
48
+ | AppLocalHostOptions<
49
+ TRpcs,
50
+ THandlers,
51
+ THandlerError,
52
+ THandlerRequirements,
53
+ TServices,
54
+ TServiceError,
55
+ TServiceRequirements,
56
+ TMigrations,
57
+ TPreflight,
58
+ TPreflightError,
59
+ TPreflightRequirements
60
+ >
61
+ | AppHttpHostOptions<
62
+ TRpcs,
63
+ THandlers,
64
+ THandlerError,
65
+ THandlerRequirements,
66
+ TServices,
67
+ TServiceError,
68
+ TServiceRequirements,
69
+ TSession,
70
+ TPreflight,
71
+ TPreflightError,
72
+ TPreflightRequirements
73
+ >
74
+ );
@@ -1,6 +1,8 @@
1
- import { Context, type Effect } from "effect";
1
+ import { Context, type Effect, Layer } from "effect";
2
2
  import type { Rpc } from "effect/rpc";
3
3
  import type { makeLiveServer } from "@shivaedev/effect-contract/makeLiveServer.ts";
4
+ import type { AppHostFactory } from "#server/AppHostFactory.ts";
5
+ import type { AppHostInput, HostPreflight } from "#server/AppHostInput.ts";
4
6
  import { appHostHttp, deferredHost, migratedHost } from "#server/appHostHttp.ts";
5
7
  import { type DatabaseConfig, databaseLayer } from "#server/databaseLayer.ts";
6
8
  import type { HostOptions, HostPolicy } from "#server/hostOptions.ts";
@@ -27,11 +29,15 @@ export type AppHostOptions<
27
29
  TServiceRequirements = never,
28
30
  TMigrations = never,
29
31
  TSession extends SessionShape = SessionShape,
30
- > = HostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> & {
31
- readonly migrations: AppDatabaseOptions<TMigrations>["migrations"];
32
- readonly policy?: undefined;
33
- readonly sessions: SessionPolicy<TSession>;
34
- };
32
+ TPreflight = never,
33
+ TPreflightError = never,
34
+ TPreflightRequirements = never,
35
+ > = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> &
36
+ HostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> & {
37
+ readonly migrations: AppDatabaseOptions<TMigrations>["migrations"];
38
+ readonly policy?: undefined;
39
+ readonly sessions: SessionPolicy<TSession>;
40
+ };
35
41
 
36
42
  export type AppLocalHostOptions<
37
43
  TRpcs extends Rpc.Any,
@@ -42,11 +48,15 @@ export type AppLocalHostOptions<
42
48
  TServiceError = never,
43
49
  TServiceRequirements = never,
44
50
  TMigrations = never,
45
- > = HostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> & {
46
- readonly migrations: AppDatabaseOptions<TMigrations>["migrations"];
47
- readonly policy: "loopback";
48
- readonly sessions?: never;
49
- };
51
+ TPreflight = never,
52
+ TPreflightError = never,
53
+ TPreflightRequirements = never,
54
+ > = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> &
55
+ HostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> & {
56
+ readonly migrations: AppDatabaseOptions<TMigrations>["migrations"];
57
+ readonly policy: "loopback";
58
+ readonly sessions?: never;
59
+ };
50
60
 
51
61
  export type AppHttpHostOptions<
52
62
  TRpcs extends Rpc.Any,
@@ -57,10 +67,13 @@ export type AppHttpHostOptions<
57
67
  TServiceError = never,
58
68
  TServiceRequirements = never,
59
69
  TSession extends SessionShape = SessionShape,
60
- > = HostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> &
70
+ TPreflight = never,
71
+ TPreflightError = never,
72
+ TPreflightRequirements = never,
73
+ > = HostPreflight<TPreflight, TPreflightError, TPreflightRequirements> &
74
+ HostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> &
61
75
  HostPolicy<TSession> & { readonly migrations?: undefined };
62
-
63
- export function appHost<
76
+ export const appHost: AppHostFactory = <
64
77
  TRpcs extends Rpc.Any,
65
78
  THandlers,
66
79
  THandlerError,
@@ -72,19 +85,11 @@ export function appHost<
72
85
  TSession extends SessionShape = SessionShape,
73
86
  TApplicationError = never,
74
87
  TApplicationRequirements = never,
88
+ TPreflight = never,
89
+ TPreflightError = never,
90
+ TPreflightRequirements = never,
75
91
  >(
76
- options:
77
- | (AppDatabaseOptions<TMigrations> & {
78
- readonly application: Effect.Effect<
79
- AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>,
80
- TApplicationError,
81
- TApplicationRequirements
82
- >;
83
- })
84
- | AppHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession>
85
- | AppLocalHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations>,
86
- ): ReturnType<
87
- typeof deferredHost<
92
+ options: AppHostInput<
88
93
  TRpcs,
89
94
  THandlers,
90
95
  THandlerError,
@@ -95,51 +100,18 @@ export function appHost<
95
100
  TMigrations,
96
101
  TSession,
97
102
  TApplicationError,
98
- TApplicationRequirements
99
- >
100
- >;
101
-
102
- export function appHost<
103
- TRpcs extends Rpc.Any,
104
- THandlers,
105
- THandlerError,
106
- THandlerRequirements,
107
- TServices = never,
108
- TServiceError = never,
109
- TServiceRequirements = never,
110
- TSession extends SessionShape = SessionShape,
111
- >(
112
- options: AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>,
113
- ): ReturnType<typeof appHostHttp<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>>;
114
- export function appHost<
115
- TRpcs extends Rpc.Any,
116
- THandlers,
117
- THandlerError,
118
- THandlerRequirements,
119
- TServices = never,
120
- TServiceError = never,
121
- TServiceRequirements = never,
122
- TMigrations = never,
123
- TSession extends SessionShape = SessionShape,
124
- TApplicationError = never,
125
- TApplicationRequirements = never,
126
- >(
127
- options:
128
- | (AppDatabaseOptions<TMigrations> & {
129
- readonly application: Effect.Effect<
130
- AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>,
131
- TApplicationError,
132
- TApplicationRequirements
133
- >;
134
- })
135
- | AppHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession>
136
- | AppLocalHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations>
137
- | AppHttpHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TSession>,
138
- ) {
103
+ TApplicationRequirements,
104
+ TPreflight,
105
+ TPreflightError,
106
+ TPreflightRequirements
107
+ >,
108
+ ) => {
139
109
  if ("application" in options) {
140
- return deferredHost(options.application, appDatabase(options));
110
+ return deferredHost(options.application, appDatabase(options)).pipe(Layer.provideMerge(options.preflight ?? Layer.empty));
141
111
  }
142
112
  return options.migrations === undefined
143
- ? appHostHttp(options)
144
- : migratedHost({ ...options, migrations: options.migrations }, appDatabase({ ...options, migrations: options.migrations }));
145
- }
113
+ ? appHostHttp(options).pipe(Layer.provideMerge(options.preflight ?? Layer.empty))
114
+ : migratedHost({ ...options, migrations: options.migrations }, appDatabase({ ...options, migrations: options.migrations })).pipe(
115
+ Layer.provideMerge(options.preflight ?? Layer.empty),
116
+ );
117
+ };
@@ -4,11 +4,12 @@ import { ByteSize, Config, Effect, Layer, Option, Schema } from "effect";
4
4
  import { HttpIncomingMessage, HttpRouter, HttpServerRequest, HttpStaticServer } from "effect/http";
5
5
  import { type Rpc, RpcSerialization, RpcServer } from "effect/rpc";
6
6
  import type { Authenticated, MaybeAuthenticated, RequestTracing } from "#rpc/middleware.ts";
7
- import type { AppHostOptions, AppHttpHostOptions, AppLocalHostOptions } from "#server/appHost.ts";
7
+ import type { AppHttpHostOptions } from "#server/appHost.ts";
8
8
  import { boundedRpcRequest } from "#server/boundedRpcRequest.ts";
9
9
  import type { databaseLayer } from "#server/databaseLayer.ts";
10
10
  import { healthRoute } from "#server/healthRoute.ts";
11
11
  import type { HostOptions, HostPolicy } from "#server/hostOptions.ts";
12
+ import type { MigrationOptions } from "#server/MigrationOptions.ts";
12
13
  import { otlpTracing } from "#server/otlpTracing.ts";
13
14
  import { localRpcGuard } from "#server/rpc-server/local.ts";
14
15
  import { authenticatedLayer, maybeAuthenticatedLayer, type SessionShape } from "#server/rpc-server/session.ts";
@@ -96,9 +97,8 @@ export function migratedHost<
96
97
  TMigrations,
97
98
  TSession extends SessionShape,
98
99
  >(
99
- options:
100
- | AppHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations, TSession>
101
- | AppLocalHostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements, TMigrations>,
100
+ options: HostOptions<TRpcs, THandlers, THandlerError, THandlerRequirements, TServices, TServiceError, TServiceRequirements> &
101
+ HostPolicy<TSession> & { readonly migrations: MigrationOptions<TMigrations> },
102
102
  database: ReturnType<typeof databaseLayer<TMigrations>>,
103
103
  ) {
104
104
  const services = Layer.mergeAll(options.services ?? Layer.empty);