Skip to content

Latest commit

 

History

History
226 lines (181 loc) · 15.6 KB

README.md

File metadata and controls

226 lines (181 loc) · 15.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@next

Usage

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

Generate TypeScript types from OpenAPI 3.x Document. Based on "openapi-typescript" (https://github.com/drwpow/openapi-typescript/)

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 by glob pattern. Eg: "/user/**,/post/**". See NPM `micromatch` package for more details.
  --operation-predefined-parameters <patterns...>  Predefined parameters for services. The specified services parameters will be optional. Eg: "/**: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 */)
  --openapi-types-import-path <path>               Path to schema types file (.d.ts), eg: "../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]                    Export the OpenAPI schema types from the generated `./index.ts` file (default: true)
  --operation-generics-import-path <path>          Path to operation generics file (default: "@openapi-qraft/react")
  --openapi-types-file-name <path>                 OpenAPI Schema types file name, eg: "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 most wanted option 💎 allows 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.
  • --explicit-component-exports: Enabling this option will export API components as separate type aliases, alongside components interface.

  • --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 [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]: 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.
  • -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.

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.