Skip to content

Commit 052d261

Browse files
authored
fix(codegen): for static schema (#1746)
* fix(codegen): for static schema * unit test fixes
1 parent d1c4116 commit 052d261

File tree

12 files changed

+106
-77
lines changed

12 files changed

+106
-77
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@smithy/core": patch
3+
"@smithy/types": patch
4+
---
5+
6+
fix ordering of static simple schema type

packages/core/src/submodules/cbor/SmithyRpcV2CborProtocol.spec.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
ResponseMetadata,
99
RetryableTrait,
1010
SchemaRef,
11+
StaticErrorSchema,
1112
StringSchema,
1213
TimestampDefaultSchema,
1314
} from "@smithy/types";
@@ -306,6 +307,14 @@ describe(SmithyRpcV2CborProtocol.name, () => {
306307
}),
307308
});
308309

310+
const errorResponseNoDiscriminator = new HttpResponse({
311+
statusCode: 404,
312+
headers: {},
313+
body: cbor.serialize({
314+
modeledProperty: "oh no",
315+
}),
316+
});
317+
309318
const serdeContext = {};
310319

311320
class ServiceBaseException extends Error {
@@ -326,18 +335,31 @@ describe(SmithyRpcV2CborProtocol.name, () => {
326335

327336
beforeEach(() => {
328337
ns.clear();
338+
synthetic.clear();
329339
});
330340

331-
const modeledExceptionSchema = error("ns", "ModeledException", 0, ["modeledProperty"], [0], null);
332-
const baseServiceExceptionSchema = error("smithy.ts.sdk.synthetic.ns", "BaseServiceException", 0, [], [], null);
341+
const modeledExceptionSchema = [
342+
-3,
343+
"ns",
344+
"ModeledException",
345+
0,
346+
["modeledProperty"],
347+
[0],
348+
] satisfies StaticErrorSchema;
349+
const baseServiceExceptionSchema = [
350+
-3,
351+
"smithy.ts.sdk.synthetic.ns",
352+
"BaseServiceException",
353+
0,
354+
[],
355+
[],
356+
] satisfies StaticErrorSchema;
333357

334358
it("should throw the schema error ctor if one exists", async () => {
335359
// this is for modeled exceptions.
336360

337-
ns.register(modeledExceptionSchema.getName(), modeledExceptionSchema);
338361
ns.registerError(modeledExceptionSchema, ModeledExceptionCtor);
339362

340-
synthetic.register(baseServiceExceptionSchema.getName(), baseServiceExceptionSchema);
341363
synthetic.registerError(baseServiceExceptionSchema, ServiceBaseException);
342364

343365
try {
@@ -353,11 +375,10 @@ describe(SmithyRpcV2CborProtocol.name, () => {
353375
it("should throw a base error if available in the namespace, when no error schema is modeled", async () => {
354376
// this is the expected fallback case for all generated clients.
355377

356-
synthetic.register(baseServiceExceptionSchema.getName(), baseServiceExceptionSchema);
357378
synthetic.registerError(baseServiceExceptionSchema, ServiceBaseException);
358379

359380
try {
360-
await protocol.deserializeResponse(operation, serdeContext as any, errorResponse);
381+
await protocol.deserializeResponse(operation, serdeContext as any, errorResponseNoDiscriminator);
361382
} catch (e) {
362383
expect(e).toBeInstanceOf(ServiceBaseException);
363384
}

packages/core/src/submodules/cbor/SmithyRpcV2CborProtocol.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type {
1010
OperationSchema,
1111
ResponseMetadata,
1212
SerdeFunctions,
13+
StaticErrorSchema,
1314
} from "@smithy/types";
1415
import { getSmithyContext } from "@smithy/util-middleware";
1516

@@ -104,9 +105,9 @@ export class SmithyRpcV2CborProtocol extends RpcProtocol {
104105

105106
const registry = TypeRegistry.for(namespace);
106107

107-
let errorSchema: ErrorSchema;
108+
let errorSchema: StaticErrorSchema;
108109
try {
109-
errorSchema = registry.getSchema(errorName) as ErrorSchema;
110+
errorSchema = registry.getSchema(errorName) as StaticErrorSchema;
110111
} catch (e) {
111112
if (dataObject.Message) {
112113
dataObject.message = dataObject.Message;

packages/core/src/submodules/schema/TypeRegistry.spec.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import type { StaticErrorSchema } from "@smithy/types";
12
import { describe, expect, test as it } from "vitest";
23

3-
import { error } from "./schemas/ErrorSchema";
44
import { list } from "./schemas/ListSchema";
55
import { map } from "./schemas/MapSchema";
66
import { struct } from "./schemas/StructureSchema";
@@ -16,15 +16,26 @@ describe(TypeRegistry.name, () => {
1616

1717
it("stores and retrieves schema objects", () => {
1818
const tr = TypeRegistry.for("NAMESPACE");
19+
tr.register(List.getName(), List);
1920
expect(tr.getSchema("List")).toBe(List);
21+
tr.register(Map.getName(), Map);
2022
expect(tr.getSchema("Map")).toBe(Map);
23+
tr.register(Struct().getName(), Struct());
2124
expect(tr.getSchema("Structure")).toBe(schema);
2225
});
2326

2427
it("has a helper method to retrieve a synthetic base exception", () => {
2528
// the service namespace is appended to the synthetic prefix.
26-
const err = error("smithy.ts.sdk.synthetic.NAMESPACE", "UhOhServiceException", 0, [], [], Error);
27-
const tr = TypeRegistry.for("smithy.ts.sdk.synthetic.NAMESPACE");
29+
const err = [
30+
-3,
31+
"smithy.ts.sdk.synthetic.NAMESPACE",
32+
"UhOhServiceException",
33+
0,
34+
[],
35+
[],
36+
] satisfies StaticErrorSchema;
37+
const tr = TypeRegistry.for(err[1]);
38+
tr.registerError(err, Error);
2839
expect(tr.getBaseException()).toBe(err);
2940
});
3041
});

packages/core/src/submodules/schema/TypeRegistry.ts

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export class TypeRegistry {
3535
*/
3636
public register(shapeId: string, schema: ISchema) {
3737
const qualifiedName = this.normalizeShapeId(shapeId);
38-
this.schemas.set(qualifiedName, schema);
38+
const registry = TypeRegistry.for(qualifiedName.split("#")[0]);
39+
registry.schemas.set(qualifiedName, schema);
3940
}
4041

4142
/**
@@ -54,15 +55,20 @@ export class TypeRegistry {
5455
* Associates an error schema with its constructor.
5556
*/
5657
public registerError(es: ErrorSchema | StaticErrorSchema, ctor: any) {
57-
this.exceptions.set(es, ctor);
58+
const $error = es as StaticErrorSchema;
59+
const registry = TypeRegistry.for($error[1]);
60+
registry.schemas.set($error[1] + "#" + $error[2], $error);
61+
registry.exceptions.set($error, ctor);
5862
}
5963

6064
/**
6165
* @param es - query.
6266
* @returns Error constructor that extends the service's base exception.
6367
*/
6468
public getErrorCtor(es: ErrorSchema | StaticErrorSchema): any {
65-
return this.exceptions.get(es);
69+
const $error = es as StaticErrorSchema;
70+
const registry = TypeRegistry.for($error[1]);
71+
return registry.exceptions.get(es);
6672
}
6773

6874
/**
@@ -78,10 +84,14 @@ export class TypeRegistry {
7884
*
7985
* @returns the synthetic base exception of the service namespace associated with this registry instance.
8086
*/
81-
public getBaseException(): ErrorSchema | undefined {
82-
for (const [id, schema] of this.schemas.entries()) {
83-
if (id.startsWith("smithy.ts.sdk.synthetic.") && id.endsWith("ServiceException")) {
84-
return schema as ErrorSchema;
87+
public getBaseException(): StaticErrorSchema | undefined {
88+
for (const exceptionKey of this.exceptions.keys()) {
89+
if (Array.isArray(exceptionKey)) {
90+
const [, ns, name] = exceptionKey;
91+
const id = ns + "#" + name;
92+
if (id.startsWith("smithy.ts.sdk.synthetic.") && id.endsWith("ServiceException")) {
93+
return exceptionKey;
94+
}
8595
}
8696
}
8797
return undefined;
@@ -109,8 +119,4 @@ export class TypeRegistry {
109119
}
110120
return this.namespace + "#" + shapeId;
111121
}
112-
113-
private getNamespace(shapeId: string) {
114-
return this.normalizeShapeId(shapeId).split("#")[0];
115-
}
116122
}

packages/core/src/submodules/schema/schemas/NormalizedSchema.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import type { OperationSchema } from "./OperationSchema";
4343
import { op } from "./OperationSchema";
4444
import { Schema } from "./Schema";
4545
import type { SimpleSchema } from "./SimpleSchema";
46-
import { sim } from "./SimpleSchema";
46+
import { simAdapter } from "./SimpleSchema";
4747
import { struct, StructureSchema } from "./StructureSchema";
4848
import { translateTraits } from "./translateTraits";
4949

@@ -450,7 +450,7 @@ export function hydrate(
450450
const [id, ...rest] = ss;
451451
return (
452452
{
453-
[0 satisfies StaticSchemaIdSimple]: sim,
453+
[0 satisfies StaticSchemaIdSimple]: simAdapter,
454454
[1 satisfies StaticSchemaIdList]: list,
455455
[2 satisfies StaticSchemaIdMap]: map,
456456
[3 satisfies StaticSchemaIdStruct]: struct,

packages/core/src/submodules/schema/schemas/Schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export abstract class Schema implements TraitsSchema {
1515

1616
public static assign<T extends Schema>(instance: T, values: Omit<T, "getName" | "symbol">): T {
1717
const schema = Object.assign(instance, values);
18-
TypeRegistry.for(schema.namespace).register(schema.name, schema);
18+
// TypeRegistry.for(schema.namespace).register(schema.name, schema);
1919
return schema;
2020
}
2121

packages/core/src/submodules/schema/schemas/SimpleSchema.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,15 @@ export const sim = (namespace: string, name: string, schemaRef: SchemaRef, trait
2929
traits,
3030
schemaRef,
3131
});
32+
33+
/**
34+
* @internal
35+
* @deprecated
36+
*/
37+
export const simAdapter = (namespace: string, name: string, traits: SchemaTraits, schemaRef: SchemaRef) =>
38+
Schema.assign(new SimpleSchema(), {
39+
name,
40+
namespace,
41+
traits,
42+
schemaRef,
43+
});

packages/core/src/submodules/schema/schemas/schemas.spec.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ describe("schemas", () => {
2323
expect(schema.ctor).toBe(null);
2424
});
2525

26-
it("has a factory and the factory registers the schema", () => {
26+
it("has a factory", () => {
2727
expect(error("ack", "Error", 0, [], [])).toEqual(schema);
28-
expect(TypeRegistry.for("ack").getSchema(schema.name)).toEqual(schema);
2928
});
3029

3130
it("has an instanceOf operator", () => {
@@ -44,9 +43,8 @@ describe("schemas", () => {
4443
it("has a value schema", () => {
4544
expect(schema.valueSchema).toBe(0 as SchemaRef);
4645
});
47-
it("has a factory and the factory registers the schema", () => {
46+
it("has a factory", () => {
4847
expect(list("ack", "List", 0, 0)).toEqual(schema);
49-
expect(TypeRegistry.for("ack").getSchema(schema.name)).toEqual(schema);
5048
});
5149
it("has an instanceOf operator", () => {
5250
const object = { ...schema };
@@ -65,9 +63,8 @@ describe("schemas", () => {
6563
expect(schema.keySchema).toBe(0 as SchemaRef);
6664
expect(schema.valueSchema).toBe(1 as SchemaRef);
6765
});
68-
it("has a factory and the factory registers the schema", () => {
66+
it("has a factory", () => {
6967
expect(map("ack", "Map", 0, 0, 1)).toEqual(schema);
70-
expect(TypeRegistry.for("ack").getSchema(schema.name)).toEqual(schema);
7168
});
7269
it("has an instanceOf operator", () => {
7370
const object = { ...schema };
@@ -86,9 +83,8 @@ describe("schemas", () => {
8683
expect(schema.input).toEqual("unit");
8784
expect(schema.output).toEqual("unit");
8885
});
89-
it("has a factory and the factory registers the schema", () => {
86+
it("has a factory", () => {
9087
expect(op("ack", "Operation", 0, "unit", "unit")).toEqual(schema);
91-
expect(TypeRegistry.for("ack").getSchema(schema.name)).toEqual(schema);
9288
});
9389
});
9490

@@ -121,9 +117,8 @@ describe("schemas", () => {
121117
expect(schema).toBeInstanceOf(Schema);
122118
expect(schema).toBeInstanceOf(SimpleSchema);
123119
});
124-
it("has a factory and the factory registers the schema", () => {
120+
it("has a factory", () => {
125121
expect(sim("ack", "Simple", 0, 0)).toEqual(schema);
126-
expect(TypeRegistry.for("ack").getSchema(schema.name)).toEqual(schema);
127122
});
128123
it("has an instanceOf operator", () => {
129124
const object = { ...schema };
@@ -143,9 +138,8 @@ describe("schemas", () => {
143138
expect(schema.memberNames).toEqual(["a", "b", "c"]);
144139
expect(schema.memberList).toEqual([0, 1, 2]);
145140
});
146-
it("has a factory and the factory registers the schema", () => {
141+
it("has a factory", () => {
147142
expect(struct("ack", "Structure", 0, ["a", "b", "c"], [0, 1, 2])).toEqual(schema);
148-
expect(TypeRegistry.for("ack").getSchema(schema.name)).toEqual(schema);
149143
});
150144
it("has an instanceOf operator", () => {
151145
const object = { ...schema };

packages/types/src/schema/static-schemas.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export type ShapeNamespace = string;
5959
/**
6060
* @alpha
6161
*/
62-
export type StaticSimpleSchema = [StaticSchemaIdSimple, ShapeNamespace, ShapeName, SchemaRef, SchemaTraits];
62+
export type StaticSimpleSchema = [StaticSchemaIdSimple, ShapeNamespace, ShapeName, SchemaTraits, SchemaRef];
6363

6464
/**
6565
* @alpha

0 commit comments

Comments
 (0)