Skip to content

Commit d12f275

Browse files
authored
Merge pull request #34 from jeskew/fix/keep-metadata-on-IO-shapes
Fix/keep metadata on IO shapes
2 parents 1b0080d + 79ed81a commit d12f275

File tree

9 files changed

+198
-126
lines changed

9 files changed

+198
-126
lines changed

packages/service-model/__tests__/TreeModel/parser.ts

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ describe('TreeModel parser', () => {
112112
operations,
113113
}));
114114

115-
expect(api.operations.GetFoo.input.name).toBe('GetFooInput');
115+
expect(api.operations.GetFoo.input.shape.name).toBe('GetFooInput');
116116
expect(api.shapes.Date).not.toBeDefined();
117117
expect(api.shapes._Date).toBeDefined();
118118
expect(api.shapes.Error).not.toBeDefined();
@@ -150,7 +150,7 @@ describe('TreeModel parser', () => {
150150
shapes,
151151
}));
152152

153-
const {members} = api.operations.GetFoo.output;
153+
const {members} = api.operations.GetFoo.output.shape;
154154
Object.keys(members).forEach(memberName => {
155155
expect(members[memberName].shape.sensitive).toBe(true);
156156
});
@@ -185,7 +185,7 @@ describe('TreeModel parser', () => {
185185
},
186186
}));
187187

188-
const {shape} = api.operations.GetFoo.output.members.foo;
188+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
189189
expect((shape as List).min).toBe(10);
190190
});
191191

@@ -216,7 +216,7 @@ describe('TreeModel parser', () => {
216216
},
217217
}));
218218

219-
const {shape} = api.operations.GetFoo.output.members.foo;
219+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
220220
expect((shape as Number).min).toBe(10);
221221
});
222222

@@ -247,7 +247,7 @@ describe('TreeModel parser', () => {
247247
},
248248
}));
249249

250-
const {shape} = api.operations.GetFoo.output.members.foo;
250+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
251251
expect((shape as String).min).toBe(10);
252252
});
253253

@@ -280,7 +280,7 @@ describe('TreeModel parser', () => {
280280
},
281281
}));
282282

283-
const {shape} = api.operations.GetFoo.output.members.foo;
283+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
284284
expect((shape as List).flattened).toBe(true);
285285
});
286286

@@ -315,7 +315,7 @@ describe('TreeModel parser', () => {
315315
},
316316
}));
317317

318-
const {shape} = api.operations.GetFoo.output.members.foo;
318+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
319319
expect((shape as Map).flattened).toBe(true);
320320
});
321321

@@ -350,7 +350,7 @@ describe('TreeModel parser', () => {
350350
},
351351
}));
352352

353-
const {shape} = api.operations.GetFoo.output.members.foo;
353+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
354354
expect((shape as Map).flattened).toBe(true);
355355
});
356356

@@ -381,7 +381,7 @@ describe('TreeModel parser', () => {
381381
},
382382
}));
383383

384-
const {shape} = api.operations.GetFoo.output.members.foo;
384+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
385385
expect((shape as String).jsonValue).toBe(true);
386386
});
387387

@@ -412,7 +412,7 @@ describe('TreeModel parser', () => {
412412
},
413413
}));
414414

415-
const {shape} = api.operations.GetFoo.output.members.foo;
415+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
416416
expect((shape as String).idempotencyToken).toBe(true);
417417
});
418418

@@ -443,7 +443,7 @@ describe('TreeModel parser', () => {
443443
},
444444
}));
445445

446-
const {shape} = api.operations.GetFoo.output.members.foo;
446+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
447447
expect((shape as TreeModelString).enum).toEqual(['fizz', 'buzz', 'pop']);
448448
});
449449

@@ -474,7 +474,7 @@ describe('TreeModel parser', () => {
474474
},
475475
}));
476476

477-
const {shape} = api.operations.GetFoo.output.members.foo;
477+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
478478
expect((shape as Blob).streaming).toBe(true);
479479
});
480480

@@ -505,7 +505,7 @@ describe('TreeModel parser', () => {
505505
},
506506
}));
507507

508-
const {shape} = api.operations.GetFoo.output.members.foo;
508+
const {shape} = api.operations.GetFoo.output.shape.members.foo;
509509
expect((shape as Timestamp).timestampFormat).toBe('atom');
510510
});
511511

@@ -537,7 +537,7 @@ describe('TreeModel parser', () => {
537537
},
538538
}));
539539

540-
expect(api.operations.GetFoo.output.required).toEqual(['foo']);
540+
expect(api.operations.GetFoo.output.shape.required).toEqual(['foo']);
541541
});
542542

543543
it('should preserve payload traits on structures', () => {
@@ -568,7 +568,7 @@ describe('TreeModel parser', () => {
568568
},
569569
}));
570570

571-
expect(api.operations.GetFoo.output.payload).toEqual('foo');
571+
expect(api.operations.GetFoo.output.shape.payload).toEqual('foo');
572572
});
573573

574574
it('should preserve exception traits on structures', () => {
@@ -595,7 +595,7 @@ describe('TreeModel parser', () => {
595595
},
596596
}));
597597

598-
expect(api.operations.GetFoo.errors[0].exception).toEqual(true);
598+
expect(api.operations.GetFoo.errors[0].shape.exception).toEqual(true);
599599
});
600600

601601
it('should preserve error codes on structures', () => {
@@ -623,7 +623,8 @@ describe('TreeModel parser', () => {
623623
},
624624
}));
625625

626-
expect(api.operations.GetFoo.errors[0].exceptionCode).toEqual('PANIC');
626+
expect(api.operations.GetFoo.errors[0].shape.exceptionCode)
627+
.toEqual('PANIC');
627628
});
628629

629630
it('should standardize xmlNamespace traits on structures', () => {
@@ -666,11 +667,11 @@ describe('TreeModel parser', () => {
666667
},
667668
}));
668669

669-
expect(api.operations.GetFoo.output.members.foo.xmlNamespace)
670+
expect(api.operations.GetFoo.output.shape.members.foo.xmlNamespace)
670671
.toEqual({uri: xmlNamespace.uri});
671-
expect(api.operations.GetFoo.output.members.bar.xmlNamespace)
672+
expect(api.operations.GetFoo.output.shape.members.bar.xmlNamespace)
672673
.toEqual(xmlNamespace);
673-
expect(api.operations.GetFoo.output.members.baz.xmlNamespace)
674+
expect(api.operations.GetFoo.output.shape.members.baz.xmlNamespace)
674675
.toBeUndefined();
675676
});
676677

@@ -702,7 +703,7 @@ describe('TreeModel parser', () => {
702703
},
703704
}));
704705

705-
const {shape} = (api.operations.GetFoo.output.members.foo.shape as TreeModelList).member;
706+
const {shape} = (api.operations.GetFoo.output.shape.members.foo.shape as TreeModelList).member;
706707
expect(shape).toBe(api.shapes[shape.name]);
707708
});
708709

@@ -736,7 +737,7 @@ describe('TreeModel parser', () => {
736737
},
737738
}));
738739

739-
const map = api.operations.GetFoo.output.members.foo.shape as TreeModelMap;
740+
const map = api.operations.GetFoo.output.shape.members.foo.shape as TreeModelMap;
740741
expect(map.key.shape).toBe(api.shapes[map.key.shape.name]);
741742
expect(map.value.shape).toBe(api.shapes[map.value.shape.name]);
742743
});
@@ -767,7 +768,7 @@ describe('TreeModel parser', () => {
767768
shapes,
768769
}));
769770

770-
const {members} = api.operations.GetFoo.output;
771+
const {members} = api.operations.GetFoo.output.shape;
771772
for (let memberName of Object.keys(members)) {
772773
const member = members[memberName];
773774
expect(member.shape).toBe(api.shapes[member.shape.name]);
@@ -805,7 +806,7 @@ describe('TreeModel parser', () => {
805806
},
806807
}));
807808

808-
expect(api.operations.GetFoo.output.members.foo.documentation)
809+
expect(api.operations.GetFoo.output.shape.members.foo.documentation)
809810
.toEqual('foo member of GetFooOutput');
810811
});
811812
});

packages/service-model/lib/TreeModel/parser.ts

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
Boolean as ProtocolBoolean,
3636
Number,
3737
String as ProtocolString,
38+
ServiceMetadata,
3839
Timestamp as ProtocolTimestamp,
3940
XmlNamespace,
4041
} from '@aws/types';
@@ -65,7 +66,11 @@ export function fromApiModel(model: ApiModel): TreeModel {
6566
const {documentation = `${metadata.serviceFullName} service`} = normalized;
6667

6768
const shapes = fromApiModelShapeMap(normalized.shapes);
68-
const operations = fromApiModelOperationMap(normalized.operations, shapes);
69+
const operations = fromApiModelOperationMap(
70+
normalized.operations,
71+
shapes,
72+
metadata
73+
);
6974

7075
return {
7176
documentation,
@@ -131,37 +136,45 @@ function fromApiModelShapeMap(shapeMap: ShapeMap): TreeModelShapeMap {
131136

132137
function fromApiModelOperationMap(
133138
operationMap: NormalizedOperationMap,
134-
shapes: TreeModelShapeMap
139+
shapes: TreeModelShapeMap,
140+
metadata: ServiceMetadata
135141
): TreeModelOperationMap {
136142
return Object.keys(operationMap).reduce((
137143
carry: TreeModelOperationMap,
138144
operationName: string
139145
) => {
140146
const {
141147
name,
142-
errors: errorDeclaration,
148+
errors,
143149
http,
144-
input: inputDeclaration,
145-
output: outputDeclaration,
150+
input,
151+
output,
146152
} = operationMap[operationName];
147153
const {
148154
documentation = `${name} operation`,
149155
} = operationMap[operationName];
150-
const input = shapes[inputDeclaration.shape] as TreeModelStructure;
151-
const output = shapes[outputDeclaration.shape] as TreeModelStructure;
152-
const errors = errorDeclaration.map(errorShape => (
153-
shapes[errorShape.shape] as TreeModelStructure
154-
));
155156

156-
carry[operationName] = {
157-
documentation,
158-
errors,
159-
http,
160-
input,
161-
name,
162-
output
157+
return {
158+
...carry,
159+
[operationName]: {
160+
documentation,
161+
http,
162+
name,
163+
metadata,
164+
input: {
165+
...input,
166+
shape: shapes[input.shape] as TreeModelStructure,
167+
},
168+
output: {
169+
...output,
170+
shape: shapes[output.shape] as TreeModelStructure,
171+
},
172+
errors: errors.map(errorShape => ({
173+
...errorShape,
174+
shape: shapes[errorShape.shape] as TreeModelStructure
175+
})),
176+
}
163177
};
164-
return carry;
165178
}, {});
166179
}
167180

packages/service-model/lib/TreeModel/types.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,25 @@ export interface TreeModelMember extends Partial<Documented>, Member {
9898
shape: TreeModelShape;
9999
}
100100

101+
/**
102+
* @inheritDoc
103+
*
104+
* This member's shape must be a structure.
105+
*/
106+
export interface TreeModelOperationMember extends TreeModelMember {
107+
shape: TreeModelStructure;
108+
}
109+
101110
/**
102111
* @inheritDoc
103112
*
104113
* Additionally contains a name and documentation string, as do all shapes
105114
* referenced by this operation.
106115
*/
107116
export interface TreeModelOperation extends NamedAndDocumented<OperationModel> {
108-
input: TreeModelStructure;
109-
output: TreeModelStructure;
110-
errors: Array<TreeModelStructure>;
117+
input: TreeModelOperationMember;
118+
output: TreeModelOperationMember;
119+
errors: Array<TreeModelOperationMember>;
111120
}
112121

113122
export interface TreeModelOperationMap {

packages/service-types-generator/__fixtures__/index.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -154,53 +154,58 @@ export const ValidationException: TreeModelStructure = {
154154
members: {},
155155
};
156156

157+
export const metadata: ServiceMetadata = {
158+
apiVersion: '2017-04-30',
159+
endpointPrefix: 'endpoint',
160+
protocol: 'rest-json',
161+
serviceFullName: 'AWS Fake Service',
162+
signatureVersion: 'v4',
163+
uid: 'fake-2017-04-30',
164+
};
165+
157166
export const model: TreeModel = {
158167
documentation: 'A fake service',
159168
name: 'FakeService',
160-
metadata: {
161-
apiVersion: '2017-04-30',
162-
endpointPrefix: 'endpoint',
163-
protocol: 'rest-json',
164-
serviceFullName: 'AWS Fake Service',
165-
signatureVersion: 'v4',
166-
uid: 'fake-2017-04-30',
167-
},
169+
metadata,
168170
operations: {
169171
DeleteResource: {
172+
metadata,
170173
name: 'DeleteResource',
171174
documentation: 'DeleteResource operation',
172175
http: {
173176
method: 'DELETE',
174177
requestUri: '/resources/{resourceId}'
175178
},
176-
input: DeleteResourceInput,
177-
output: DeleteResourceOutput,
179+
input: {shape: DeleteResourceInput},
180+
output: {shape: DeleteResourceOutput},
178181
errors: [],
179182
},
180183
GetResource: {
184+
metadata,
181185
name: 'GetResource',
182186
documentation: 'GetResource operation',
183187
http: {
184188
method: 'GET',
185189
requestUri: '/resources/{resourceId}'
186190
},
187-
input: GetResourceInput,
188-
output: GetResourceOutput,
191+
input: {shape: GetResourceInput},
192+
output: {shape: GetResourceOutput},
189193
errors: [
190-
ResourceNotFoundException,
194+
{shape: ResourceNotFoundException},
191195
],
192196
},
193197
PutResource: {
198+
metadata,
194199
name: 'PutResource',
195200
documentation: 'PutResource operation',
196201
http: {
197202
method: 'PUT',
198203
requestUri: '/resources/{resourceId}'
199204
},
200-
input: PutResourceInput,
201-
output: PutResourceOutput,
205+
input: {shape: PutResourceInput},
206+
output: {shape: PutResourceOutput},
202207
errors: [
203-
ValidationException,
208+
{shape: ValidationException},
204209
],
205210
},
206211
},
@@ -229,4 +234,4 @@ export const minimalValidServiceMetadata: ServiceMetadata = {
229234
serviceFullName: 'string',
230235
signatureVersion: 'v4',
231236
uid: 'string',
232-
};
237+
};

0 commit comments

Comments
 (0)