Skip to main content
Version: 2.x ๐Ÿšง

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.

tip

If you missed the installation step, you can install the @openapi-qraft/cli using the following command:

npm install -D @openapi-qraft/cli@next

Usage exampleโ€‹

The command below generates Qraft API services for the OpenAPI schema and places them in the src/api directory:

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

Optionsโ€‹

Requiredโ€‹

  • -o <path>, --output-dir <path>: Specify where to output the generated services.
    • Example: --output-dir src/api

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. See micromatch package 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/
  • --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' - set header.x-monite-version as optional parameters for all services.
      • --operation-predefined-parameters '/**,!/auth/token:header.x-entity-id' - set header.x-entity-id as optional parameters for all services except /auth/token.
      • --operation-predefined-parameters 'post,put /**:header.x-entity-id' - set the Header record x-entity-id as an optional parameter for the POST and PUT methods.

    Note: In future versions of the library, this feature will be expanded. Not only will it make parameters optional, but it will also offer typed suggestions for these predefined parameters when creating a client. This enhancement will further improve type safety and developer experience.

  • --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 all GET operations with Id suffix to findOne.
      • --operation-name-modifier 'get /**:get(.*) ==> find-$1' - will change all GET operations with get prefix to findById | 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 all PUT and PATCH operations with Id suffix to updateOne.
      • --operation-name-modifier '/posts,/files:create[a-zA-Z]+ ==> createOne' - will change all operations under /posts and /files to createOne if the operation name starts with create.
      • --operation-name-modifier 'post /files ==> createOne' 'put /posts ==> updateOne' - will change all POST operations under /files to createOne and all PUT operations under /posts to updateOne.
  • --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. (optional, default: endpoint[0]).

    • Examples:
      • --service-name-base endpoint[0] generates services/FooService.ts for the endpoint /foo/bar/baz
      • --service-name-base endpoint[1] generates services/BarService.ts for the endpoint /foo/bar/baz
      • --service-name-base endpoint[3] generates services/BazService.ts for the endpoint /foo/bar/baz (if the endpoint is shorter than the index, the last part is used)
      • --service-name-base tags will 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 generate services/FooService.ts and services/BarService.ts.
        • If there are no tags for the operation, the services will be created under the default tag. Operation with empty tags: [] will generate services/DefaultService.ts.
  • --explicit-import-extensions: Include explicit .js extensions in all import statements. Ideal for projects using ECMAScript modules when TypeScript's --moduleResolution is node16 or nodenext (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 */'
  • --postfix-services <string>: Customize the generated service names with a specific postfix (optional, default: Service).

    • Example: --postfix-services Endpoint will generate services/UserEndpoint.ts instead of services/UserService.ts.
  • --plugin <name_1> --plugin <name_2>: Generator plugins to be used. (choices: tanstack-query-react, openapi-typescript)

    • Examples:
      • --plugin tanstack-query-react --plugin openapi-typescript generates Qraft Services and openapi-typescript types file.
      • --plugin tanstack-query-react generates Qraft Services only.
      • --plugin openapi-typescript generates openapi-typescript types file only.
  • -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 original openapi-typescript package is that format: binary fields default to Blob types instead of remaining as string. This behavior can be altered using the --no-blob-from-binary option.
  • tanstack-query-react - Generates Qraft API services for React.
tip

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 have schema.d.ts as a result of the openapi-typescript utility). You also probably don't need the --plugin openapi-typescript option in this case.
    • 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-typescript is 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'
  • --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]: Export the OpenAPI schema types from the generated ./index.ts file. (optional, default: true, if --plugin openapi-typescript is used)

--plugin openapi-typescript optionsโ€‹

  • --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 --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, format: binary fields will not be converted to Blob types, preserving the native type. Could be used with --plugin openapi-typescript option.
  • --explicit-component-exports: Enabling this option will export API components as separate type aliases, alongside components interface.

In-project Setupโ€‹

Add the following "scripts" to your package.json file:

package.json
{
"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
}
}