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 CHANGED
@@ -1,9 +1,9 @@
1
- import { ZodType, z } from 'zod';
1
+ import { z } from 'zod';
2
2
 
3
- interface EndpointDefinition {
4
- type: 'query' | 'mutation';
5
- input: ZodType;
6
- output: ZodType;
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: ZodType;
27
- output: ZodType;
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: ZodType;
48
- output: ZodType;
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, 'middleware'> : 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: ZodType;
120
- }> = z.infer<T['input']>;
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: ZodType;
128
- }> = z.infer<T['output']>;
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.1",
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"
@@ -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
+ >;