11import { NormalizedSchema } from "@smithy/core/schema" ;
2- import { parseEpochTimestamp } from "@smithy/core/serde" ;
2+ import { generateIdempotencyToken , parseEpochTimestamp } from "@smithy/core/serde" ;
33import { Codec , Schema , SerdeFunctions , ShapeDeserializer , ShapeSerializer } from "@smithy/types" ;
4+ import { fromBase64 } from "@smithy/util-base64" ;
45
56import { cbor } from "./cbor" ;
67import { dateToTag } from "./parseCborBody" ;
@@ -50,70 +51,70 @@ export class CborShapeSerializer implements ShapeSerializer {
5051 public serialize ( schema : Schema , source : unknown ) : any {
5152 const ns = NormalizedSchema . of ( schema ) ;
5253
53- switch ( typeof source ) {
54- case "undefined" :
55- return null ;
56- case "boolean" :
57- case "number" :
58- case "string" :
59- case "bigint" :
60- case "symbol" :
61- return source ;
62- case "function" :
63- case "object" :
64- if ( source === null ) {
65- return null ;
66- }
54+ if ( source == null ) {
55+ if ( ns . isIdempotencyToken ( ) ) {
56+ return generateIdempotencyToken ( ) ;
57+ }
58+ return source as null | undefined ;
59+ }
6760
68- const sourceObject = source as Record < string , unknown > ;
69- const sparse = ! ! ns . getMergedTraits ( ) . sparse ;
61+ if ( ns . isBlobSchema ( ) ) {
62+ if ( typeof source === "string" ) {
63+ return ( this . serdeContext ?. base64Decoder ?? fromBase64 ) ( source ) ;
64+ }
65+ return source as Uint8Array ;
66+ }
67+
68+ if ( ns . isTimestampSchema ( ) ) {
69+ if ( typeof source === "number" || typeof source === "bigint" ) {
70+ return dateToTag ( new Date ( ( Number ( source ) / 1000 ) | 0 ) ) ;
71+ }
72+ return dateToTag ( source as Date ) ;
73+ }
7074
71- if ( ns . isListSchema ( ) && Array . isArray ( sourceObject ) ) {
72- const newArray = [ ] ;
73- let i = 0 ;
74- for ( const item of sourceObject ) {
75- const value = this . serialize ( ns . getValueSchema ( ) , item ) ;
76- if ( value != null || sparse ) {
77- newArray [ i ++ ] = value ;
78- }
75+ if ( typeof source === "function" || typeof source === "object" ) {
76+ const sourceObject = source as Record < string , unknown > ;
77+
78+ if ( ns . isListSchema ( ) && Array . isArray ( sourceObject ) ) {
79+ const sparse = ! ! ns . getMergedTraits ( ) . sparse ;
80+ const newArray = [ ] ;
81+ let i = 0 ;
82+ for ( const item of sourceObject ) {
83+ const value = this . serialize ( ns . getValueSchema ( ) , item ) ;
84+ if ( value != null || sparse ) {
85+ newArray [ i ++ ] = value ;
7986 }
80- return newArray ;
81- }
82- if ( sourceObject instanceof Uint8Array ) {
83- const newBytes = new Uint8Array ( sourceObject . byteLength ) ;
84- newBytes . set ( sourceObject , 0 ) ;
85- return newBytes ;
86- }
87- if ( sourceObject instanceof Date ) {
88- return dateToTag ( sourceObject ) ;
8987 }
90- const newObject = { } as any ;
91- if ( ns . isMapSchema ( ) ) {
92- for ( const key of Object . keys ( sourceObject ) ) {
93- const value = this . serialize ( ns . getValueSchema ( ) , sourceObject [ key ] ) ;
94- if ( value != null || sparse ) {
95- newObject [ key ] = value ;
96- }
97- }
98- } else if ( ns . isStructSchema ( ) ) {
99- for ( const [ key , memberSchema ] of ns . structIterator ( ) ) {
100- const value = this . serialize ( memberSchema , sourceObject [ key ] ) ;
101- if ( value != null ) {
102- newObject [ key ] = value ;
103- }
88+ return newArray ;
89+ }
90+ if ( sourceObject instanceof Date ) {
91+ return dateToTag ( sourceObject ) ;
92+ }
93+ const newObject = { } as any ;
94+ if ( ns . isMapSchema ( ) ) {
95+ const sparse = ! ! ns . getMergedTraits ( ) . sparse ;
96+ for ( const key of Object . keys ( sourceObject ) ) {
97+ const value = this . serialize ( ns . getValueSchema ( ) , sourceObject [ key ] ) ;
98+ if ( value != null || sparse ) {
99+ newObject [ key ] = value ;
104100 }
105- } else if ( ns . isDocumentSchema ( ) ) {
106- for ( const key of Object . keys ( sourceObject ) ) {
107- const value = this . serialize ( ns . getValueSchema ( ) , sourceObject [ key ] ) ;
108- if ( value != null ) {
109- newObject [ key ] = value ;
110- }
101+ }
102+ } else if ( ns . isStructSchema ( ) ) {
103+ for ( const [ key , memberSchema ] of ns . structIterator ( ) ) {
104+ const value = this . serialize ( memberSchema , sourceObject [ key ] ) ;
105+ if ( value != null ) {
106+ newObject [ key ] = value ;
111107 }
112108 }
113- return newObject ;
114- default :
115- return source ;
109+ } else if ( ns . isDocumentSchema ( ) ) {
110+ for ( const key of Object . keys ( sourceObject ) ) {
111+ newObject [ key ] = this . serialize ( ns . getValueSchema ( ) , sourceObject [ key ] ) ;
112+ }
113+ }
114+ return newObject ;
116115 }
116+
117+ return source ;
117118 }
118119
119120 public flush ( ) : Uint8Array {
@@ -140,16 +141,17 @@ export class CborShapeDeserializer implements ShapeDeserializer {
140141
141142 private readValue ( _schema : Schema , value : any ) : any {
142143 const ns = NormalizedSchema . of ( _schema ) ;
143- const schema = ns . getSchema ( ) ;
144144
145- if ( typeof schema === "number" ) {
146- if ( ns . isTimestampSchema ( ) ) {
147- // format is ignored.
148- return parseEpochTimestamp ( value ) ;
149- }
150- if ( ns . isBlobSchema ( ) ) {
151- return value ;
145+ if ( ns . isTimestampSchema ( ) && typeof value === "number" ) {
146+ // format is ignored.
147+ return parseEpochTimestamp ( value ) ;
148+ }
149+
150+ if ( ns . isBlobSchema ( ) ) {
151+ if ( typeof value === "string" ) {
152+ return ( this . serdeContext ?. base64Decoder ?? fromBase64 ) ( value ) ;
152153 }
154+ return value as Uint8Array | undefined ;
153155 }
154156
155157 if (
@@ -176,14 +178,14 @@ export class CborShapeDeserializer implements ShapeDeserializer {
176178 }
177179
178180 if ( ns . isListSchema ( ) ) {
179- const newArray = [ ] ;
181+ const newArray = [ ] as any [ ] ;
180182 const memberSchema = ns . getValueSchema ( ) ;
181- const sparse = ns . isListSchema ( ) && ! ! ns . getMergedTraits ( ) . sparse ;
183+ const sparse = ! ! ns . getMergedTraits ( ) . sparse ;
182184
183185 for ( const item of value ) {
184- newArray . push ( this . readValue ( memberSchema , item ) ) ;
185- if ( ! sparse && newArray [ newArray . length - 1 ] == null ) {
186- newArray . pop ( ) ;
186+ const itemValue = this . readValue ( memberSchema , item ) ;
187+ if ( itemValue != null || sparse ) {
188+ newArray . push ( itemValue ) ;
187189 }
188190 }
189191 return newArray ;
@@ -192,14 +194,13 @@ export class CborShapeDeserializer implements ShapeDeserializer {
192194 const newObject = { } as any ;
193195
194196 if ( ns . isMapSchema ( ) ) {
195- const sparse = ns . getMergedTraits ( ) . sparse ;
197+ const sparse = ! ! ns . getMergedTraits ( ) . sparse ;
196198 const targetSchema = ns . getValueSchema ( ) ;
197199
198200 for ( const key of Object . keys ( value ) ) {
199- newObject [ key ] = this . readValue ( targetSchema , value [ key ] ) ;
200-
201- if ( newObject [ key ] == null && ! sparse ) {
202- delete newObject [ key ] ;
201+ const itemValue = this . readValue ( targetSchema , value [ key ] ) ;
202+ if ( itemValue != null || sparse ) {
203+ newObject [ key ] = itemValue ;
203204 }
204205 }
205206 } else if ( ns . isStructSchema ( ) ) {
0 commit comments