1
1
import { NormalizedSchema } from "@smithy/core/schema" ;
2
- import { parseEpochTimestamp } from "@smithy/core/serde" ;
2
+ import { generateIdempotencyToken , parseEpochTimestamp } from "@smithy/core/serde" ;
3
3
import { Codec , Schema , SerdeFunctions , ShapeDeserializer , ShapeSerializer } from "@smithy/types" ;
4
+ import { fromBase64 } from "@smithy/util-base64" ;
4
5
5
6
import { cbor } from "./cbor" ;
6
7
import { dateToTag } from "./parseCborBody" ;
@@ -50,70 +51,70 @@ export class CborShapeSerializer implements ShapeSerializer {
50
51
public serialize ( schema : Schema , source : unknown ) : any {
51
52
const ns = NormalizedSchema . of ( schema ) ;
52
53
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
+ }
67
60
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
+ }
70
74
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 ;
79
86
}
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 ) ;
89
87
}
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 ;
104
100
}
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 ;
111
107
}
112
108
}
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 ;
116
115
}
116
+
117
+ return source ;
117
118
}
118
119
119
120
public flush ( ) : Uint8Array {
@@ -140,16 +141,17 @@ export class CborShapeDeserializer implements ShapeDeserializer {
140
141
141
142
private readValue ( _schema : Schema , value : any ) : any {
142
143
const ns = NormalizedSchema . of ( _schema ) ;
143
- const schema = ns . getSchema ( ) ;
144
144
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 ) ;
152
153
}
154
+ return value as Uint8Array | undefined ;
153
155
}
154
156
155
157
if (
@@ -176,14 +178,14 @@ export class CborShapeDeserializer implements ShapeDeserializer {
176
178
}
177
179
178
180
if ( ns . isListSchema ( ) ) {
179
- const newArray = [ ] ;
181
+ const newArray = [ ] as any [ ] ;
180
182
const memberSchema = ns . getValueSchema ( ) ;
181
- const sparse = ns . isListSchema ( ) && ! ! ns . getMergedTraits ( ) . sparse ;
183
+ const sparse = ! ! ns . getMergedTraits ( ) . sparse ;
182
184
183
185
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 ) ;
187
189
}
188
190
}
189
191
return newArray ;
@@ -192,14 +194,13 @@ export class CborShapeDeserializer implements ShapeDeserializer {
192
194
const newObject = { } as any ;
193
195
194
196
if ( ns . isMapSchema ( ) ) {
195
- const sparse = ns . getMergedTraits ( ) . sparse ;
197
+ const sparse = ! ! ns . getMergedTraits ( ) . sparse ;
196
198
const targetSchema = ns . getValueSchema ( ) ;
197
199
198
200
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 ;
203
204
}
204
205
}
205
206
} else if ( ns . isStructSchema ( ) ) {
0 commit comments