Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
81697b6
feat(plugin): add Redocly config support for global `x-openapi-qraft`…
radist2s May 30, 2025
bf56e77
chore: add future `--override-import-type` option support test cases
radist2s May 30, 2025
8eb6d65
chore(tanstack-query-react-types): add `/shared` to the exports
radist2s May 30, 2025
e19023a
chore(tanstack-query-react-types): add shared `OperationError<TError>…
radist2s May 30, 2025
c7e1f48
chore(tanstack-query-react-types): replace `@tanstack/query-core` typ…
radist2s May 30, 2025
3a95d53
chore(tanstack-query-react-plugin): add support for `--override-impor…
radist2s May 30, 2025
d89a155
fix(plugin): command params hud
radist2s May 30, 2025
87a1a7d
feat(tanstack-query-react-plugin): --override-import-type` option sup…
radist2s May 30, 2025
f71431a
feat(react-client): add `--override-import-type` option to the redocl…
radist2s May 30, 2025
d245120
feat(tanstack-query-react-plugin): --override-import-type` option sup…
radist2s May 31, 2025
3223352
feat(tanstack-query-react-plugin): --override-import-type` option sup…
radist2s May 31, 2025
6755d31
chore(tanstack-query-react-plugin): add `--override-import-type` opti…
radist2s May 31, 2025
a0dfbe4
docs(website): update redocly-config.mdx
radist2s May 31, 2025
3373446
docs(website): move `--create-api-client-fn` description for the cli.mdx
radist2s May 31, 2025
6f8f808
docs(website): add `--override-import-type` to the cli.mdx
radist2s Jun 1, 2025
2e579e9
chore(cli): update README.md
radist2s Jun 1, 2025
9c1c611
docs(changeset): New `--override-import-type` option for the CLI that…
radist2s Jun 1, 2025
339250c
docs(changeset): Global x-openapi-qraft configuration has been added …
radist2s Jun 1, 2025
c990dc0
docs(changeset): Updated the generated services to always import type…
radist2s Jun 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/gentle-sites-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@openapi-qraft/tanstack-query-react-plugin': minor
---

New `--override-import-type` option for the CLI that has been implemented to allow overriding import paths for specific
types in generated files

This feature has been designed to enable using custom type implementations instead of the default ones
8 changes: 8 additions & 0 deletions .changeset/global-redocly-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@openapi-qraft/cli': minor
---

Global x-openapi-qraft configuration has been added to the Redocly config support.

This feature has been implemented to allow specifying x-openapi-qraft options at the global level in the Redocly
configuration, rather than repeating the same options for each API client.
7 changes: 7 additions & 0 deletions .changeset/orange-foxes-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@openapi-qraft/tanstack-query-react-plugin': minor
'@openapi-qraft/react': minor
---

Updated the generated services to always import types from `@tanstack/react-query` instead of `@tanstack/query-core`.
This simplifies the generated code and makes it easier to override types if needed.
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ https
ssh
ubuntu
workarounds
createapiclient
82 changes: 47 additions & 35 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,43 +24,55 @@ Usage: openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript [
Generate a type-safe TanStack Query client for React from an OpenAPI Document.

Arguments:
input Input OpenAPI Document file path, URL (json, yml) (default: null)
input Input OpenAPI Document file path, URL (json, yml) (default: null)

Options:
-o, --output-dir <path> Output directory for generated services
-rm, --clean Clean output directory before generating services
--filter-services <glob-patterns...> Filter services to be generated using glob patterns. Example: "/user/**,/post/**". For more details, see the NPM `micromatch` package documentation.
--operation-predefined-parameters <patterns...> Predefined parameters for services. The specified service parameters will be optional. Example: "/**:header.x-monite-version,query.x-api-key" or "get /**:header.x-monite-entity-id"
--operation-name-modifier <patterns...> Modifies operation names using a pattern. Use the `==>` operator to separate the regular expression (left) and the substitution string (right). For example: "post /**:[A-Za-z]+Id ==> createOne"
--postfix-services <string> Postfix to be added to the generated service name (eg: Service)
--service-name-base <endpoint[<index>] | tags> Use OpenAPI Operation `endpoint[<index>]` path part (e.g.: "/0/1/2") or `tags` as the base name of the service. (default: "endpoint[0]")
--file-header <string> Header to be added to the generated file (eg: /* eslint-disable */)
--redocly [config] Use the Redocly configuration to generate multiple API clients
If the [config] parameter is not specified, the default Redocly configuration will be used: [redocly.yaml | redocly.yml | .redocly.yaml | .redocly.yml].
For more information about this option, use the command: --redocly-help
Examples: "openapi-qraft --redocly", "openapi-qraft my-api@v1 external-api --redocly", "openapi-qraft --redocly
./my-redocly-config.yaml"
--openapi-types-import-path <path> Path to schema types file (.d.ts), e.g.: "../schema.d.ts"
--explicit-import-extensions [extension] All import statements will contain an explicit file extension. Ideal for projects using ECMAScript modules. (choices: ".js", ".ts", preset: ".js")
--export-openapi-types [bool] Add an export statement of the generated OpenAPI document types from the `./index.ts' file. Useful for sharing types within your project. (default: true)
--queryable-write-operations [bool] Enable generation of query hooks (useQuery, useSuspenseQuery, etc.) for writable HTTP methods like POST, PUT, PATCH. By default, only mutation hooks are generated for writable operations.
--openapi-types-file-name <path> OpenAPI Schema types file name, e.g.: "schema.d.ts" (default: "schema.ts")
--enum Export true TS enums instead of unions
--enum-values Export enum values as arrays.
--dedupe-enums Dedupe enum types when `--enum` is set
-t, --export-type Export top-level `type` instead of `interface`
--immutable Generate readonly types
--additional-properties Treat schema objects as if `additionalProperties: true` is set
--empty-objects-unknown Generate `unknown` instead of `Record<string, never>` for empty objects
--default-non-nullable Set to `false` to ignore default values when generating non-nullable types
--properties-required-by-default Treat schema objects as if `required` is set to all properties by default
--array-length Generate tuples using array minItems / maxItems
--path-params-as-types Convert paths to template literal types
--alphabetize Sort object keys alphabetically
--exclude-deprecated Exclude deprecated types
--no-blob-from-binary If this option is enabled, binary format fields will not be converted to Blob types, preserving the native representation
--explicit-component-exports Enabling this option will export API components as separate type aliases, alongside `components` interface
-h, --help display help for command
-o, --output-dir <path> Output directory for generated services
-rm, --clean Clean output directory before generating services
--filter-services <glob-patterns...> Filter services to be generated using glob patterns. Example: "/user/**,/post/**". For more details, see the NPM `micromatch` package documentation.
--operation-predefined-parameters <patterns...> Predefined parameters for services. The specified service parameters will be optional. Example: "/**:header.x-monite-version,query.x-api-key" or
"get /**:header.x-monite-entity-id"
--operation-name-modifier <patterns...> Modifies operation names using a pattern. Use the `==>` operator to separate the regular expression (left) and the substitution string (right). For
example: "post /**:[A-Za-z]+Id ==> createOne"
--postfix-services <string> Postfix to be added to the generated service name (eg: Service)
--service-name-base <endpoint[<index>] | tags> Use OpenAPI Operation `endpoint[<index>]` path part (e.g.: "/0/1/2") or `tags` as the base name of the service. (default: "endpoint[0]")
--file-header <string> Header to be added to the generated file (eg: /* eslint-disable */)
--redocly [config] Use the Redocly configuration to generate multiple API clients
If the [config] parameter is not specified, the default Redocly configuration will be used: [redocly.yaml | redocly.yml | .redocly.yaml |
.redocly.yml].
For more information about this option, use the command: --redocly-help
Examples:
$ bin --redocly
$ bin my-api --redocly
$ bin my-api@v1 my-api@v2 --redocly
$ bin --redocly ./my-redocly-config.yaml
--openapi-types-import-path <path> Path to schema types file (.d.ts), e.g.: "../schema.d.ts"
--explicit-import-extensions [extension] All import statements will contain an explicit file extension. Ideal for projects using ECMAScript modules. (choices: ".js", ".ts", preset: ".js")
--export-openapi-types [bool] Add an export statement of the generated OpenAPI document types from the `./index.ts' file. Useful for sharing types within your project. Default:
true when --plugin openapi-typescript is used. (default: true)
--queryable-write-operations [bool] Enable generation of query hooks (useQuery, useSuspenseQuery, etc.) for writable HTTP methods like POST, PUT, PATCH. By default, only mutation hooks
are generated for writable operations.
--create-api-client-fn <functionName> [options...] Configure API client creation function. Allows specifying the function name, included services, and callbacks. Can be specified multiple times to
generate several different API client functions from a single OpenAPI document. (default: null)
--override-import-type <pathname overrides...> Override import paths for specific types in generated files. This allows using custom type implementations instead of the default ones. Expected
format: filepath originalModule:importTypeName:customImportPath
--openapi-types-file-name <path> OpenAPI Schema types file name, e.g.: "schema.d.ts" (default: "schema.ts")
--enum Export true TS enums instead of unions
--enum-values Export enum values as arrays.
--dedupe-enums Dedupe enum types when `--enum` is set
-t, --export-type Export top-level `type` instead of `interface`
--immutable Generate readonly types
--additional-properties Treat schema objects as if `additionalProperties: true` is set
--empty-objects-unknown Generate `unknown` instead of `Record<string, never>` for empty objects
--default-non-nullable Set to `false` to ignore default values when generating non-nullable types
--properties-required-by-default Treat schema objects as if `required` is set to all properties by default
--array-length Generate tuples using array minItems / maxItems
--path-params-as-types Convert paths to template literal types
--alphabetize Sort object keys alphabetically
--exclude-deprecated Exclude deprecated types
--no-blob-from-binary If this option is enabled, binary format fields will not be converted to Blob types, preserving the native representation
--explicit-component-exports Enabling this option will export API components as separate type aliases, alongside `components` interface
-h, --help display help for command
```

## Usage example
Expand Down
17 changes: 14 additions & 3 deletions packages/plugin/src/lib/RedoclyConfigCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,16 @@ export class RedoclyConfigCommand extends Command {
}

redocAPIsToQraftEntries.forEach(([apiName, api]) => {
const globalQraftConfig =
'x-openapi-qraft' in redoc.rawConfig
? redoc.rawConfig['x-openapi-qraft']
: undefined;

const {
['x-openapi-qraft']: { ['output-dir']: outputDir, ...qraftConfig },
['x-openapi-qraft']: {
['output-dir']: outputDir,
...apiQraftConfig
},
} = api;

const cwd = fileURLToPath(this.cwd);
Expand All @@ -115,7 +123,10 @@ export class RedoclyConfigCommand extends Command {
...parseConfigToArgs({
redocly: relative(cwd, redocConfigFile),
'output-dir': relative(cwd, outputDir),
...qraftConfig,
...(globalQraftConfig && typeof globalQraftConfig === 'object'
? globalQraftConfig
: undefined),
...apiQraftConfig,
}),
];
});
Expand Down Expand Up @@ -155,7 +166,7 @@ export class RedoclyConfigCommand extends Command {
spinner.info(
`Generating API client for ${c.magenta(apiName)} with the following parameters:\n` +
c.gray.italic('bin ') +
`${c.green.italic(openAPIDocument)}` +
`${c.green.italic(openAPIDocument)} ` +
apiProcessArgv
.map((arg) =>
arg.startsWith('--')
Expand Down
32 changes: 32 additions & 0 deletions packages/plugin/src/lib/parseConfigToArgs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,36 @@ describe('configParser', () => {
'callbacks:setQueryData,getQueryData,fetchQuery',
]);
});

it('should parse complex nested mappings', () => {
expect(
parseConfigToArgs({
'override-import-type': {
services: {
'@openapi-qraft/tanstack-query-react-types': {
ResultError: '../ResponseError',
ResultSuccess: '../ResultSuccess',
},
'@openapi-qraft/react': {
UseQueryOperation: '../UseQueryOperation',
},
},
'create-client': {
'@openapi-qraft/react': {
UseQueryOperation: '../UseQueryOperation',
},
},
},
})
).toEqual([
'--override-import-type',
'services',
'@openapi-qraft/tanstack-query-react-types:ResultError:../ResponseError',
'@openapi-qraft/tanstack-query-react-types:ResultSuccess:../ResultSuccess',
'@openapi-qraft/react:UseQueryOperation:../UseQueryOperation',
'--override-import-type',
'create-client',
'@openapi-qraft/react:UseQueryOperation:../UseQueryOperation',
]);
});
});
29 changes: 23 additions & 6 deletions packages/react-client/redocly.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
x-openapi-qraft:
plugin:
tanstack-query-react: true
openapi-typescript: true

rules:
operation-operationId-unique:
severity: 'error'
Expand All @@ -6,9 +11,6 @@ apis:
main:
root: ../test-fixtures/openapi.json
x-openapi-qraft:
plugin:
tanstack-query-react: true
openapi-typescript: true
output-dir: src/tests/fixtures/api
clean: true
enum-values: true
Expand Down Expand Up @@ -37,12 +39,27 @@ apis:
filter-services:
- '/approval_policies/**'
- '/files/**'
operation-predefined-parameters:
'/approval_policies/**': 'header.x-monite-entity-id'
override-import-type:
services:
'@openapi-qraft/tanstack-query-react-types':
OperationError: '../../type-overrides/operation-error.js'
'@tanstack/react-query':
UseSuspenseQueryOptions: '../../type-overrides/suspense-query.js'
UseSuspenseQueryResult: '../../type-overrides/suspense-query.js'
UseInfiniteQueryResult: '../../type-overrides/use-infinite-query-result.js'
create-api-client:
'@openapi-qraft/react':
CreateAPIQueryClientOptions: '../type-overrides/create-query-client-options.js'
create-predefined-parameters-request-fn:
'@openapi-qraft/react':
RequestFn: '../type-overrides/qraft-predefined-parameters.js'
'@openapi-qraft/react/qraftPredefinedParametersRequestFn':
QraftPredefinedParameterValue: '../type-overrides/qraft-predefined-parameters.js'
files:
root: ../test-fixtures/openapi.json
x-openapi-qraft:
plugin:
tanstack-query-react: true
openapi-typescript: true
output-dir: src/tests/fixtures/files-api
clean: true
openapi-types-file-name: internal-openapi.ts
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type { CreateAPIQueryClientOptions } from '@openapi-qraft/react';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type { OperationError } from '@openapi-qraft/tanstack-query-react-types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export type { RequestFn } from '@openapi-qraft/react';
export type { QraftPredefinedParameterValue } from '@openapi-qraft/react/qraftPredefinedParametersRequestFn';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type {
UseSuspenseQueryOptions,
UseSuspenseQueryResult,
} from '@tanstack/react-query';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type { UseInfiniteQueryResult } from '@tanstack/react-query';
Loading
Loading