Skip to content

Commit

Permalink
feat(api): add support for openapi-ts.config.js file
Browse files Browse the repository at this point in the history
  • Loading branch information
mrlubos committed Mar 18, 2024
1 parent 486ba7f commit 81d2360
Show file tree
Hide file tree
Showing 122 changed files with 1,326 additions and 817 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dist
node_modules
samples
temp
test/e2e/generated
test/generated
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@typescript-eslint/ban-ts-ignore": 0,
"@typescript-eslint/explicit-function-return-type": 0,
"@typescript-eslint/explicit-module-boundary-types": 0,
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-inferrable-types": 0,
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/no-var-requires": 0,
Expand Down
9 changes: 5 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
.DS_Store
.idea
.tmp
junit.xml
node_modules
npm-debug.log*
temp
yarn-debug.log*
yarn-error.log*
junit.xml
.DS_Store
.tmp
.idea

# IDE config
.vscode
Expand Down
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20.10.0
132 changes: 93 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

> ✨ Turn your OpenAPI specification into a beautiful TypeScript client
## Table of Contents
- [Table of Contents](#table-of-contents)
- [About](#about)
- [Features](#features)
- [Quick Start](#quick-start)
- [Installation](#installation)
- [Configuration](#configuration)
- [Formatting](#formatting)
- [Enums](#enums)
- [Config API](#config-api)
- [Contributing](#contributing)

## About

This is an opinionated fork of the [openapi-typescript-codegen](https://github.com/ferdikoomen/openapi-typescript-codegen) package. We created it after the original project became [unmaintained](https://github.com/ferdikoomen/openapi-typescript-codegen/issues/1276#issuecomment-1302392146) because we wanted to support OpenAPI v3.1 introduced in the FastAPI [v0.99.0](https://fastapi.tiangolo.com/release-notes/#0990) release. We plan to resolve the most pressing issues in the original project – open an issue if you'd like to prioritise your use case!
Expand All @@ -15,31 +27,105 @@ This is an opinionated fork of the [openapi-typescript-codegen](https://github.c
- can be used with CLI, Node.js, or npx
- abortable requests through cancellable promise pattern

## Quickstart
## Quick Start

The fastest way to use this package is via npx
The fastest way to use `openapi-ts` is via npx

```sh
npx @nicolas-chaulet/openapi-typescript-codegen -i path/to/openapi.json -o src/client
```

Congratulations on generating your first client! 🎉
Congratulations on creating your first client! 🎉

## Install
## Installation

```
```sh
npm install @nicolas-chaulet/openapi-typescript-codegen --save-dev
```

or

```
```sh
yarn add @nicolas-chaulet/openapi-typescript-codegen -D
```

## Usage
and add a script to your `package.json` file

```json
"scripts": {
"openapi-ts": "openapi-ts"
}
```

> ⚠️ You need to be running Node.js v18 or newer
## Configuration

<!-- `openapi-ts` supports loading configuration from a file inside your project root directory. You can either create a `openapi-ts.config.js` file -->

`openapi-ts` supports loading configuration from a file inside your project root directory. You just need to create a `openapi-ts.config.js` file

```js
/** @type {import('@nicolas-chaulet/openapi-typescript-codegen').Config} */
export default {
input: 'path/to/openapi.json',
output: 'src/client',
}
```

<!-- or `openapi-ts.config.ts`
```ts
import { defineConfig } from '@nicolas-chaulet/openapi-typescript-codegen';
export default defineConfig({
input: 'path/to/openapi.json',
output: 'src/client',
})
``` -->

### Formatting

By default, `openapi-ts` will automatically format your client according to your project configuration. To disable automatic formatting, set `autoformat` to false

```ts
import { defineConfig } from '@nicolas-chaulet/openapi-typescript-codegen';

export default defineConfig({
autoformat: false,
input: 'path/to/openapi.json',
output: 'src/client',
})
```

You can also prevent your client from being processed by formatters and linters by adding your output path to the tool's ignore file (e.g. `.eslintignore`, `.prettierignore`).

### Enums

We do not generate TypeScript [enums](https://www.typescriptlang.org/docs/handbook/enums.html) because they are not standard JavaScript and pose [typing challenges](https://dev.to/ivanzm123/dont-use-enums-in-typescript-they-are-very-dangerous-57bh). If you want to iterate through possible field values without manually typing arrays, you can export enums by running

```ts
import { defineConfig } from '@nicolas-chaulet/openapi-typescript-codegen';

export default defineConfig({
enums: true,
input: 'path/to/openapi.json',
output: 'src/client',
})
```

This will export your enums as plain JavaScript objects. For example, `Foo` will generate the following

```ts
export const FooEnum = {
FOO: 'foo',
BAR: 'bar',
} as const;
```

### Config API

```sh
$ openapi-ts --help

Usage: openapi-ts [options]
Expand All @@ -66,41 +152,9 @@ $ openapi-ts --help
-h, --help display help for command
```
## Formatting

By default, your client will be automatically formatted according to your configuration. To disable automatic formatting, run

```sh
openapi-ts -i path/to/openapi.json -o src/client --no-autoformat
```

You can also prevent your client from being processed by formatters and linters by adding your output path to the tool's ignore file (e.g. `.eslintignore`, `.prettierignore`).

## Enums

We do not generate TypeScript [enums](https://www.typescriptlang.org/docs/handbook/enums.html) because they are not standard JavaScript and pose [typing challenges](https://dev.to/ivanzm123/dont-use-enums-in-typescript-they-are-very-dangerous-57bh). If you want to iterate through possible field values without manually typing arrays, you can export enums by running

```sh
openapi-ts -i path/to/openapi.json -o src/client --enums
```

This will export your enums as plain JavaScript objects. For example, `Foo` will generate the following

```ts
export const FooEnum = {
FOO: 'foo',
BAR: 'bar',
} as const;
```

## Contributing
This section is WIP.
- recommend using VS Code
- configure Prettier

## Documentation

The original documentation can be found in the [openapi-typescript-codegen/wiki](https://github.com/ferdikoomen/openapi-typescript-codegen/wiki)

71 changes: 34 additions & 37 deletions bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,53 @@

'use strict';

const Path = require('path');
const { program } = require('commander');
const json = require('../package.json');
import { readFileSync } from 'node:fs';

import { program } from 'commander';

const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url)).toString());

const params = program
.name(Object.keys(json.bin)[0])
.name(Object.keys(pkg.bin)[0])
.usage('[options]')
.version(json.version)
.requiredOption('-i, --input <value>', 'OpenAPI specification, can be a path, url or string content (required)')
.requiredOption('-o, --output <value>', 'Output directory (required)')
.option('-c, --client <value>', 'HTTP client to generate [fetch, xhr, node, axios, angular]')
.version(pkg.version)
.option('-i, --input <value>', 'OpenAPI specification (path, url, or string content)')
.option('-o, --output <value>', 'Output directory')
.option('-c, --client <value>', 'HTTP client to generate [angular, axios, fetch, node, xhr]')
.option('--name <value>', 'Custom client class name')
.option('--useOptions [value]', 'Use options instead of arguments', false)
.option('--useOptions [value]', 'Use options instead of arguments')
.option('--autoformat', 'Process generated files with formatter?')
.option('--no-autoformat', 'Disable processing generated files with formatter')
.option('--base [value]', 'Manually set base in OpenAPI config instead of inferring from server value')
.option('--enums', 'Generate JavaScript objects from enum definitions', false)
.option('--exportCore <value>', 'Write core files to disk', true)
.option('--exportServices <value>', 'Write services to disk', true)
.option('--exportModels <value>', 'Write models to disk', true)
.option('--exportSchemas <value>', 'Write schemas to disk', false)
.option('--enums', 'Generate JavaScript objects from enum definitions')
.option('--exportCore <value>', 'Write core files to disk')
.option('--exportServices <value>', 'Write services to disk')
.option('--exportModels <value>', 'Write models to disk')
.option('--exportSchemas <value>', 'Write schemas to disk')
.option('--operationId', 'Use operationd ID?')
.option('--no-operationId', 'Use path URL to generate operation ID')
.option('--postfixServices <value>', 'Service name postfix', 'Service')
.option('--postfixServices <value>', 'Service name postfix')
.option('--serviceResponse [value]', 'Define shape of returned value from service calls')
.option('--useDateType <value>', 'Output Date instead of string for the format "date-time" in the models', false)
.option('--useDateType <value>', 'Output Date instead of string for the format "date-time" in the models')
.option('--postfixModels <value>', 'Model name postfix')
.option('--request <value>', 'Path to custom request file')
.option('--write', 'Write files to disk? (used for testing)')
.option('--no-write', 'Skip writing files to disk (used for testing)')
.parse(process.argv)
.opts();

const OpenAPI = require(Path.resolve(__dirname, '../dist/index.js'));

const parseBooleanOrString = value => (value === true || value === 'true' ? true : value);

if (OpenAPI) {
OpenAPI.generate({
...params,
clientName: params.name,
exportCore: JSON.parse(params.exportCore) === true,
exportModels: parseBooleanOrString(params.exportModels),
exportSchemas: JSON.parse(params.exportSchemas) === true,
exportServices: parseBooleanOrString(params.exportServices),
useDateType: JSON.parse(params.useDateType) === true,
useOptions: JSON.parse(params.useOptions) === true,
})
.then(() => {
process.exit(0);
})
.catch(error => {
console.error(error);
process.exit(1);
async function start() {
try {
const OpenAPI = await import(new URL('../dist/index.js', import.meta.url));
await OpenAPI.generate({
...params,
clientName: params.name,
});
process.exit(0);
} catch (error) {
console.error(error);
process.exit(1);
}
}

start();
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const config: Config.InitialOptions = {
{
displayName: 'UNIT',
testEnvironment: 'node',
testMatch: ['<rootDir>/test/index.spec.ts', '<rootDir>/bin/index.spec.js', '<rootDir>/src/**/*.spec.ts'],
testMatch: ['<rootDir>/test/index.spec.ts', '<rootDir>/test/bin.spec.ts', '<rootDir>/src/**/*.spec.ts'],
moduleFileExtensions: ['js', 'ts', 'd.ts'],
moduleNameMapper: {
'\\.hbs$': '<rootDir>/src/templates/__mocks__/index.ts',
Expand Down
Loading

0 comments on commit 81d2360

Please sign in to comment.