diff --git a/.changeset/blue-bikes-approve.md b/.changeset/blue-bikes-approve.md new file mode 100644 index 000000000..b1dbc185a --- /dev/null +++ b/.changeset/blue-bikes-approve.md @@ -0,0 +1,170 @@ +--- +'@hey-api/openapi-ts': minor +'@hey-api/docs': minor +--- + +feat: make plugins first-class citizens + +This release makes plugins first-class citizens. In order to achieve that, the following breaking changes were introduced. + +### Removed CLI options + +The `--types`, `--schemas`, and `--services` CLI options have been removed. You can list which plugins you'd like to use explicitly by passing a list of plugins as `--plugins ` + +### Removed `*.export` option + +Previously, you could explicitly disable export of certain artifacts using the `*.export` option or its shorthand variant. These were both removed. You can now disable export of specific artifacts by manually defining an array of `plugins` and excluding the unwanted plugin. + +::: code-group + +```js [shorthand] +export default { + client: '@hey-api/client-fetch', + input: 'path/to/openapi.json', + output: 'src/client', + schemas: false, // [!code --] + plugins: ['@hey-api/types', '@hey-api/services'], // [!code ++] +}; +``` + +```js [*.export] +export default { + client: '@hey-api/client-fetch', + input: 'path/to/openapi.json', + output: 'src/client', + schemas: { + export: false, // [!code --] + }, + plugins: ['@hey-api/types', '@hey-api/services'], // [!code ++] +}; +``` + +::: + +### Renamed `schemas.name` option + +Each plugin definition contains a `name` field. This was conflicting with the `schemas.name` option. As a result, it has been renamed to `nameBuilder`. + +```js +export default { + client: '@hey-api/client-fetch', + input: 'path/to/openapi.json', + output: 'src/client', + schemas: { + name: (name) => `${name}Schema`, // [!code --] + }, + plugins: [ + // ...other plugins + { + nameBuilder: (name) => `${name}Schema`, // [!code ++] + name: '@hey-api/schemas', + }, + ], +}; +``` + +### Removed `services.include` shorthand option + +Previously, you could use a string value as a shorthand for the `services.include` configuration option. You can now achieve the same result using the `include` option. + +```js +export default { + client: '@hey-api/client-fetch', + input: 'path/to/openapi.json', + output: 'src/client', + services: '^MySchema', // [!code --] + plugins: [ + // ...other plugins + { + include: '^MySchema', // [!code ++] + name: '@hey-api/services', + }, + ], +}; +``` + +### Renamed `services.name` option + +Each plugin definition contains a `name` field. This was conflicting with the `services.name` option. As a result, it has been renamed to `serviceNameBuilder`. + +```js +export default { + client: '@hey-api/client-fetch', + input: 'path/to/openapi.json', + output: 'src/client', + services: { + name: '{{name}}Service', // [!code --] + }, + plugins: [ + // ...other plugins + { + serviceNameBuilder: '{{name}}Service', // [!code ++] + name: '@hey-api/services', + }, + ], +}; +``` + +### Renamed `types.dates` option + +Previously, you could set `types.dates` to a boolean or a string value, depending on whether you wanted to transform only type strings into dates, or runtime code too. Many people found these options confusing, so they have been simplified to a boolean and extracted into a separate `@hey-api/transformers` plugin. + +```js +export default { + client: '@hey-api/client-fetch', + input: 'path/to/openapi.json', + output: 'src/client', + types: { + dates: 'types+transform', // [!code --] + }, + plugins: [ + // ...other plugins + { + dates: true, // [!code ++] + name: '@hey-api/transformers', + }, + ], +}; +``` + +### Removed `types.include` shorthand option + +Previously, you could use a string value as a shorthand for the `types.include` configuration option. You can now achieve the same result using the `include` option. + +```js +export default { + client: '@hey-api/client-fetch', + input: 'path/to/openapi.json', + output: 'src/client', + types: '^MySchema', // [!code --] + plugins: [ + // ...other plugins + { + include: '^MySchema', // [!code ++] + name: '@hey-api/types', + }, + ], +}; +``` + +### Renamed `types.name` option + +Each plugin definition contains a `name` field. This was conflicting with the `types.name` option. As a result, it has been renamed to `style`. + +```js +export default { + client: '@hey-api/client-fetch', + input: 'path/to/openapi.json', + output: 'src/client', + types: { + name: 'PascalCase', // [!code --] + }, + plugins: [ + // ...other plugins + { + name: '@hey-api/types', + style: 'PascalCase', // [!code ++] + }, + ], +}; +``` diff --git a/docs/index.md b/docs/index.md index fe64f186b..082f0558a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,7 +3,7 @@ layout: home hero: name: High-quality tools for interacting with APIs - tagline: Codegen for your TypeScript projects. Trusted more than 500k times each month to generate reliable API clients and SDKs. + tagline: Codegen for your TypeScript projects. Trusted more than 600k times each month to generate reliable API clients and SDKs. actions: - theme: brand text: Get Started diff --git a/docs/openapi-ts/configuration.md b/docs/openapi-ts/configuration.md index 18d4e3957..defe9d2aa 100644 --- a/docs/openapi-ts/configuration.md +++ b/docs/openapi-ts/configuration.md @@ -5,7 +5,7 @@ description: Configure @hey-api/openapi-ts. # Configuration -`@hey-api/openapi-ts` supports loading configuration from any file inside your project root directory supported by [jiti loader](https://github.com/unjs/c12?tab=readme-ov-file#-features). Below are the most common file formats. +`@hey-api/openapi-ts` supports loading configuration from any file inside your project root folder supported by [jiti loader](https://github.com/unjs/c12?tab=readme-ov-file#-features). Below are the most common file formats. ::: code-group @@ -41,128 +41,25 @@ export default { Alternatively, you can use `openapi-ts.config.js` and configure the export statement depending on your project setup. -## Clients - -Clients are responsible for sending the actual HTTP requests. Apart from input and output, this is the only required option. - -You can learn more on the [Clients](/openapi-ts/clients) page. - - - - -## Services +## Input -Services are abstractions on top of clients and serve the same purpose. By default, `@hey-api/openapi-ts` will generate a flat service layer. Your choice to use services comes down to personal preferences and bundle size considerations. - -You can learn more on the [Output](/openapi-ts/output#api-services) page. - -## Enums - -By default, `@hey-api/openapi-ts` will only emit enums as types. You may want to generate runtime artifacts. A good use case is iterating through possible field values without manually typing arrays. To emit runtime enums, set `types.enums` to a valid option. - -::: code-group - -```js [disabled] -export default { - client: '@hey-api/client-fetch', - input: 'path/to/openapi.json', - output: 'src/client', - types: { - enums: false, // [!code ++] - }, -}; -``` - -```js [javascript] -export default { - client: '@hey-api/client-fetch', - input: 'path/to/openapi.json', - output: 'src/client', - types: { - enums: 'javascript', // [!code ++] - }, -}; -``` - -```js [typescript] -export default { - client: '@hey-api/client-fetch', - input: 'path/to/openapi.json', - output: 'src/client', - types: { - enums: 'typescript', // [!code ++] - }, -}; -``` +Input is the first thing you must define. It can be a local path, remote URL, or a string content resolving to an OpenAPI specification. Hey API supports all valid OpenAPI versions and file formats. +::: info +We use [`@apidevtools/json-schema-ref-parser`](https://github.com/APIDevTools/json-schema-ref-parser) to resolve file locations. Please note that accessing a HTTPS URL on localhost has a known [workaround](https://github.com/hey-api/openapi-ts/issues/276). ::: -We recommend exporting enums as plain JavaScript objects. [TypeScript enums](https://www.typescriptlang.org/docs/handbook/enums.html) are not a type-level extension of JavaScript and pose [typing challenges](https://dev.to/ivanzm123/dont-use-enums-in-typescript-they-are-very-dangerous-57bh). +## Output -## JSON Schemas - -By default, `@hey-api/openapi-ts` generates schemas from your OpenAPI specification. A great use case for schemas is client-side form input validation. If you're using OpenAPI 3.1, your [schemas](/openapi-ts/output#json-schemas) are JSON Schema compliant and can be used with other tools supporting JSON Schema. However, if you only want to validate form input, you probably don't want to include string descriptions inside your bundle. You can choose your preferred type using `schemas.type` option. - -::: code-group - -```js [json] -export default { - client: '@hey-api/client-fetch', - input: 'path/to/openapi.json', - output: 'src/client', - schemas: { - type: 'json', // [!code ++] - }, -}; -``` - -```js [form] -export default { - client: '@hey-api/client-fetch', - input: 'path/to/openapi.json', - output: 'src/client', - schemas: { - type: 'form', // [!code ++] - }, -}; -``` - -```js [disabled] -export default { - client: '@hey-api/client-fetch', - input: 'path/to/openapi.json', - output: 'src/client', - schemas: false, // [!code ++] -}; -``` +Output is the next thing to define. It can be either a string pointing to the destination folder or a configuration object containing the destination folder path and optional settings (these are described below). +::: tip +You should treat the output folder as a dependency. Do not directly modify its contents as your changes might be erased when you run `@hey-api/openapi-ts` again. ::: ## Formatting -By default, `@hey-api/openapi-ts` will not automatically format your output. To enable this feature, set `output.format` to a valid formatter. +To format your output folder contents, set `output.format` to a valid formatter. ::: code-group @@ -205,7 +102,7 @@ You can also prevent your output from being formatted by adding your output path ## Linting -By default, `@hey-api/openapi-ts` will not automatically lint your output. To enable this feature, set `output.lint` to a valid linter. +To lint your output folder contents, set `output.lint` to a valid linter. ::: code-group @@ -246,6 +143,43 @@ export default { You can also prevent your output from being linted by adding your output path to the linter's ignore file. +## Clients + +Clients are responsible for sending the actual HTTP requests. The `client` value is not required, but you must define it if you're generating the service layer (enabled by default). + +You can learn more on the [Clients](/openapi-ts/clients) page. + + + + +## Plugins + +Plugins are responsible for generating artifacts from your input. By default, Hey API will generate TypeScript interfaces, JSON Schemas, and services from your OpenAPI specification. You can add, remove, or customize any of the plugins. In fact, we highly encourage you to do so! + +You can learn more on the [Output](/openapi-ts/output) page. + ## Config API You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/types/config.ts) interface. diff --git a/docs/openapi-ts/get-started.md b/docs/openapi-ts/get-started.md index f65c79d20..9dd765e37 100644 --- a/docs/openapi-ts/get-started.md +++ b/docs/openapi-ts/get-started.md @@ -13,7 +13,7 @@ import { embedProject } from '../embed' This package is in initial development. The interface might change before it becomes stable. We encourage you to leave feedback on [GitHub](https://github.com/hey-api/openapi-ts/issues). ::: -[@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) is an OpenAPI to TypeScript codegen trusted more than 500k times each month to generate reliable API clients and SDKs. +[@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) is an OpenAPI to TypeScript codegen trusted more than 600k times each month to generate reliable API clients and SDKs.