Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

.idea

.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
67 changes: 58 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
# openapi-code-generator

**Status:** Early, experimental. Not yet published to NPM.

However, as shown by the integration tests, a fair job of generating a typed client
is achieved for even fairly large/complex definitions like the GitHub api. The koa
generation is less refined.

<!-- toc -->

- [Goal](#goal)
- [CLI Usage](#cli-usage)
- [Architecture](#architecture)
- [`./packages/openapi-code-generator/src/core`](#packagesopenapi-code-generatorsrccore)
- [`file-loader`](#file-loader)
- [`openapi-validator`](#openapi-validator)
- [`openapi-loader`](#openapi-loader)
- [`input`](#input)
- [./packages/openapi-code-generator/src/typescript](#packagesopenapi-code-generatorsrctypescript)
- [Contributing](#contributing)
- [Setup](#setup)
- [Workflow](#workflow)

<!-- tocstop -->

## Goal
To make it fun, easy and productive to generate both client and server "glue"

To make it fun, easy and productive to generate both client and server "glue"
code from openapi 3 definitions.

Additionally, the code output should be "stable" in the sense that it will not
arbitrarily change between generation without need (for a given version). For
arbitrarily change between generation without need (for a given version). For
example outputting entities in alphabetic order where possible. The intent
is that the generated code can and should be committed to the consuming project
repositories, allowing it to be eyeballed, and audited overtime.

The initial focus on typescript, but nothing in the core of the library is assuming this.

## Build
Refer to [package.json](package.json) `scripts` for pointers on building / testing.

## CLI Usage

Usage like so:

```shell
node ../../packages/openapi-code-generator/dist/index.js \
--input="./my-openapi-file.yaml" \
Expand All @@ -30,45 +48,52 @@ node ../../packages/openapi-code-generator/dist/index.js \
```

Where template is one of:

- typescript-angular
- typescript-fetch
- typescript-koa

## Architecture
The project is still evolving dramatically, but this should give a good overview

The project is still evolving dramatically, but this should give a good overview
of the current approach

![architecture](./architecture.svg)

### `./packages/openapi-code-generator/src/core`

This contains the generator/target language agnostic parts of the project.

The process of generation resembles a pipeline in many ways

#### `file-loader`

does what it says on the tin, given a path/uri it reads in the file and parses it from json/yaml
**(http support todo)**

#### `openapi-validator`

nothing particular interesting here, just takes a loaded document and validates it against
the openapi3 specification in json schema format.

Useful for detecting emission errors due to bad input rather than bugs in the code generation.

#### `openapi-loader`

`openapi-loader` takes an entrypoint path, and loads + validates a collection of files .

It then provides typed access to the raw openapi structures, with methods able to convert
It then provides typed access to the raw openapi structures, with methods able to convert
"maybe refs" into the referenced objects.

This is important because one of the more painful (and bug prone) parts of parsing openapi
This is important because one of the more painful (and bug prone) parts of parsing openapi
documents is correctly following $ref's, as you need to carry around the context of which
document you came from.

The `openapi-loader` makes this much less complicated by loading all files up front, and normalizing
the contained $ref to absolute paths.

#### `input`

Ultimately an instance of the `input` class is passed to a generator.

The goal of the `input` class is to provide ergonomic, target language agnostic access to
Expand All @@ -78,12 +103,13 @@ It primarily surfaces api operations, with optional grouping strategies, as a no
that has already de-referenced parameters / responses, and set default values on various properties.

### ./packages/openapi-code-generator/src/typescript

This contains the various typescript generator functions. Each generator currently has a simple
signature:

```typescript
export interface OpenapiGenerator {
(args: { dest: string, input: Input }): Promise<void>
(args: { dest: string; input: Input }): Promise<void>;
}
```

Expand All @@ -92,3 +118,26 @@ of the `Input` class described above.

You can find all registered generators in `templates.ts` - eventually this likely be split into
packages that consume the core modules.

## Contributing

### Setup

1. Install a node version manager that respects `.nvmrc` files, such as [fnm](https://github.com/Schniz/fnm)
2. Enable [corepack](https://nodejs.org/api/corepack.html) using `corepack enable`
3. Install `devDependencies` using `yarn`

### Workflow

See [package.json](./package.json) for available scripts.
Main ones of interest are `build`, `test`, `lint`. Eg:

```shell
yarn test
```

There's also a `ci-pipeline` script that can be used as a pre-push check, eg:

```shell
yarn ci-pipeline && git push --force-with-lease
```
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"description": "",
"scripts": {
"postinstall": "husky install",
"docs:generate": "markdown-toc -i --bullets=- ./README.md",
"refresh": "./scripts/refresh-data.sh",
"start": "nodemon",
"lint": "eslint . --cache --report-unused-disable-directives --fix",
Expand Down Expand Up @@ -33,10 +34,12 @@
"husky": "^8.0.3",
"lerna": "^6.6.1",
"lint-staged": "^13.2.0",
"markdown-toc": "^1.2.0",
"mocha": "^10.2.0",
"mocha-teamcity-reporter": "^4.2.0",
"nodemon": "^2.0.22",
"nyc": "^15.1.0",
"prettier": "^2.8.7",
"source-map-support": "^0.5.21",
"ts-node": "^10.9.1",
"typescript": "~4.9.5"
Expand All @@ -48,6 +51,10 @@
"lint-staged": {
"*.{ts,js,tsx,jsx}": [
"yarn lint"
],
"*.md": [
"sh -c 'yarn docs:generate'",
"yarn prettier --write"
]
},
"engines": {
Expand Down
Loading