Skip to content

Commit 309ff54

Browse files
committed
Add namespace support
1 parent 110d5d1 commit 309ff54

File tree

3 files changed

+43
-23
lines changed

3 files changed

+43
-23
lines changed

README.md

+35-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
1-
Node script that can convert Swagger files to TypeScript interfaces. This uses
2-
[prettier][prettier] to format the interfaces to be somewhat human-readable.
1+
Convert Swagger files to TypeScript interfaces using Node.js. This uses
2+
[Prettier][prettier] to prettify the interfaces.
33

44
### Installation
55

66
```shell
77
npm i --save-dev @manifoldco/swagger-to-ts
88
```
99

10-
### Generating
10+
### Usage
11+
12+
The function takes 2 parameters: a **filepath** to a JSON file, and a
13+
**namespace** for the API. Namespace is required because it’s very likely
14+
entities within the Swagger spec will collide with some other type in your
15+
system, but you still want to access something predictably-named.
16+
17+
```js
18+
const swaggerToTS = require('swagger-to-ts');
19+
20+
const filepath = './path/to/my/file.json';
21+
const namespace = 'MySpec';
22+
const typeData = swaggerToJS(filepath, namespace);
23+
```
1124

1225
#### From Swagger JSON
1326

@@ -16,10 +29,14 @@ const { readFileSync, writeFileSync } = require('fs');
1629
const swaggerToTS = require('swagger-to-ts');
1730

1831
const file = './spec/swagger.json';
19-
const typeData = swaggerToTS(readFileSync(file, 'UTF-8'));
32+
const typeData = swaggerToTS(readFileSync(file, 'UTF-8'), 'MySpec');
2033
writeFileSync('./types/swagger.ts'), typeData);
2134
```
2235

36+
```js
37+
import MySpec from './types/swagger.ts';
38+
```
39+
2340
#### From Swagger YAML
2441

2542
Swagger files must be passed to `swaggerToTS()` in a JSON format, so you’ll
@@ -31,10 +48,14 @@ const { readFileSync, writeFileSync } = require('fs');
3148
const yaml = require('js-yaml');
3249

3350
const file = './spec/swagger.json';
34-
const typeData = swaggerToTS(yaml.safeLoad(fs.readFileSync(file, 'UTF-8')));
51+
const typeData = swaggerToTS(yaml.safeLoad(fs.readFileSync(file, 'UTF-8')), 'MySpec');
3552
writeFileSync('./types/swagger.ts'), typeData);
3653
```
3754

55+
```js
56+
import MySpec from './types/swagger.ts';
57+
```
58+
3859
#### Generating multiple files
3960

4061
The [glob][glob] package is helpful in converting entire folders. The
@@ -50,8 +71,12 @@ const source1 = glob.sync('./swaggerspec/v1/**/*.yaml');
5071
const source2 = glob.sync('./swaggerspec/v2/**/*.yaml');
5172

5273
[...source1, ...source2].forEach(file => {
53-
const typeData = swaggerToTS(yaml.safeLoad(readFileSync(file, 'UTF-8')));
54-
const filename = path.basename(file).replace(/\.ya?ml$/i, '.ts');
74+
const basename = path.basename(file);
75+
const filename = basename.replace(/\.ya?ml$/i, '.ts');
76+
const typeData = swaggerToTS(
77+
yaml.safeLoad(readFileSync(file, 'UTF-8')),
78+
basename
79+
);
5580
writeFileSync(path.resolve(__dirname, 'types', filename), typeData);
5681
});
5782
```
@@ -70,7 +95,7 @@ const file = './spec/swagger.json';
7095
console.log('🏗 Generating types…');
7196
const timeStart = process.hrtime();
7297

73-
const typeData = swaggerToTS(readFileSync(file, 'UTF-8'));
98+
const typeData = swaggerToTS(readFileSync(file, 'UTF-8'), 'MySpec');
7499
writeFileSync('./types/swagger.ts'), typeData);
75100

76101
const timeEnd = process.hrtime(timeStart);
@@ -94,9 +119,9 @@ It’s recommended to name the file `*.ts` and `import` the definitions. `*.d.ts
94119
can’t be imported; they’re meant to be shipped alongside modules.
95120

96121
```js
97-
import { User } from '../types/swagger';
122+
import Swagger from '../types/swagger';
98123

99-
const logIn = (user: User) => {
124+
const logIn = (user: Swagger.User) => {
100125
// …
101126
```
102127

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@manifoldco/swagger-to-ts",
3-
"version": "0.2.1",
3+
"version": "0.3.0",
44
"description": "Convert Swagger files to TypeScript",
55
"main": "dist/swaggerToTS.js",
66
"scripts": {

src/swaggerToTS.js

+7-12
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
const { format } = require('prettier'); // eslint-disable-line import/no-extraneous-dependencies
22

3-
const DEFAULT_OPTIONS = {
4-
enum: false,
5-
};
6-
73
// Primitives only!
84
const TYPES = {
95
string: 'string',
@@ -18,12 +14,12 @@ const camelCase = name =>
1814
letter.toUpperCase().replace(/[^0-9a-z]/gi, '')
1915
);
2016

21-
const buildTypes = (spec, options) => {
17+
const buildTypes = (spec, namespace) => {
2218
const { definitions } = spec;
2319

2420
const queue = [];
2521
const enumQueue = [];
26-
const output = [];
22+
const output = [`namespace ${namespace} {`];
2723

2824
const getRef = lookup => {
2925
const ref = lookup.replace('#/definitions/', '');
@@ -47,7 +43,7 @@ const buildTypes = (spec, options) => {
4743
};
4844

4945
const buildNextEnum = ([ID, options]) => {
50-
output.push(`enum ${ID} {`);
46+
output.push(`export enum ${ID} {`);
5147
options.forEach(option => {
5248
if (typeof option === 'number') {
5349
const lastWord = ID.search(/[A-Z](?=[^A-Z]*$)/);
@@ -70,7 +66,7 @@ const buildTypes = (spec, options) => {
7066
}
7167

7268
// Open interface
73-
output.push(`interface ${camelCase(ID)} {`);
69+
output.push(`export interface ${camelCase(ID)} {`);
7470

7571
// Populate interface
7672
Object.entries(properties).forEach(([key, value]) => {
@@ -117,13 +113,12 @@ const buildTypes = (spec, options) => {
117113
buildNextInterface();
118114
}
119115

116+
output.push('}'); // Close namespace
120117
return output.join('\n');
121118
};
122119

123-
module.exports = (input, userOptions = {}) => {
124-
const options = { ...DEFAULT_OPTIONS, ...userOptions };
125-
126-
return format(buildTypes(input, options), {
120+
module.exports = (filename, namespace) => {
121+
return format(buildTypes(filename, namespace), {
127122
parser: 'typescript',
128123
printWidth: 100,
129124
singleQuote: true,

0 commit comments

Comments
 (0)