@ts-kizuna/hono 1.49.7 → 1.51.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.
package/dist/index.cjs CHANGED
@@ -1,6 +1,22 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let _ts_kizuna_core_adapter = require("@ts-kizuna/core/adapter");
3
3
  //#region src/server.ts
4
+ /**
5
+ * A guard per identity, keyed by name. Each receives the handler context, a
6
+ * `deny` helper, and the matched route's required scopes, and returns that
7
+ * identity's {@link GuardSuccess} (its context and access fields) or a `deny(...)`
8
+ * result. Keying by name lets each guard's return be typed against its own
9
+ * identity, so access values narrow without an annotation. An
10
+ * authentication-only identity (no context, no access) returns nothing on
11
+ * success, or `deny(...)`.
12
+ */
13
+ /**
14
+ * One guard per identity declared on the contract.
15
+ */
16
+ /**
17
+ * The resolver functions for the request context schemas declared on `kizuna`,
18
+ * keyed by name. Each runs on every route and returns its schema's value.
19
+ */
4
20
  const honoAdapter = (0, _ts_kizuna_core_adapter.createAdapter)({
5
21
  buildHandlerContext: (_adapterRequest, { c }) => ({ c }),
6
22
  respond: (result, { c, formatError }) => {
@@ -72,48 +88,17 @@ function mountHono(api, app, options) {
72
88
  for (const [routeKey, route] of Object.entries(routes)) mountRoute(routeKey, route, routes, router);
73
89
  }
74
90
  }
75
- const createServerSurface = (contract, options) => {
76
- (0, _ts_kizuna_core_adapter.warnUnsupportedJobOptions)(contract.jobs, options?.jobTransport);
77
- return {
78
- guard: (_name, run) => run,
79
- requestContext: (_name, run) => run,
80
- router: (groupOrRouter, groupRouter) => groupRouter ?? groupOrRouter,
81
- jobs: (handlers) => handlers,
82
- api: ({ jobs, ...parts }) => {
83
- const api = Object.assign((0, _ts_kizuna_core_adapter.assembleApi)(contract, parts), { [_ts_kizuna_core_adapter.JOBS_META]: contract.jobs ? {
84
- jobs: contract.jobs,
85
- handlers: jobs ?? {},
86
- config: contract.jobsConfig,
87
- transport: options?.jobTransport,
88
- onError: options?.onJobError
89
- } : void 0 });
90
- return Object.assign(api, { mount: (app, mountOptions) => mountHono(api, app, mountOptions) });
91
- }
92
- };
93
- };
94
91
  /**
95
92
  * Turn a contract into a server handle: the serving counterpart to `Kizuna`.
96
93
  * Keep the instance and use `server.guard` to define guards, `server.router`
97
94
  * to write typed handlers, and `server.api` to assemble them.
98
- *
99
- * @example
100
- * const server = new KizunaServer(contract);
101
- *
102
- * const requireUser = server.guard('user', ({ bearer, deny }) => {
103
- * const session = bearer && sessions.get(bearer.token);
104
- * return session ? { userId: session.userId } : deny(401, 'Unauthorized');
105
- * });
106
- *
107
- * export const api = server.api({
108
- * router,
109
- * guards: {
110
- * user: requireUser,
111
- * },
112
- * });
113
95
  */
114
96
  var KizunaServer = class {
115
97
  constructor(contract, options) {
116
- Object.assign(this, createServerSurface(contract, options));
98
+ Object.assign(this, (0, _ts_kizuna_core_adapter.createServerSurface)(contract, options, (assembled) => {
99
+ const api = assembled;
100
+ return Object.assign(api, { mount: (app, mountOptions) => mountHono(api, app, mountOptions) });
101
+ }));
117
102
  }
118
103
  };
119
104
  //#endregion
package/dist/index.d.cts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { Context, Env, Hono } from "hono";
2
- import { ApiWithRouter, ContractPlugins, ErrorFormatter, GUARDS_META, GuardDenial, GuardDeny, GuardParams, GuardRun, HandlersFromAuth, JOBS_META, Jobs, PluginArgs, PluginImplementations, REQUEST_CONTEXT_META, RequestContextRun, RequestContextValues, RouteDefinition, RouteHandler as RouteHandler$1, Router as Router$1, Routes, SCHEMES_META, ServerOptions } from "@ts-kizuna/core/adapter";
3
- import { z } from "zod";
4
- import { Contract, CredentialOf, GuardSuccess, JobHandlers, JobsArg, RequestContextHeaderValues, RequestContextSchema, SecurityScheme, TagOptions } from "@ts-kizuna/core";
2
+ import { ApiWithRouter, ContractJobsRouter, ContractRouter, ErrorFormatter, GUARDS_META, JOBS_META, REQUEST_CONTEXT_META, RouteDefinition, RouteHandler as RouteHandler$1, Routes, SCHEMES_META, Server as Server$1, ServerOptions } from "@ts-kizuna/core/adapter";
3
+ import { Contract, RoutesOf } from "@ts-kizuna/core";
5
4
 
6
5
  //#region src/server.d.ts
7
6
  type HonoApi<R extends Routes = Routes> = ApiWithRouter<R> & {
@@ -27,18 +26,12 @@ type RouteHandler<R extends RouteDefinition, E extends Env = Env> = RouteHandler
27
26
  * contract's `auth` map additionally receive each required identity's context
28
27
  * in their handler args, under `auth`, keyed by the identity's name.
29
28
  */
30
- type Router<C, E extends Env = Env> = C extends Contract<infer R, infer _Tags, infer _Codes, infer Schemes, infer Auth, infer RequestContext, infer Plugins, infer J> ? HandlersFromAuth<R, HonoHandlerContext<E> & RequestContextValues<RequestContext> & PluginArgs<Plugins> & JobsArg<J>, Schemes, Auth> : C extends Routes ? Router$1<C, HonoHandlerContext<E>> : never;
29
+ type Router<C, E extends Env = Env> = ContractRouter<C, HonoHandlerContext<E>>;
31
30
  /**
32
31
  * The handler for each of a contract's scheduled jobs, typed against it. Each
33
32
  * receives only the job's `input`, so the same handler can be run in process.
34
33
  */
35
- type JobsRouter<C> = C extends Contract<infer _R, infer _Tags, infer _Codes, infer _Schemes, infer _Auth, infer _RequestContext, infer _Plugins, infer J> ? JobHandlers<J> : never;
36
- /**
37
- * The handlers for a group named on the contract, or for a bare route group.
38
- * Both forms resolve through one signature: a second candidate of the same
39
- * arity costs zero-argument handlers their contextual type.
40
- */
41
- type GroupRouter<Source, GroupOrRoutes, E extends Env> = GroupOrRoutes extends string ? Router<Source, E>[Extract<GroupOrRoutes, keyof Router<Source, E>>] : Router<GroupOrRoutes, E>;
34
+ type JobsRouter<C> = ContractJobsRouter<C>;
42
35
  interface HonoOptions {
43
36
  /**
44
37
  * Validate handler return values against the routes' response schemas.
@@ -54,32 +47,6 @@ interface HonoOptions {
54
47
  */
55
48
  formatError?: ErrorFormatter<Request>;
56
49
  }
57
- /**
58
- * A guard per identity, keyed by name. Each receives the handler context, a
59
- * `deny` helper, and the matched route's required scopes, and returns that
60
- * identity's {@link GuardSuccess} (its context and access fields) or a `deny(...)`
61
- * result. Keying by name lets each guard's return be typed against its own
62
- * identity, so access values narrow without an annotation. An
63
- * authentication-only identity (no context, no access) returns nothing on
64
- * success, or `deny(...)`.
65
- */
66
- type GuardFns<Schemes extends Record<string, SecurityScheme>, Params, E extends Env> = { [Name in keyof Schemes]: (args: HonoHandlerContext<E> & CredentialOf<Schemes[Name]> & {
67
- params: Params;
68
- deny: GuardDeny;
69
- scopes: string[];
70
- }) => [keyof GuardSuccess<Schemes[Name]>] extends [never] ? void | GuardDenial | Promise<void | GuardDenial> : GuardSuccess<Schemes[Name]> | GuardDenial | Promise<GuardSuccess<Schemes[Name]> | GuardDenial> };
71
- /**
72
- * One guard per identity declared on the contract.
73
- */
74
- type GuardsForSchemes<Schemes extends Record<string, SecurityScheme>, E extends Env> = { [Name in keyof Schemes]: GuardRun<HonoHandlerContext<E>> };
75
- /**
76
- * The resolver functions for the request context schemas declared on `kizuna`,
77
- * keyed by name. Each runs on every route and returns its schema's value.
78
- */
79
- type RequestResolverFns<RequestContext extends Record<string, RequestContextSchema>, E extends Env> = { [Name in keyof RequestContext]: (args: HonoHandlerContext<E> & {
80
- params: Record<string, string>;
81
- headers: RequestContextHeaderValues<RequestContext[Name]>;
82
- }) => z.output<RequestContext[Name]['context']> | Promise<z.output<RequestContext[Name]['context']>> };
83
50
  /**
84
51
  * Mount a ts-kizuna API onto a Hono app.
85
52
  *
@@ -88,95 +55,19 @@ type RequestResolverFns<RequestContext extends Record<string, RequestContextSche
88
55
  * api.mount(app);
89
56
  */
90
57
  declare function mountHono<E extends Env = Env>(api: HonoApi, app: Hono<E>, options?: HonoOptions): void;
91
- type ServerContract<R extends Routes, Schemes extends Record<string, SecurityScheme>, Auth, RequestContext extends Record<string, RequestContextSchema>, Plugins extends ContractPlugins, J extends Jobs = Jobs> = Contract<R, Record<string, TagOptions>, string, Schemes, Auth, RequestContext, Plugins, J>;
92
- interface Server<R extends Routes, Schemes extends Record<string, SecurityScheme>, Auth, RequestContext extends Record<string, RequestContextSchema>, Plugins extends ContractPlugins, E extends Env = Env, J extends Jobs = Jobs> {
93
- /**
94
- * Define a guard for one of the contract's identities. It runs before the
95
- * handlers of every route whose `auth` entry requires the identity, and
96
- * receives the credential its method extracted (`bearer`, `apiKey`, or
97
- * `basic`, `null` when absent). Return the identity's context and access
98
- * fields to allow the request, or call `deny(status, detail)`.
99
- */
100
- guard<const Name extends Extract<keyof Schemes, string>>(name: Name, run: GuardFns<Schemes, GuardParams<R, Auth, Name>, E>[Name]): GuardRun<HonoHandlerContext<E>>;
101
- /**
102
- * Define a request context resolver declared on the contract. It runs on
103
- * every route, public ones included, and never denies.
104
- */
105
- requestContext<const Name extends Extract<keyof RequestContext, string>>(name: Name, run: RequestResolverFns<RequestContext, E>[Name]): RequestContextRun<HonoHandlerContext<E>>;
106
- /**
107
- * Write typed handlers for the contract or one of its route groups.
108
- */
109
- router: {
110
- <const GroupOrRoutes extends Extract<keyof Router<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, E>, string> | Routes>(group: GroupOrRoutes, router: GroupRouter<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, GroupOrRoutes, E>): GroupRouter<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, GroupOrRoutes, E>;
111
- (router: Router<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, E>): Router<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, E>;
112
- };
113
- /**
114
- * Write a handler for each of the contract's jobs.
115
- *
116
- * Pass a `transport` to say where a queued job goes. Without one, `queue`
117
- * runs the job in this process and it is lost on a crash.
118
- *
119
- * @example
120
- * export const jobs = server.jobs({
121
- * sendDigests: async () => ({
122
- * status: 200,
123
- * body: {
124
- * sent: await sendPendingDigests(),
125
- * },
126
- * }),
127
- * });
128
- */
129
- jobs(handlers: JobsRouter<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>>): JobsRouter<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>>;
130
- /**
131
- * Assemble the router, guards, and job handlers into the api object.
132
- */
133
- api(options: {
134
- router: Router<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, E>;
135
- } & (string extends keyof Schemes ? {
136
- guards?: undefined;
137
- } : {
138
- guards: NoInfer<GuardsForSchemes<Schemes, E>>;
139
- }) & (string extends keyof J ? {
140
- jobs?: undefined;
141
- } : {
142
- jobs: NoInfer<JobsRouter<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>>>;
143
- }) & (string extends keyof RequestContext ? {
144
- requestContext?: undefined;
145
- } : {
146
- requestContext: NoInfer<{ [Name in keyof RequestContext]: RequestContextRun<HonoHandlerContext<E>> }>;
147
- }) & (string extends keyof Plugins ? {
148
- plugins?: undefined;
149
- } : {
150
- plugins: PluginImplementations<Plugins, HonoHandlerContext<E>>;
151
- })): HonoApi<R>;
152
- }
58
+ interface Server<C extends Contract, E extends Env = Env> extends Server$1<C, HonoHandlerContext<E>, HonoApi<RoutesOf<C>>> {}
153
59
  /**
154
60
  * Turn a contract into a server handle: the serving counterpart to `Kizuna`.
155
61
  * Keep the instance and use `server.guard` to define guards, `server.router`
156
62
  * to write typed handlers, and `server.api` to assemble them.
157
- *
158
- * @example
159
- * const server = new KizunaServer(contract);
160
- *
161
- * const requireUser = server.guard('user', ({ bearer, deny }) => {
162
- * const session = bearer && sessions.get(bearer.token);
163
- * return session ? { userId: session.userId } : deny(401, 'Unauthorized');
164
- * });
165
- *
166
- * export const api = server.api({
167
- * router,
168
- * guards: {
169
- * user: requireUser,
170
- * },
171
- * });
172
63
  */
173
- declare class KizunaServer<const R extends Routes, Schemes extends Record<string, SecurityScheme>, Auth, RequestContext extends Record<string, RequestContextSchema>, Plugins extends ContractPlugins, E extends Env = Env, J extends Jobs = Jobs> implements Server<R, Schemes, Auth, RequestContext, Plugins, E, J> {
174
- readonly guard: Server<R, Schemes, Auth, RequestContext, Plugins, E, J>['guard'];
175
- readonly requestContext: Server<R, Schemes, Auth, RequestContext, Plugins, E, J>['requestContext'];
176
- readonly router: Server<R, Schemes, Auth, RequestContext, Plugins, E, J>['router'];
177
- readonly jobs: Server<R, Schemes, Auth, RequestContext, Plugins, E, J>['jobs'];
178
- readonly api: Server<R, Schemes, Auth, RequestContext, Plugins, E, J>['api'];
179
- constructor(contract: ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, options?: ServerOptions);
64
+ declare class KizunaServer<C extends Contract, E extends Env = Env> implements Server<C, E> {
65
+ readonly guard: Server<C, E>['guard'];
66
+ readonly requestContext: Server<C, E>['requestContext'];
67
+ readonly router: Server<C, E>['router'];
68
+ readonly jobs: Server<C, E>['jobs'];
69
+ readonly api: Server<C, E>['api'];
70
+ constructor(contract: C, options?: ServerOptions);
180
71
  }
181
72
  //#endregion
182
73
  export { HonoApi, HonoHandlerContext, HonoOptions, JobsRouter, KizunaServer, RouteHandler, Router, Server, mountHono };
package/dist/index.d.mts CHANGED
@@ -1,7 +1,6 @@
1
- import { ApiWithRouter, ContractPlugins, ErrorFormatter, GUARDS_META, GuardDenial, GuardDeny, GuardParams, GuardRun, HandlersFromAuth, JOBS_META, Jobs, PluginArgs, PluginImplementations, REQUEST_CONTEXT_META, RequestContextRun, RequestContextValues, RouteDefinition, RouteHandler as RouteHandler$1, Router as Router$1, Routes, SCHEMES_META, ServerOptions } from "@ts-kizuna/core/adapter";
1
+ import { ApiWithRouter, ContractJobsRouter, ContractRouter, ErrorFormatter, GUARDS_META, JOBS_META, REQUEST_CONTEXT_META, RouteDefinition, RouteHandler as RouteHandler$1, Routes, SCHEMES_META, Server as Server$1, ServerOptions } from "@ts-kizuna/core/adapter";
2
2
  import { Context, Env, Hono } from "hono";
3
- import { z } from "zod";
4
- import { Contract, CredentialOf, GuardSuccess, JobHandlers, JobsArg, RequestContextHeaderValues, RequestContextSchema, SecurityScheme, TagOptions } from "@ts-kizuna/core";
3
+ import { Contract, RoutesOf } from "@ts-kizuna/core";
5
4
 
6
5
  //#region src/server.d.ts
7
6
  type HonoApi<R extends Routes = Routes> = ApiWithRouter<R> & {
@@ -27,18 +26,12 @@ type RouteHandler<R extends RouteDefinition, E extends Env = Env> = RouteHandler
27
26
  * contract's `auth` map additionally receive each required identity's context
28
27
  * in their handler args, under `auth`, keyed by the identity's name.
29
28
  */
30
- type Router<C, E extends Env = Env> = C extends Contract<infer R, infer _Tags, infer _Codes, infer Schemes, infer Auth, infer RequestContext, infer Plugins, infer J> ? HandlersFromAuth<R, HonoHandlerContext<E> & RequestContextValues<RequestContext> & PluginArgs<Plugins> & JobsArg<J>, Schemes, Auth> : C extends Routes ? Router$1<C, HonoHandlerContext<E>> : never;
29
+ type Router<C, E extends Env = Env> = ContractRouter<C, HonoHandlerContext<E>>;
31
30
  /**
32
31
  * The handler for each of a contract's scheduled jobs, typed against it. Each
33
32
  * receives only the job's `input`, so the same handler can be run in process.
34
33
  */
35
- type JobsRouter<C> = C extends Contract<infer _R, infer _Tags, infer _Codes, infer _Schemes, infer _Auth, infer _RequestContext, infer _Plugins, infer J> ? JobHandlers<J> : never;
36
- /**
37
- * The handlers for a group named on the contract, or for a bare route group.
38
- * Both forms resolve through one signature: a second candidate of the same
39
- * arity costs zero-argument handlers their contextual type.
40
- */
41
- type GroupRouter<Source, GroupOrRoutes, E extends Env> = GroupOrRoutes extends string ? Router<Source, E>[Extract<GroupOrRoutes, keyof Router<Source, E>>] : Router<GroupOrRoutes, E>;
34
+ type JobsRouter<C> = ContractJobsRouter<C>;
42
35
  interface HonoOptions {
43
36
  /**
44
37
  * Validate handler return values against the routes' response schemas.
@@ -54,32 +47,6 @@ interface HonoOptions {
54
47
  */
55
48
  formatError?: ErrorFormatter<Request>;
56
49
  }
57
- /**
58
- * A guard per identity, keyed by name. Each receives the handler context, a
59
- * `deny` helper, and the matched route's required scopes, and returns that
60
- * identity's {@link GuardSuccess} (its context and access fields) or a `deny(...)`
61
- * result. Keying by name lets each guard's return be typed against its own
62
- * identity, so access values narrow without an annotation. An
63
- * authentication-only identity (no context, no access) returns nothing on
64
- * success, or `deny(...)`.
65
- */
66
- type GuardFns<Schemes extends Record<string, SecurityScheme>, Params, E extends Env> = { [Name in keyof Schemes]: (args: HonoHandlerContext<E> & CredentialOf<Schemes[Name]> & {
67
- params: Params;
68
- deny: GuardDeny;
69
- scopes: string[];
70
- }) => [keyof GuardSuccess<Schemes[Name]>] extends [never] ? void | GuardDenial | Promise<void | GuardDenial> : GuardSuccess<Schemes[Name]> | GuardDenial | Promise<GuardSuccess<Schemes[Name]> | GuardDenial> };
71
- /**
72
- * One guard per identity declared on the contract.
73
- */
74
- type GuardsForSchemes<Schemes extends Record<string, SecurityScheme>, E extends Env> = { [Name in keyof Schemes]: GuardRun<HonoHandlerContext<E>> };
75
- /**
76
- * The resolver functions for the request context schemas declared on `kizuna`,
77
- * keyed by name. Each runs on every route and returns its schema's value.
78
- */
79
- type RequestResolverFns<RequestContext extends Record<string, RequestContextSchema>, E extends Env> = { [Name in keyof RequestContext]: (args: HonoHandlerContext<E> & {
80
- params: Record<string, string>;
81
- headers: RequestContextHeaderValues<RequestContext[Name]>;
82
- }) => z.output<RequestContext[Name]['context']> | Promise<z.output<RequestContext[Name]['context']>> };
83
50
  /**
84
51
  * Mount a ts-kizuna API onto a Hono app.
85
52
  *
@@ -88,95 +55,19 @@ type RequestResolverFns<RequestContext extends Record<string, RequestContextSche
88
55
  * api.mount(app);
89
56
  */
90
57
  declare function mountHono<E extends Env = Env>(api: HonoApi, app: Hono<E>, options?: HonoOptions): void;
91
- type ServerContract<R extends Routes, Schemes extends Record<string, SecurityScheme>, Auth, RequestContext extends Record<string, RequestContextSchema>, Plugins extends ContractPlugins, J extends Jobs = Jobs> = Contract<R, Record<string, TagOptions>, string, Schemes, Auth, RequestContext, Plugins, J>;
92
- interface Server<R extends Routes, Schemes extends Record<string, SecurityScheme>, Auth, RequestContext extends Record<string, RequestContextSchema>, Plugins extends ContractPlugins, E extends Env = Env, J extends Jobs = Jobs> {
93
- /**
94
- * Define a guard for one of the contract's identities. It runs before the
95
- * handlers of every route whose `auth` entry requires the identity, and
96
- * receives the credential its method extracted (`bearer`, `apiKey`, or
97
- * `basic`, `null` when absent). Return the identity's context and access
98
- * fields to allow the request, or call `deny(status, detail)`.
99
- */
100
- guard<const Name extends Extract<keyof Schemes, string>>(name: Name, run: GuardFns<Schemes, GuardParams<R, Auth, Name>, E>[Name]): GuardRun<HonoHandlerContext<E>>;
101
- /**
102
- * Define a request context resolver declared on the contract. It runs on
103
- * every route, public ones included, and never denies.
104
- */
105
- requestContext<const Name extends Extract<keyof RequestContext, string>>(name: Name, run: RequestResolverFns<RequestContext, E>[Name]): RequestContextRun<HonoHandlerContext<E>>;
106
- /**
107
- * Write typed handlers for the contract or one of its route groups.
108
- */
109
- router: {
110
- <const GroupOrRoutes extends Extract<keyof Router<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, E>, string> | Routes>(group: GroupOrRoutes, router: GroupRouter<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, GroupOrRoutes, E>): GroupRouter<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, GroupOrRoutes, E>;
111
- (router: Router<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, E>): Router<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, E>;
112
- };
113
- /**
114
- * Write a handler for each of the contract's jobs.
115
- *
116
- * Pass a `transport` to say where a queued job goes. Without one, `queue`
117
- * runs the job in this process and it is lost on a crash.
118
- *
119
- * @example
120
- * export const jobs = server.jobs({
121
- * sendDigests: async () => ({
122
- * status: 200,
123
- * body: {
124
- * sent: await sendPendingDigests(),
125
- * },
126
- * }),
127
- * });
128
- */
129
- jobs(handlers: JobsRouter<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>>): JobsRouter<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>>;
130
- /**
131
- * Assemble the router, guards, and job handlers into the api object.
132
- */
133
- api(options: {
134
- router: Router<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, E>;
135
- } & (string extends keyof Schemes ? {
136
- guards?: undefined;
137
- } : {
138
- guards: NoInfer<GuardsForSchemes<Schemes, E>>;
139
- }) & (string extends keyof J ? {
140
- jobs?: undefined;
141
- } : {
142
- jobs: NoInfer<JobsRouter<ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>>>;
143
- }) & (string extends keyof RequestContext ? {
144
- requestContext?: undefined;
145
- } : {
146
- requestContext: NoInfer<{ [Name in keyof RequestContext]: RequestContextRun<HonoHandlerContext<E>> }>;
147
- }) & (string extends keyof Plugins ? {
148
- plugins?: undefined;
149
- } : {
150
- plugins: PluginImplementations<Plugins, HonoHandlerContext<E>>;
151
- })): HonoApi<R>;
152
- }
58
+ interface Server<C extends Contract, E extends Env = Env> extends Server$1<C, HonoHandlerContext<E>, HonoApi<RoutesOf<C>>> {}
153
59
  /**
154
60
  * Turn a contract into a server handle: the serving counterpart to `Kizuna`.
155
61
  * Keep the instance and use `server.guard` to define guards, `server.router`
156
62
  * to write typed handlers, and `server.api` to assemble them.
157
- *
158
- * @example
159
- * const server = new KizunaServer(contract);
160
- *
161
- * const requireUser = server.guard('user', ({ bearer, deny }) => {
162
- * const session = bearer && sessions.get(bearer.token);
163
- * return session ? { userId: session.userId } : deny(401, 'Unauthorized');
164
- * });
165
- *
166
- * export const api = server.api({
167
- * router,
168
- * guards: {
169
- * user: requireUser,
170
- * },
171
- * });
172
63
  */
173
- declare class KizunaServer<const R extends Routes, Schemes extends Record<string, SecurityScheme>, Auth, RequestContext extends Record<string, RequestContextSchema>, Plugins extends ContractPlugins, E extends Env = Env, J extends Jobs = Jobs> implements Server<R, Schemes, Auth, RequestContext, Plugins, E, J> {
174
- readonly guard: Server<R, Schemes, Auth, RequestContext, Plugins, E, J>['guard'];
175
- readonly requestContext: Server<R, Schemes, Auth, RequestContext, Plugins, E, J>['requestContext'];
176
- readonly router: Server<R, Schemes, Auth, RequestContext, Plugins, E, J>['router'];
177
- readonly jobs: Server<R, Schemes, Auth, RequestContext, Plugins, E, J>['jobs'];
178
- readonly api: Server<R, Schemes, Auth, RequestContext, Plugins, E, J>['api'];
179
- constructor(contract: ServerContract<R, Schemes, Auth, RequestContext, Plugins, J>, options?: ServerOptions);
64
+ declare class KizunaServer<C extends Contract, E extends Env = Env> implements Server<C, E> {
65
+ readonly guard: Server<C, E>['guard'];
66
+ readonly requestContext: Server<C, E>['requestContext'];
67
+ readonly router: Server<C, E>['router'];
68
+ readonly jobs: Server<C, E>['jobs'];
69
+ readonly api: Server<C, E>['api'];
70
+ constructor(contract: C, options?: ServerOptions);
180
71
  }
181
72
  //#endregion
182
73
  export { HonoApi, HonoHandlerContext, HonoOptions, JobsRouter, KizunaServer, RouteHandler, Router, Server, mountHono };
package/dist/index.mjs CHANGED
@@ -1,5 +1,21 @@
1
- import { GUARDS_META, JOBS_META, REQUEST_CONTEXT_META, ROUTER_META, SCHEMES_META, assembleApi, createAdapter, headersToObject, jobRouter, jobRoutes, jobRunnerFrom, parseFetchBody, pluginExportsOf, pluginRouterOf, pluginRoutesOf, renderJsonResult, warnUnsupportedJobOptions } from "@ts-kizuna/core/adapter";
1
+ import { GUARDS_META, JOBS_META, REQUEST_CONTEXT_META, ROUTER_META, SCHEMES_META, createAdapter, createServerSurface, headersToObject, jobRouter, jobRoutes, jobRunnerFrom, parseFetchBody, pluginExportsOf, pluginRouterOf, pluginRoutesOf, renderJsonResult } from "@ts-kizuna/core/adapter";
2
2
  //#region src/server.ts
3
+ /**
4
+ * A guard per identity, keyed by name. Each receives the handler context, a
5
+ * `deny` helper, and the matched route's required scopes, and returns that
6
+ * identity's {@link GuardSuccess} (its context and access fields) or a `deny(...)`
7
+ * result. Keying by name lets each guard's return be typed against its own
8
+ * identity, so access values narrow without an annotation. An
9
+ * authentication-only identity (no context, no access) returns nothing on
10
+ * success, or `deny(...)`.
11
+ */
12
+ /**
13
+ * One guard per identity declared on the contract.
14
+ */
15
+ /**
16
+ * The resolver functions for the request context schemas declared on `kizuna`,
17
+ * keyed by name. Each runs on every route and returns its schema's value.
18
+ */
3
19
  const honoAdapter = createAdapter({
4
20
  buildHandlerContext: (_adapterRequest, { c }) => ({ c }),
5
21
  respond: (result, { c, formatError }) => {
@@ -71,48 +87,17 @@ function mountHono(api, app, options) {
71
87
  for (const [routeKey, route] of Object.entries(routes)) mountRoute(routeKey, route, routes, router);
72
88
  }
73
89
  }
74
- const createServerSurface = (contract, options) => {
75
- warnUnsupportedJobOptions(contract.jobs, options?.jobTransport);
76
- return {
77
- guard: (_name, run) => run,
78
- requestContext: (_name, run) => run,
79
- router: (groupOrRouter, groupRouter) => groupRouter ?? groupOrRouter,
80
- jobs: (handlers) => handlers,
81
- api: ({ jobs, ...parts }) => {
82
- const api = Object.assign(assembleApi(contract, parts), { [JOBS_META]: contract.jobs ? {
83
- jobs: contract.jobs,
84
- handlers: jobs ?? {},
85
- config: contract.jobsConfig,
86
- transport: options?.jobTransport,
87
- onError: options?.onJobError
88
- } : void 0 });
89
- return Object.assign(api, { mount: (app, mountOptions) => mountHono(api, app, mountOptions) });
90
- }
91
- };
92
- };
93
90
  /**
94
91
  * Turn a contract into a server handle: the serving counterpart to `Kizuna`.
95
92
  * Keep the instance and use `server.guard` to define guards, `server.router`
96
93
  * to write typed handlers, and `server.api` to assemble them.
97
- *
98
- * @example
99
- * const server = new KizunaServer(contract);
100
- *
101
- * const requireUser = server.guard('user', ({ bearer, deny }) => {
102
- * const session = bearer && sessions.get(bearer.token);
103
- * return session ? { userId: session.userId } : deny(401, 'Unauthorized');
104
- * });
105
- *
106
- * export const api = server.api({
107
- * router,
108
- * guards: {
109
- * user: requireUser,
110
- * },
111
- * });
112
94
  */
113
95
  var KizunaServer = class {
114
96
  constructor(contract, options) {
115
- Object.assign(this, createServerSurface(contract, options));
97
+ Object.assign(this, createServerSurface(contract, options, (assembled) => {
98
+ const api = assembled;
99
+ return Object.assign(api, { mount: (app, mountOptions) => mountHono(api, app, mountOptions) });
100
+ }));
116
101
  }
117
102
  };
118
103
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ts-kizuna/hono",
3
- "version": "1.49.7",
3
+ "version": "1.51.0",
4
4
  "description": "Hono adapter for ts-kizuna",
5
5
  "keywords": [
6
6
  "ts-kizuna",
@@ -57,14 +57,14 @@
57
57
  "peerDependencies": {
58
58
  "hono": "^4.0.0",
59
59
  "zod": "^4.0.0",
60
- "@ts-kizuna/core": "1.49.7"
60
+ "@ts-kizuna/core": "1.51.0"
61
61
  },
62
62
  "devDependencies": {
63
63
  "hono": "^4.7.0",
64
64
  "tsdown": "^0.21.0",
65
- "typescript": "^5.6.3",
65
+ "typescript": "^6.0.3",
66
66
  "zod": "^4.0.0",
67
- "@ts-kizuna/core": "1.49.7"
67
+ "@ts-kizuna/core": "1.51.0"
68
68
  },
69
69
  "scripts": {
70
70
  "build": "tsdown src/index.ts --format esm,cjs --dts --clean --external @ts-kizuna/core --external hono --external zod",