@ir-kit/openapi-ts-orpc 0.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.
Files changed (84) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +234 -0
  3. package/dist/config.d.ts +7 -0
  4. package/dist/config.d.ts.map +1 -0
  5. package/dist/config.js +101 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/generators/client.d.ts +7 -0
  8. package/dist/generators/client.d.ts.map +1 -0
  9. package/dist/generators/client.js +113 -0
  10. package/dist/generators/client.js.map +1 -0
  11. package/dist/generators/contract-validator.d.ts +21 -0
  12. package/dist/generators/contract-validator.d.ts.map +1 -0
  13. package/dist/generators/contract-validator.js +250 -0
  14. package/dist/generators/contract-validator.js.map +1 -0
  15. package/dist/generators/contract.d.ts +9 -0
  16. package/dist/generators/contract.d.ts.map +1 -0
  17. package/dist/generators/contract.js +159 -0
  18. package/dist/generators/contract.js.map +1 -0
  19. package/dist/generators/faker.d.ts +15 -0
  20. package/dist/generators/faker.d.ts.map +1 -0
  21. package/dist/generators/faker.js +61 -0
  22. package/dist/generators/faker.js.map +1 -0
  23. package/dist/generators/handlers/ast.d.ts +65 -0
  24. package/dist/generators/handlers/ast.d.ts.map +1 -0
  25. package/dist/generators/handlers/ast.js +262 -0
  26. package/dist/generators/handlers/ast.js.map +1 -0
  27. package/dist/generators/handlers/index.d.ts +37 -0
  28. package/dist/generators/handlers/index.d.ts.map +1 -0
  29. package/dist/generators/handlers/index.js +48 -0
  30. package/dist/generators/handlers/index.js.map +1 -0
  31. package/dist/generators/index.d.ts +14 -0
  32. package/dist/generators/index.d.ts.map +1 -0
  33. package/dist/generators/index.js +13 -0
  34. package/dist/generators/index.js.map +1 -0
  35. package/dist/generators/router.d.ts +7 -0
  36. package/dist/generators/router.d.ts.map +1 -0
  37. package/dist/generators/router.js +21 -0
  38. package/dist/generators/router.js.map +1 -0
  39. package/dist/generators/server.d.ts +7 -0
  40. package/dist/generators/server.d.ts.map +1 -0
  41. package/dist/generators/server.js +22 -0
  42. package/dist/generators/server.js.map +1 -0
  43. package/dist/generators/tanstack.d.ts +7 -0
  44. package/dist/generators/tanstack.d.ts.map +1 -0
  45. package/dist/generators/tanstack.js +27 -0
  46. package/dist/generators/tanstack.js.map +1 -0
  47. package/dist/generators/types.d.ts +74 -0
  48. package/dist/generators/types.d.ts.map +1 -0
  49. package/dist/generators/types.js +2 -0
  50. package/dist/generators/types.js.map +1 -0
  51. package/dist/index.d.ts +4 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +3 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/plugin.d.ts +7 -0
  56. package/dist/plugin.d.ts.map +1 -0
  57. package/dist/plugin.js +124 -0
  58. package/dist/plugin.js.map +1 -0
  59. package/dist/router-organizer.d.ts +13 -0
  60. package/dist/router-organizer.d.ts.map +1 -0
  61. package/dist/router-organizer.js +42 -0
  62. package/dist/router-organizer.js.map +1 -0
  63. package/dist/schema/extractor.d.ts +16 -0
  64. package/dist/schema/extractor.d.ts.map +1 -0
  65. package/dist/schema/extractor.js +133 -0
  66. package/dist/schema/extractor.js.map +1 -0
  67. package/dist/schema/index.d.ts +2 -0
  68. package/dist/schema/index.d.ts.map +1 -0
  69. package/dist/schema/index.js +2 -0
  70. package/dist/schema/index.js.map +1 -0
  71. package/dist/symbols/external.d.ts +8 -0
  72. package/dist/symbols/external.d.ts.map +1 -0
  73. package/dist/symbols/external.js +67 -0
  74. package/dist/symbols/external.js.map +1 -0
  75. package/dist/types.d.ts +238 -0
  76. package/dist/types.d.ts.map +1 -0
  77. package/dist/types.js +2 -0
  78. package/dist/types.js.map +1 -0
  79. package/dist/utils.d.ts +4 -0
  80. package/dist/utils.d.ts.map +1 -0
  81. package/dist/utils.js +13 -0
  82. package/dist/utils.js.map +1 -0
  83. package/docs/typia.md +152 -0
  84. package/package.json +101 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ahmed Rowaihi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,234 @@
1
+ # @ir-kit/openapi-ts-orpc
2
+
3
+ Generates type-safe [oRPC](https://orpc.unnoq.com/) contracts, routers, server skeletons, clients, and mock factories from OpenAPI specifications. Plugin for [@hey-api/openapi-ts](https://heyapi.dev/).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add -d @ir-kit/openapi-ts-orpc @hey-api/openapi-ts
9
+ bun add @orpc/contract @orpc/server @orpc/client zod
10
+ ```
11
+
12
+ ## What it generates
13
+
14
+ | File | Description | Required |
15
+ | ----------------------- | -------------------------------------------------------- | --------------------- |
16
+ | `contract.gen.ts` | Type-safe oRPC contracts with input/output schemas | Always |
17
+ | `router.gen.ts` | Organized router structure | Always |
18
+ | `server.gen.ts` | `os = implement(router)` helper | Optional |
19
+ | `client.gen.ts` | Client factory functions (RPC, WebSocket, OpenAPI, etc.) | Optional |
20
+ | `tanstack.gen.ts` | TanStack Query utilities | Optional |
21
+ | `faker.gen.ts` | Mock data factory functions per tag | Optional (faker mode) |
22
+ | `src/handlers/<tag>.ts` | Handler files with three modes | Optional |
23
+
24
+ ---
25
+
26
+ ## Basic Usage
27
+
28
+ ```typescript
29
+ import { defineConfig } from "@hey-api/openapi-ts";
30
+ import { defineConfig as defineORPCConfig } from "@ir-kit/openapi-ts-orpc";
31
+
32
+ export default defineConfig({
33
+ input: "openapi.json",
34
+ output: { path: "./src/generated" },
35
+ plugins: [
36
+ "@hey-api/typescript",
37
+ "zod",
38
+ defineORPCConfig(), // contracts + router only (default)
39
+ ],
40
+ });
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Server (Backend)
46
+
47
+ ```typescript
48
+ defineORPCConfig({
49
+ server: {
50
+ implementation: true,
51
+ handlers: {
52
+ dir: "src/handlers",
53
+ importAlias: "#/",
54
+ mode: "stub", // 'stub' | 'faker' | 'proxy'
55
+ },
56
+ },
57
+ });
58
+ ```
59
+
60
+ ### Handler modes
61
+
62
+ **`stub`** (default) — throws `ORPCError('NOT_IMPLEMENTED')`:
63
+
64
+ ```typescript
65
+ getUser: os.users.getUser.handler(async () => {
66
+ throw new ORPCError("NOT_IMPLEMENTED");
67
+ }),
68
+ ```
69
+
70
+ **`faker`** — returns mock data from generated `faker.gen.ts` factories:
71
+
72
+ ```typescript
73
+ getUser: os.users.getUser.handler(async () => mockGetUser()),
74
+ ```
75
+
76
+ Requires `@faker-js/faker` as a dependency. Generates type-safe factories with:
77
+
78
+ - Field name heuristics (email, phone, url, etc.)
79
+ - Enum support via `faker.helpers.arrayElement()`
80
+ - Nested objects and arrays from schema
81
+ - Date `.toISOString()` chaining
82
+
83
+ **`proxy`** — forwards requests through the generated OpenAPI client:
84
+
85
+ ```typescript
86
+ getUser: os.users.getUser.handler(async ({ input }) => apiClient.users.getUser(input)),
87
+ ```
88
+
89
+ Configure the client import:
90
+
91
+ ```typescript
92
+ handlers: {
93
+ mode: 'proxy',
94
+ proxy: { clientImport: { name: 'apiClient', from: '#/lib/client' } },
95
+ }
96
+ ```
97
+
98
+ ### Handler file management
99
+
100
+ - **New tags** create new handler files
101
+ - **Existing files** only get missing procedures appended (never overwritten)
102
+ - **`override: true`** rewrites files completely on each run
103
+
104
+ ---
105
+
106
+ ## Client (Frontend)
107
+
108
+ ```typescript
109
+ defineORPCConfig({
110
+ client: {
111
+ rpc: true, // HTTP client (native oRPC RPC protocol)
112
+ openapi: true, // REST client (OpenAPI protocol)
113
+ tanstack: true, // TanStack Query utilities
114
+ },
115
+ });
116
+ ```
117
+
118
+ | Option | Description |
119
+ | ------------- | ----------------------------------------- |
120
+ | `rpc` | HTTP/Fetch client (native RPC protocol) |
121
+ | `websocket` | WebSocket client |
122
+ | `messageport` | MessagePort client (Web Workers, iframes) |
123
+ | `openapi` | REST client (OpenAPI protocol) |
124
+ | `tanstack` | TanStack Query utilities |
125
+
126
+ ---
127
+
128
+ ## Full Configuration Reference
129
+
130
+ ```typescript
131
+ defineORPCConfig({
132
+ // Server-side generation
133
+ server: {
134
+ implementation: false,
135
+ handlers: {
136
+ dir: "src/handlers",
137
+ importAlias: "#/",
138
+ implementer: { name: "publicOs", from: "#/procedures" },
139
+ mode: "stub", // 'stub' | 'faker' | 'proxy'
140
+ override: false, // rewrite files on each run
141
+ proxy: { clientImport: { name: "apiClient", from: "#/lib/client" } },
142
+ },
143
+ },
144
+
145
+ // Client-side generation
146
+ client: {
147
+ rpc: false,
148
+ websocket: false,
149
+ messageport: false,
150
+ openapi: false,
151
+ tanstack: false,
152
+ },
153
+
154
+ // Input structure mode
155
+ mode: "compact", // 'compact' | 'detailed'
156
+
157
+ // Router grouping
158
+ group: "tags", // 'tags' | 'paths' | 'flat' | 'operationId'
159
+
160
+ // JSDoc comments on contracts
161
+ comments: true,
162
+
163
+ // Naming rules (uses hey-api's applyNaming)
164
+ naming: {
165
+ contract: { casing: "PascalCase" }, // contract constant names
166
+ operation: { casing: "camelCase" }, // router/procedure keys
167
+ },
168
+
169
+ // Validator configuration
170
+ validator: "zod", // string | false | { input: string | false, output: string | false }
171
+ });
172
+ ```
173
+
174
+ ### `mode` — Input structure
175
+
176
+ | Mode | Description |
177
+ | --- | --- |
178
+ | `compact` (default) | Flat merged input — path + body for mutations, path + query for reads |
179
+ | `detailed` | Structured `{ params, query, body, headers }` input |
180
+
181
+ > **Note:** Standard validators (zod, valibot, arktype) always use detailed mode regardless of this setting. Compact mode is only supported with Typia. This is because hey-api's `createRequestSchema` API always returns a structured object.
182
+
183
+ ### `group` — Router grouping
184
+
185
+ | Mode | Description | Example |
186
+ | ---------------- | --------------------------- | ---------------------------- |
187
+ | `tags` (default) | Group by OpenAPI tag | `router.users.getById()` |
188
+ | `paths` | Group by URL structure | `router.api.users.getById()` |
189
+ | `flat` | No grouping | `router.getUserById()` |
190
+ | `operationId` | Group by operationId prefix | `router.auth.login()` |
191
+
192
+ ### `validator` — Validation configuration
193
+
194
+ Works with any hey-api validator plugin (zod, valibot, arktype):
195
+
196
+ ```typescript
197
+ // Single validator for both input and output (default)
198
+ validator: 'zod'
199
+
200
+ // Separate input/output validators
201
+ validator: { input: 'zod', output: false }
202
+
203
+ // Disable validation entirely
204
+ validator: false
205
+ ```
206
+
207
+ ### `naming` — Name customization
208
+
209
+ Uses `applyNaming` from `@hey-api/shared`:
210
+
211
+ ```typescript
212
+ naming: {
213
+ contract: { casing: 'PascalCase' }, // GetUserContract
214
+ operation: { casing: 'camelCase' }, // getUser
215
+ }
216
+ ```
217
+
218
+ Supports `'camelCase'`, `'PascalCase'`, `'snake_case'`, `'SCREAMING_SNAKE_CASE'`, `'preserve'`, or a custom transform function.
219
+
220
+ ---
221
+
222
+ ## Requirements
223
+
224
+ - `@hey-api/openapi-ts` >= 0.95.0
225
+ - `@hey-api/typescript` plugin (auto-included as dependency)
226
+ - A validator plugin (`zod`, `valibot`, `arktype`) configured in your plugins
227
+
228
+ ---
229
+
230
+ ## Typia Integration
231
+
232
+ Want compile-time validators instead of Zod? See [docs/typia.md](docs/typia.md).
233
+
234
+ Set `validator: { input: 'typia', output: 'typia' }` to use Typia's Standard Schema validators.
@@ -0,0 +1,7 @@
1
+ import type { ORPCPlugin, UserConfig } from "./types";
2
+ export declare const resolveConfig: (userConfig: Partial<UserConfig>) => ORPCPlugin["Config"]["config"];
3
+ export declare const defaultConfig: ORPCPlugin["Config"];
4
+ export declare const defineConfig: (userConfig?: Omit<UserConfig, "name"> | undefined) => Omit<import("@hey-api/shared").Plugin.Config<import("@hey-api/shared").Plugin.Types<UserConfig, import("./types").Config, never>>, "name"> & {
5
+ name: any;
6
+ };
7
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAiDtD,eAAO,MAAM,aAAa,GACxB,YAAY,OAAO,CAAC,UAAU,CAAC,KAC9B,UAAU,CAAC,QAAQ,CAAC,CAAC,QAAQ,CA2B/B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,UAAU,CAAC,QAAQ,CAkC9C,CAAC;AAEF,eAAO,MAAM,YAAY;;CAAoC,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,101 @@
1
+ import { definePluginConfig, resolveNaming } from "@hey-api/shared";
2
+ import { handler } from "./plugin";
3
+ function resolveHandlers(server) {
4
+ const handlers = server?.handlers;
5
+ const implementation = server?.implementation ?? false;
6
+ if (handlers === false)
7
+ return false;
8
+ if (handlers === true || (handlers === undefined && implementation)) {
9
+ return { dir: "src/handlers", mode: "stub", override: false };
10
+ }
11
+ if (typeof handlers === "object") {
12
+ return {
13
+ dir: handlers.dir ?? "src/handlers",
14
+ importAlias: handlers.importAlias,
15
+ implementer: handlers.implementer,
16
+ mode: handlers.mode ?? "stub",
17
+ override: handlers.override ?? false,
18
+ faker: handlers.faker,
19
+ proxy: handlers.proxy,
20
+ };
21
+ }
22
+ return false;
23
+ }
24
+ function resolveValidator(validator) {
25
+ if (validator === false)
26
+ return { input: false, output: false };
27
+ if (typeof validator === "string")
28
+ return { input: validator, output: validator };
29
+ if (typeof validator === "object") {
30
+ return {
31
+ input: validator.input ?? "zod",
32
+ output: validator.output ?? "zod",
33
+ };
34
+ }
35
+ return { input: "zod", output: "zod" };
36
+ }
37
+ export const resolveConfig = (userConfig) => {
38
+ return {
39
+ server: {
40
+ implementation: userConfig.server?.implementation ?? false,
41
+ handlers: resolveHandlers(userConfig.server),
42
+ },
43
+ client: {
44
+ rpc: userConfig.client?.rpc ?? false,
45
+ websocket: userConfig.client?.websocket ?? false,
46
+ messageport: userConfig.client?.messageport ?? false,
47
+ openapi: userConfig.client?.openapi ?? false,
48
+ tanstack: userConfig.client?.tanstack ?? false,
49
+ },
50
+ comments: userConfig.comments ?? true,
51
+ group: userConfig.group ?? "tags",
52
+ includeInEntry: true,
53
+ mode: userConfig.mode ?? "compact",
54
+ naming: {
55
+ contract: resolveNaming(userConfig.naming?.contract) ?? {
56
+ casing: "PascalCase",
57
+ },
58
+ operation: resolveNaming(userConfig.naming?.operation) ?? {
59
+ casing: "camelCase",
60
+ },
61
+ },
62
+ validator: resolveValidator(userConfig.validator),
63
+ };
64
+ };
65
+ export const defaultConfig = {
66
+ config: {
67
+ server: { implementation: false, handlers: false },
68
+ client: {
69
+ rpc: false,
70
+ websocket: false,
71
+ messageport: false,
72
+ openapi: false,
73
+ tanstack: false,
74
+ },
75
+ comments: true,
76
+ group: "tags",
77
+ includeInEntry: true,
78
+ mode: "compact",
79
+ naming: {
80
+ contract: { casing: "PascalCase" },
81
+ operation: { casing: "camelCase" },
82
+ },
83
+ validator: { input: "zod", output: "zod" },
84
+ },
85
+ dependencies: ["@hey-api/typescript"],
86
+ handler,
87
+ name: "@ir-kit/orpc",
88
+ resolveConfig: (plugin) => {
89
+ plugin.config.server ??= { implementation: false, handlers: false };
90
+ plugin.config.server.handlers = resolveHandlers(plugin.config.server);
91
+ plugin.config.validator = resolveValidator(plugin.config.validator);
92
+ const { input, output } = plugin.config.validator;
93
+ if (input)
94
+ plugin.dependencies?.add(input);
95
+ if (output && output !== input)
96
+ plugin.dependencies?.add(output);
97
+ },
98
+ tags: ["transformer"],
99
+ };
100
+ export const defineConfig = definePluginConfig(defaultConfig);
101
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ClientGeneratorInput } from "./types";
2
+ /**
3
+ * Generates client creation functions for oRPC.
4
+ * Creates type-safe client factory functions based on user configuration.
5
+ */
6
+ export declare const generateClients: ({ clientTypes, context, }: ClientGeneratorInput) => void;
7
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/generators/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAoB,MAAM,SAAS,CAAC;AA+BtE;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,2BAG7B,oBAAoB,KAAG,IAkDzB,CAAC"}
@@ -0,0 +1,113 @@
1
+ import { $ } from "@hey-api/openapi-ts";
2
+ /**
3
+ * Client type configurations.
4
+ * Maps client types to their external symbols and config.
5
+ */
6
+ const CLIENT_TYPE_CONFIGS = {
7
+ openapi: {
8
+ configTypeName: "OpenApiLinkClientConfig",
9
+ functionName: "createOpenApiClient",
10
+ linkSymbolResource: "@orpc/openapi-client/fetch.OpenAPILink",
11
+ needsRouter: true, // OpenAPILink requires router as first arg
12
+ },
13
+ rpc: {
14
+ configTypeName: "RpcLinkClientConfig",
15
+ functionName: "createRpcLinkClient",
16
+ linkSymbolResource: "@orpc/client/fetch.RPCLink",
17
+ },
18
+ messageport: {
19
+ configTypeName: "RpcMessagePortClientConfig",
20
+ functionName: "createRpcMessagePortClient",
21
+ linkSymbolResource: "@orpc/client/message-port.RPCLink",
22
+ },
23
+ websocket: {
24
+ configTypeName: "RpcWebSocketClientConfig",
25
+ functionName: "createRpcWebSocketClient",
26
+ linkSymbolResource: "@orpc/client/websocket.RPCLink",
27
+ },
28
+ tanstack: null, // Handled by tanstack generator
29
+ };
30
+ /**
31
+ * Generates client creation functions for oRPC.
32
+ * Creates type-safe client factory functions based on user configuration.
33
+ */
34
+ export const generateClients = ({ clientTypes, context, }) => {
35
+ const { clientFile, plugin, routerSymbol } = context;
36
+ const contractRouterClientSymbol = plugin.external("@orpc/contract.ContractRouterClient");
37
+ const createORPCClientSymbol = plugin.external("@orpc/client.createORPCClient");
38
+ // Filter out tanstack and get configs
39
+ const clientConfigs = clientTypes
40
+ .filter((type) => type !== "tanstack")
41
+ .map((type) => CLIENT_TYPE_CONFIGS[type])
42
+ .filter((config) => config !== null);
43
+ // Generate each client
44
+ for (const config of clientConfigs) {
45
+ generateClient(plugin, routerSymbol, clientFile, contractRouterClientSymbol, createORPCClientSymbol, config);
46
+ }
47
+ // Export shared Client type if any clients were generated
48
+ if (clientConfigs.length > 0) {
49
+ const clientTypeSymbol = plugin.symbol("Client", {
50
+ getFilePath: () => clientFile,
51
+ meta: {
52
+ category: "client",
53
+ resource: "client",
54
+ tool: "orpc",
55
+ },
56
+ });
57
+ const clientTypeAlias = $.type
58
+ .alias(clientTypeSymbol)
59
+ .export()
60
+ .type($.type
61
+ .expr(contractRouterClientSymbol)
62
+ .generic($.type.query($(routerSymbol))));
63
+ plugin.node(clientTypeAlias);
64
+ }
65
+ };
66
+ /**
67
+ * Helper function to generate a single client creation function.
68
+ */
69
+ function generateClient(plugin, routerSymbol, clientFile, contractRouterClientSymbol, createORPCClientSymbol, config) {
70
+ const { configTypeName, functionName, linkSymbolResource, needsRouter = false, } = config;
71
+ const linkSymbol = plugin.external(linkSymbolResource);
72
+ // ClientConfig type: inferred from Link constructor
73
+ const clientConfigSymbol = plugin.symbol(configTypeName, {
74
+ getFilePath: () => clientFile,
75
+ meta: {
76
+ category: "client",
77
+ resource: configTypeName,
78
+ tool: "orpc",
79
+ },
80
+ });
81
+ // For OpenAPILink, config is the second parameter
82
+ const configParamIndex = needsRouter ? 1 : 0;
83
+ const clientConfigType = $.type.idx($.type.expr("ConstructorParameters").generic($.type.query($(linkSymbol))), configParamIndex);
84
+ const clientConfigStatement = $.type
85
+ .alias(clientConfigSymbol)
86
+ .export()
87
+ .type(clientConfigType);
88
+ plugin.node(clientConfigStatement);
89
+ // createClient function
90
+ const createClientSymbol = plugin.symbol(functionName, {
91
+ getFilePath: () => clientFile,
92
+ meta: {
93
+ category: "client",
94
+ resource: functionName,
95
+ tool: "orpc",
96
+ },
97
+ });
98
+ const createClientFunc = $.const(createClientSymbol)
99
+ .export()
100
+ .assign($.func()
101
+ .param("config", (p) => p.type($.type.expr(clientConfigSymbol)))
102
+ .returns($.type
103
+ .expr(contractRouterClientSymbol)
104
+ .generic($.type.query($(routerSymbol))))
105
+ .do(
106
+ // OpenAPILink needs router as first arg: new OpenAPILink(router, config)
107
+ // RPCLink only needs config: new RPCLink(config)
108
+ needsRouter
109
+ ? $.const("link").assign($.new(linkSymbol, $(routerSymbol), $.id("config")))
110
+ : $.const("link").assign($.new(linkSymbol, $.id("config"))), $.return($.call(createORPCClientSymbol, $.id("link")))));
111
+ plugin.node(createClientFunc);
112
+ }
113
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/generators/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAC;AAIxC;;;GAGG;AACH,MAAM,mBAAmB,GAAgD;IACvE,OAAO,EAAE;QACP,cAAc,EAAE,yBAAyB;QACzC,YAAY,EAAE,qBAAqB;QACnC,kBAAkB,EAAE,wCAAwC;QAC5D,WAAW,EAAE,IAAI,EAAE,2CAA2C;KAC/D;IACD,GAAG,EAAE;QACH,cAAc,EAAE,qBAAqB;QACrC,YAAY,EAAE,qBAAqB;QACnC,kBAAkB,EAAE,4BAA4B;KACjD;IACD,WAAW,EAAE;QACX,cAAc,EAAE,4BAA4B;QAC5C,YAAY,EAAE,4BAA4B;QAC1C,kBAAkB,EAAE,mCAAmC;KACxD;IACD,SAAS,EAAE;QACT,cAAc,EAAE,0BAA0B;QAC1C,YAAY,EAAE,0BAA0B;QACxC,kBAAkB,EAAE,gCAAgC;KACrD;IACD,QAAQ,EAAE,IAAI,EAAE,gCAAgC;CACjD,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAC9B,WAAW,EACX,OAAO,GACc,EAAQ,EAAE;IAC/B,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAErD,MAAM,0BAA0B,GAAG,MAAM,CAAC,QAAQ,CAChD,qCAAqC,CACtC,CAAC;IACF,MAAM,sBAAsB,GAAG,MAAM,CAAC,QAAQ,CAC5C,+BAA+B,CAChC,CAAC;IAEF,sCAAsC;IACtC,MAAM,aAAa,GAAG,WAAW;SAC9B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,UAAU,CAAC;SACrC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;SACxC,MAAM,CAAC,CAAC,MAAM,EAA8B,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;IAEnE,uBAAuB;IACvB,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;QACnC,cAAc,CACZ,MAAM,EACN,YAAY,EACZ,UAAU,EACV,0BAA0B,EAC1B,sBAAsB,EACtB,MAAM,CACP,CAAC;IACJ,CAAC;IAED,0DAA0D;IAC1D,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE;YAC/C,WAAW,EAAE,GAAG,EAAE,CAAC,UAAU;YAC7B,IAAI,EAAE;gBACJ,QAAQ,EAAE,QAAQ;gBAClB,QAAQ,EAAE,QAAQ;gBAClB,IAAI,EAAE,MAAM;aACb;SACF,CAAC,CAAC;QAEH,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI;aAC3B,KAAK,CAAC,gBAAgB,CAAC;aACvB,MAAM,EAAE;aACR,IAAI,CACH,CAAC,CAAC,IAAI;aACH,IAAI,CAAC,0BAA0B,CAAC;aAChC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAC1C,CAAC;QAEJ,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,SAAS,cAAc,CACrB,MAAW,EACX,YAAiB,EACjB,UAAkB,EAClB,0BAA+B,EAC/B,sBAA2B,EAC3B,MAAwB;IAExB,MAAM,EACJ,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,WAAW,GAAG,KAAK,GACpB,GAAG,MAAM,CAAC;IAEX,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAEvD,oDAAoD;IACpD,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE;QACvD,WAAW,EAAE,GAAG,EAAE,CAAC,UAAU;QAC7B,IAAI,EAAE;YACJ,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,cAAc;YACxB,IAAI,EAAE,MAAM;SACb;KACF,CAAC,CAAC;IAEH,kDAAkD;IAClD,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CACjC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EACzE,gBAAgB,CACjB,CAAC;IAEF,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI;SACjC,KAAK,CAAC,kBAAkB,CAAC;SACzB,MAAM,EAAE;SACR,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAE1B,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAEnC,wBAAwB;IACxB,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE;QACrD,WAAW,EAAE,GAAG,EAAE,CAAC,UAAU;QAC7B,IAAI,EAAE;YACJ,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,MAAM;SACb;KACF,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;SACjD,MAAM,EAAE;SACR,MAAM,CACL,CAAC,CAAC,IAAI,EAAE;SACL,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC;SAC/D,OAAO,CACN,CAAC,CAAC,IAAI;SACH,IAAI,CAAC,0BAA0B,CAAC;SAChC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAC1C;SACA,EAAE;IACD,yEAAyE;IACzE,iDAAiD;IACjD,WAAW;QACT,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CACpB,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CACnD;QACH,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAC7D,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CACvD,CACJ,CAAC;IAEJ,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Standard validator API contract builders.
3
+ * Works with any hey-api validator plugin (zod, valibot, arktype)
4
+ * that exposes the `createRequestSchema` API.
5
+ */
6
+ import type { IR } from "@hey-api/shared";
7
+ import type { ORPCPlugin } from "../types";
8
+ type Plugin = ORPCPlugin["Instance"];
9
+ type InputResult = {
10
+ expr: any;
11
+ useDetailedMode: boolean;
12
+ };
13
+ export type BodyKind = "json" | "raw-file" | "multipart" | "other";
14
+ /** Classify the body media-type so callers don't pass loose booleans. */
15
+ export declare function classifyBody(mediaType: string | undefined): BodyKind;
16
+ /** Build a validator-backed `.input()` expression for a contract. */
17
+ export declare function buildValidatorInput(plugin: Plugin, operation: IR.OperationObject, bodyKind: BodyKind): InputResult | null;
18
+ export declare function buildValidatorOutput(plugin: Plugin, operationId: string): any | null;
19
+ export declare function buildValidatorErrorMap(plugin: Plugin, operation: IR.OperationObject): any | null;
20
+ export {};
21
+ //# sourceMappingURL=contract-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-validator.d.ts","sourceRoot":"","sources":["../../src/generators/contract-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAM3C,KAAK,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;AACrC,KAAK,WAAW,GAAG;IAAE,IAAI,EAAE,GAAG,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,CAAC;AAE3D,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;AAMnE,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAWpE;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,EAAE,CAAC,eAAe,EAC7B,QAAQ,EAAE,QAAQ,GACjB,WAAW,GAAG,IAAI,CAoCpB;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,GAAG,GAAG,IAAI,CAeZ;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,EAAE,CAAC,eAAe,GAC5B,GAAG,GAAG,IAAI,CAOZ"}