Skip to content

Commit 0547fab

Browse files
authored
feat(core/schema): add schema types (#1593)
1 parent 5213dfc commit 0547fab

File tree

8 files changed

+498
-0
lines changed

8 files changed

+498
-0
lines changed

.changeset/fresh-otters-tickle.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@smithy/types": minor
3+
---
4+
5+
add types for schemas

packages/types/src/command.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Handler, MiddlewareStack } from "./middleware";
22
import { MetadataBearer } from "./response";
3+
import { OperationSchema } from "./schema/schema";
34

45
/**
56
* @public
@@ -13,6 +14,8 @@ export interface Command<
1314
> extends CommandIO<InputType, OutputType> {
1415
readonly input: InputType;
1516
readonly middlewareStack: MiddlewareStack<InputType, OutputType>;
17+
readonly schema?: OperationSchema;
18+
1619
resolveMiddleware(
1720
stack: MiddlewareStack<ClientInput, ClientOutput>,
1821
configuration: ResolvedConfiguration,

packages/types/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export * from "./pagination";
2121
export * from "./profile";
2222
export * from "./response";
2323
export * from "./retry";
24+
export * from "./schema/schema";
25+
export * from "./schema/sentinels";
2426
export * from "./serde";
2527
export * from "./shapes";
2628
export * from "./signature";
@@ -30,6 +32,7 @@ export * from "./streaming-payload/streaming-blob-payload-input-types";
3032
export * from "./streaming-payload/streaming-blob-payload-output-types";
3133
export * from "./transfer";
3234
export * from "./transform/client-payload-blob-type-narrow";
35+
export * from "./transform/mutable";
3336
export * from "./transform/no-undefined";
3437
export * from "./transform/type-transform";
3538
export * from "./uri";

packages/types/src/schema/schema.ts

Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
import type { EndpointV2 } from "../endpoint";
2+
import type { HandlerExecutionContext } from "../middleware";
3+
import type { MetadataBearer } from "../response";
4+
import type { EndpointBearer, SerdeFunctions } from "../serde";
5+
import type {
6+
BigDecimalSchema,
7+
BigIntegerSchema,
8+
BlobSchema,
9+
BooleanSchema,
10+
DocumentSchema,
11+
NumericSchema,
12+
StreamingBlobSchema,
13+
StringSchema,
14+
TimestampDateTimeSchema,
15+
TimestampDefaultSchema,
16+
TimestampEpochSecondsSchema,
17+
TimestampHttpDateSchema,
18+
} from "./sentinels";
19+
import type { TraitBitVector } from "./traits";
20+
21+
/**
22+
* A schema is an object or value that describes how to serialize/deserialize data.
23+
* @public
24+
*/
25+
export type Schema =
26+
| UnitSchema
27+
| TraitsSchema
28+
| SimpleSchema
29+
| ListSchema
30+
| MapSchema
31+
| StructureSchema
32+
| MemberSchema
33+
| OperationSchema
34+
| NormalizedSchema;
35+
36+
/**
37+
* Traits attached to schema objects.
38+
*
39+
* When this is a number, it refers to a pre-allocated
40+
* trait combination that is equivalent to one of the
41+
* object type's variations.
42+
*
43+
* @public
44+
*/
45+
export type SchemaTraits = TraitBitVector | SchemaTraitsObject;
46+
47+
/**
48+
* A schema that has traits.
49+
*
50+
* @public
51+
*/
52+
export interface TraitsSchema {
53+
name: string;
54+
traits: SchemaTraits;
55+
}
56+
57+
/**
58+
* Simple schemas are those corresponding to simple Smithy types.
59+
* @see https://smithy.io/2.0/spec/simple-types.html
60+
* @public
61+
*/
62+
export type SimpleSchema =
63+
| BlobSchemas
64+
| StringSchema
65+
| BooleanSchema
66+
| NumericSchema
67+
| BigIntegerSchema
68+
| BigDecimalSchema
69+
| DocumentSchema
70+
| TimestampSchemas
71+
| number;
72+
73+
/**
74+
* Sentinel value for Timestamp schema.
75+
* "Default" means unspecified and to use the protocol serializer's default format.
76+
*
77+
* @public
78+
*/
79+
export type TimestampSchemas =
80+
| TimestampDefaultSchema
81+
| TimestampDateTimeSchema
82+
| TimestampHttpDateSchema
83+
| TimestampEpochSecondsSchema;
84+
85+
/**
86+
* Sentinel values for Blob schema.
87+
* @public
88+
*/
89+
export type BlobSchemas = BlobSchema | StreamingBlobSchema;
90+
91+
/**
92+
* Signal value for the Smithy void value. Typically used for
93+
* operation input and outputs.
94+
*
95+
* @internal
96+
*/
97+
export type UnitSchema = "unit";
98+
99+
/**
100+
* See https://smithy.io/2.0/trait-index.html for individual definitions.
101+
*
102+
* @public
103+
*/
104+
export type SchemaTraitsObject = {
105+
idempotent?: 1;
106+
idempotencyToken?: 1;
107+
sensitive?: 1;
108+
sparse?: 1;
109+
110+
/**
111+
* timestampFormat is expressed by the schema sentinel values of 4, 5, 6, and 7,
112+
* and not contained in trait objects.
113+
* @deprecated use schema value.
114+
*/
115+
timestampFormat?: never;
116+
117+
httpLabel?: 1;
118+
httpHeader?: string;
119+
httpQuery?: string;
120+
httpPrefixHeaders?: string;
121+
httpQueryParams?: 1;
122+
httpPayload?: 1;
123+
/**
124+
* [method, path, statusCode]
125+
*/
126+
http?: [string, string, number];
127+
httpResponseCode?: 1;
128+
/**
129+
* [hostPrefix]
130+
*/
131+
endpoint?: [string];
132+
133+
xmlAttribute?: 1;
134+
xmlName?: string;
135+
/**
136+
* [prefix, uri]
137+
*/
138+
xmlNamespace?: [string, string];
139+
xmlFlattened?: 1;
140+
jsonName?: string;
141+
142+
mediaType?: string;
143+
error?: "client" | "server";
144+
145+
[traitName: string]: unknown;
146+
};
147+
148+
/**
149+
* Schema for the structure aggregate type.
150+
* @public
151+
*/
152+
export interface StructureSchema extends TraitsSchema {
153+
name: string;
154+
traits: SchemaTraits;
155+
members: Record<string, [SchemaRef, SchemaTraits]>;
156+
}
157+
158+
/**
159+
* Schema for the list aggregate type.
160+
* @public
161+
*/
162+
export interface ListSchema extends TraitsSchema {
163+
name: string;
164+
traits: SchemaTraits;
165+
valueSchema: SchemaRef;
166+
}
167+
168+
/**
169+
* Schema for the map aggregate type.
170+
* @public
171+
*/
172+
export interface MapSchema extends TraitsSchema {
173+
name: string;
174+
traits: SchemaTraits;
175+
keySchema: SchemaRef;
176+
valueSchema: SchemaRef;
177+
}
178+
179+
/**
180+
* @public
181+
*/
182+
export type MemberSchema = [SchemaRef, SchemaTraits];
183+
184+
/**
185+
* Schema for an operation.
186+
*
187+
* @public
188+
*/
189+
export interface OperationSchema extends TraitsSchema {
190+
name: string;
191+
traits: SchemaTraits;
192+
input: SchemaRef;
193+
output: SchemaRef;
194+
}
195+
196+
/**
197+
* Normalization wrapper for various schema data objects.
198+
* @internal
199+
*/
200+
export interface NormalizedSchema extends TraitsSchema {
201+
name: string;
202+
traits: SchemaTraits;
203+
getSchema(): Schema;
204+
getName(): string | undefined;
205+
isMemberSchema(): boolean;
206+
isListSchema(): boolean;
207+
isMapSchema(): boolean;
208+
isStructSchema(): boolean;
209+
isBlobSchema(): boolean;
210+
isTimestampSchema(): boolean;
211+
isStringSchema(): boolean;
212+
isBooleanSchema(): boolean;
213+
isNumericSchema(): boolean;
214+
isBigIntegerSchema(): boolean;
215+
isBigDecimalSchema(): boolean;
216+
isStreaming(): boolean;
217+
getMergedTraits(): SchemaTraitsObject;
218+
getMemberTraits(): SchemaTraitsObject;
219+
getOwnTraits(): SchemaTraitsObject;
220+
/**
221+
* For list/set/map.
222+
*/
223+
getValueSchema(): NormalizedSchema;
224+
/**
225+
* For struct/union.
226+
*/
227+
getMemberSchema(member: string): NormalizedSchema | undefined;
228+
getMemberSchemas(): Record<string, NormalizedSchema>;
229+
}
230+
231+
/**
232+
* A schema "reference" is either a schema or a function that
233+
* provides a schema. This is useful for lazy loading, and to allow
234+
* code generation to define schema out of dependency order.
235+
* @public
236+
*/
237+
export type SchemaRef = Schema | (() => Schema);
238+
239+
/**
240+
* A codec creates serializers and deserializers for some format such as JSON, XML, or CBOR.
241+
*
242+
* @public
243+
*/
244+
export interface Codec<S, D> extends ConfigurableSerdeContext {
245+
createSerializer(): ShapeSerializer<S>;
246+
createDeserializer(): ShapeDeserializer<D>;
247+
}
248+
249+
/**
250+
* Configuration for codecs. Different protocols may share codecs, but require different behaviors from them.
251+
*
252+
* @public
253+
*/
254+
export type CodecSettings = {
255+
timestampFormat: {
256+
/**
257+
* Whether to use member timestamp format traits.
258+
*/
259+
useTrait: boolean;
260+
/**
261+
* Default timestamp format.
262+
*/
263+
default: TimestampDateTimeSchema | TimestampHttpDateSchema | TimestampEpochSecondsSchema;
264+
};
265+
/**
266+
* Whether to use HTTP binding traits.
267+
*/
268+
httpBindings?: boolean;
269+
};
270+
271+
/**
272+
* Turns a serialization into a data object.
273+
* @public
274+
*/
275+
export interface ShapeDeserializer<SerializationType = Uint8Array> extends ConfigurableSerdeContext {
276+
/**
277+
* Optionally async.
278+
*/
279+
read(schema: Schema, data: SerializationType): any | Promise<any>;
280+
}
281+
282+
/**
283+
* Turns a data object into a serialization.
284+
* @public
285+
*/
286+
export interface ShapeSerializer<SerializationType = Uint8Array> extends ConfigurableSerdeContext {
287+
write(schema: Schema, value: unknown): void;
288+
289+
flush(): SerializationType;
290+
}
291+
292+
/**
293+
* A client protocol defines how to convert a message (e.g. HTTP request/response) to and from a data object.
294+
* @public
295+
*/
296+
export interface ClientProtocol<Request, Response> extends ConfigurableSerdeContext {
297+
/**
298+
* @returns the Smithy qualified shape id.
299+
*/
300+
getShapeId(): string;
301+
302+
getRequestType(): { new (...args: any[]): Request };
303+
getResponseType(): { new (...args: any[]): Response };
304+
305+
/**
306+
* @returns the payload codec if the requests/responses have a symmetric format.
307+
* It otherwise may return null.
308+
*/
309+
getPayloadCodec(): Codec<any, any>;
310+
311+
serializeRequest<Input extends object>(
312+
operationSchema: OperationSchema,
313+
input: Input,
314+
context: HandlerExecutionContext & SerdeFunctions & EndpointBearer
315+
): Promise<Request>;
316+
317+
updateServiceEndpoint(request: Request, endpoint: EndpointV2): Request;
318+
319+
deserializeResponse<Output extends MetadataBearer>(
320+
operationSchema: OperationSchema,
321+
context: HandlerExecutionContext & SerdeFunctions,
322+
response: Response
323+
): Promise<Output>;
324+
}
325+
326+
/**
327+
* Allows a protocol, codec, or serde utility to accept the serdeContext
328+
* from a client configuration or request/response handlerExecutionContext.
329+
*
330+
* @public
331+
*/
332+
export interface ConfigurableSerdeContext {
333+
setSerdeContext(serdeContext: SerdeFunctions): void;
334+
}
335+
336+
// TODO(schema): transports are not required in the current implementation.
337+
// /**
338+
// * @public
339+
// */
340+
// export interface Transport<Request, Response> {
341+
// getRequestType(): { new (...args: any[]): Request };
342+
// getResponseType(): { new (...args: any[]): Response };
343+
//
344+
// send(context: HandlerExecutionContext, request: Request): Promise<Response>;
345+
// }

0 commit comments

Comments
 (0)