ts-procedures 3.0.2 → 3.1.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/build/implementations/http/express-rpc/index.d.ts +6 -3
- package/build/implementations/http/express-rpc/index.js +18 -6
- package/build/implementations/http/express-rpc/index.js.map +1 -1
- package/build/implementations/http/express-rpc/index.test.js +153 -0
- package/build/implementations/http/express-rpc/index.test.js.map +1 -1
- package/build/implementations/http/express-rpc/types.d.ts +6 -23
- package/build/implementations/http/hono-rpc/index.d.ts +6 -3
- package/build/implementations/http/hono-rpc/index.js +18 -6
- package/build/implementations/http/hono-rpc/index.js.map +1 -1
- package/build/implementations/http/hono-rpc/index.test.js +153 -0
- package/build/implementations/http/hono-rpc/index.test.js.map +1 -1
- package/build/implementations/http/hono-rpc/types.d.ts +6 -23
- package/build/implementations/types.d.ts +32 -1
- package/package.json +1 -1
- package/src/implementations/http/express-rpc/index.test.ts +225 -0
- package/src/implementations/http/express-rpc/index.ts +39 -10
- package/src/implementations/http/express-rpc/types.ts +8 -25
- package/src/implementations/http/hono-rpc/README.md +82 -42
- package/src/implementations/http/hono-rpc/index.test.ts +225 -0
- package/src/implementations/http/hono-rpc/index.ts +40 -11
- package/src/implementations/http/hono-rpc/types.ts +8 -25
- package/src/implementations/types.ts +39 -1
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { Hono, Context } from 'hono'
|
|
2
2
|
import { kebabCase } from 'es-toolkit/string'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { TProcedureRegistration } from '../../../index.js'
|
|
4
|
+
import {
|
|
5
|
+
ExtractConfig,
|
|
6
|
+
ExtractContext,
|
|
7
|
+
ProceduresFactory,
|
|
8
|
+
RPCConfig,
|
|
9
|
+
RPCHttpRouteDoc,
|
|
10
|
+
} from '../../types.js'
|
|
5
11
|
import { castArray } from 'es-toolkit/compat'
|
|
6
|
-
import { HonoFactoryItem
|
|
12
|
+
import { HonoFactoryItem } from './types.js'
|
|
7
13
|
|
|
8
14
|
export type { RPCConfig, RPCHttpRouteDoc }
|
|
9
15
|
|
|
@@ -110,7 +116,7 @@ export class HonoRPCAppBuilder {
|
|
|
110
116
|
private factories: HonoFactoryItem<any>[] = []
|
|
111
117
|
|
|
112
118
|
private _app: Hono = new Hono()
|
|
113
|
-
private _docs: RPCHttpRouteDoc[] = []
|
|
119
|
+
private _docs: (RPCHttpRouteDoc & object)[] = []
|
|
114
120
|
|
|
115
121
|
get app(): Hono {
|
|
116
122
|
return this._app
|
|
@@ -125,14 +131,21 @@ export class HonoRPCAppBuilder {
|
|
|
125
131
|
* @param factory - The procedure factory created by Procedures<Context, RPCConfig>()
|
|
126
132
|
* @param factoryContext - The context for procedure handlers. Can be a direct value,
|
|
127
133
|
* a sync function (c) => Context, or an async function (c) => Promise<Context>
|
|
134
|
+
* @param extendProcedureDoc - A custom function to extend the generated RPC route documentation for each procedure.
|
|
128
135
|
*/
|
|
129
136
|
register<TFactory extends ProceduresFactory>(
|
|
130
137
|
factory: TFactory,
|
|
131
138
|
factoryContext:
|
|
132
139
|
| ExtractContext<TFactory>
|
|
133
|
-
| ((c: Context) => ExtractContext<TFactory> | Promise<ExtractContext<TFactory>>)
|
|
140
|
+
| ((c: Context) => ExtractContext<TFactory> | Promise<ExtractContext<TFactory>>),
|
|
141
|
+
extendProcedureDoc?: (params: {
|
|
142
|
+
/* RPC App builder base http route doc */
|
|
143
|
+
base: RPCHttpRouteDoc
|
|
144
|
+
/* Procedure registration */
|
|
145
|
+
procedure: TProcedureRegistration<any, ExtractConfig<TFactory>>
|
|
146
|
+
}) => Record<string, any>
|
|
134
147
|
): this {
|
|
135
|
-
this.factories.push({ factory, factoryContext } as HonoFactoryItem<any>)
|
|
148
|
+
this.factories.push({ factory, factoryContext, extendProcedureDoc } as HonoFactoryItem<any>)
|
|
136
149
|
return this
|
|
137
150
|
}
|
|
138
151
|
|
|
@@ -141,9 +154,9 @@ export class HonoRPCAppBuilder {
|
|
|
141
154
|
* @return Hono
|
|
142
155
|
*/
|
|
143
156
|
build(): Hono {
|
|
144
|
-
this.factories.forEach(({ factory, factoryContext }) => {
|
|
157
|
+
this.factories.forEach(({ factory, factoryContext, extendProcedureDoc }) => {
|
|
145
158
|
factory.getProcedures().map((procedure: TProcedureRegistration<any, RPCConfig>) => {
|
|
146
|
-
const route = this.buildRpcHttpRouteDoc(procedure)
|
|
159
|
+
const route = this.buildRpcHttpRouteDoc(procedure, extendProcedureDoc)
|
|
147
160
|
|
|
148
161
|
this._docs.push(route)
|
|
149
162
|
|
|
@@ -182,14 +195,17 @@ export class HonoRPCAppBuilder {
|
|
|
182
195
|
* Generates the RPC HTTP route for the given procedure.
|
|
183
196
|
* @param procedure
|
|
184
197
|
*/
|
|
185
|
-
private buildRpcHttpRouteDoc(
|
|
198
|
+
private buildRpcHttpRouteDoc(
|
|
199
|
+
procedure: TProcedureRegistration<any, RPCConfig>,
|
|
200
|
+
extendProcedureDoc: HonoFactoryItem['extendProcedureDoc']
|
|
201
|
+
): RPCHttpRouteDoc {
|
|
186
202
|
const { config } = procedure
|
|
187
203
|
const path = HonoRPCAppBuilder.makeRPCHttpRoutePath({
|
|
188
204
|
name: procedure.name,
|
|
189
205
|
config,
|
|
190
206
|
prefix: this.config?.pathPrefix,
|
|
191
207
|
})
|
|
192
|
-
const method = 'post' // RPCs use POST method
|
|
208
|
+
const method = 'post' as const // RPCs use POST method
|
|
193
209
|
const jsonSchema: { body?: object; response?: object } = {}
|
|
194
210
|
|
|
195
211
|
if (config.schema?.params) {
|
|
@@ -199,10 +215,23 @@ export class HonoRPCAppBuilder {
|
|
|
199
215
|
jsonSchema.response = config.schema.returnType
|
|
200
216
|
}
|
|
201
217
|
|
|
202
|
-
|
|
218
|
+
const base = {
|
|
219
|
+
name: procedure.name,
|
|
220
|
+
version: config.version,
|
|
221
|
+
scope: config.scope,
|
|
203
222
|
path,
|
|
204
223
|
method,
|
|
205
224
|
jsonSchema,
|
|
206
225
|
}
|
|
226
|
+
let extendedDoc: object = {}
|
|
227
|
+
|
|
228
|
+
if (extendProcedureDoc) {
|
|
229
|
+
extendedDoc = extendProcedureDoc({ base, procedure })
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
...extendedDoc,
|
|
234
|
+
...base,
|
|
235
|
+
}
|
|
207
236
|
}
|
|
208
237
|
}
|
|
@@ -1,33 +1,16 @@
|
|
|
1
|
-
import { RPCConfig } from '../../types.js'
|
|
2
|
-
import { Procedures } from '../../../index.js'
|
|
1
|
+
import { ExtractConfig, ExtractContext, RPCConfig, RPCHttpRouteDoc } from '../../types.js'
|
|
2
|
+
import { Procedures, TProcedureRegistration } from '../../../index.js'
|
|
3
3
|
import { Context } from 'hono'
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Extracts the TContext type from a Procedures factory return type.
|
|
7
|
-
* Uses the first parameter of the handler function to infer the context type.
|
|
8
|
-
*/
|
|
9
|
-
export type ExtractContext<TFactory> = TFactory extends {
|
|
10
|
-
getProcedures: () => Array<{ handler: (ctx: infer TContext, ...args: any[]) => any }>
|
|
11
|
-
}
|
|
12
|
-
? TContext
|
|
13
|
-
: never
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Minimal structural type for a Procedures factory.
|
|
17
|
-
* Uses explicit `any` types to avoid variance issues with generic constraints.
|
|
18
|
-
*/
|
|
19
|
-
export type ProceduresFactory = {
|
|
20
|
-
getProcedures: () => Array<{
|
|
21
|
-
name: string
|
|
22
|
-
config: any
|
|
23
|
-
handler: (ctx: any, params?: any) => Promise<any>
|
|
24
|
-
}>
|
|
25
|
-
Create: (...args: any[]) => any
|
|
26
|
-
}
|
|
27
|
-
|
|
28
5
|
export type HonoFactoryItem<TFactory = ReturnType<typeof Procedures<any, RPCConfig>>> = {
|
|
29
6
|
factory: TFactory
|
|
30
7
|
factoryContext:
|
|
31
8
|
| ExtractContext<TFactory>
|
|
32
9
|
| ((c: Context) => ExtractContext<TFactory> | Promise<ExtractContext<TFactory>>)
|
|
10
|
+
extendProcedureDoc?: (params: {
|
|
11
|
+
/* RPC App builder base http route doc */
|
|
12
|
+
base: RPCHttpRouteDoc
|
|
13
|
+
/* Procedure registration */
|
|
14
|
+
procedure: TProcedureRegistration<any, ExtractConfig<TFactory>>
|
|
15
|
+
}) => Record<string, any>
|
|
33
16
|
}
|
|
@@ -11,7 +11,8 @@ export type FactoryItem<C> = {
|
|
|
11
11
|
factoryContext: (req: Request) => C
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export interface RPCHttpRouteDoc {
|
|
14
|
+
export interface RPCHttpRouteDoc extends RPCConfig {
|
|
15
|
+
name: string // procedure name
|
|
15
16
|
path: string
|
|
16
17
|
method: 'post'
|
|
17
18
|
jsonSchema: {
|
|
@@ -19,3 +20,40 @@ export interface RPCHttpRouteDoc {
|
|
|
19
20
|
response?: object
|
|
20
21
|
}
|
|
21
22
|
}
|
|
23
|
+
|
|
24
|
+
// ================
|
|
25
|
+
// Utility types
|
|
26
|
+
// ================
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Extracts the TContext type from a Procedures factory return type.
|
|
30
|
+
* Uses the first parameter of the handler function to infer the context type.
|
|
31
|
+
*/
|
|
32
|
+
export type ExtractContext<TFactory> = TFactory extends {
|
|
33
|
+
getProcedures: () => Array<{ handler: (ctx: infer TContext, ...args: any[]) => any }>
|
|
34
|
+
}
|
|
35
|
+
? TContext
|
|
36
|
+
: never
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Extracts the TConfig type from a Procedures factory return type.
|
|
40
|
+
* Uses the config property of the procedure registration to infer the config type.
|
|
41
|
+
*/
|
|
42
|
+
export type ExtractConfig<TFactory> = TFactory extends {
|
|
43
|
+
getProcedures: () => Array<{ config: infer TConfig }>
|
|
44
|
+
}
|
|
45
|
+
? TConfig
|
|
46
|
+
: never
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Minimal structural type for a Procedures factory.
|
|
50
|
+
* Uses explicit `any` types to avoid variance issues with generic constraints.
|
|
51
|
+
*/
|
|
52
|
+
export type ProceduresFactory = {
|
|
53
|
+
getProcedures: () => Array<{
|
|
54
|
+
name: string
|
|
55
|
+
config: any
|
|
56
|
+
handler: (ctx: any, params?: any) => Promise<any>
|
|
57
|
+
}>
|
|
58
|
+
Create: (...args: any[]) => any
|
|
59
|
+
}
|