Skip to content

Commit c73cf78

Browse files
committed
Add an I/O type union generator
1 parent a026bf6 commit c73cf78

File tree

5 files changed

+90
-1
lines changed

5 files changed

+90
-1
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {Union} from './Union';
2+
3+
describe('Union', () => {
4+
it('should import the shapes provided to the constructor', () => {
5+
const union = new Union(
6+
['Foo', 'Bar', 'Baz', 'Quux'],
7+
'MyUnion'
8+
);
9+
10+
expect(union.toString()).toMatch(
11+
`import {Foo} from './Foo';
12+
import {Bar} from './Bar';
13+
import {Baz} from './Baz';
14+
import {Quux} from './Quux';`
15+
);
16+
});
17+
18+
it('should export a type union of all shapes provided to the constructor', () => {
19+
const union = new Union(
20+
['Foo', 'Bar', 'Baz', 'Quux'],
21+
'MyUnion'
22+
);
23+
24+
expect(union.toString()).toMatch(
25+
`export type MyUnion = Foo |
26+
Bar |
27+
Baz |
28+
Quux;`
29+
);
30+
});
31+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {Import} from '../Import';
2+
3+
export class Union {
4+
constructor(
5+
private readonly constituentShapeNames: Array<string>,
6+
private readonly typeName: string
7+
) {}
8+
9+
toString(): string {
10+
return `${this.imports}
11+
12+
export type ${this.typeName} = ${this.constituentShapeNames.join(' |\n ')};
13+
`;
14+
}
15+
16+
protected get imports(): string {
17+
return this.constituentShapeNames
18+
.map(shape => new Import(`./${shape}`, shape))
19+
.join('\n');
20+
}
21+
}

packages/service-types-generator/src/Components/Type/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ export * from './getStringDeclaration';
55
export * from './Input';
66
export * from './ModeledStructure';
77
export * from './Output';
8-
export * from './Structure';
8+
export * from './Structure';
9+
export * from './Union';

packages/service-types-generator/src/TypeGenerator.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,28 @@ describe('TypeGenerator', () => {
2020
.length
2121
).toBe(0);
2222
});
23+
24+
it('should yield a union of the input types defined in the model', () => {
25+
let found = false;
26+
for (const [fileName, content] of new TypeGenerator(model)) {
27+
if (fileName === 'InputTypesUnion') {
28+
found = true;
29+
expect(content).toMatch('export type InputTypesUnion = ');
30+
}
31+
}
32+
33+
expect(found).toBe(true);
34+
});
35+
36+
it('should yield a union of the output types defined in the model', () => {
37+
let found = false;
38+
for (const [fileName, content] of new TypeGenerator(model)) {
39+
if (fileName === 'OutputTypesUnion') {
40+
found = true;
41+
expect(content).toMatch('export type OutputTypesUnion = ');
42+
}
43+
}
44+
45+
expect(found).toBe(true);
46+
});
2347
});

packages/service-types-generator/src/TypeGenerator.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,31 @@ import {
33
Input,
44
ModeledStructure,
55
Output,
6+
Union,
67
} from "./Components/Type";
78
import {TreeModel} from "@aws/build-types";
89

910
export class TypeGenerator {
1011
constructor(private readonly model: TreeModel) {}
1112

1213
*[Symbol.iterator](): Iterator<[string, string]> {
14+
const ioShapes: {[key: string]: Array<string>} = {
15+
InputTypesUnion: [],
16+
OutputTypesUnion: [],
17+
};
1318
const {shapes} = this.model;
19+
1420
for (let shapeName of Object.keys(shapes)) {
1521
const shape = shapes[shapeName];
1622
if (shape.type === 'structure') {
1723
if (shape.topLevel === 'input') {
24+
ioShapes.InputTypesUnion.push(shapeName);
1825
yield [
1926
shapeName,
2027
new Input(shape).toString(),
2128
];
2229
} else if (shape.topLevel === 'output') {
30+
ioShapes.OutputTypesUnion.push(shapeName);
2331
yield [
2432
shapeName,
2533
new Output(shape).toString(),
@@ -37,5 +45,9 @@ export class TypeGenerator {
3745
}
3846
}
3947
}
48+
49+
for (const name of Object.keys(ioShapes)) {
50+
yield [name, new Union(ioShapes[name], name).toString()];
51+
}
4052
}
4153
}

0 commit comments

Comments
 (0)