Skip to content

Commit 28c2d9e

Browse files
committed
Add imports to typescript generator when the resource has fields that reference other fields
Add test to test interface without references
1 parent d9e38cc commit 28c2d9e

File tree

4 files changed

+85
-5
lines changed

4 files changed

+85
-5
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/lib/
22
/node_modules/
33
/tmp
4+
.idea

src/generators/TypescriptInterfaceGenerator.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ export default class TypescriptInterfaceGenerator extends BaseGenerator {
1616

1717
generate(api, resource, dir) {
1818
const dest = `${dir}/interfaces`;
19+
const {fields, imports} = this.parseFields(resource);
1920

2021
this.createDir(dest, false);
2122
this.createFile(
2223
"interface.ts",
2324
`${dest}/${resource.title.toLowerCase()}.ts`,
2425
{
25-
fields: this.parseFields(resource),
26+
fields: fields,
27+
imports: imports,
2628
name: resource.title
2729
}
2830
);
@@ -63,7 +65,8 @@ export default class TypescriptInterfaceGenerator extends BaseGenerator {
6365
name: field.name,
6466
type: this.getType(field),
6567
description: this.getDescription(field),
66-
readonly: false
68+
readonly: false,
69+
reference: field.reference
6770
};
6871
}
6972

@@ -77,10 +80,26 @@ export default class TypescriptInterfaceGenerator extends BaseGenerator {
7780
name: field.name,
7881
type: this.getType(field),
7982
description: this.getDescription(field),
80-
readonly: true
83+
readonly: true,
84+
reference: field.reference
8185
};
8286
}
8387

84-
return Object.keys(fields).map(e => fields[e]);
88+
// Parse fields to add relevant imports, required for Typescript
89+
const fieldsArray = Object.keys(fields).map(e => fields[e]);
90+
const imports = {};
91+
92+
for (const field of fieldsArray) {
93+
if (field.reference) {
94+
imports[field.type] = {
95+
type: field.type,
96+
file: "./" + field.type.toLowerCase()
97+
};
98+
}
99+
}
100+
101+
const importsArray = Object.keys(imports).map(e => imports[e]);
102+
103+
return { fields: fieldsArray, imports: importsArray };
85104
}
86105
}

src/generators/TypescriptInterfaceGenerator.test.js

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ test("Generate a typescript interface", () => {
5050

5151
expect(fs.existsSync(tmpobj.name + "/interfaces/foo.ts")).toBe(true);
5252

53-
const res = `export interface Foo {
53+
const res = `import { FooBar } from "./foobar";
54+
55+
export interface Foo {
5456
'@id'?: string;
5557
id: string;
5658
foo: any;
@@ -64,3 +66,55 @@ test("Generate a typescript interface", () => {
6466

6567
tmpobj.removeCallback();
6668
});
69+
70+
71+
test("Generate a typescript interface without references to other interfaces", () => {
72+
const generator = new TypescriptInterfaceGenerator({
73+
templateDirectory: `${__dirname}/../../templates`
74+
});
75+
const tmpobj = tmp.dirSync({ unsafeCleanup: true });
76+
77+
const resource = new Resource("abc", "http://example.com/foos", {
78+
id: "foo",
79+
title: "Foo",
80+
readableFields: [
81+
new Field("bar", {
82+
id: "http://schema.org/url",
83+
range: "http://www.w3.org/2001/XMLSchema#string",
84+
reference: null,
85+
required: true,
86+
description: "An URL"
87+
})
88+
],
89+
writableFields: [
90+
new Field("foo", {
91+
id: "http://schema.org/url",
92+
range: "http://www.w3.org/2001/XMLSchema#datetime",
93+
reference: null,
94+
required: true,
95+
description: "An URL"
96+
})
97+
]
98+
});
99+
const api = new Api("http://example.com", {
100+
entrypoint: "http://example.com:8080",
101+
title: "My API",
102+
resources: [resource]
103+
});
104+
generator.generate(api, resource, tmpobj.name);
105+
106+
expect(fs.existsSync(tmpobj.name + "/interfaces/foo.ts")).toBe(true);
107+
108+
const res = `export interface Foo {
109+
'@id'?: string;
110+
id: string;
111+
foo: any;
112+
readonly bar: string;
113+
}
114+
`;
115+
expect(
116+
fs.readFileSync(tmpobj.name + "/interfaces/foo.ts").toString()
117+
).toEqual(res);
118+
119+
tmpobj.removeCallback();
120+
});

templates/typescript/interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
{{#each imports}}
2+
import { {{type}} } from "{{file}}";
3+
{{/each}}
4+
{{#if imports.length}}
5+
6+
{{/if}}
17
export interface {{{name}}} {
28
'@id'?: string;
39
id: string;

0 commit comments

Comments
 (0)