@kubb/plugin-client 5.12.0 → 6.0.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 (72) hide show
  1. package/README.md +1 -1
  2. package/dist/client-Dq0z61hu.d.ts +554 -0
  3. package/dist/index.cjs +1378 -784
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +114 -74
  6. package/dist/index.d.ts +114 -74
  7. package/dist/index.js +1376 -786
  8. package/dist/index.js.map +1 -1
  9. package/dist/serializers-BRgfPGr1.d.ts +119 -0
  10. package/dist/{standardSchema-BShJWz2i.d.ts → standardSchema-CGuiSK7F.d.ts} +15 -37
  11. package/dist/templates/client.d.ts +3 -2
  12. package/dist/templates/core.d.ts +3 -3
  13. package/dist/templates/mediaTypes/formData.d.ts +5 -0
  14. package/dist/templates/mediaTypes/urlencoded.d.ts +5 -0
  15. package/dist/templates/mediaTypes.d.ts +2 -0
  16. package/dist/templates/serializers/cookies.d.ts +5 -0
  17. package/dist/templates/serializers/headers.d.ts +5 -0
  18. package/dist/templates/serializers/path.d.ts +5 -0
  19. package/dist/templates/serializers/pathStyles.d.ts +5 -0
  20. package/dist/templates/serializers/query.d.ts +5 -0
  21. package/dist/templates/serializers/queryStyles.d.ts +14 -0
  22. package/dist/templates/serializers.d.ts +2 -2
  23. package/dist/templates/sse.d.ts +20 -113
  24. package/dist/templates/standardSchema.d.ts +1 -1
  25. package/docs/guides/authentication.md +9 -1
  26. package/docs/guides/migrate-to-v6.md +139 -0
  27. package/docs/guides/validate-requests-and-responses.md +8 -3
  28. package/docs/guides/write-your-client.md +117 -11
  29. package/docs/options.md +2 -2
  30. package/docs/overview.md +1 -1
  31. package/kubb-extension.json +1 -1
  32. package/package.json +6 -5
  33. package/src/builders/callConfig.ts +80 -0
  34. package/src/builders/contentType.ts +35 -0
  35. package/src/builders/generics.ts +29 -0
  36. package/src/builders/operationBody.ts +43 -0
  37. package/src/builders/operationData.ts +64 -0
  38. package/src/builders/returnStatement.ts +103 -0
  39. package/src/builders/security.ts +125 -0
  40. package/src/builders/signature.ts +71 -0
  41. package/src/builders/styles.ts +94 -0
  42. package/src/builders/validator.ts +84 -0
  43. package/src/builders/validatorOptions.ts +53 -0
  44. package/src/clientTypes.ts +195 -0
  45. package/src/components/ClientRuntime.tsx +97 -0
  46. package/src/components/Operation.tsx +72 -0
  47. package/src/components/SdkClient.tsx +100 -0
  48. package/src/components/SdkFacade.tsx +35 -0
  49. package/src/generators/clientGenerator.tsx +91 -6
  50. package/src/generators/sdkGenerator.tsx +209 -0
  51. package/src/index.ts +3 -1
  52. package/src/macros.ts +9 -0
  53. package/src/plugin.ts +7 -8
  54. package/src/resolver.ts +28 -0
  55. package/src/setup.ts +90 -0
  56. package/src/types.ts +4 -2
  57. package/templates/client.ts +2 -1
  58. package/templates/core.ts +735 -286
  59. package/templates/mediaTypes/formData.ts +59 -0
  60. package/templates/mediaTypes/urlencoded.ts +33 -0
  61. package/templates/mediaTypes.ts +147 -0
  62. package/templates/serializers/cookies.ts +58 -0
  63. package/templates/serializers/headers.ts +35 -0
  64. package/templates/serializers/path.ts +19 -0
  65. package/templates/serializers/pathStyles.ts +27 -0
  66. package/templates/serializers/query.ts +21 -0
  67. package/templates/serializers/queryStyles.ts +107 -0
  68. package/templates/serializers.ts +48 -364
  69. package/templates/sse.ts +87 -178
  70. package/templates/standardSchema.ts +16 -37
  71. package/dist/client-BxO6Dygu.d.ts +0 -355
  72. package/dist/serializers-Ds8zZwOO.d.ts +0 -190
@@ -0,0 +1,209 @@
1
+ import path from 'node:path'
2
+ import { type OperationTypeSource, resolveOperationTypes, resultTypeName } from '@internals/client'
3
+ import { isEventStream } from '@internals/shared'
4
+ import { ensureValidVarName } from '@internals/utils'
5
+ import { ast, defineGenerator, Diagnostics } from '@kubb/kit'
6
+ import type { Generator } from '@kubb/kit'
7
+ import { File, jsxRenderer } from '@kubb/renderer-jsx'
8
+ import { type GeneratorContext, type OperationData, resolveOperationData } from '../builders/operationData.ts'
9
+ import { buildEventStreamImports } from '../builders/returnStatement.ts'
10
+ import { isValidatorEnabled } from '../builders/validatorOptions.ts'
11
+ import { SdkClient } from '../components/SdkClient.tsx'
12
+ import { ClientRuntime } from '../components/ClientRuntime.tsx'
13
+ import { SdkFacade } from '../components/SdkFacade.tsx'
14
+ import type { ContractClientFactory } from '../types.ts'
15
+
16
+ type Controller = {
17
+ name: string
18
+ tag: string | undefined
19
+ file: ast.FileNode
20
+ operations: Array<OperationData>
21
+ }
22
+
23
+ /**
24
+ * Groups operations into one controller per tag. Operations without a tag fall back to a single
25
+ * `Client`/`ApiClient` controller, matching the resolver's default naming.
26
+ */
27
+ function buildControllers(nodes: ReadonlyArray<ast.OperationNode>, ctx: GeneratorContext, types: OperationTypeSource): Array<Controller> {
28
+ const { resolver, root } = ctx
29
+ const { output, group } = ctx.options
30
+
31
+ return nodes.reduce((acc, operationNode) => {
32
+ if (!ast.http.isOperation(operationNode)) return acc
33
+ const tag = operationNode.tags[0]
34
+ const name = tag ? ensureValidVarName(resolver.groupName(tag)) : resolver.className('ApiClient')
35
+ // `group.name` names the folder and file, never the class.
36
+ const fileName = tag && group ? ensureValidVarName(path.basename(resolver.groupDir(group, tag))) : name
37
+ const file = resolver.file({ name: fileName, extname: '.ts', tag, root, output, group: group ?? undefined })
38
+ const operationData = resolveOperationData({ node: operationNode, ctx, types })
39
+ const previous = acc.find((item) => item.file.path === file.path)
40
+
41
+ if (previous) {
42
+ previous.operations.push(operationData)
43
+ } else {
44
+ acc.push({ name, tag, file, operations: [operationData] })
45
+ }
46
+
47
+ return acc
48
+ }, [] as Array<Controller>)
49
+ }
50
+
51
+ function collectImportsByFile(ops: Array<OperationData>, pick: (op: OperationData) => { file: ast.FileNode | null; names: Array<string> }) {
52
+ const namesByPath = new Map<string, Set<string>>()
53
+ const filesByPath = new Map<string, ast.FileNode>()
54
+
55
+ ops.forEach((op) => {
56
+ const { file, names } = pick(op)
57
+ if (!file || names.length === 0) return
58
+ if (!namesByPath.has(file.path)) namesByPath.set(file.path, new Set())
59
+ const set = namesByPath.get(file.path)!
60
+ names.forEach((n) => set.add(n))
61
+ filesByPath.set(file.path, file)
62
+ })
63
+
64
+ return { namesByPath, filesByPath }
65
+ }
66
+
67
+ /**
68
+ * Builds the class-based SDK generator for a client plugin (`@kubb/plugin-fetch`,
69
+ * `@kubb/plugin-axios`). Only registered when `sdk` is set; otherwise the plugin keeps its
70
+ * standalone per-operation functions.
71
+ *
72
+ * Every tag client is an instance class whose constructor takes a client config and builds its own
73
+ * client, or takes an existing client, so each environment is a separate instance. With `sdk.mode:
74
+ * 'tag'` (the default) it emits one class per tag, named by `resolver.groupName`, and, when `sdk.name`
75
+ * is set, a composed root that creates one client and shares it with every tag client. With
76
+ * `sdk.mode: 'flat'` it emits one class named by `sdk.name`, with every operation as a direct method.
77
+ *
78
+ * `templates` is the folder the optional runtime is copied from: `sse.ts` only for a document that streams, and each
79
+ * form media type only for a document with a body of that type.
80
+ */
81
+ export function createSdkGenerator<TFactory extends ContractClientFactory>({ templates }: { templates?: string } = {}): Generator<TFactory> {
82
+ return defineGenerator<TFactory>({
83
+ name: 'sdk',
84
+ renderer: jsxRenderer,
85
+ operations(nodes, ctx) {
86
+ const { config, resolver, root } = ctx
87
+ const { output, group, validator, returnType, throwOnErrorDefault, sdk } = ctx.options
88
+
89
+ if (!sdk) return null
90
+
91
+ // `resolver.file(...)` resolves every tag to the same single `output.path` under `mode:
92
+ // 'file'`, so a tag-per-class split has nothing to split into: every tag would collapse
93
+ // into whichever controller `buildControllers` reduces first, silently dropping the rest.
94
+ if (sdk.mode === 'tag' && output.mode === 'file') {
95
+ throw new Diagnostics.Error({
96
+ code: Diagnostics.code.invalidPluginOptions,
97
+ severity: 'error',
98
+ message: `Plugin "${ctx.plugin.name}" resolves \`output.mode\` to 'file' but also configures \`sdk.mode: 'tag'\`.`,
99
+ help: "A single-file output has nothing to split tag classes into. Set `sdk.mode: 'flat'` to emit one class into that file, or give `output.path` an extensionless directory name (or set `output.mode: 'directory'` explicitly) so each tag gets its own file.",
100
+ location: { kind: 'config' },
101
+ plugin: ctx.plugin.name,
102
+ })
103
+ }
104
+
105
+ const types = resolveOperationTypes(ctx.driver, ctx.plugin.name)
106
+
107
+ const validatorEnabled = isValidatorEnabled(validator)
108
+ const controllers = buildControllers(nodes, ctx, types)
109
+ const clientPath = path.resolve(root, '.kubb/client.ts')
110
+ const standardSchemaPath = path.resolve(root, '.kubb/standardSchema.ts')
111
+
112
+ const banner = (file: ast.FileNode) => resolver.default.banner(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } })
113
+ const footer = (file: ast.FileNode) => resolver.default.footer(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } })
114
+
115
+ const renderClassFile = (className: string, file: ast.FileNode, ops: Array<OperationData>) => {
116
+ const { namesByPath: typeNamesByPath, filesByPath: typeFilesByPath } = collectImportsByFile(ops, (op) => ({
117
+ file: op.typeFile,
118
+ names: [op.types.response.options(op.node), op.types.response.responses(op.node), ...op.headerTypeNames],
119
+ }))
120
+ const { namesByPath: zodNamesByPath, filesByPath: zodFilesByPath } = validatorEnabled
121
+ ? collectImportsByFile(ops, (op) => ({ file: op.zodFile, names: op.validatorHooks.importedZodNames }))
122
+ : { namesByPath: new Map<string, Set<string>>(), filesByPath: new Map<string, ast.FileNode>() }
123
+ const resultOps = ops.filter((op) => !isEventStream(op.node))
124
+ const typedHeaders = (op: OperationData) => op.headerTypeNames.length > 0
125
+ const resultName = returnType === 'data' ? 'UnwrappedResult' : 'RequestResult'
126
+
127
+ return (
128
+ <File key={file.path} baseName={file.baseName} path={file.path} meta={file.meta} banner={banner(file)} footer={footer(file)}>
129
+ <File.Import
130
+ name={[
131
+ 'createClient',
132
+ returnType === 'data' ? 'unwrapResult' : 'withUnwrap',
133
+ 'resolveThrowOnError',
134
+ ...(ctx.options.importPath === undefined && ops.some((op) => op.security) ? ['securitySchemes'] : []),
135
+ ]}
136
+ root={file.path}
137
+ path={clientPath}
138
+ />
139
+ <File.Import
140
+ name={Array.from(
141
+ new Set([
142
+ 'ClientConfig',
143
+ 'ClientInstance',
144
+ 'Options',
145
+ ...(returnType === 'data' ? [] : ['Unwrappable']),
146
+ ...(resultOps.some((op) => !typedHeaders(op)) ? [resultName] : []),
147
+ ...(resultOps.some(typedHeaders) ? [resultTypeName(resultName, true)] : []),
148
+ ...ops.filter((op) => isEventStream(op.node)).flatMap((op) => buildEventStreamImports({ node: op.node, types: op.types, returnType })),
149
+ ]),
150
+ )}
151
+ root={file.path}
152
+ path={clientPath}
153
+ isTypeOnly
154
+ />
155
+
156
+ {validator === 'zod' && ops.some((op) => ast.http.requestBody.getSchema(op.node) != null) && <File.Import name={['z']} path="zod" isTypeOnly />}
157
+
158
+ {Array.from(typeNamesByPath.entries()).map(([filePath, set]) => (
159
+ <File.Import key={filePath} name={Array.from(set)} root={file.path} path={typeFilesByPath.get(filePath)!.path} isTypeOnly />
160
+ ))}
161
+
162
+ {validatorEnabled &&
163
+ Array.from(zodNamesByPath.entries()).map(([filePath, set]) => (
164
+ <File.Import key={filePath} name={Array.from(set)} root={file.path} path={zodFilesByPath.get(filePath)!.path} />
165
+ ))}
166
+
167
+ {ops.some((op) => op.validatorHooks.headers) && <File.Import name={['toHeadersStandardSchema']} root={file.path} path={standardSchemaPath} />}
168
+
169
+ <SdkClient name={className} operations={ops} returnType={returnType} throwOnErrorDefault={throwOnErrorDefault} />
170
+ </File>
171
+ )
172
+ }
173
+
174
+ // `flat` collapses every operation into one class named by `sdk.name`, so callers reach
175
+ // an operation as `new PetStore(config).getPetById(...)` without a per-tag sub-client.
176
+ const renderFacadeFile = (name: string) => {
177
+ const sdkFile = resolver.file({ name, extname: '.ts', root, output, group: group ?? undefined })
178
+ const members = controllers.map(({ name, tag }) => ({ className: name, propName: resolver.propertyName(tag ?? name) }))
179
+
180
+ return (
181
+ <File key={sdkFile.path} baseName={sdkFile.baseName} path={sdkFile.path} meta={sdkFile.meta} banner={banner(sdkFile)} footer={footer(sdkFile)}>
182
+ <File.Import name={['createClient']} root={sdkFile.path} path={clientPath} />
183
+ <File.Import name={['ClientConfig', 'ClientInstance']} root={sdkFile.path} path={clientPath} isTypeOnly />
184
+ {controllers.map(({ name, file }) => (
185
+ <File.Import key={name} name={[name]} root={sdkFile.path} path={file.path} />
186
+ ))}
187
+ <SdkFacade name={resolver.className(name)} members={members} />
188
+ </File>
189
+ )
190
+ }
191
+
192
+ const files =
193
+ sdk.mode === 'flat'
194
+ ? renderClassFile(
195
+ resolver.className(sdk.name ?? 'sdk'),
196
+ resolver.file({ name: sdk.name ?? 'sdk', extname: '.ts', root, output, group: group ?? undefined }),
197
+ controllers.flatMap((controller) => controller.operations),
198
+ )
199
+ : [...controllers.map(({ name, file, operations: ops }) => renderClassFile(name, file, ops)), sdk.name && renderFacadeFile(sdk.name)]
200
+
201
+ return (
202
+ <>
203
+ <ClientRuntime nodes={nodes} root={root} templates={templates} baseURL={ctx.options.baseURL} servers={ctx.meta.servers} auth={ctx.meta.auth} />
204
+ {files}
205
+ </>
206
+ )
207
+ },
208
+ })
209
+ }
package/src/index.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  export { default, pluginClient, pluginClientName } from './plugin.ts'
2
- export type { Options, PluginClient, ResolvedOptions, ResolverClient } from './types.ts'
2
+ export { resolverClient } from './resolver.ts'
3
+ export { clientDependencies, resolveClientOptions, setupClient } from './setup.ts'
4
+ export type { ClientOptions, ClientResolvedOptions, Options, PluginClient, ResolvedOptions, ResolverClient } from './types.ts'
package/src/macros.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { macroDedupeUnion } from '@kubb/kit'
2
+ import type { ast } from '@kubb/kit'
3
+
4
+ /**
5
+ * Macros the client plugins apply by default, ahead of any user macros. `macroDedupeUnion`
6
+ * drops repeated union members, keeping the generated response and error
7
+ * unions tidy. A plugin wires them with `ctx.setMacros([...defaultMacros, ...userMacros])`.
8
+ */
9
+ export const defaultMacros: ReadonlyArray<ast.Macro> = [macroDedupeUnion]
package/src/plugin.ts CHANGED
@@ -1,11 +1,10 @@
1
- import { createGroupConfig } from '@internals/shared'
2
1
  import { addGenerator, defineExtension, Resolver, setMacros, setResolver } from '@kubb/kit'
3
2
  import { compatibility } from '../kubb-extension.json'
4
3
  import { version } from '../package.json'
5
- import { pluginTsName } from '@kubb/plugin-ts'
6
- import { pluginZodName } from '@kubb/plugin-zod'
7
- import { clientGenerator } from './generators/clientGenerator.tsx'
8
- import { defaultMacros, isValidatorEnabled, resolverClient } from '@internals/client'
4
+ import { createClientGenerator } from './generators/clientGenerator.tsx'
5
+ import { defaultMacros } from './macros.ts'
6
+ import { resolverClient } from './resolver.ts'
7
+ import { clientDependencies } from './setup.ts'
9
8
  import type { PluginClient, ResolverClient } from './types.ts'
10
9
 
11
10
  /**
@@ -26,7 +25,7 @@ export const pluginClientName = 'plugin-client' satisfies PluginClient['name']
26
25
  export const pluginClient = defineExtension<PluginClient>({
27
26
  kind: 'plugin',
28
27
  meta: { name: pluginClientName, version, compatibility },
29
- dependencies: (options) => ({ [pluginTsName]: { optional: true }, [pluginZodName]: { optional: !isValidatorEnabled(options.validator) } }),
28
+ dependencies: clientDependencies,
30
29
  setup(options) {
31
30
  const {
32
31
  output = { path: 'clients', barrel: { type: 'named' } },
@@ -45,14 +44,14 @@ export const pluginClient = defineExtension<PluginClient>({
45
44
 
46
45
  setResolver(resolver)
47
46
  setMacros([...defaultMacros, ...(options.macros ?? [])])
48
- addGenerator(clientGenerator)
47
+ addGenerator(createClientGenerator<PluginClient>('client'))
49
48
 
50
49
  return {
51
50
  output,
52
51
  exclude,
53
52
  include,
54
53
  override,
55
- group: createGroupConfig(group),
54
+ group: group ?? null,
56
55
  importPath,
57
56
  baseURL: undefined,
58
57
  throwOnErrorDefault,
@@ -0,0 +1,28 @@
1
+ import { resolveOperationName } from '@internals/shared'
2
+ import { ensureValidVarName } from '@internals/utils'
3
+ import { casing, createResolver } from '@kubb/kit'
4
+ import type { PluginContractClient, ResolverClient } from './types.ts'
5
+
6
+ /**
7
+ * Default resolver shared by the client plugins. Functions use safe camelCase identifiers and
8
+ * files inherit the built-in casing; classes and tag groups use PascalCase.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * resolverClient.name('show pet by id') // 'showPetById'
13
+ * resolverClient.groupName('pet') // 'PetClient'
14
+ * ```
15
+ */
16
+ export const resolverClient: ResolverClient = createResolver<PluginContractClient>({
17
+ pluginName: 'plugin-contract-client',
18
+ name: resolveOperationName,
19
+ className(name) {
20
+ return ensureValidVarName(casing.pascal(name))
21
+ },
22
+ groupName(name) {
23
+ return ensureValidVarName(casing.pascal(`${name} Client`))
24
+ },
25
+ propertyName(name) {
26
+ return ensureValidVarName(casing.camel(name))
27
+ },
28
+ })
package/src/setup.ts ADDED
@@ -0,0 +1,90 @@
1
+ import path from 'node:path'
2
+ import { fileURLToPath } from 'node:url'
3
+ import { addGenerator, injectFile, Resolver, setMacros, setResolver, useConfig } from '@kubb/kit'
4
+ import { pluginTsName } from '@kubb/plugin-ts'
5
+ import { pluginZodName } from '@kubb/plugin-zod'
6
+ import { isValidatorEnabled } from './builders/validatorOptions.ts'
7
+ import { createClientGenerator } from './generators/clientGenerator.tsx'
8
+ import { createSdkGenerator } from './generators/sdkGenerator.tsx'
9
+ import { defaultMacros } from './macros.ts'
10
+ import { resolverClient } from './resolver.ts'
11
+ import type { ClientOptions, ClientResolvedOptions, ContractClientFactory, ResolverClient } from './types.ts'
12
+
13
+ // Resolved from a file directly in `src/`, so the same `../templates/` path works from `dist/`.
14
+ const templatePath = (name: string) => fileURLToPath(new URL(`../templates/${name}`, import.meta.url))
15
+
16
+ /**
17
+ * Applies the client option defaults and merges a user `resolver` over the built-in one.
18
+ */
19
+ export function resolveClientOptions(options: ClientOptions): ClientResolvedOptions {
20
+ const {
21
+ output = { path: 'clients', barrel: { type: 'named' } },
22
+ exclude = [],
23
+ include,
24
+ override = [],
25
+ baseURL,
26
+ throwOnErrorDefault = true,
27
+ validator = false,
28
+ returnType = 'full',
29
+ group,
30
+ sdk,
31
+ resolver: userResolver,
32
+ } = options
33
+
34
+ return {
35
+ output,
36
+ exclude,
37
+ include,
38
+ override,
39
+ group: group ?? null,
40
+ baseURL,
41
+ throwOnErrorDefault,
42
+ validator,
43
+ returnType,
44
+ sdk: sdk ? { mode: sdk.mode ?? 'tag', name: sdk.name } : undefined,
45
+ resolver: userResolver ? Resolver.merge<ResolverClient>(resolverClient, userResolver) : resolverClient,
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Wires a client plugin in its `setup`: resolver, macros, client or SDK generator, and the `.kubb/` runtime with the plugin's own `client.ts`.
51
+ */
52
+ export function setupClient({
53
+ name,
54
+ resolved,
55
+ macros = [],
56
+ client,
57
+ }: {
58
+ name: string
59
+ resolved: ClientResolvedOptions
60
+ macros?: ClientOptions['macros']
61
+ client: string
62
+ }): void {
63
+ const config = useConfig()
64
+
65
+ setResolver(resolved.resolver)
66
+ setMacros([...defaultMacros, ...macros])
67
+
68
+ const templates = templatePath('')
69
+ addGenerator<ContractClientFactory>(resolved.sdk ? createSdkGenerator({ templates }) : createClientGenerator(name, { templates }))
70
+
71
+ const root = path.resolve(config.root, config.output.path)
72
+ const files = [
73
+ ['serializers.ts', templatePath('serializers.ts')],
74
+ ['mediaTypes.ts', templatePath('mediaTypes.ts')],
75
+ ['core.ts', templatePath('core.ts')],
76
+ ['client.ts', client],
77
+ ['standardSchema.ts', templatePath('standardSchema.ts')],
78
+ ] as const
79
+
80
+ for (const [baseName, copy] of files) {
81
+ injectFile({ baseName, path: path.resolve(root, '.kubb', baseName), copy })
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Declares `plugin-ts` as optional and `plugin-zod` as required once `validator` enables a direction.
87
+ */
88
+ export function clientDependencies(options: Pick<ClientOptions, 'validator'>) {
89
+ return { [pluginTsName]: { optional: true }, [pluginZodName]: { optional: !isValidatorEnabled(options.validator) } }
90
+ }
package/src/types.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import type { Override, PluginType } from '@kubb/kit'
2
- import type { Options as ClientOptions, ResolvedOptions as ClientResolvedOptions, ResolverClient, ReturnTypeOption } from '@internals/client'
2
+ import type { ReturnTypeOption } from '@internals/client'
3
+ import type { ClientOptions, ClientResolvedOptions, ResolverClient } from './clientTypes.ts'
3
4
 
4
- export type { ResolverClient } from '@internals/client'
5
+ export type * from './clientTypes.ts'
6
+ export type { ReturnTypeOption } from '@internals/client'
5
7
 
6
8
  /**
7
9
  * Omits keys from every member of a union, where the built-in `Omit` would collapse the union into one shape.
@@ -1,5 +1,6 @@
1
1
  // Stands in for the transport's `client.ts` next to `sse.ts`, so the shared templates typecheck on their own. In the
2
2
  // generated `.kubb/` folder, `sse.ts` reads these from the real client; this file is never copied.
3
- export type { DataShape, Options, RequestResult, SuccessOf } from './core.ts'
3
+ export type * from './core.ts'
4
+ export type NativeOptions = Record<string, unknown>
4
5
  export type NativeRequest = unknown
5
6
  export type NativeResponse = unknown