xrpckit 0.0.1 → 0.0.2
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.d.ts +19 -19
- package/package.json +6 -3
- package/src/endpoint.ts +72 -0
- package/src/index.ts +11 -0
- package/src/router.ts +113 -0
- package/src/types.ts +17 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
interface EndpointDefinition {
|
|
4
|
-
type:
|
|
5
|
-
input:
|
|
6
|
-
output:
|
|
3
|
+
interface EndpointDefinition<TInputSchema extends z.ZodTypeAny = z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny> {
|
|
4
|
+
type: "query" | "mutation";
|
|
5
|
+
input: TInputSchema;
|
|
6
|
+
output: TOutputSchema;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Creates a query endpoint definition.
|
|
@@ -22,10 +22,10 @@ interface EndpointDefinition {
|
|
|
22
22
|
* });
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
declare function query(config: {
|
|
26
|
-
input:
|
|
27
|
-
output:
|
|
28
|
-
}): EndpointDefinition
|
|
25
|
+
declare function query<TInputSchema extends z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny>(config: {
|
|
26
|
+
input: TInputSchema;
|
|
27
|
+
output: TOutputSchema;
|
|
28
|
+
}): EndpointDefinition<TInputSchema, TOutputSchema>;
|
|
29
29
|
/**
|
|
30
30
|
* Creates a mutation endpoint definition.
|
|
31
31
|
* Mutations are typically used for write operations that modify server state.
|
|
@@ -43,13 +43,13 @@ declare function query(config: {
|
|
|
43
43
|
* });
|
|
44
44
|
* ```
|
|
45
45
|
*/
|
|
46
|
-
declare function mutation(config: {
|
|
47
|
-
input:
|
|
48
|
-
output:
|
|
49
|
-
}): EndpointDefinition
|
|
46
|
+
declare function mutation<TInputSchema extends z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny>(config: {
|
|
47
|
+
input: TInputSchema;
|
|
48
|
+
output: TOutputSchema;
|
|
49
|
+
}): EndpointDefinition<TInputSchema, TOutputSchema>;
|
|
50
50
|
|
|
51
51
|
interface EndpointGroup {
|
|
52
|
-
[endpointName: string]: EndpointDefinition
|
|
52
|
+
[endpointName: string]: EndpointDefinition<z.ZodTypeAny, z.ZodTypeAny>;
|
|
53
53
|
}
|
|
54
54
|
interface RouterDefinition {
|
|
55
55
|
[groupName: string]: EndpointGroup;
|
|
@@ -108,7 +108,7 @@ declare function createEndpoint<T extends EndpointGroup>(endpoints: T): T;
|
|
|
108
108
|
* greeting: createEndpoint({ ... })
|
|
109
109
|
* });
|
|
110
110
|
*/
|
|
111
|
-
declare function createRouter<T extends RouterConfig | RouterDefinition>(config: T): T extends RouterConfig ? Omit<T,
|
|
111
|
+
declare function createRouter<T extends RouterConfig | RouterDefinition>(config: T): T extends RouterConfig ? Omit<T, "middleware"> : T;
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
114
|
* Infer input type from an endpoint definition
|
|
@@ -116,15 +116,15 @@ declare function createRouter<T extends RouterConfig | RouterDefinition>(config:
|
|
|
116
116
|
* type CreateInput = InferInput<typeof router.todo.create>;
|
|
117
117
|
*/
|
|
118
118
|
type InferInput<T extends {
|
|
119
|
-
input:
|
|
120
|
-
}> = z.infer<T[
|
|
119
|
+
input: z.ZodTypeAny;
|
|
120
|
+
}> = z.infer<T["input"]>;
|
|
121
121
|
/**
|
|
122
122
|
* Infer output type from an endpoint definition
|
|
123
123
|
* @example
|
|
124
124
|
* type CreateOutput = InferOutput<typeof router.todo.create>;
|
|
125
125
|
*/
|
|
126
126
|
type InferOutput<T extends {
|
|
127
|
-
output:
|
|
128
|
-
}> = z.infer<T[
|
|
127
|
+
output: z.ZodTypeAny;
|
|
128
|
+
}> = z.infer<T["output"]>;
|
|
129
129
|
|
|
130
130
|
export { type EndpointDefinition, type EndpointGroup, type InferInput, type InferOutput, type Middleware, type RouterConfig, type RouterDefinition, createEndpoint, createRouter, getRouterMiddleware, mutation, query };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xrpckit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Type-safe, cross-platform RPC framework - define API contracts with Zod schemas",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,10 +28,13 @@
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
"files": [
|
|
31
|
-
"dist"
|
|
31
|
+
"dist",
|
|
32
|
+
"src"
|
|
32
33
|
],
|
|
33
34
|
"scripts": {
|
|
34
|
-
"build": "tsup src/index.ts --format esm --dts --clean"
|
|
35
|
+
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
36
|
+
"prepublishOnly": "npm run build",
|
|
37
|
+
"release": "npm publish --//registry.npmjs.org/:_authToken=$NPM_XRPC_APIKEY"
|
|
35
38
|
},
|
|
36
39
|
"dependencies": {
|
|
37
40
|
"zod": "^4.0.0"
|
package/src/endpoint.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export interface EndpointDefinition<
|
|
4
|
+
TInputSchema extends z.ZodTypeAny = z.ZodTypeAny,
|
|
5
|
+
TOutputSchema extends z.ZodTypeAny = z.ZodTypeAny,
|
|
6
|
+
> {
|
|
7
|
+
type: "query" | "mutation";
|
|
8
|
+
input: TInputSchema;
|
|
9
|
+
output: TOutputSchema;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates a query endpoint definition.
|
|
14
|
+
* Queries are typically used for read operations that don't modify server state.
|
|
15
|
+
*
|
|
16
|
+
* @param config - Configuration object containing input and output Zod schemas
|
|
17
|
+
* @param config.input - Zod schema for validating the input parameters
|
|
18
|
+
* @param config.output - Zod schema for validating the output response
|
|
19
|
+
* @returns An endpoint definition with type 'query'
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const getUser = query({
|
|
24
|
+
* input: z.object({ id: z.string() }),
|
|
25
|
+
* output: z.object({ id: z.string(), name: z.string() }),
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function query<
|
|
30
|
+
TInputSchema extends z.ZodTypeAny,
|
|
31
|
+
TOutputSchema extends z.ZodTypeAny,
|
|
32
|
+
>(config: {
|
|
33
|
+
input: TInputSchema;
|
|
34
|
+
output: TOutputSchema;
|
|
35
|
+
}): EndpointDefinition<TInputSchema, TOutputSchema> {
|
|
36
|
+
return {
|
|
37
|
+
type: "query",
|
|
38
|
+
input: config.input,
|
|
39
|
+
output: config.output,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Creates a mutation endpoint definition.
|
|
45
|
+
* Mutations are typically used for write operations that modify server state.
|
|
46
|
+
*
|
|
47
|
+
* @param config - Configuration object containing input and output Zod schemas
|
|
48
|
+
* @param config.input - Zod schema for validating the input parameters
|
|
49
|
+
* @param config.output - Zod schema for validating the output response
|
|
50
|
+
* @returns An endpoint definition with type 'mutation'
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const createUser = mutation({
|
|
55
|
+
* input: z.object({ name: z.string(), email: z.string().email() }),
|
|
56
|
+
* output: z.object({ id: z.string(), name: z.string() }),
|
|
57
|
+
* });
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export function mutation<
|
|
61
|
+
TInputSchema extends z.ZodTypeAny,
|
|
62
|
+
TOutputSchema extends z.ZodTypeAny,
|
|
63
|
+
>(config: {
|
|
64
|
+
input: TInputSchema;
|
|
65
|
+
output: TOutputSchema;
|
|
66
|
+
}): EndpointDefinition<TInputSchema, TOutputSchema> {
|
|
67
|
+
return {
|
|
68
|
+
type: "mutation",
|
|
69
|
+
input: config.input,
|
|
70
|
+
output: config.output,
|
|
71
|
+
};
|
|
72
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export {
|
|
2
|
+
createRouter,
|
|
3
|
+
createEndpoint,
|
|
4
|
+
getRouterMiddleware,
|
|
5
|
+
type RouterDefinition,
|
|
6
|
+
type EndpointGroup,
|
|
7
|
+
type Middleware,
|
|
8
|
+
type RouterConfig,
|
|
9
|
+
} from "./router";
|
|
10
|
+
export { query, mutation, type EndpointDefinition } from "./endpoint";
|
|
11
|
+
export type { InferInput, InferOutput } from "./types";
|
package/src/router.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { EndpointDefinition } from "./endpoint";
|
|
3
|
+
|
|
4
|
+
export interface EndpointGroup {
|
|
5
|
+
[endpointName: string]: EndpointDefinition<z.ZodTypeAny, z.ZodTypeAny>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface RouterDefinition {
|
|
9
|
+
[groupName: string]: EndpointGroup;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// WeakMap to store middleware separately from router definition
|
|
13
|
+
const routerMiddleware = new WeakMap<RouterDefinition, Middleware[]>();
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Get middleware associated with a router definition
|
|
17
|
+
* Used by parser to extract middleware metadata
|
|
18
|
+
*/
|
|
19
|
+
export function getRouterMiddleware(
|
|
20
|
+
router: RouterDefinition,
|
|
21
|
+
): Middleware[] | undefined {
|
|
22
|
+
return routerMiddleware.get(router);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Middleware function type for extending context
|
|
27
|
+
* Middleware receives the request and current context, and returns updated context
|
|
28
|
+
* Note: In generated code, middleware is implemented per-target (Go, TypeScript, etc.)
|
|
29
|
+
* This type is for documentation and type checking in the contract definition
|
|
30
|
+
*/
|
|
31
|
+
export type Middleware<TContext = Record<string, unknown>> = (
|
|
32
|
+
req: Request,
|
|
33
|
+
context: TContext,
|
|
34
|
+
) => Promise<TContext | Response>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Router configuration with optional middleware
|
|
38
|
+
*/
|
|
39
|
+
export interface RouterConfig {
|
|
40
|
+
middleware?: Middleware[];
|
|
41
|
+
[groupName: string]: EndpointGroup | Middleware[] | undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Type guard to check if a value is a RouterConfig
|
|
46
|
+
*/
|
|
47
|
+
function isRouterConfig(
|
|
48
|
+
value: RouterDefinition | RouterConfig,
|
|
49
|
+
): value is RouterConfig {
|
|
50
|
+
return (
|
|
51
|
+
value &&
|
|
52
|
+
typeof value === "object" &&
|
|
53
|
+
"middleware" in value &&
|
|
54
|
+
Array.isArray(value.middleware)
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Creates an endpoint group containing one or more endpoints.
|
|
60
|
+
*
|
|
61
|
+
* @param endpoints - An object mapping endpoint names to their definitions (query or mutation)
|
|
62
|
+
* @returns The endpoint group with preserved types
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const greeting = createEndpoint({
|
|
67
|
+
* greet: query({
|
|
68
|
+
* input: z.object({ name: z.string() }),
|
|
69
|
+
* output: z.object({ message: z.string() }),
|
|
70
|
+
* }),
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export function createEndpoint<T extends EndpointGroup>(endpoints: T): T {
|
|
75
|
+
return endpoints;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Creates a router with optional middleware support
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* // Without middleware
|
|
83
|
+
* const router = createRouter({
|
|
84
|
+
* greeting: createEndpoint({ ... })
|
|
85
|
+
* });
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* // With middleware
|
|
89
|
+
* const router = createRouter({
|
|
90
|
+
* middleware: [
|
|
91
|
+
* async (req, ctx) => ({ ...ctx, userId: extractUserId(req) })
|
|
92
|
+
* ],
|
|
93
|
+
* greeting: createEndpoint({ ... })
|
|
94
|
+
* });
|
|
95
|
+
*/
|
|
96
|
+
export function createRouter<T extends RouterConfig | RouterDefinition>(
|
|
97
|
+
config: T,
|
|
98
|
+
): T extends RouterConfig ? Omit<T, "middleware"> : T {
|
|
99
|
+
// If it's a RouterConfig with middleware, extract the endpoints
|
|
100
|
+
if (isRouterConfig(config)) {
|
|
101
|
+
const { middleware, ...endpoints } = config;
|
|
102
|
+
const routerDef = endpoints as RouterDefinition;
|
|
103
|
+
|
|
104
|
+
// Store middleware in WeakMap instead of property
|
|
105
|
+
if (middleware && middleware.length > 0) {
|
|
106
|
+
routerMiddleware.set(routerDef, middleware);
|
|
107
|
+
}
|
|
108
|
+
return routerDef as T extends RouterConfig ? Omit<T, "middleware"> : T;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Otherwise, it's a plain RouterDefinition
|
|
112
|
+
return config as T extends RouterConfig ? Omit<T, "middleware"> : T;
|
|
113
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Infer input type from an endpoint definition
|
|
5
|
+
* @example
|
|
6
|
+
* type CreateInput = InferInput<typeof router.todo.create>;
|
|
7
|
+
*/
|
|
8
|
+
export type InferInput<T extends { input: z.ZodTypeAny }> = z.infer<T["input"]>;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Infer output type from an endpoint definition
|
|
12
|
+
* @example
|
|
13
|
+
* type CreateOutput = InferOutput<typeof router.todo.create>;
|
|
14
|
+
*/
|
|
15
|
+
export type InferOutput<T extends { output: z.ZodTypeAny }> = z.infer<
|
|
16
|
+
T["output"]
|
|
17
|
+
>;
|