hono-takibi 0.9.78 → 0.9.80

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.
@@ -18,240 +18,49 @@
18
18
  * @link https://github.com/honojs/hono/blob/main/src/client/types.ts#L46-L76
19
19
  */
20
20
  import path from 'node:path';
21
- import { core } from '../../helper/index.js';
21
+ import { buildInferRequestType, buildOperationDocs, core, createOperationDeps, formatPath, HTTP_METHODS, isOpenAPIPaths, isOperationLike, operationHasArgs, parsePathItem, resolveSplitOutDir, } from '../../helper/index.js';
22
22
  import { isRecord, methodPath } from '../../utils/index.js';
23
- /* ─────────────────────────────── Guards ─────────────────────────────── */
24
- const isOpenAPIPaths = (v) => {
25
- if (!isRecord(v))
26
- return false;
27
- for (const k in v) {
28
- if (!isRecord(v[k]))
29
- return false;
30
- }
31
- return true;
32
- };
33
- /* ─────────────────────────────── Formatters ─────────────────────────────── */
34
- const esc = (s) => s.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
35
- /** Check if a string is a valid JavaScript identifier */
36
- const isValidIdent = (s) => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(s);
37
- /**
38
- * Format path for Hono RPC access (both type and runtime).
39
- * Hono hc client uses PathToChain which splits paths by '/'.
40
- *
41
- * Rules:
42
- * - '/' -> '.index'
43
- * - Valid identifiers use dot notation: '/users' -> '.users'
44
- * - Invalid identifiers use bracket notation: '/:id' -> "[':id']"
45
- * - Path params converted: '/files/{fileId}' -> ".files[':fileId']"
46
- *
47
- * For InferRequestType, when bracket notation exists in the path,
48
- * we need to wrap `typeof client.<prefix>` in parentheses and use
49
- * all bracket notation after:
50
- * - `/users/{id}` -> type: `(typeof client.users)[':id']['$get']`
51
- * - `/users/{id}/avatar` -> type: `(typeof client.users)[':id']['avatar']['$post']`
52
- */
53
- const formatPath = (p) => {
54
- if (p === '/') {
55
- return {
56
- runtimePath: '.index',
57
- typeofPrefix: '.index',
58
- bracketSuffix: '',
59
- hasBracket: false,
60
- };
61
- }
62
- const segs = p.replace(/^\/+/, '').split('/').filter(Boolean);
63
- // Convert {param} to :param (handles both full segments like {id} and partial like {Sid}.json)
64
- const honoSegs = segs.map((seg) => seg.replace(/\{([^}]+)\}/g, ':$1'));
65
- // Find the first segment that needs bracket notation
66
- const firstBracketIdx = honoSegs.findIndex((seg) => !isValidIdent(seg));
67
- const hasBracket = firstBracketIdx !== -1;
68
- // Runtime path: mixed notation (current behavior)
69
- const runtimeParts = honoSegs.map((seg) => (isValidIdent(seg) ? `.${seg}` : `['${esc(seg)}']`));
70
- const runtimePath = runtimeParts.join('');
71
- // For type expression: split at first bracket
72
- const typeofPrefix = hasBracket
73
- ? honoSegs
74
- .slice(0, firstBracketIdx)
75
- .map((seg) => `.${seg}`)
76
- .join('')
77
- : runtimePath;
78
- const bracketSuffix = hasBracket
79
- ? honoSegs
80
- .slice(firstBracketIdx)
81
- .map((seg) => `['${esc(seg)}']`)
82
- .join('')
83
- : '';
84
- return { runtimePath, typeofPrefix, bracketSuffix, hasBracket };
85
- };
86
- const isRefObject = (v) => isRecord(v) && typeof v.$ref === 'string';
87
- const isParameterObject = (v) => {
88
- if (!isRecord(v))
89
- return false;
90
- if (typeof v.name !== 'string')
91
- return false;
92
- const pos = v.in;
93
- return pos === 'path' || pos === 'query' || pos === 'header' || pos === 'cookie';
94
- };
95
- const refParamName = (refLike) => {
96
- const ref = typeof refLike === 'string' ? refLike : isRefObject(refLike) ? refLike.$ref : undefined;
97
- const m = ref?.match(/^#\/components\/parameters\/(.+)$/);
98
- return m ? m[1] : undefined;
99
- };
100
- const createResolveParameter = (componentsParameters) => (p) => {
101
- if (isParameterObject(p))
102
- return p;
103
- const name = refParamName(p);
104
- const cand = name ? componentsParameters[name] : undefined;
105
- return isParameterObject(cand) ? cand : undefined;
106
- };
107
- const createToParameterLikes = (resolveParam) => (arr) => Array.isArray(arr) ? arr.map((x) => resolveParam(x)).filter((param) => param !== undefined) : [];
108
- const isOperationLike = (v) => isRecord(v) && 'responses' in v;
109
- const HTTP_METHODS = [
110
- 'get',
111
- 'put',
112
- 'post',
113
- 'delete',
114
- 'options',
115
- 'head',
116
- 'patch',
117
- 'trace',
118
- ];
119
- const hasSchemaProp = (v) => isRecord(v) && 'schema' in v;
120
- /** Extract requestBody name from $ref like "#/components/requestBodies/CreateProduct" */
121
- const refRequestBodyName = (refLike) => {
122
- const ref = typeof refLike === 'string' ? refLike : isRefObject(refLike) ? refLike.$ref : undefined;
123
- const m = ref?.match(/^#\/components\/requestBodies\/(.+)$/);
124
- return m ? m[1] : undefined;
125
- };
126
- /**
127
- * Collect all body infos from content to handle multiple content-types.
128
- * Groups by body key ('form' or 'json') with union types.
129
- */
130
- const pickAllBodyInfoFromContent = (content) => {
131
- if (!isRecord(content))
132
- return undefined;
133
- const formContentTypes = ['multipart/form-data', 'application/x-www-form-urlencoded'];
134
- const isFormContentType = (ct) => formContentTypes.includes(ct.split(';')[0].trim());
135
- const validEntries = Object.entries(content).filter(([_, mediaObj]) => isRecord(mediaObj) && hasSchemaProp(mediaObj) && isRecord(mediaObj.schema));
136
- const formInfos = validEntries
137
- .filter(([ct]) => isFormContentType(ct))
138
- .map(([ct]) => ({ contentType: ct }));
139
- const jsonInfos = validEntries
140
- .filter(([ct]) => !isFormContentType(ct))
141
- .map(([ct]) => ({ contentType: ct }));
142
- if (formInfos.length === 0 && jsonInfos.length === 0)
143
- return undefined;
144
- return { form: formInfos, json: jsonInfos };
145
- };
146
- const createPickAllBodyInfo = (componentsRequestBodies) => (op) => {
147
- const rb = op.requestBody;
148
- if (!isRecord(rb))
149
- return undefined;
150
- // Handle $ref to components/requestBodies
151
- const refName = refRequestBodyName(rb);
152
- if (refName) {
153
- const resolved = componentsRequestBodies[refName];
154
- if (isRecord(resolved) && isRecord(resolved.content)) {
155
- return pickAllBodyInfoFromContent(resolved.content);
156
- }
157
- // If $ref exists but can't resolve content, still consider it has a body
158
- if (resolved !== undefined)
159
- return { form: [], json: [{ contentType: 'application/json' }] };
160
- return undefined;
161
- }
162
- // Direct inline requestBody
163
- return pickAllBodyInfoFromContent(rb.content);
164
- };
165
- const generateOperationCode = (pathStr, method, item, deps) => {
23
+ /* ─────────────────────────────── Single-operation generator ─────────────────────────────── */
24
+ const makeOperationCode = (pathStr, method, item, deps) => {
166
25
  const op = item[method];
167
26
  if (!isOperationLike(op))
168
27
  return null;
169
28
  const funcName = methodPath(method, pathStr);
170
- const { runtimePath, typeofPrefix, bracketSuffix, hasBracket } = formatPath(pathStr);
171
- const pathLevelParams = deps.toParameterLikes(item.parameters);
172
- const opParams = deps.toParameterLikes(op.parameters);
173
- const allParams = [...pathLevelParams, ...opParams];
174
- const pathParams = allParams.filter((p) => p.in === 'path');
175
- const queryParams = allParams.filter((p) => p.in === 'query');
176
- const headerParams = allParams.filter((p) => p.in === 'header');
177
- const cookieParams = allParams.filter((p) => p.in === 'cookie');
178
- const allBodyInfo = deps.pickAllBodyInfo(op);
179
- const hasBody = allBodyInfo !== undefined && (allBodyInfo.form.length > 0 || allBodyInfo.json.length > 0);
180
- const hasArgs = pathParams.length > 0 ||
181
- queryParams.length > 0 ||
182
- headerParams.length > 0 ||
183
- cookieParams.length > 0 ||
184
- hasBody;
185
- // For runtime calls, always use dot notation for method access
186
- const methodAccess = `.$${method}`;
187
- // For InferRequestType, handle bracket notation properly:
188
- // - No bracket: `typeof client.users.$get`
189
- // - With bracket: `(typeof client.users)[':id']['avatar']['$post']`
190
- const inferType = hasBracket
191
- ? `InferRequestType<(typeof ${deps.client}${typeofPrefix})${bracketSuffix}['$${method}']>`
192
- : `InferRequestType<typeof ${deps.client}${runtimePath}.$${method}>`;
29
+ const pathResult = formatPath(pathStr);
30
+ const hasArgs = operationHasArgs(item, op, deps);
31
+ const inferType = buildInferRequestType(deps.client, pathResult, method);
193
32
  const argSig = hasArgs
194
33
  ? `args:${inferType},options?:ClientRequestOptions`
195
34
  : 'options?:ClientRequestOptions';
196
35
  const call = hasArgs
197
- ? `${deps.client}${runtimePath}${methodAccess}(args,options)`
198
- : `${deps.client}${runtimePath}${methodAccess}(undefined,options)`;
36
+ ? `${deps.client}${pathResult.runtimePath}.$${method}(args,options)`
37
+ : `${deps.client}${pathResult.runtimePath}.$${method}(undefined,options)`;
199
38
  const summary = typeof op.summary === 'string' ? op.summary : '';
200
39
  const description = typeof op.description === 'string' ? op.description : '';
201
- // Format multiline description with JSDoc prefix on each line
202
- const formatJsDocLines = (text) => text
203
- .trimEnd()
204
- .split('\n')
205
- .map((line) => ` * ${line}`);
206
- // Escape /* in path to avoid oxfmt regex parsing issue (/* looks like /regex/)
207
- const safePathStr = pathStr.replace(/\/\*/g, '/[*]');
208
- const docs = [
209
- '/**',
210
- ` * ${method.toUpperCase()} ${safePathStr}`,
211
- ...(summary ? [' *', ...formatJsDocLines(summary)] : []),
212
- ...(description ? [' *', ...formatJsDocLines(description)] : []),
213
- ' */',
214
- ].join('\n');
40
+ const docs = buildOperationDocs(method, pathStr, summary || undefined, description || undefined);
215
41
  const func = `export async function ${funcName}(${argSig}){return await ${call}}`;
216
42
  return { code: `${docs}\n${func}`, hasArgs };
217
43
  };
218
44
  /**
219
45
  * Builds operation codes from OpenAPI paths.
220
- *
221
- * Iterates through all HTTP methods for each path and generates
222
- * typed RPC client wrapper functions.
223
- *
224
- * @param paths - OpenAPI paths object
225
- * @param deps - Dependencies including client name and parameter utilities
226
- * @returns Array of operation codes with function names and generated code
227
46
  */
228
47
  const makeOperationCodes = (paths, deps) => Object.entries(paths)
229
48
  .filter((entry) => isRecord(entry[1]))
230
49
  .flatMap(([p, rawItem]) => {
231
- const pathItem = {
232
- parameters: rawItem.parameters,
233
- get: isOperationLike(rawItem.get) ? rawItem.get : undefined,
234
- put: isOperationLike(rawItem.put) ? rawItem.put : undefined,
235
- post: isOperationLike(rawItem.post) ? rawItem.post : undefined,
236
- delete: isOperationLike(rawItem.delete) ? rawItem.delete : undefined,
237
- options: isOperationLike(rawItem.options) ? rawItem.options : undefined,
238
- head: isOperationLike(rawItem.head) ? rawItem.head : undefined,
239
- patch: isOperationLike(rawItem.patch) ? rawItem.patch : undefined,
240
- trace: isOperationLike(rawItem.trace) ? rawItem.trace : undefined,
241
- };
50
+ const pathItem = parsePathItem(rawItem);
242
51
  return HTTP_METHODS.map((method) => {
243
- const result = generateOperationCode(p, method, pathItem, deps);
52
+ const result = makeOperationCode(p, method, pathItem, deps);
244
53
  return result
245
54
  ? { funcName: methodPath(method, p), code: result.code, hasArgs: result.hasArgs }
246
55
  : null;
247
56
  }).filter((item) => item !== null);
248
57
  });
249
- /* ─────────────────────────────── Split ─────────────────────────────── */
250
- const resolveSplitOutDir = (output) => {
251
- const looksLikeFile = output.endsWith('.ts');
252
- const outDir = looksLikeFile ? path.dirname(output) : output;
253
- const indexPath = path.join(outDir, 'index.ts');
254
- return { outDir, indexPath };
58
+ /* ─────────────────────────────── Header ─────────────────────────────── */
59
+ const makeHeader = (importPath, needsInferRequestType, clientName) => {
60
+ const typeImports = needsInferRequestType
61
+ ? 'InferRequestType,ClientRequestOptions'
62
+ : 'ClientRequestOptions';
63
+ return `import type{${typeImports}}from'hono/client'\nimport{${clientName}}from'${importPath}'\n\n`;
255
64
  };
256
65
  /* ─────────────────────────────── Entry ─────────────────────────────── */
257
66
  /**
@@ -275,6 +84,7 @@ const resolveSplitOutDir = (output) => {
275
84
  * @param output - Output file path or directory
276
85
  * @param importPath - Import path for the Hono client
277
86
  * @param split - Whether to split into multiple files (one per operation)
87
+ * @param clientName - Name of the client export (default: 'client')
278
88
  * @returns Promise resolving to success message or error
279
89
  *
280
90
  * @example
@@ -288,42 +98,20 @@ const resolveSplitOutDir = (output) => {
288
98
  * // Generates: src/rpc/getUsers.ts, src/rpc/postUsers.ts, src/rpc/index.ts
289
99
  * ```
290
100
  */
291
- /**
292
- * Generates the import header for RPC client files.
293
- *
294
- * @param importPath - The import path for the Hono client
295
- * @param needsInferRequestType - Whether InferRequestType import is needed
296
- * @param clientName - The name of the client to import (default: 'client')
297
- * @returns Import header string
298
- */
299
- const makeHeader = (importPath, needsInferRequestType, clientName) => {
300
- const typeImports = needsInferRequestType
301
- ? 'InferRequestType,ClientRequestOptions'
302
- : 'ClientRequestOptions';
303
- return `import type{${typeImports}}from'hono/client'\nimport{${clientName}}from'${importPath}'\n\n`;
304
- };
305
101
  export async function rpc(openAPI, output, importPath, split, clientName = 'client') {
306
- const client = clientName;
307
102
  const pathsMaybe = openAPI.paths;
308
103
  if (!isOpenAPIPaths(pathsMaybe)) {
309
104
  return { ok: false, error: 'Invalid OpenAPI paths' };
310
105
  }
311
106
  const componentsParameters = openAPI.components?.parameters ?? {};
312
107
  const componentsRequestBodies = openAPI.components?.requestBodies ?? {};
313
- const resolveParameter = createResolveParameter(componentsParameters);
314
- const toParameterLikes = createToParameterLikes(resolveParameter);
315
- const pickAllBodyInfo = createPickAllBodyInfo(componentsRequestBodies);
316
- const deps = {
317
- client,
318
- toParameterLikes,
319
- pickAllBodyInfo,
320
- };
108
+ const deps = createOperationDeps(clientName, componentsParameters, componentsRequestBodies);
321
109
  const operationCodes = makeOperationCodes(pathsMaybe, deps);
322
110
  // Non-split: write single file
323
111
  if (!split) {
324
112
  const body = operationCodes.map(({ code }) => code).join('\n\n');
325
113
  const needsInferRequestType = operationCodes.some(({ hasArgs }) => hasArgs);
326
- const header = makeHeader(importPath, needsInferRequestType, client);
114
+ const header = makeHeader(importPath, needsInferRequestType, clientName);
327
115
  const code = `${header}${body}${operationCodes.length ? '\n' : ''}`;
328
116
  const coreResult = await core(code, path.dirname(output), output);
329
117
  if (!coreResult.ok)
@@ -336,7 +124,7 @@ export async function rpc(openAPI, output, importPath, split, clientName = 'clie
336
124
  const index = `${exportLines.join('\n')}\n`;
337
125
  const allResults = await Promise.all([
338
126
  ...operationCodes.map(({ funcName, code, hasArgs }) => {
339
- const header = makeHeader(importPath, hasArgs, client);
127
+ const header = makeHeader(importPath, hasArgs, clientName);
340
128
  const fileSrc = `${header}${code}\n`;
341
129
  const filePath = path.join(outDir, `${funcName}.ts`);
342
130
  return core(fileSrc, path.dirname(filePath), filePath);
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Svelte Query hook generation module.
3
+ *
4
+ * Generates type-safe Svelte Query hooks from OpenAPI specifications
5
+ * for use with Hono's RPC client.
6
+ *
7
+ * - GET operations generate `createQuery` hooks
8
+ * - POST/PUT/DELETE/PATCH operations generate `createMutation` hooks
9
+ *
10
+ * ```mermaid
11
+ * flowchart TD
12
+ * A["svelteQuery(openAPI, output, importPath, split)"] --> B["Parse OpenAPI paths"]
13
+ * B --> C["Build hook codes"]
14
+ * C --> D{"split mode?"}
15
+ * D -->|No| E["Write single file"]
16
+ * D -->|Yes| F["Write per-hook files"]
17
+ * F --> G["Write index.ts barrel"]
18
+ * ```
19
+ *
20
+ * @module core/svelte-query
21
+ * @link https://tanstack.com/query/latest/docs/framework/svelte/overview
22
+ * @link https://hono.dev/docs/guides/rpc
23
+ */
24
+ import type { OpenAPI } from '../../openapi/index.js';
25
+ /**
26
+ * Generates Svelte Query hooks from OpenAPI specification.
27
+ *
28
+ * Creates type-safe Svelte Query hooks that wrap Hono RPC client calls,
29
+ * with proper TypeScript types derived from OpenAPI schemas.
30
+ *
31
+ * - GET operations generate `createQuery` hooks
32
+ * - POST/PUT/DELETE/PATCH operations generate `createMutation` hooks
33
+ *
34
+ * ```mermaid
35
+ * flowchart LR
36
+ * subgraph "Generated Code"
37
+ * A["export function createGetUsers(...) { return createQuery(...) }"]
38
+ * end
39
+ * subgraph "Usage"
40
+ * B["const { data, error } = createGetUsers({ query: { limit: 10 } })"]
41
+ * end
42
+ * A --> B
43
+ * ```
44
+ *
45
+ * @param openAPI - Parsed OpenAPI specification
46
+ * @param output - Output file path or directory
47
+ * @param importPath - Import path for the Hono client
48
+ * @param split - Whether to split into multiple files (one per hook)
49
+ * @param clientName - Name of the client export (default: 'client')
50
+ * @returns Promise resolving to success message or error
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * // Single file output
55
+ * await svelteQuery(openAPI, 'src/hooks.ts', './client')
56
+ * // Generates: src/hooks.ts with all Svelte Query hooks
57
+ *
58
+ * // Split mode output
59
+ * await svelteQuery(openAPI, 'src/hooks', './client', true)
60
+ * // Generates: src/hooks/createGetUsers.ts, src/hooks/createPostUsers.ts, src/hooks/index.ts
61
+ * ```
62
+ */
63
+ export declare function svelteQuery(openAPI: OpenAPI, output: string | `${string}.ts`, importPath: string, split?: boolean, clientName?: string): Promise<{
64
+ readonly ok: true;
65
+ readonly value: string;
66
+ } | {
67
+ readonly ok: false;
68
+ readonly error: string;
69
+ }>;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Svelte Query hook generation module.
3
+ *
4
+ * Generates type-safe Svelte Query hooks from OpenAPI specifications
5
+ * for use with Hono's RPC client.
6
+ *
7
+ * - GET operations generate `createQuery` hooks
8
+ * - POST/PUT/DELETE/PATCH operations generate `createMutation` hooks
9
+ *
10
+ * ```mermaid
11
+ * flowchart TD
12
+ * A["svelteQuery(openAPI, output, importPath, split)"] --> B["Parse OpenAPI paths"]
13
+ * B --> C["Build hook codes"]
14
+ * C --> D{"split mode?"}
15
+ * D -->|No| E["Write single file"]
16
+ * D -->|Yes| F["Write per-hook files"]
17
+ * F --> G["Write index.ts barrel"]
18
+ * ```
19
+ *
20
+ * @module core/svelte-query
21
+ * @link https://tanstack.com/query/latest/docs/framework/svelte/overview
22
+ * @link https://hono.dev/docs/guides/rpc
23
+ */
24
+ import { makeQueryHooks } from '../../helper/query.js';
25
+ /**
26
+ * Generates Svelte Query hooks from OpenAPI specification.
27
+ *
28
+ * Creates type-safe Svelte Query hooks that wrap Hono RPC client calls,
29
+ * with proper TypeScript types derived from OpenAPI schemas.
30
+ *
31
+ * - GET operations generate `createQuery` hooks
32
+ * - POST/PUT/DELETE/PATCH operations generate `createMutation` hooks
33
+ *
34
+ * ```mermaid
35
+ * flowchart LR
36
+ * subgraph "Generated Code"
37
+ * A["export function createGetUsers(...) { return createQuery(...) }"]
38
+ * end
39
+ * subgraph "Usage"
40
+ * B["const { data, error } = createGetUsers({ query: { limit: 10 } })"]
41
+ * end
42
+ * A --> B
43
+ * ```
44
+ *
45
+ * @param openAPI - Parsed OpenAPI specification
46
+ * @param output - Output file path or directory
47
+ * @param importPath - Import path for the Hono client
48
+ * @param split - Whether to split into multiple files (one per hook)
49
+ * @param clientName - Name of the client export (default: 'client')
50
+ * @returns Promise resolving to success message or error
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * // Single file output
55
+ * await svelteQuery(openAPI, 'src/hooks.ts', './client')
56
+ * // Generates: src/hooks.ts with all Svelte Query hooks
57
+ *
58
+ * // Split mode output
59
+ * await svelteQuery(openAPI, 'src/hooks', './client', true)
60
+ * // Generates: src/hooks/createGetUsers.ts, src/hooks/createPostUsers.ts, src/hooks/index.ts
61
+ * ```
62
+ */
63
+ export async function svelteQuery(openAPI, output, importPath, split, clientName = 'client') {
64
+ // Svelte Query v5+ requires thunk pattern: createQuery(() => options)
65
+ // @see https://tanstack.com/query/v5/docs/framework/svelte/reactivity
66
+ const config = {
67
+ packageName: '@tanstack/svelte-query',
68
+ frameworkName: 'Svelte Query',
69
+ hookPrefix: 'create',
70
+ queryFn: 'createQuery',
71
+ mutationFn: 'createMutation',
72
+ useThunk: true,
73
+ useQueryOptionsType: 'CreateQueryOptions',
74
+ useMutationOptionsType: 'CreateMutationOptions',
75
+ };
76
+ return makeQueryHooks(openAPI, output, importPath, config, split, clientName);
77
+ }
@@ -0,0 +1,46 @@
1
+ import type { OpenAPI } from '../../openapi/index.js';
2
+ /**
3
+ * Generates SWR hooks from OpenAPI specification.
4
+ *
5
+ * Creates type-safe SWR hooks that wrap Hono RPC client calls,
6
+ * with proper TypeScript types derived from OpenAPI schemas.
7
+ *
8
+ * - GET operations generate `useSWR` hooks
9
+ * - POST/PUT/DELETE/PATCH operations generate `useSWRMutation` hooks
10
+ *
11
+ * ```mermaid
12
+ * flowchart LR
13
+ * subgraph "Generated Code"
14
+ * A["export function useGetUsers(...) { return useSWR(...) }"]
15
+ * end
16
+ * subgraph "Usage"
17
+ * B["const { data, error } = useGetUsers({ query: { limit: 10 } })"]
18
+ * end
19
+ * A --> B
20
+ * ```
21
+ *
22
+ * @param openAPI - Parsed OpenAPI specification
23
+ * @param output - Output file path or directory
24
+ * @param importPath - Import path for the Hono client
25
+ * @param split - Whether to split into multiple files (one per hook)
26
+ * @param clientName - Name of the client export (default: 'client')
27
+ * @returns Promise resolving to success message or error
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * // Single file output
32
+ * await swr(openAPI, 'src/hooks.ts', './client')
33
+ * // Generates: src/hooks.ts with all SWR hooks
34
+ *
35
+ * // Split mode output
36
+ * await swr(openAPI, 'src/hooks', './client', true)
37
+ * // Generates: src/hooks/useGetUsers.ts, src/hooks/usePostUsers.ts, src/hooks/index.ts
38
+ * ```
39
+ */
40
+ export declare function swr(openAPI: OpenAPI, output: string | `${string}.ts`, importPath: string, split?: boolean, clientName?: string): Promise<{
41
+ readonly ok: true;
42
+ readonly value: string;
43
+ } | {
44
+ readonly ok: false;
45
+ readonly error: string;
46
+ }>;