OpenAPI Qraft CLI
OpenAPI Qraft CLI is a command-line utility that generates API schemas and interfaces for the @openapi-qraft/react.
With the @openapi-qraft/cli and @openapi-qraft/react packages, you can build a type-safe API client with React Hooks
based on the OpenAPI Document.
Qraft relies on types from the generation result of openapi-typescript package,
which is a powerful tool for generating types from an OpenAPI schema.
If you missed the installation step, you can install the @openapi-qraft/cli using the following command:
- npm
- yarn
- pnpm
npm install -D @openapi-qraft/cli
yarn add --dev @openapi-qraft/cli
pnpm add -D @openapi-qraft/cli
Usageโ
The command below generates Qraft API services for the OpenAPI schema and places them in the src/api directory:
- npm
- yarn
- pnpm
npx openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml \
--output-dir src/api
yarn exec openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml \
--output-dir src/api
pnpm exec openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml \
--output-dir src/api
Optionsโ
Requiredโ
-o <path>, --output-dir <path>: Specify where to output the generated services.- Example:
--output-dir src/api
- Example:
Edge-case Optionsโ
-
-rm, --clean: Clean the specified output directory services before generating to remove stale files (optional). -
--filter-services <glob-patterns...>: Filter services to be generated by glob pattern (optional).- Pattern syntax:
<glob-pattern>,<glob-pattern>,...- comma-separated list of glob patterns. Seemicromatchpackage for more details. More than one pattern can be specified.
- Examples:
--filter-services '/user/**,/post/**'- include only API endpoints that start with/user/or/post/--filter-services '**,!/internal/**'- include all API endpoints except those that start with/internal/
- Pattern syntax:
-
--operation-predefined-parameters <patterns...>: Predefined parameters for services. The specified services parameters will be optional. (optional)- Pattern syntax:
<path glob>:<operation parameter>,...<method> <path glob>:<operation parameter>,...- Each modifier consists of an optional method, a path glob pattern, a colon, and a comma-separated list of operation parameters to be set as optional. More than one predefined parameter option can be specified.
This option ๐ is arguably one of the most awesome features, allowing you to set default parameters across multiple endpoints. However, if an endpoint doesn't contain a parameter specified in this option, an error will be displayed. For example:
โ Missing predefined parameter 'header' 'x-monite-version' in 'post /files' in '/**'To resolve such errors, you can exclude specific endpoints from the predefined parameters using the negation syntax in the glob pattern, like:
--operation-predefined-parameters '/**,!/files:header.x-monite-version'- Examples:
--operation-predefined-parameters '/**:header.x-monite-version'- setheader.x-monite-versionas optional parameters for all services.--operation-predefined-parameters '/**,!/auth/token:header.x-entity-id'- setheader.x-entity-idas optional parameters for all services except/auth/token.--operation-predefined-parameters 'post,put /**:header.x-entity-id'- set theHeaderrecordx-entity-idas an optional parameter for thePOSTandPUTmethods.
- Pattern syntax:
-
--operation-name-modifier <patterns...>: Modifies operation names using a pattern.- Pattern syntax:
<path glob>:<regular expression> ==> <new operation name><method> <path glob>:<regular expression> ==> <new operation name>- Each modifier consists of an optional method, a path glob pattern,
a colon, and a regular expression that matches the operation name. The part after
==>is the new operation name. More than one modifier option can be specified.
- Examples:
--operation-name-modifier 'get /**:[A-Za-z]+Id ==> findOne'- will change allGEToperations withIdsuffix tofindOne.--operation-name-modifier 'get /**:get(.*) ==> find-$1'- will change allGEToperations withgetprefix tofindById | findAll | ....- The pattern is a regular expression that matches the operation name.
- The operation name is converted to Camel Case. Spaces, hyphens, and underscores are removed.
--operation-name-modifier 'put,patch /**:[A-Za-z]+Id ==> updateOne'- will change allPUTandPATCHoperations withIdsuffix toupdateOne.--operation-name-modifier '/posts,/files:create[a-zA-Z]+ ==> createOne'- will change all operations under/postsand/filestocreateOneif the operation name starts withcreate.--operation-name-modifier 'post /files ==> createOne' 'put /posts ==> updateOne'- will change allPOSToperations under/filestocreateOneand allPUToperations under/poststoupdateOne.
- Pattern syntax:
-
--explicit-component-exports: Enabling this option will export API components as separate type aliases, alongsidecomponentsinterface. -
--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]. (optional)- Examples:
--redocly- use the default Redocly configuration file--redocly ./my-redocly-config.yaml- use a custom Redocly configuration fileopenapi-qraft my-api@v1 external-api --redocly- generate clients for multiple APIs defined in the Redocly configuration
- For more information about this option, use the command:
--redocly-helpor read the docs.
- Examples:
-
--service-name-base <endpoint[<index>] | tags>: Use OpenAPI Operationendpoint[<index>]path part (e.g.:/0/1/2) ortagsas the base name of the service. (optional, default:endpoint[0]).endpoint[<index>]- Use the path segment (e.g.,/0/1/2) as the base name for the service.- Examples:
--service-name-base endpoint[0]generatesservices/FooService.tsfor the endpoint/foo/bar/baz--service-name-base endpoint[1]generatesservices/BarService.tsfor the endpoint/foo/bar/baz--service-name-base endpoint[3]generatesservices/BazService.tsfor the endpoint/foo/bar/baz(if the endpoint is shorter than the index, the last part is used)- If used
endpoint[<index>]as the base name, operation names will be generated according to the specified index.- For example:
--service-name-base endpoint[1]for the endpoint/api/bargeneratesgetoperation name.--service-name-base endpoint[1]for the endpoint/api/foo/bargeneratesgetBaroperation name.
- For example:
- Examples:
tags- Use the OpenAPI Operationtagsas the base name of the service.- Examples:
--service-name-base tagswill generate services based on the OpenAPI Operation tags instead of the endpoint.- If multiple tags are present for the operation, similar services will be created for each tag. Operation with
tags: [Foo, Bar]will generateservices/FooService.tsandservices/BarService.ts. - If there are no tags for the operation, the services will be created under the
defaulttag. Operation with emptytags: []will generateservices/DefaultService.ts. - If
tagsare used as the base name, operation names will be generated based on theoperationIdfrom the OpenAPI Operation, or from the path ifoperationIdis not provided. You can use--operation-name-modifierto customize the operation names.
- If multiple tags are present for the operation, similar services will be created for each tag. Operation with
- Examples:
-
--explicit-import-extensions [extension]: All import statements will contain an explicit file extension. Ideal for projects using ECMAScript modules when TypeScript's --moduleResolution isnode16ornodenext. Choices:.js,.ts, preset:.js. (optional) -
--file-header <string>: Add a custom header to each generated file, useful for disabling linting rules or adding file comments (optional).- Example:
--file-header '/* eslint-disable */'
- Example:
-
--postfix-services <string>: Customize the generated service names with a specific postfix (optional, default:Service).- Example:
--postfix-services Endpointwill generateservices/UserEndpoint.tsinstead ofservices/UserService.ts.
- Example:
-
--plugin <name_1> --plugin <name_2>: Generator plugins to be used. (choices:tanstack-query-react,openapi-typescript)- Examples:
--plugin tanstack-query-react --plugin openapi-typescriptgenerates Qraft Services andopenapi-typescripttypes file.--plugin tanstack-query-reactgenerates Qraft Services only.--plugin openapi-typescriptgeneratesopenapi-typescripttypes file only.
- Examples:
-
-h, --help: Display help for the command (optional).
Plugin Systemโ
The following plugins are currently supported:
openapi-typescript- Generates TypeScript types from an OpenAPI Document. The main difference from the originalopenapi-typescriptpackage is thatformat: binaryfields default toBlobtypes instead of remaining asstring. This behavior can be altered using the--no-blob-from-binaryoption.tanstack-query-react- Generates Qraft API services for React.
Plugin must be provided with the --plugin <name> option. By default, the tanstack-query-react plugin is used.
It is possible to use multiple plugins at the same time. For example, --plugin tanstack-query-react --plugin openapi-typescript generates Qraft API services & schema types file.
--plugin tanstack-query-react optionsโ
-
--openapi-types-import-path <path>: Set the path to the schema types definition file to ensure consistent type usage (assumed, you already haveschema.d.tsas a result of theopenapi-typescriptutility). You also probably don't need theoption in this case.--plugin openapi-typescript- The path is the exact import specifier used in the generated services. It should be relative to the service
output directory. Optional, if the
--plugin openapi-typescriptis used. Required otherwise.- Examples:
--openapi-types-import-path ../openapi.d.ts--openapi-types-import-path '@/api/openapi.d.ts'--openapi-types-import-path '@external-package-types'
- Examples:
- The path is the exact import specifier used in the generated services. It should be relative to the service
output directory. Optional, if the
-
--operation-generics-import-path <path>: Define the path to the operation generics file, allowing for custom operation handling (optional, default:@openapi-qraft/react). -
--export-openapi-types [bool]: Add an export statement of the generated OpenAPI document types from the./index.tsfile. Useful for sharing types within your project. (optional, default:true, if--plugin openapi-typescriptis used) -
--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. The option expects a filepath followed by one or more type override definitions in formatoriginalModule:importTypeName:customImportPath. Can be specified multiple times to define different overrides. (optional)- Examples:
--override-import-type services @openapi-qraft/tanstack-query-react-types:OperationError:../../type-overrides/operation-error.js- replaces the import ofOperationErrortype from@openapi-qraft/tanstack-query-react-typeswith an import from../../type-overrides/operation-error.jsin all service files.--override-import-type create-api-client @openapi-qraft/react:CreateAPIQueryClientOptions:../type-overrides/create-query-client-options.js- replaces the import in thecreate-api-client.tsfile.
- This option is particularly useful when you need to provide custom implementations of library types that better suit your project's needs.
- Examples:
-
--create-api-client-fn <functionName> [options...]: Configure API client creation function. Allows specifying the function name used to create the API client, as well as fine-tuning included services and callbacks. You can specify this option multiple times to generate several different API client creation functions from a single OpenAPI document - for example, a fully-featured client for Node.js and a lightweight client for React or service workers. (optional) See examples on theuseQuery()documentation page.- Options:
filename:<name>- filename where the function will be generated (defaults to function name)services:[all|none]- Specify whether the generated API client should include services: either all available services, or no services by default.all- include all available servicesnone- don't include any services by default (they must be specified when calling the function)
callbacks:[all|none|callback1,callback2,...]- list of callbacks to be included in the API client by defaultall- include all available callbacks (useQuery, useMutation, setQueryData, etc.)none- don't include any callbacks by default (they must be specified when calling the function)useQuery,useMutation,...- list of specific callbacks to include
- Examples:
--create-api-client-fn createAPIClient services:all callbacks:all- creates thecreateAPIClient()function that includes all services and all callbacks by default (default behavior)--create-api-client-fn createMinimalAPIClient services:none callbacks:none- creates thecreateMinimalAPIClient()function that generates a super lightweight ๐ชถ API client with zero overhead - no default services or callbacks included. Perfect for building a minimal bundle size client where you explicitly control which services and callbacks to include.--create-api-client-fn createCustomClient filename:create-custom-api services:none callbacks:setQueryData,getQueryData- creates thecreateCustomClient()function in thecreate-custom-api.tsfile with no default services and onlysetQueryData()andgetQueryData()callbacks
tipWhen generating multiple API client functions with different parameters, it might be more convenient to use a configuration file instead of command-line parameters. See the Redocly configuration documentation for more details on how to configure multiple create API client functions in a YAML file.
- Options:
--plugin openapi-typescript optionsโ
--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 TypeScript enums instead of unions.--enum-values: Export enum values as arrays.--dedupe-enums: Dedupe enum types when--enumis set.-t, --export-type: Export top-leveltypeinstead ofinterface.--immutable: Generate readonly types.--additional-properties: Treat schema objects as ifadditionalProperties: trueis set.--empty-objects-unknown: Generateunknowninstead ofRecord<string, never>for empty objects.--default-non-nullable: Set tofalseto ignore default values when generating non-nullable types.--properties-required-by-default: Treat schema objects as ifrequiredis set to all properties by default.--array-length: Generate tuples using arrayminItems/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,format: binaryfields will not be converted toBlobtypes, preserving the native type. Could be used with--plugin openapi-typescriptoption.--explicit-component-exports: Enabling this option will export API components as separate type aliases, alongsidecomponentsinterface.
In-project Setupโ
Add the following "scripts" to your package.json file:
{
"devDependencies": {
"@openapi-qraft/cli": "latest"
},
"scripts": {
"generate-client": "openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml --output-dir src/api",
// ...other scripts
}
}