@okay-e9g/hono-config 0.0.16 → 0.0.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/package.json CHANGED
@@ -48,5 +48,5 @@
48
48
  "prepublishOnly": "bun run typecheck && bun test",
49
49
  "typecheck": "tsc --noEmit"
50
50
  },
51
- "version": "0.0.16"
51
+ "version": "0.0.18"
52
52
  }
@@ -5,12 +5,14 @@
5
5
  import type { Env, NotFoundHandler } from 'hono/types';
6
6
 
7
7
  import type { ResponseEnv } from '../middlewares/ensure-rt';
8
- import { statusText } from '../schemas';
8
+ import { rpcStandardErrorText, statusText } from '../schemas';
9
9
 
10
10
  /**
11
11
  * Creates the shared 404 handler used by the configured Hono factories.
12
12
  *
13
- * Falls back to a plain text 404 when no response helper has been installed.
13
+ * API helpers produce an HTTP 404 envelope. RPC helpers produce a JSON-RPC
14
+ * `Method Not Found` error with a `null` id and an HTTP 200 status. Falls back
15
+ * to a plain text 404 when no response helper has been installed.
14
16
  *
15
17
  * @internal
16
18
  */
@@ -26,6 +28,11 @@ export const notFound = <T extends Env>(): NotFoundHandler<T> => {
26
28
  return c.json(response.error(404), 404);
27
29
  }
28
30
 
29
- return c.json(response.error(statusText[404]));
31
+ return c.json(
32
+ response.error({
33
+ code: -32601,
34
+ message: rpcStandardErrorText['-32601'],
35
+ }),
36
+ );
30
37
  };
31
38
  };
@@ -7,10 +7,10 @@ import type { Env, ErrorHandler } from 'hono/types';
7
7
  import { z } from 'zod';
8
8
 
9
9
  import type { ResponseEnv } from '../middlewares/ensure-rt';
10
- import { type ClientErrorStatusCode, type ServerErrorStatusCode, statusText } from '../schemas';
10
+ import { type ClientErrorStatusCode, rpcStandardErrorText, type ServerErrorStatusCode } from '../schemas';
11
11
 
12
12
  interface TypedHTTPException extends Omit<HTTPException, 'status'> {
13
- status: ClientErrorStatusCode & ServerErrorStatusCode;
13
+ status: ClientErrorStatusCode | ServerErrorStatusCode;
14
14
  }
15
15
 
16
16
  const assertHTTPException = (err: Error): err is TypedHTTPException => {
@@ -22,7 +22,10 @@ const assertHTTPException = (err: Error): err is TypedHTTPException => {
22
22
  *
23
23
  * Errors are rethrown when no response helper has been installed, allowing
24
24
  * Hono's fallback error handling to handle apps that are not using this
25
- * package's response envelopes.
25
+ * package's response envelopes. API helpers preserve HTTP error semantics.
26
+ * RPC helpers map validation failures to `Invalid Params`, 4xx HTTP exceptions
27
+ * to `Invalid Request`, and 5xx or generic failures to `Internal Error`,
28
+ * returning a JSON-RPC envelope with a `null` id.
26
29
  *
27
30
  * @internal
28
31
  */
@@ -39,7 +42,13 @@ export const onError = <T extends Env>(): ErrorHandler<T> => {
39
42
  return c.json(response.error(400, z.flattenError(err)), 400);
40
43
  }
41
44
 
42
- return c.json(response.error(z.flattenError(err)));
45
+ return c.json(
46
+ response.error({
47
+ code: -32602,
48
+ data: z.flattenError(err),
49
+ message: rpcStandardErrorText['-32602'],
50
+ }),
51
+ );
43
52
  }
44
53
 
45
54
  if (assertHTTPException(err)) {
@@ -49,7 +58,9 @@ export const onError = <T extends Env>(): ErrorHandler<T> => {
49
58
  return c.json(response.error(status, message), status);
50
59
  }
51
60
 
52
- return c.json(response.error(message === '' ? statusText[status] : message));
61
+ const code = status < 500 ? -32600 : -32603;
62
+
63
+ return c.json(response.error({ code, message: message === '' ? rpcStandardErrorText[code] : message }));
53
64
  }
54
65
 
55
66
  const errMessage = err instanceof Error ? err.message : err;
@@ -58,6 +69,11 @@ export const onError = <T extends Env>(): ErrorHandler<T> => {
58
69
  return c.json(response.error(500, errMessage), 500);
59
70
  }
60
71
 
61
- return c.json(response.error(errMessage === '' ? statusText[500] : errMessage));
72
+ return c.json(
73
+ response.error({
74
+ code: -32603,
75
+ message: errMessage === '' ? rpcStandardErrorText['-32603'] : errMessage,
76
+ }),
77
+ );
62
78
  };
63
79
  };
@@ -96,11 +96,13 @@ export const apiResponseType = <T extends ApiResponseEnv>(): MiddlewareHandler<T
96
96
  };
97
97
 
98
98
  interface TypedRpcError<T = unknown> extends RpcError {
99
- error?: T;
99
+ error: Omit<RpcError['error'], 'data'> & {
100
+ data?: T;
101
+ };
100
102
  }
101
103
 
102
104
  interface TypedRpcResult<T = unknown> extends RpcResult {
103
- result?: T;
105
+ result: T;
104
106
  }
105
107
 
106
108
  /**
@@ -113,13 +115,15 @@ export interface RpcResponseEnv extends Env {
113
115
  */
114
116
  response: {
115
117
  /**
116
- * Builds a JSON-RPC error response envelope for the provided request id.
118
+ * Builds a JSON-RPC error response envelope from a numeric code, message,
119
+ * and optional data. The request id defaults to `null` when omitted.
117
120
  */
118
- error: <T>(error?: T, id?: JsonRpc['id']) => TypedRpcError<T>;
121
+ error: <T>(error: TypedRpcError<T>['error'], id?: JsonRpc['id']) => TypedRpcError<T>;
119
122
  /**
120
- * Builds a JSON-RPC result response envelope for the provided request id.
123
+ * Builds a JSON-RPC result response envelope for the required result. The
124
+ * request id defaults to `null` when omitted.
121
125
  */
122
- result: <T>(result?: T, id?: JsonRpc['id']) => TypedRpcResult<T>;
126
+ result: <T>(result: T, id?: JsonRpc['id']) => TypedRpcResult<T>;
123
127
  /**
124
128
  * Discriminator used by shared error handlers and response guards.
125
129
  */
@@ -132,7 +136,7 @@ export interface RpcResponseEnv extends Env {
132
136
  * Installs `c.var.response` helpers for JSON-RPC 2.0 responses.
133
137
  *
134
138
  * The helpers produce `error` and `result` envelopes validated by the exported
135
- * JSON-RPC schemas and default missing ids to the schema default. If another
139
+ * JSON-RPC schemas and default missing ids to `null`. If another
136
140
  * response helper is already installed, the existing helper is kept so
137
141
  * applications can compose middleware safely.
138
142
  *
@@ -142,10 +146,10 @@ export const rpcResponseType = <T extends RpcResponseEnv>(): MiddlewareHandler<T
142
146
  return createMiddleware<RpcResponseEnv>(async (c, next) => {
143
147
  if (c.var.response === undefined) {
144
148
  c.set('response', {
145
- error: <T>(error?: T, id?: JsonRpc['id']) => {
149
+ error: <T>(error: TypedRpcError<T>['error'], id?: JsonRpc['id']) => {
146
150
  return rpcError.parse({ error, id }) as TypedRpcError<T>;
147
151
  },
148
- result: <T>(result?: T, id?: JsonRpc['id']) => {
152
+ result: <T>(result: T, id?: JsonRpc['id']) => {
149
153
  return rpcResult.parse({ id, result }) as TypedRpcResult<T>;
150
154
  },
151
155
  type: 'rpc',
@@ -5,3 +5,4 @@
5
5
  export * from './api';
6
6
  export * from './http-status';
7
7
  export * from './rpc';
8
+ export * from './rpc-error';
@@ -0,0 +1,37 @@
1
+ /*
2
+ * SPDX-License-Identifier: MIT
3
+ */
4
+
5
+ import { z } from 'zod';
6
+
7
+ /**
8
+ * Zod schema for the five pre-defined JSON-RPC 2.0 error codes.
9
+ *
10
+ * This schema excludes the reserved server-error range and application-defined
11
+ * error codes. Use it when a value must be one of the protocol's standard
12
+ * errors rather than any valid JSON-RPC error code.
13
+ */
14
+ export const rpcStandardErrorCode = z.union([
15
+ z.literal(-32600),
16
+ z.literal(-32601),
17
+ z.literal(-32602),
18
+ z.literal(-32603),
19
+ z.literal(-32700),
20
+ ]);
21
+
22
+ /**
23
+ * One of the five pre-defined JSON-RPC 2.0 error codes.
24
+ */
25
+ export type RpcStandardErrorCode = z.infer<typeof rpcStandardErrorCode>;
26
+
27
+ /**
28
+ * Title-cased short messages for the pre-defined JSON-RPC 2.0 errors, keyed by
29
+ * their numeric code for consistency with the package's HTTP status text.
30
+ */
31
+ export const rpcStandardErrorText: Record<RpcStandardErrorCode, string> = {
32
+ '-32600': 'Invalid Request',
33
+ '-32601': 'Method Not Found',
34
+ '-32602': 'Invalid Params',
35
+ '-32603': 'Internal Error',
36
+ '-32700': 'Parse Error',
37
+ };
@@ -4,11 +4,13 @@
4
4
 
5
5
  import { z } from 'zod';
6
6
 
7
+ import { rpcStandardErrorCode } from './rpc-error';
8
+
7
9
  /**
8
10
  * Zod schema for JSON-RPC 2.0 fields shared by requests and responses.
9
11
  */
10
12
  export const jsonRpc = z.object({
11
- id: z.union([z.number(), z.string()]).default(1),
13
+ id: z.union([z.null(), z.number(), z.string()]).default(null),
12
14
  jsonrpc: z.literal('2.0').default('2.0'),
13
15
  });
14
16
 
@@ -43,11 +45,22 @@ export type RpcRequests = z.infer<typeof rpcRequests>;
43
45
 
44
46
  /**
45
47
  * Zod schema for a JSON-RPC 2.0 error response.
48
+ *
49
+ * The error object requires a standard or reserved server-error code and a
50
+ * message, and may include implementation-defined data.
46
51
  */
47
- export const rpcError = z.object({
48
- ...jsonRpc.shape,
49
- error: z.unknown().optional(),
50
- }).strict();
52
+ export const rpcError = z
53
+ .object({
54
+ ...jsonRpc.shape,
55
+ error: z
56
+ .object({
57
+ code: z.union([rpcStandardErrorCode, z.int().min(-32099).max(-32000)]),
58
+ data: z.unknown().optional(),
59
+ message: z.string(),
60
+ })
61
+ .strict(),
62
+ })
63
+ .strict();
51
64
 
52
65
  /**
53
66
  * TypeScript type inferred from `rpcError`.
@@ -57,10 +70,12 @@ export type RpcError = z.infer<typeof rpcError>;
57
70
  /**
58
71
  * Zod schema for a JSON-RPC 2.0 result response.
59
72
  */
60
- export const rpcResult = z.object({
61
- ...jsonRpc.shape,
62
- result: z.unknown().optional(),
63
- }).strict();
73
+ export const rpcResult = z
74
+ .object({
75
+ ...jsonRpc.shape,
76
+ result: z.unknown(),
77
+ })
78
+ .strict();
64
79
 
65
80
  /**
66
81
  * TypeScript type inferred from `rpcResult`.