Skip to content

Commit 7bb608d

Browse files
committed
Add executable
1 parent 51c373b commit 7bb608d

File tree

9 files changed

+503
-338
lines changed

9 files changed

+503
-338
lines changed

.eslintrc.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
module.exports = {
2-
parser: 'babel-eslint',
32
extends: ['prettier/react', 'airbnb'],
43
plugins: ['prettier', 'import'],
54
env: {

README.md

Lines changed: 24 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,145 +1,46 @@
11
[![version (scoped)](https://img.shields.io/npm/v/@manifoldco/swagger-to-ts.svg)](https://www.npmjs.com/package/@manifoldco/swagger-to-ts)
22

3-
Convert Swagger files to TypeScript interfaces using Node.js. This uses
4-
[Prettier][prettier] to prettify the interfaces.
3+
# 📘️ swagger-to-ts
54

6-
### Installation
5+
Convert Swagger files to TypeScript interfaces using Node.js.
76

8-
```shell
9-
npm i --save-dev @manifoldco/swagger-to-ts
10-
```
11-
12-
### Usage
13-
14-
The function takes 2 parameters: a **filepath** to a JSON file, and a
15-
**namespace** for the API. Namespace is required because it’s very likely
16-
entities within the Swagger spec will collide with some other type in your
17-
system, but you still want to access something predictably-named.
18-
19-
```js
20-
const swaggerToTS = require('swagger-to-ts');
21-
22-
const filepath = './path/to/my/file.json';
23-
const namespace = 'MySpec';
24-
const typeData = swaggerToJS(filepath, namespace);
25-
```
26-
27-
#### From Swagger JSON
28-
29-
```js
30-
const { readFileSync, writeFileSync } = require('fs');
31-
const swaggerToTS = require('swagger-to-ts');
32-
33-
const file = './spec/swagger.json';
34-
const typeData = swaggerToTS(readFileSync(file, 'UTF-8'), 'MySpec');
35-
writeFileSync('./types/swagger.ts', typeData);
36-
```
37-
38-
#### From Swagger YAML
39-
40-
Swagger files must be passed to `swaggerToTS()` in a JSON format, so you’ll
41-
have to configure that part yourself using [js-yaml][js-yaml] or something
42-
similar.
43-
44-
```js
45-
const { readFileSync, writeFileSync } = require('fs');
46-
const yaml = require('js-yaml');
7+
💅 Prettifies output with [Prettier][prettier].
478

48-
const file = './spec/swagger.yaml';
49-
const json = yaml.safeLoad(fs.readFileSync(file, 'UTF-8'));
50-
const typeData = swaggerToTS(json, 'MySpec');
51-
writeFileSync('./types/swagger.ts', typeData);
52-
```
9+
## Usage
5310

54-
#### Generating multiple files
11+
### CLI
5512

56-
The [glob][glob] package is helpful in converting entire folders. The
57-
renaming & mapping is up to you!
13+
```bash
14+
npx @manifoldco/swagger-to-ts schema.yaml --output schema.ts --namespace OpenAPI
5815

59-
```js
60-
const { readFileSync, writeFileSync } = require('fs');
61-
const path = require('path');
62-
const glob = require('glob');
63-
const swaggerToTS = require('swagger-to-ts');
64-
65-
const source1 = glob.sync('./swaggerspec/v1/**/*.yaml');
66-
const source2 = glob.sync('./swaggerspec/v2/**/*.yaml');
67-
68-
[...source1, ...source2].forEach(file => {
69-
const basename = path.basename(file);
70-
const filename = basename.replace(/\.ya?ml$/i, '.ts');
71-
const json = yaml.safeLoad(readFileSync(file, 'UTF-8'));
72-
const typeData = swaggerToTS(json, basename);
73-
writeFileSync(path.resolve(__dirname, 'types', filename), typeData);
74-
});
16+
# 🚀 schema.yaml -> schema.ts [2ms]
7517
```
7618

77-
#### Fancy Console Messages
78-
79-
Using the [chalk][chalk] package you can spice up the console message a little:
80-
81-
```js
82-
const { readFileSync, writeFileSync } = require('fs');
83-
const chalk = require('chalk');
84-
const swaggerToTS = require('swagger-to-ts');
19+
This will save a `schema.ts` file in the current folder under the TypeScript
20+
[namespace][namespace] `OpenAPI`. The CLI can accept YAML or JSON for the
21+
input file.
8522

86-
const file = './spec/swagger.json';
87-
88-
console.log('🏗 Generating types…');
89-
const timeStart = process.hrtime();
90-
91-
const typeData = swaggerToTS(readFileSync(file, 'UTF-8'), 'MySpec');
92-
writeFileSync('./types/swagger.ts'), typeData);
93-
94-
const timeEnd = process.hrtime(timeStart);
95-
console.log(
96-
chalk.green(
97-
`Done generating types in ${chalk.bold(timeEnd[0] + Math.round(timeEnd[1] / 1000000))}ms`
98-
)
99-
);
100-
```
23+
### Node
10124

102-
This will output something like the following:
103-
104-
```shell
105-
🏗 Generating types…
106-
Done generating types in 212ms
25+
```bash
26+
npm i --save-dev @manifoldco/swagger-to-ts
10727
```
10828

109-
### Using in TypeScript project
110-
111-
It’s recommended to name the file `*.ts` and `import` the definitions. `*.d.ts`
112-
can’t be imported; they’re meant to be shipped alongside modules.
113-
11429
```js
115-
import { Swagger } from '../types/swagger';
30+
const swaggerToTS = require('@manifoldco/swagger-to-ts');
11631

117-
const logIn = (user: Swagger.User) => {
118-
// …
32+
graphqlGen(spec, [options]);
11933
```
12034

121-
TypeScript would much rather have you ship `*.d.ts` files as part of an
122-
existing package, but sometimes that’s not possible when it comes to Swagger
123-
specs. `import`-ing everything like this isn’t ideal, but it’s better than
124-
not using static typing at all!
35+
`spec` must be in JSON format. For an example of converting YAML to JSON, see
36+
the [generate.js](./scripts/generate.js) script.
12537

126-
### Node Scripts
127-
128-
Setting this up to auto-run in a Node script is ideal. For instance, if you
129-
ship Swagger specs as part of a node package, and you want to regenerate the
130-
types on `postinstall`, you can specify that in your `package.json`:
131-
132-
```js
133-
"scripts": {
134-
"generate:types": "node scripts/generateTypesFromSwagger",
135-
"postinstall": "npm run generate:types",
136-
},
137-
```
38+
### Options
13839

139-
In this example, `scripts/generateTypesFromSwagger` is a JS file you’ve manually
140-
created from one of the examples above, customized to fit your needs.
40+
| Name | Default | Description |
41+
| :-------- | :------- | :--------------------------------------------------------- |
42+
| `output` | (stdout) | Where should the output file be saved? |
43+
| `swagger` | `2` | Which Swagger version to use. Currently only supports `2`. |
14144

142-
[chalk]: https://www.npmjs.com/package/chalk
143-
[glob]: https://npmjs.com/glob
144-
[js-yaml]: https://npmjs.com/js-yaml
45+
[namespace]: https://www.typescriptlang.org/docs/handbook/namespaces.html
14546
[prettier]: https://npmjs.com/prettier

bin/cli.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env node
2+
3+
const { readFileSync, existsSync, writeFileSync } = require('fs');
4+
const { mkdirpSync } = require('fs-extra');
5+
const chalk = require('chalk');
6+
const { dirname, resolve } = require('path');
7+
const meow = require('meow');
8+
const yaml = require('js-yaml');
9+
const swaggerToTS = require('../dist/cjs');
10+
11+
const cli = meow(
12+
`
13+
Usage
14+
$ swagger-to-ts [input] [options]
15+
16+
Options
17+
--namespace, -n specify namespace to prefix types
18+
--help display this
19+
--output, -o specify output file
20+
--swagger, -s specify Swagger version (default 2)
21+
`,
22+
{
23+
flags: {
24+
namespace: {
25+
type: 'string',
26+
alias: 'n',
27+
},
28+
output: {
29+
type: 'string',
30+
alias: 'o',
31+
},
32+
swagger: {
33+
type: 'number',
34+
alias: 's',
35+
},
36+
},
37+
}
38+
);
39+
40+
let spec = cli.input[0];
41+
42+
// If input is a file, load it
43+
const pathname = resolve(process.cwd(), spec);
44+
if (existsSync(pathname)) {
45+
spec = readFileSync(pathname, 'UTF-8');
46+
}
47+
48+
// Attempt to parse YAML
49+
try {
50+
if (/\.ya?ml$/i.test(spec) || spec[0] !== '{') {
51+
spec = yaml.safeLoad(spec);
52+
}
53+
} catch (e) {
54+
console.error(
55+
chalk.red(`❌ "${spec}" seems to be YAML, but it couldn’t be parsed.
56+
${e}`)
57+
);
58+
}
59+
60+
// Attempt to parse JSON
61+
try {
62+
if (typeof spec === 'string') {
63+
spec = JSON.parse(spec);
64+
}
65+
} catch (e) {
66+
console.error(
67+
chalk.red(`❌ Could not parse JSON for "${spec}." Is this a valid Swagger spec?
68+
${e}`)
69+
);
70+
}
71+
72+
const result = swaggerToTS(spec, cli.flags.namespace, cli.flags);
73+
74+
// Write to file if specifying output
75+
if (cli.flags.output) {
76+
const timeStart = process.hrtime();
77+
const outputFile = resolve(process.cwd(), cli.flags.output);
78+
const parent = dirname(outputFile);
79+
mkdirpSync(parent);
80+
writeFileSync(outputFile, result);
81+
82+
const timeEnd = process.hrtime(timeStart);
83+
const time = timeEnd[0] + Math.round(timeEnd[1] / 1e6);
84+
console.log(
85+
chalk.green(
86+
`🚀 ${cli.input[0]} -> ${chalk.bold(cli.flags.output)} [${time}ms]`
87+
)
88+
);
89+
return;
90+
}
91+
92+
// Otherwise, return result
93+
return result;

0 commit comments

Comments
 (0)