Skip to content

Latest commit

 

History

History
245 lines (200 loc) · 17.6 KB

README.md

File metadata and controls

245 lines (200 loc) · 17.6 KB

@openapi-qraft/cli

@openapi-qraft/cli is a powerful command-line utility designed to streamline the development process by generating service declarations and typed React Query interfaces directly from an OpenAPI Schema. With @openapi-qraft/cli, frontend developers can easily generate typed API clients, ensuring type safety and improving development efficiency within React applications.

Features

  • Typed React Query Interfaces: Create typed React Query hooks for seamless and type-safe API requests.
  • Generate Typed Services: Automatically generate service declarations from an OpenAPI Schema.

Installation

npm install -g @openapi-qraft/cli

Usage

Usage: openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript [input] [options]

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)

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)
  --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

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.
  • --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.
  • --explicit-component-exports: Enabling this option will export API components as separate type aliases, alongside components interface.

  • --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 file
      • openapi-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-help
  • --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]).

    • endpoint[<index>] - Use the path segment (e.g., /0/1/2) as the base name for the service.
      • 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)
        • 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/bar generates get operation name.
            • --service-name-base endpoint[1] for the endpoint /api/foo/bar generates getBar operation name.
    • tags - Use the OpenAPI Operation tags as the base name of the service.
      • Examples:
        • --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.
          • If tags are used as the base name, operation names will be generated based on the operationId from the OpenAPI Operation, or from the path if operationId is not provided. You can use --operation-name-modifier to customize the operation names.
  • --explicit-import-extensions [extension]: All import statements will contain an explicit file extension. Ideal for projects using ECMAScript modules when TypeScript's --moduleResolution is node16 or nodenext. 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 */'
  • --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.

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]: Add an export statement of the generated OpenAPI document types from the ./index.ts file. Useful for sharing types within your project. (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:

{
  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
  },
}

Contributing

Contributions to @openapi-qraft/cli are welcome! Please feel free to submit issues, pull requests, or suggest features to help improve the utility.

License

This project is licensed under the MIT License.