honertia 0.1.17 → 0.1.18

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.
package/README.md CHANGED
@@ -84,18 +84,7 @@ class BindingsService extends Context.Tag('app/Bindings')<
84
84
  { KV: KVNamespace }
85
85
  >() {}
86
86
 
87
- // Request-scoped setup: put db/auth on c.var so Honertia/Effect can read them.
88
- app.use('*', async (c, next) => {
89
- c.set('db', createDb(c.env.DATABASE_URL))
90
- c.set('auth', createAuth({
91
- db: c.var.db,
92
- secret: c.env.BETTER_AUTH_SECRET,
93
- baseURL: new URL(c.req.url).origin,
94
- }))
95
- await next()
96
- })
97
-
98
- // Honertia bundles the core middleware + auth loading + Effect runtime setup.
87
+ // Honertia bundles db/auth setup + core middleware + Effect runtime.
99
88
  app.use('*', setupHonertia<Env, BindingsService>({
100
89
  honertia: {
101
90
  // Use your asset manifest hash so Inertia reloads on deploy.
@@ -109,9 +98,19 @@ app.use('*', setupHonertia<Env, BindingsService>({
109
98
  head: isProd ? '' : vite.hmrHead(),
110
99
  }
111
100
  }),
101
+ // Database factory (creates c.var.db for each request)
102
+ database: (c) => createDb(c.env.DATABASE_URL),
103
+ // Auth factory (can access c.var.db since database runs first)
104
+ auth: (c) => createAuth({
105
+ db: c.var.db,
106
+ secret: c.env.BETTER_AUTH_SECRET,
107
+ baseURL: new URL(c.req.url).origin,
108
+ }),
109
+ // Schema for route model binding (optional)
110
+ schema,
112
111
  },
113
112
  effect: {
114
- // Expose Cloudflare bindings to Effect handlers via a service layer.
113
+ // Custom Effect services (e.g., Cloudflare bindings)
115
114
  services: (c) => Layer.succeed(BindingsService, {
116
115
  KV: c.env.MY_KV,
117
116
  }),
@@ -119,7 +118,6 @@ app.use('*', setupHonertia<Env, BindingsService>({
119
118
  // Optional: extra Hono middleware in the same chain.
120
119
  middleware: [
121
120
  logger(),
122
- // register additional middleware here...
123
121
  ],
124
122
  }))
125
123
 
@@ -963,13 +961,19 @@ declare module 'honertia/effect' {
963
961
  }
964
962
  ```
965
963
 
966
- 2. Pass your schema to `effectRoutes`:
964
+ 2. Pass your schema to `setupHonertia`:
967
965
 
968
966
  ```typescript
969
967
  import * as schema from '~/db/schema'
970
968
 
971
- effectRoutes(app, { schema })
972
- .get('/projects/{project}', showProject)
969
+ app.use('*', setupHonertia({
970
+ honertia: {
971
+ version: '1.0.0',
972
+ render: createTemplate({ ... }),
973
+ database: (c) => createDb(c.env.DATABASE_URL),
974
+ schema, // Schema is shared with all effectRoutes
975
+ },
976
+ }))
973
977
  ```
974
978
 
975
979
  **Basic Usage:**
@@ -980,7 +984,7 @@ import { bound } from 'honertia/effect'
980
984
  // Route: /projects/{project}
981
985
  // Automatically queries: SELECT * FROM projects WHERE id = :project
982
986
 
983
- effectRoutes(app, { schema }).get('/projects/{project}', showProject)
987
+ effectRoutes(app).get('/projects/{project}', showProject)
984
988
 
985
989
  const showProject = Effect.gen(function* () {
986
990
  const project = yield* bound('project') // Already fetched, guaranteed to exist
@@ -994,7 +998,7 @@ By default, bindings query the `id` column. Use `{param:column}` syntax to bind
994
998
 
995
999
  ```typescript
996
1000
  // Bind by slug instead of id
997
- effectRoutes(app, { schema }).get('/projects/{project:slug}', showProject)
1001
+ effectRoutes(app).get('/projects/{project:slug}', showProject)
998
1002
  // Queries: SELECT * FROM projects WHERE slug = :project
999
1003
  ```
1000
1004
 
@@ -1004,7 +1008,7 @@ For nested routes, Honertia automatically scopes child models to their parents u
1004
1008
 
1005
1009
  ```typescript
1006
1010
  // Route: /users/{user}/posts/{post}
1007
- effectRoutes(app, { schema }).get('/users/{user}/posts/{post}', showUserPost)
1011
+ effectRoutes(app).get('/users/{user}/posts/{post}', showUserPost)
1008
1012
 
1009
1013
  // Queries:
1010
1014
  // 1. SELECT * FROM users WHERE id = :user
@@ -1039,7 +1043,7 @@ If no relation is found, the child is resolved without scoping (useful for unrel
1039
1043
  Route model binding and param validation work together. Validation runs first:
1040
1044
 
1041
1045
  ```typescript
1042
- effectRoutes(app, { schema }).get(
1046
+ effectRoutes(app).get(
1043
1047
  '/projects/{project}',
1044
1048
  showProject,
1045
1049
  { params: S.Struct({ project: uuid }) } // Validates UUID format first
@@ -1058,7 +1062,7 @@ You can mix Laravel-style `{binding}` with Hono-style `:param` in the same route
1058
1062
  ```typescript
1059
1063
  // :version is a regular Hono param (not bound)
1060
1064
  // {project} is resolved from the database
1061
- effectRoutes(app, { schema }).get(
1065
+ effectRoutes(app).get(
1062
1066
  '/api/:version/projects/{project}',
1063
1067
  showProject
1064
1068
  )
@@ -65,7 +65,7 @@ export const bound = (key) => Effect.gen(function* () {
65
65
  if (models.has('__schema_not_configured__')) {
66
66
  return yield* new RouteConfigurationError({
67
67
  message: `Route model binding requires schema configuration. Cannot resolve bound('${key}') without schema.`,
68
- hint: `Pass your schema to effectRoutes: effectRoutes(app, { schema })`
68
+ hint: `Pass your schema to setupHonertia: setupHonertia({ honertia: { schema } })`
69
69
  });
70
70
  }
71
71
  const model = models.get(key);
@@ -15,7 +15,6 @@ import { DatabaseService, AuthService, AuthUserService, HonertiaService, Request
15
15
  * @example
16
16
  * // Provide Cloudflare Worker bindings as a service
17
17
  * effectBridge<Env, BindingsService>({
18
- * database: (c) => createDb(c.env.DATABASE_URL),
19
18
  * services: (c) => Layer.succeed(BindingsService, c.env),
20
19
  * })
21
20
  *
@@ -29,7 +28,6 @@ import { DatabaseService, AuthService, AuthUserService, HonertiaService, Request
29
28
  * })
30
29
  */
31
30
  export interface EffectBridgeConfig<E extends Env, CustomServices = never> {
32
- database?: (c: HonoContext<E>) => unknown;
33
31
  /**
34
32
  * Custom services to provide to all Effect handlers.
35
33
  * Return a Layer that provides your custom services.
@@ -37,14 +35,8 @@ export interface EffectBridgeConfig<E extends Env, CustomServices = never> {
37
35
  services?: (c: HonoContext<E>) => Layer.Layer<CustomServices, never, never>;
38
36
  /**
39
37
  * Drizzle schema for route model binding.
40
- * Required if using Laravel-style route model binding.
41
- *
42
- * @example
43
- * ```typescript
44
- * import * as schema from '~/db/schema'
45
- *
46
- * effectRoutes(app, { schema })
47
- * ```
38
+ * Usually configured via `setupHonertia({ honertia: { schema } })`.
39
+ * Can also be passed here for standalone effectBridge usage.
48
40
  */
49
41
  schema?: Record<string, unknown>;
50
42
  }
@@ -53,11 +45,16 @@ export interface EffectBridgeConfig<E extends Env, CustomServices = never> {
53
45
  */
54
46
  declare const EFFECT_RUNTIME: unique symbol;
55
47
  /**
56
- * Extend Hono context with Effect runtime.
48
+ * Symbol for storing schema in Hono context.
49
+ */
50
+ declare const EFFECT_SCHEMA: unique symbol;
51
+ /**
52
+ * Extend Hono context with Effect runtime and schema.
57
53
  */
58
54
  declare module 'hono' {
59
55
  interface ContextVariableMap {
60
56
  [EFFECT_RUNTIME]?: ManagedRuntime.ManagedRuntime<DatabaseService | AuthService | AuthUserService | HonertiaService | RequestService | ResponseFactoryService, never>;
57
+ [EFFECT_SCHEMA]?: Record<string, unknown>;
61
58
  }
62
59
  }
63
60
  /**
@@ -72,5 +69,9 @@ export declare function getEffectRuntime<E extends Env>(c: HonoContext<E>): Mana
72
69
  * Middleware that sets up the Effect runtime for each request.
73
70
  */
74
71
  export declare function effectBridge<E extends Env, CustomServices = never>(config?: EffectBridgeConfig<E, CustomServices>): MiddlewareHandler<E>;
72
+ /**
73
+ * Get the schema from Hono context (set by effectBridge).
74
+ */
75
+ export declare function getEffectSchema<E extends Env>(c: HonoContext<E>): Record<string, unknown> | undefined;
75
76
  export {};
76
77
  //# sourceMappingURL=bridge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/effect/bridge.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC9C,OAAO,KAAK,EAAE,OAAO,IAAI,WAAW,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,MAAM,CAAA;AAC1E,OAAO,EACL,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,sBAAsB,EAOvB,MAAM,eAAe,CAAA;AAEtB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,GAAG,EAAE,cAAc,GAAG,KAAK;IACvE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAA;IACzC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;IAC3E;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC;AAED;;GAEG;AACH,QAAA,MAAM,cAAc,eAA0B,CAAA;AAE9C;;GAEG;AACH,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,kBAAkB;QAC1B,CAAC,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,cAAc,CAC5C,eAAe,GACf,WAAW,GACX,eAAe,GACf,eAAe,GACf,cAAc,GACd,sBAAsB,EACxB,KAAK,CACN,CAAA;KACF;CACF;AAqDD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,GAAG,EAAE,cAAc,GAAG,KAAK,EACrE,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EACjB,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,EAAE,cAAc,CAAC,GAC7C,KAAK,CAAC,KAAK,CACV,cAAc,GACd,sBAAsB,GACtB,eAAe,GACf,eAAe,GACf,WAAW,GACX,eAAe,GACf,cAAc,EAChB,KAAK,EACL,KAAK,CACN,CA0CA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,GAAG,EAC5C,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GAChB,cAAc,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,SAAS,CAEvD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,GAAG,EAAE,cAAc,GAAG,KAAK,EAChE,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,EAAE,cAAc,CAAC,GAC7C,iBAAiB,CAAC,CAAC,CAAC,CAetB"}
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/effect/bridge.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC9C,OAAO,KAAK,EAAE,OAAO,IAAI,WAAW,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,MAAM,CAAA;AAC1E,OAAO,EACL,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,sBAAsB,EAOvB,MAAM,eAAe,CAAA;AAEtB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,GAAG,EAAE,cAAc,GAAG,KAAK;IACvE;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;IAC3E;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC;AAED;;GAEG;AACH,QAAA,MAAM,cAAc,eAA0B,CAAA;AAE9C;;GAEG;AACH,QAAA,MAAM,aAAa,eAAyB,CAAA;AA6B5C;;GAEG;AACH,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,kBAAkB;QAC1B,CAAC,cAAc,CAAC,CAAC,EAAE,cAAc,CAAC,cAAc,CAC5C,eAAe,GACf,WAAW,GACX,eAAe,GACf,eAAe,GACf,cAAc,GACd,sBAAsB,EACxB,KAAK,CACN,CAAA;QACD,CAAC,aAAa,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAC1C;CACF;AAqDD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,GAAG,EAAE,cAAc,GAAG,KAAK,EACrE,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EACjB,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,EAAE,cAAc,CAAC,GAC7C,KAAK,CAAC,KAAK,CACV,cAAc,GACd,sBAAsB,GACtB,eAAe,GACf,eAAe,GACf,WAAW,GACX,eAAe,GACf,cAAc,EAChB,KAAK,EACL,KAAK,CACN,CA0DA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,GAAG,EAC5C,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GAChB,cAAc,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,SAAS,CAEvD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,GAAG,EAAE,cAAc,GAAG,KAAK,EAChE,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,EAAE,cAAc,CAAC,GAC7C,iBAAiB,CAAC,CAAC,CAAC,CAoBtB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,GAAG,EAC3C,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAErC"}
@@ -9,6 +9,28 @@ import { DatabaseService, AuthService, AuthUserService, HonertiaService, Request
9
9
  * Symbol for storing Effect runtime in Hono context.
10
10
  */
11
11
  const EFFECT_RUNTIME = Symbol('effectRuntime');
12
+ /**
13
+ * Symbol for storing schema in Hono context.
14
+ */
15
+ const EFFECT_SCHEMA = Symbol('effectSchema');
16
+ /**
17
+ * Creates a proxy that throws a helpful error when any property is accessed.
18
+ * Used when a service (database, auth) is not configured but the user tries to use it.
19
+ */
20
+ function createUnconfiguredServiceProxy(serviceName, configPath, example) {
21
+ const message = `${serviceName} is not configured. Add it to setupHonertia: setupHonertia({ honertia: { ${configPath} } })`;
22
+ return new Proxy({}, {
23
+ get(_, prop) {
24
+ // Allow certain properties that might be checked without meaning to "use" the service
25
+ if (prop === 'then' || prop === Symbol.toStringTag || prop === Symbol.iterator) {
26
+ return undefined;
27
+ }
28
+ const error = new Error(message);
29
+ error.hint = `Example: ${example}`;
30
+ throw error;
31
+ },
32
+ });
33
+ }
12
34
  /**
13
35
  * Create a RequestContext from Hono context.
14
36
  */
@@ -64,14 +86,15 @@ export function buildContextLayer(c, config) {
64
86
  const requestLayer = Layer.succeed(RequestService, createRequestContext(c));
65
87
  const responseLayer = Layer.succeed(ResponseFactoryService, createResponseFactory(c));
66
88
  const honertiaLayer = Layer.succeed(HonertiaService, createHonertiaRenderer(c));
67
- // Build optional layers (cast to satisfy type checker - actual type comes from augmentation)
68
- const databaseLayer = config?.database
69
- ? Layer.succeed(DatabaseService, config.database(c))
70
- : Layer.succeed(DatabaseService, c.var?.db);
71
- let baseLayer = Layer.mergeAll(requestLayer, responseLayer, honertiaLayer, databaseLayer);
72
- if (c.var?.auth) {
73
- baseLayer = Layer.merge(baseLayer, Layer.succeed(AuthService, c.var.auth));
74
- }
89
+ // Database layer - provide helpful error proxy if not configured
90
+ const db = c.var?.db;
91
+ const databaseLayer = Layer.succeed(DatabaseService, (db ??
92
+ createUnconfiguredServiceProxy('DatabaseService', 'database: (c) => createDb(...)', 'database: (c) => drizzle(c.env.DB)')));
93
+ // Auth layer - provide helpful error proxy if not configured
94
+ const auth = c.var?.auth;
95
+ const authLayer = Layer.succeed(AuthService, (auth ??
96
+ createUnconfiguredServiceProxy('AuthService', 'auth: (c) => createAuth(...)', 'auth: (c) => betterAuth({ database: c.var.db, ... })')));
97
+ let baseLayer = Layer.mergeAll(requestLayer, responseLayer, honertiaLayer, databaseLayer, authLayer);
75
98
  if (c.var?.authUser) {
76
99
  baseLayer = Layer.merge(baseLayer, Layer.succeed(AuthUserService, c.var.authUser));
77
100
  }
@@ -97,6 +120,10 @@ export function effectBridge(config) {
97
120
  const runtime = ManagedRuntime.make(layer);
98
121
  // Store runtime in context
99
122
  c.set(EFFECT_RUNTIME, runtime);
123
+ // Store schema in context for route model binding
124
+ if (config?.schema) {
125
+ c.set(EFFECT_SCHEMA, config.schema);
126
+ }
100
127
  try {
101
128
  await next();
102
129
  }
@@ -106,3 +133,9 @@ export function effectBridge(config) {
106
133
  }
107
134
  };
108
135
  }
136
+ /**
137
+ * Get the schema from Hono context (set by effectBridge).
138
+ */
139
+ export function getEffectSchema(c) {
140
+ return c.var?.[EFFECT_SCHEMA];
141
+ }
@@ -7,7 +7,7 @@ export { DatabaseService, AuthService, AuthUserService, HonertiaService, Request
7
7
  export { ValidationError, UnauthorizedError, NotFoundError, ForbiddenError, HttpError, RouteConfigurationError, Redirect, type AppError, } from './errors.js';
8
8
  export * from './schema.js';
9
9
  export { getValidationData, formatSchemaErrors, validate, validateRequest, asValidated, asTrusted, type Validated, type Trusted, } from './validation.js';
10
- export { effectBridge, buildContextLayer, getEffectRuntime, type EffectBridgeConfig, } from './bridge.js';
10
+ export { effectBridge, buildContextLayer, getEffectRuntime, getEffectSchema, type EffectBridgeConfig, } from './bridge.js';
11
11
  export { effectHandler, effect, handle, errorToResponse, } from './handler.js';
12
12
  export { action, authorize, dbMutation, dbTransaction, type SafeTx, } from './action.js';
13
13
  export { redirect, render, renderWithErrors, json, text, notFound, forbidden, httpError, prefersJson, jsonOrRender, share, } from './responses.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/effect/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,QAAQ,GACd,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,QAAQ,EACR,KAAK,QAAQ,GACd,MAAM,aAAa,CAAA;AAGpB,cAAc,aAAa,CAAA;AAG3B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,WAAW,EACX,SAAS,EACT,KAAK,SAAS,EACd,KAAK,OAAO,GACb,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,aAAa,EACb,MAAM,EACN,MAAM,EACN,eAAe,GAChB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,MAAM,EACN,SAAS,EACT,UAAU,EACV,aAAa,EACb,KAAK,MAAM,GACZ,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,QAAQ,EACR,MAAM,EACN,gBAAgB,EAChB,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,KAAK,GACN,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,kBAAkB,GACxB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,KAAK,EACL,SAAS,EACT,aAAa,EACb,UAAU,EACV,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,QAAQ,EACR,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,GAC5B,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/effect/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,QAAQ,GACd,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,QAAQ,EACR,KAAK,QAAQ,GACd,MAAM,aAAa,CAAA;AAGpB,cAAc,aAAa,CAAA;AAG3B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,WAAW,EACX,SAAS,EACT,KAAK,SAAS,EACd,KAAK,OAAO,GACb,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,aAAa,EACb,MAAM,EACN,MAAM,EACN,eAAe,GAChB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,MAAM,EACN,SAAS,EACT,UAAU,EACV,aAAa,EACb,KAAK,MAAM,GACZ,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,QAAQ,EACR,MAAM,EACN,gBAAgB,EAChB,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,KAAK,GACN,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,kBAAkB,GACxB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,KAAK,EACL,SAAS,EACT,aAAa,EACb,UAAU,EACV,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,cAAc,CAAA;AAGrB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,QAAQ,EACR,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,GAC5B,MAAM,WAAW,CAAA"}
@@ -12,7 +12,7 @@ export * from './schema.js';
12
12
  // Validation Helpers
13
13
  export { getValidationData, formatSchemaErrors, validate, validateRequest, asValidated, asTrusted, } from './validation.js';
14
14
  // Bridge
15
- export { effectBridge, buildContextLayer, getEffectRuntime, } from './bridge.js';
15
+ export { effectBridge, buildContextLayer, getEffectRuntime, getEffectSchema, } from './bridge.js';
16
16
  // Handler
17
17
  export { effectHandler, effect, handle, errorToResponse, } from './handler.js';
18
18
  // Action Composables
@@ -1 +1 @@
1
- {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/effect/routing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/effect/routing.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { Effect, Exit, Layer, Schema as S } from 'effect';
7
7
  import { effectHandler } from './handler.js';
8
- import { buildContextLayer } from './bridge.js';
8
+ import { buildContextLayer, getEffectSchema } from './bridge.js';
9
9
  import { parseBindings, toHonoPath, pluralize, findRelation, BoundModels, } from './binding.js';
10
10
  /**
11
11
  * Effect Route Builder with layer composition.
@@ -125,18 +125,20 @@ export class EffectRouteBuilder {
125
125
  const contextLayer = buildContextLayer(c, bridgeConfig);
126
126
  // Resolve route model bindings if we have any and schema is configured
127
127
  let boundModelsLayer;
128
- if (bindings.length > 0 && bridgeConfig?.schema) {
129
- const db = bridgeConfig.database ? bridgeConfig.database(c) : c.var?.db;
128
+ // Get schema from bridgeConfig or from context (set by setupHonertia/effectBridge)
129
+ const schema = bridgeConfig?.schema ?? getEffectSchema(c);
130
+ if (bindings.length > 0 && schema) {
131
+ const db = c.var?.db;
130
132
  if (!db) {
131
133
  return c.notFound();
132
134
  }
133
- const result = await this.resolveBindings(c, bindings, db, bridgeConfig.schema);
135
+ const result = await this.resolveBindings(c, bindings, db, schema);
134
136
  if (result instanceof Response) {
135
137
  return result;
136
138
  }
137
139
  boundModelsLayer = Layer.succeed(BoundModels, result);
138
140
  }
139
- else if (bindings.length > 0 && !bridgeConfig?.schema) {
141
+ else if (bindings.length > 0 && !schema) {
140
142
  // Bindings exist but no schema - provide a map that signals this for better errors
141
143
  const unconfiguredMap = new Map();
142
144
  unconfiguredMap.set('__schema_not_configured__', true);
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * For schema validators, import from 'honertia/schema'.
7
7
  * For auth helpers, import from 'honertia/auth'.
8
8
  */
9
- export { setupHonertia, createErrorHandlers, registerErrorHandlers, type HonertiaSetupConfig, type ErrorHandlerConfig, } from './setup.js';
9
+ export { setupHonertia, createErrorHandlers, registerErrorHandlers, type HonertiaSetupConfig, type HonertiaFullConfig, type ErrorHandlerConfig, } from './setup.js';
10
10
  export { honertia, HEADERS } from './middleware.js';
11
11
  export type { PageObject, HonertiaConfig, HonertiaInstance, RenderOptions, } from './types.js';
12
12
  export { createTemplate, createVersion, vite, type PageProps, } from './helpers.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAEnD,YAAY,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,aAAa,GACd,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,cAAc,EACd,aAAa,EACb,IAAI,EACJ,KAAK,SAAS,GACf,MAAM,cAAc,CAAA;AAOrB,cAAc,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAEnD,YAAY,EACV,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,aAAa,GACd,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,cAAc,EACd,aAAa,EACb,IAAI,EACJ,KAAK,SAAS,GACf,MAAM,cAAc,CAAA;AAOrB,cAAc,mBAAmB,CAAA"}
package/dist/setup.d.ts CHANGED
@@ -7,20 +7,66 @@
7
7
  import type { MiddlewareHandler, Env, Context } from 'hono';
8
8
  import type { HonertiaConfig } from './types.js';
9
9
  import { type EffectBridgeConfig } from './effect/bridge.js';
10
+ /**
11
+ * Extended Honertia configuration with database, auth, and schema.
12
+ */
13
+ export interface HonertiaFullConfig<E extends Env = Env> extends HonertiaConfig {
14
+ /**
15
+ * Database factory function.
16
+ * Creates the database client for each request.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * database: (c) => createDb(c.env.DATABASE_URL)
21
+ * ```
22
+ */
23
+ database?: (c: Context<E>) => unknown;
24
+ /**
25
+ * Auth factory function.
26
+ * Creates the auth client for each request.
27
+ * Receives context with `c.var.db` already set (if database is configured).
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * auth: (c) => createAuth({
32
+ * db: c.var.db,
33
+ * secret: c.env.BETTER_AUTH_SECRET,
34
+ * baseURL: new URL(c.req.url).origin,
35
+ * })
36
+ * ```
37
+ */
38
+ auth?: (c: Context<E>) => unknown;
39
+ /**
40
+ * Drizzle schema for route model binding.
41
+ * Required if using Laravel-style route model binding.
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * import * as schema from '~/db/schema'
46
+ *
47
+ * setupHonertia({
48
+ * honertia: { version, render, schema }
49
+ * })
50
+ * ```
51
+ */
52
+ schema?: Record<string, unknown>;
53
+ }
10
54
  /**
11
55
  * Configuration for Honertia setup.
12
56
  */
13
57
  export interface HonertiaSetupConfig<E extends Env = Env, CustomServices = never> {
14
58
  /**
15
- * Honertia core configuration.
59
+ * Honertia core configuration including database, auth, and schema.
16
60
  */
17
- honertia: HonertiaConfig;
61
+ honertia: HonertiaFullConfig<E>;
18
62
  /**
19
63
  * Effect bridge configuration (optional).
64
+ * Only needed for custom Effect services.
20
65
  */
21
66
  effect?: EffectBridgeConfig<E, CustomServices>;
22
67
  /**
23
- * Auth configuration (optional).
68
+ * Auth loading configuration (optional).
69
+ * Controls how the authenticated user is loaded from the session.
24
70
  */
25
71
  auth?: {
26
72
  userKey?: string;
@@ -36,6 +82,7 @@ export interface HonertiaSetupConfig<E extends Env = Env, CustomServices = never
36
82
  * Sets up all Honertia middleware in the correct order.
37
83
  *
38
84
  * This bundles:
85
+ * - Database and auth setup (sets `c.var.db` and `c.var.auth`)
39
86
  * - `honertia()` - Core Honertia middleware
40
87
  * - `loadUser()` - Loads authenticated user into context
41
88
  * - `shareAuthMiddleware()` - Shares auth state with pages
@@ -44,11 +91,19 @@ export interface HonertiaSetupConfig<E extends Env = Env, CustomServices = never
44
91
  * @example
45
92
  * ```ts
46
93
  * import { setupHonertia, createTemplate } from 'honertia'
94
+ * import * as schema from '~/db/schema'
47
95
  *
48
96
  * app.use('*', setupHonertia({
49
97
  * honertia: {
50
98
  * version: '1.0.0',
51
99
  * render: createTemplate({ title: 'My App', scripts: [...] }),
100
+ * database: (c) => createDb(c.env.DATABASE_URL),
101
+ * auth: (c) => createAuth({
102
+ * db: c.var.db,
103
+ * secret: c.env.BETTER_AUTH_SECRET,
104
+ * baseURL: new URL(c.req.url).origin,
105
+ * }),
106
+ * schema,
52
107
  * },
53
108
  * }))
54
109
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAE3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAE1E;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,EAAE,cAAc,GAAG,KAAK;IAC9E;;OAEG;IACH,QAAQ,EAAE,cAAc,CAAA;IAExB;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,EAAE,cAAc,CAAC,CAAA;IAE9C;;OAEG;IACH,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,CAAA;IAED;;;OAGG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAA;CACpC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,GAAG,EAAE,cAAc,GAAG,KAAK,EACjE,MAAM,EAAE,mBAAmB,CAAC,CAAC,EAAE,cAAc,CAAC,GAC7C,iBAAiB,CAAC,CAAC,CAAC,CAmBtB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,GAAE,kBAAuB;kBAQ3D,OAAO,CAAC,CAAC,CAAC;mBAOT,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC;EAU3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,GAAG,EACjD,GAAG,EAAE;IAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IAAC,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAA;CAAE,EAC1E,MAAM,GAAE,kBAAuB,GAC9B,IAAI,CAIN"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAE3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAE1E;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,CAAE,SAAQ,cAAc;IAC7E;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAA;IAErC;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAA;IAEjC;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,EAAE,cAAc,GAAG,KAAK;IAC9E;;OAEG;IACH,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAA;IAE/B;;;OAGG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,EAAE,cAAc,CAAC,CAAA;IAE9C;;;OAGG;IACH,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,CAAA;IAED;;;OAGG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAA;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,GAAG,EAAE,cAAc,GAAG,KAAK,EACjE,MAAM,EAAE,mBAAmB,CAAC,CAAC,EAAE,cAAc,CAAC,GAC7C,iBAAiB,CAAC,CAAC,CAAC,CA2CtB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,GAAE,kBAAuB;kBAQ3D,OAAO,CAAC,CAAC,CAAC;mBAOT,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC;EAa3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,GAAG,EACjD,GAAG,EAAE;IAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IAAC,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAA;CAAE,EAC1E,MAAM,GAAE,kBAAuB,GAC9B,IAAI,CAIN"}
package/dist/setup.js CHANGED
@@ -12,6 +12,7 @@ import { effectBridge } from './effect/bridge.js';
12
12
  * Sets up all Honertia middleware in the correct order.
13
13
  *
14
14
  * This bundles:
15
+ * - Database and auth setup (sets `c.var.db` and `c.var.auth`)
15
16
  * - `honertia()` - Core Honertia middleware
16
17
  * - `loadUser()` - Loads authenticated user into context
17
18
  * - `shareAuthMiddleware()` - Shares auth state with pages
@@ -20,21 +21,48 @@ import { effectBridge } from './effect/bridge.js';
20
21
  * @example
21
22
  * ```ts
22
23
  * import { setupHonertia, createTemplate } from 'honertia'
24
+ * import * as schema from '~/db/schema'
23
25
  *
24
26
  * app.use('*', setupHonertia({
25
27
  * honertia: {
26
28
  * version: '1.0.0',
27
29
  * render: createTemplate({ title: 'My App', scripts: [...] }),
30
+ * database: (c) => createDb(c.env.DATABASE_URL),
31
+ * auth: (c) => createAuth({
32
+ * db: c.var.db,
33
+ * secret: c.env.BETTER_AUTH_SECRET,
34
+ * baseURL: new URL(c.req.url).origin,
35
+ * }),
36
+ * schema,
28
37
  * },
29
38
  * }))
30
39
  * ```
31
40
  */
32
41
  export function setupHonertia(config) {
42
+ const { database, auth, schema, ...honertiaConfig } = config.honertia;
43
+ // Middleware to set up db and auth on c.var
44
+ const setupServices = createMiddleware(async (c, next) => {
45
+ // Set up database first (auth may depend on it)
46
+ if (database) {
47
+ c.set('db', database(c));
48
+ }
49
+ // Set up auth (can access c.var.db)
50
+ if (auth) {
51
+ c.set('auth', auth(c));
52
+ }
53
+ await next();
54
+ });
55
+ // Build effect bridge config, passing schema from honertia config
56
+ const effectConfig = {
57
+ ...config.effect,
58
+ schema,
59
+ };
33
60
  const middlewares = [
34
- honertia(config.honertia),
61
+ setupServices,
62
+ honertia(honertiaConfig),
35
63
  loadUser(config.auth),
36
64
  shareAuthMiddleware(),
37
- effectBridge(config.effect),
65
+ effectBridge(effectConfig),
38
66
  ...(config.middleware ?? []),
39
67
  ];
40
68
  return createMiddleware(async (c, next) => {
@@ -72,9 +100,12 @@ export function createErrorHandlers(config = {}) {
72
100
  const onError = (err, c) => {
73
101
  console.error(err);
74
102
  const isDev = showDevErrors && c.env?.[envKey] === devValue;
103
+ const status = err.status ?? 500;
104
+ const hint = isDev ? err.hint : undefined;
75
105
  return c.var.honertia.render(component, {
76
- status: 500,
106
+ status,
77
107
  message: isDev ? err.message : 'Something went wrong',
108
+ ...(hint && { hint }),
78
109
  });
79
110
  };
80
111
  return { notFound, onError };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "honertia",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "Inertia.js-style server-driven SPA adapter for Hono",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",