@aws-sdk/core 3.977.3 → 3.977.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1022,14 +1022,20 @@ class JsonShapeDeserializer2 extends SerdeContextConfig {
1022
1022
  const reviver = needsReviver(schema) ? jsonReviver : undefined;
1023
1023
  let parsed;
1024
1024
  if (typeof data === "string") {
1025
+ if (data.length === 0) {
1026
+ return {};
1027
+ }
1025
1028
  parsed = JSON.parse(data, reviver);
1026
1029
  }
1027
1030
  else if (data instanceof Uint8Array && detectBufferParsing()) {
1031
+ if (data.byteLength === 0) {
1032
+ return {};
1033
+ }
1028
1034
  const buf = Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
1029
1035
  parsed = JSON.parse(buf, reviver);
1030
1036
  }
1031
1037
  else {
1032
- parsed = await parseJsonBody(data, this.serdeContext);
1038
+ parsed = await parseJsonBody(data, this.serdeContext, schema);
1033
1039
  }
1034
1040
  return this._read(schema, parsed);
1035
1041
  }
@@ -1045,19 +1051,23 @@ class JsonShapeDeserializer2 extends SerdeContextConfig {
1045
1051
  }
1046
1052
  if (Array.isArray(value) && ns.isListSchema()) {
1047
1053
  const listMember = ns.getValueSchema();
1048
- for (let i = 0; i < value.length; ++i) {
1049
- value[i] = this._read(listMember, value[i]);
1054
+ if (this.needsTransform(listMember)) {
1055
+ for (let i = 0; i < value.length; ++i) {
1056
+ value[i] = this._read(listMember, value[i]);
1057
+ }
1050
1058
  }
1051
1059
  return value;
1052
1060
  }
1053
1061
  if (ns.isMapSchema()) {
1054
1062
  const mapMember = ns.getValueSchema();
1055
1063
  const map = value;
1056
- for (const k in map) {
1057
- if (k === "__proto__") {
1058
- writeKey(map);
1064
+ if (this.needsTransform(mapMember)) {
1065
+ for (const k in map) {
1066
+ if (k === "__proto__") {
1067
+ writeKey(map);
1068
+ }
1069
+ map[k] = this._read(mapMember, map[k]);
1059
1070
  }
1060
- map[k] = this._read(mapMember, map[k]);
1061
1071
  }
1062
1072
  return map;
1063
1073
  }
@@ -1133,10 +1143,6 @@ class JsonShapeDeserializer2 extends SerdeContextConfig {
1133
1143
  }
1134
1144
  }
1135
1145
  }
1136
- return value;
1137
- }
1138
- else {
1139
- return value;
1140
1146
  }
1141
1147
  }
1142
1148
  return value;
@@ -1144,9 +1150,10 @@ class JsonShapeDeserializer2 extends SerdeContextConfig {
1144
1150
  _readStruct(ns, record) {
1145
1151
  const union = ns.isUnionSchema();
1146
1152
  const out = {};
1147
- let nameMap = void 0;
1153
+ let nameMap;
1154
+ const hasType = typeof record.__type === "string";
1148
1155
  const { jsonName } = this.settings;
1149
- if (jsonName) {
1156
+ if (jsonName && hasType) {
1150
1157
  nameMap = {};
1151
1158
  }
1152
1159
  let unionSerde;
@@ -1157,7 +1164,9 @@ class JsonShapeDeserializer2 extends SerdeContextConfig {
1157
1164
  let fromKey = memberName;
1158
1165
  if (jsonName) {
1159
1166
  fromKey = memberSchema.getMergedTraits().jsonName ?? fromKey;
1160
- nameMap[fromKey] = memberName;
1167
+ if (hasType) {
1168
+ nameMap[fromKey] = memberName;
1169
+ }
1161
1170
  }
1162
1171
  if (union) {
1163
1172
  unionSerde.mark(fromKey);
@@ -1169,7 +1178,7 @@ class JsonShapeDeserializer2 extends SerdeContextConfig {
1169
1178
  if (union) {
1170
1179
  unionSerde.writeUnknown();
1171
1180
  }
1172
- else if (typeof record.__type === "string") {
1181
+ else if (hasType) {
1173
1182
  for (const k in record) {
1174
1183
  const v = record[k];
1175
1184
  const t = jsonName ? (nameMap[k] ?? k) : k;
@@ -1180,8 +1189,123 @@ class JsonShapeDeserializer2 extends SerdeContextConfig {
1180
1189
  }
1181
1190
  return out;
1182
1191
  }
1192
+ needsTransform(ns) {
1193
+ if (ns.isBlobSchema() || ns.isTimestampSchema() || ns.isBigIntegerSchema() || ns.isBigDecimalSchema()) {
1194
+ return true;
1195
+ }
1196
+ if (ns.isDocumentSchema() || ns.isStructSchema() || ns.isListSchema() || ns.isMapSchema()) {
1197
+ return true;
1198
+ }
1199
+ if (ns.isStringSchema() && ns.getMergedTraits().mediaType) {
1200
+ return true;
1201
+ }
1202
+ return false;
1203
+ }
1183
1204
  }
1184
1205
 
1206
+ class JsonBytesStringAdapter extends Uint8Array {
1207
+ string = null;
1208
+ static allocUnsafe(bytes) {
1209
+ if (typeof Buffer === "function") {
1210
+ const buffer = Buffer.allocUnsafe(bytes);
1211
+ return new JsonBytesStringAdapter(buffer.buffer, buffer.byteOffset, buffer.byteLength);
1212
+ }
1213
+ return new JsonBytesStringAdapter(bytes);
1214
+ }
1215
+ toString() {
1216
+ return this.s();
1217
+ }
1218
+ valueOf() {
1219
+ return this.s();
1220
+ }
1221
+ includes(searchString, position) {
1222
+ if (typeof searchString === "string") {
1223
+ return this.s().includes(searchString, position);
1224
+ }
1225
+ return Uint8Array.prototype.includes.call(this, searchString, position);
1226
+ }
1227
+ indexOf(searchString, position) {
1228
+ if (typeof searchString === "string") {
1229
+ return this.s().indexOf(searchString, position);
1230
+ }
1231
+ return Uint8Array.prototype.indexOf.call(this, searchString, position);
1232
+ }
1233
+ lastIndexOf(searchString, position) {
1234
+ if (typeof searchString === "string") {
1235
+ return this.s().lastIndexOf(searchString, position);
1236
+ }
1237
+ const fn = Uint8Array.prototype.lastIndexOf;
1238
+ if (position !== undefined) {
1239
+ return fn.call(this, searchString, position);
1240
+ }
1241
+ return fn.call(this, searchString);
1242
+ }
1243
+ startsWith(searchString, position) {
1244
+ return this.s().startsWith(searchString, position);
1245
+ }
1246
+ endsWith(searchString, endPosition) {
1247
+ return this.s().endsWith(searchString, endPosition);
1248
+ }
1249
+ match(regexp) {
1250
+ return this.s().match(regexp);
1251
+ }
1252
+ replace(searchValue, replaceValue) {
1253
+ return this.s().replace(searchValue, replaceValue);
1254
+ }
1255
+ search(regexp) {
1256
+ return this.s().search(regexp);
1257
+ }
1258
+ split(separator, limit) {
1259
+ return this.s().split(separator, limit);
1260
+ }
1261
+ substring(start, end) {
1262
+ return this.s().substring(start, end);
1263
+ }
1264
+ trim() {
1265
+ return this.s().trim();
1266
+ }
1267
+ trimStart() {
1268
+ return this.s().trimStart();
1269
+ }
1270
+ trimEnd() {
1271
+ return this.s().trimEnd();
1272
+ }
1273
+ charAt(pos) {
1274
+ return this.s().charAt(pos);
1275
+ }
1276
+ charCodeAt(index) {
1277
+ return this.s().charCodeAt(index);
1278
+ }
1279
+ padStart(maxLength, fillString) {
1280
+ return this.s().padStart(maxLength, fillString);
1281
+ }
1282
+ padEnd(maxLength, fillString) {
1283
+ return this.s().padEnd(maxLength, fillString);
1284
+ }
1285
+ repeat(count) {
1286
+ return this.s().repeat(count);
1287
+ }
1288
+ toUpperCase() {
1289
+ return this.s().toUpperCase();
1290
+ }
1291
+ toLowerCase() {
1292
+ return this.s().toLowerCase();
1293
+ }
1294
+ s() {
1295
+ if (this.string == null) {
1296
+ const n = Date.now();
1297
+ if (n > warned + 60_000) {
1298
+ console.warn("@aws-sdk/core/protocols - WARN - JsonCodec2: you have called a string method on a Uint8Array request body. " +
1299
+ "It has been automatically converted to string. In a future version this will throw an error.");
1300
+ warned = n;
1301
+ }
1302
+ this.string = toUtf8(this);
1303
+ }
1304
+ return this.string;
1305
+ }
1306
+ }
1307
+ var warned = 0;
1308
+
1185
1309
  const encoder = new TextEncoder();
1186
1310
  const OPEN_BRACE = 0x7b;
1187
1311
  const CLOSE_BRACE = 0x7d;
@@ -1209,7 +1333,7 @@ for (let i = 0; i < 0x20; i++) {
1209
1333
  }
1210
1334
  const INITIAL_BUFFER_SIZE = 2048;
1211
1335
  function alloc(size) {
1212
- return typeof Buffer !== "undefined" ? Buffer.allocUnsafe(size) : new Uint8Array(size);
1336
+ return JsonBytesStringAdapter.allocUnsafe(size);
1213
1337
  }
1214
1338
  class JsonShapeSerializer2 extends SerdeContextConfig {
1215
1339
  settings;
@@ -1227,10 +1351,7 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1227
1351
  this.i = 0;
1228
1352
  this.rawValue = value;
1229
1353
  this.rootSchema = NormalizedSchema.of(schema);
1230
- this.passthrough =
1231
- !this.rootSchema.isStructSchema() &&
1232
- !this.rootSchema.isDocumentSchema() &&
1233
- (this.rootSchema.isBlobSchema() || this.rootSchema.isStringSchema());
1354
+ this.passthrough = this.rootSchema.isBlobSchema() || this.rootSchema.isStringSchema();
1234
1355
  if (!this.passthrough) {
1235
1356
  this.writeValue(this.rootSchema, value, undefined);
1236
1357
  }
@@ -1240,30 +1361,13 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1240
1361
  this.rootSchema = NormalizedSchema.of(schema);
1241
1362
  const ns = this.rootSchema;
1242
1363
  if (ns.isStructSchema() && value != null && typeof value === "object") {
1243
- this.ensure(2);
1244
- this.json[this.i++] = OPEN_BRACE;
1245
- this.writeAsciiQuoted("__type");
1246
- this.json[this.i++] = COLON;
1247
- this.writeAsciiQuoted(ns.getName(true) ?? "Unknown");
1248
- let wroteAny = true;
1249
- const { jsonName } = this.settings;
1250
- for (const [memberName, memberSchema] of ns.structIterator()) {
1251
- const item = value[memberName];
1252
- if (item == null && !memberSchema.isIdempotencyToken()) {
1253
- continue;
1254
- }
1255
- if (wroteAny) {
1256
- this.ensure(1);
1257
- this.json[this.i++] = COMMA;
1258
- }
1259
- const targetKey = jsonName ? (memberSchema.getMergedTraits().jsonName ?? memberName) : memberName;
1260
- this.writeAsciiQuoted(targetKey);
1261
- this.json[this.i++] = COLON;
1262
- this.writeValue(memberSchema, item, ns);
1263
- wroteAny = true;
1264
- }
1265
- this.ensure(1);
1266
- this.json[this.i++] = CLOSE_BRACE;
1364
+ this.writeValue(ns, value, undefined);
1365
+ const prefix = `"__type":"${ns.getName(true) ?? "Unknown"}",`;
1366
+ const z = prefix.length;
1367
+ this.ensure(z);
1368
+ this.json.copyWithin(1 + z, 1, this.i);
1369
+ encoder.encodeInto(prefix, this.json.subarray(1));
1370
+ this.i += z;
1267
1371
  }
1268
1372
  else {
1269
1373
  this.writeValue(ns, value, undefined);
@@ -1316,7 +1420,7 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1316
1420
  this.i = i;
1317
1421
  }
1318
1422
  writeJsonString(s) {
1319
- this.ensure(s.length * 2 + 2);
1423
+ this.ensure(s.length * 3 + 2);
1320
1424
  this.json[this.i++] = QUOTE;
1321
1425
  const z = s.length;
1322
1426
  for (let j = 0; j < z; ++j) {
@@ -1343,7 +1447,7 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1343
1447
  this.ensure(4);
1344
1448
  const { written } = encoder.encodeInto(s.substring(j, j + 2), this.json.subarray(this.i));
1345
1449
  this.i += written;
1346
- j++;
1450
+ ++j;
1347
1451
  }
1348
1452
  else {
1349
1453
  this.ensure(6);
@@ -1383,8 +1487,9 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1383
1487
  static B64 = (() => {
1384
1488
  const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1385
1489
  const table = new Uint8Array(64);
1386
- for (let i = 0; i < 64; i++)
1490
+ for (let i = 0; i < 64; ++i) {
1387
1491
  table[i] = chars.charCodeAt(i);
1492
+ }
1388
1493
  return table;
1389
1494
  })();
1390
1495
  writeBase64(data) {
@@ -1511,14 +1616,16 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1511
1616
  }
1512
1617
  if (typeof value === "boolean") {
1513
1618
  this.ensure(5);
1619
+ let { i, json } = this;
1514
1620
  if (value) {
1515
- this.json.set(TRUE, this.i);
1516
- this.i += 4;
1621
+ json.set(TRUE, i);
1622
+ i += 4;
1517
1623
  }
1518
1624
  else {
1519
- this.json.set(FALSE, this.i);
1520
- this.i += 5;
1625
+ json.set(FALSE, i);
1626
+ i += 5;
1521
1627
  }
1628
+ this.i = i;
1522
1629
  return;
1523
1630
  }
1524
1631
  if (typeof value === "bigint") {
@@ -1530,7 +1637,6 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1530
1637
  writeStruct(ns, value) {
1531
1638
  this.ensure(2);
1532
1639
  this.json[this.i++] = OPEN_BRACE;
1533
- let first = true;
1534
1640
  let wroteAny = false;
1535
1641
  const hasType = typeof value.__type === "string";
1536
1642
  let writtenKeys;
@@ -1539,13 +1645,13 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1539
1645
  }
1540
1646
  for (const [memberName, memberSchema] of ns.structIterator()) {
1541
1647
  const item = value[memberName];
1542
- if (item == null && !memberSchema.isIdempotencyToken())
1648
+ if (item == null && !memberSchema.isIdempotencyToken()) {
1543
1649
  continue;
1544
- if (!first) {
1650
+ }
1651
+ if (wroteAny) {
1545
1652
  this.ensure(1);
1546
1653
  this.json[this.i++] = COMMA;
1547
1654
  }
1548
- first = false;
1549
1655
  wroteAny = true;
1550
1656
  const targetKey = this.settings.jsonName ? (memberSchema.getMergedTraits().jsonName ?? memberName) : memberName;
1551
1657
  if (writtenKeys) {
@@ -1568,17 +1674,17 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1568
1674
  }
1569
1675
  else if (hasType) {
1570
1676
  for (const k in value) {
1571
- const targetKey = this.settings.jsonName ? (writtenKeys.has(k) ? k : k) : k;
1572
- if (writtenKeys.has(targetKey))
1677
+ if (writtenKeys.has(k)) {
1573
1678
  continue;
1574
- writtenKeys.add(targetKey);
1679
+ }
1680
+ writtenKeys.add(k);
1575
1681
  const v = value[k];
1576
- if (!first) {
1682
+ if (wroteAny) {
1577
1683
  this.ensure(1);
1578
1684
  this.json[this.i++] = COMMA;
1579
1685
  }
1580
- first = false;
1581
- this.writeAsciiQuoted(targetKey);
1686
+ wroteAny = true;
1687
+ this.writeAsciiQuoted(k);
1582
1688
  this.ensure(1);
1583
1689
  this.json[this.i++] = COLON;
1584
1690
  this.writeValue(15, v, undefined);
@@ -1588,20 +1694,30 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1588
1694
  this.json[this.i++] = CLOSE_BRACE;
1589
1695
  }
1590
1696
  writeList(ns, value, isDocument) {
1591
- this.ensure(2);
1592
- this.json[this.i++] = OPEN_BRACKET;
1593
1697
  const sparse = !!ns.getMergedTraits().sparse;
1594
1698
  const valueSchema = ns.getValueSchema();
1699
+ if (!isDocument) {
1700
+ if (valueSchema.isStringSchema() || valueSchema.isNumericSchema() || valueSchema.isBooleanSchema()) {
1701
+ const json = sparse ? JSON.stringify(value) : JSON.stringify(value.filter((_) => _ != null));
1702
+ this.ensure(json.length * 3);
1703
+ this.i += encoder.encodeInto(json, this.json.subarray(this.i)).written;
1704
+ return;
1705
+ }
1706
+ }
1707
+ this.ensure(2);
1708
+ this.json[this.i++] = OPEN_BRACKET;
1709
+ let wroteFirstItem = false;
1595
1710
  for (let i = 0; i < value.length; ++i) {
1596
1711
  const item = value[i];
1597
1712
  if (isDocument ? item === undefined : item == null && !sparse) {
1598
1713
  continue;
1599
1714
  }
1600
- if (i !== 0) {
1715
+ if (wroteFirstItem) {
1601
1716
  this.ensure(1);
1602
1717
  this.json[this.i++] = COMMA;
1603
1718
  }
1604
1719
  this.writeValue(valueSchema, item, undefined);
1720
+ wroteFirstItem = true;
1605
1721
  }
1606
1722
  this.ensure(1);
1607
1723
  this.json[this.i++] = CLOSE_BRACKET;
@@ -1623,8 +1739,7 @@ class JsonShapeSerializer2 extends SerdeContextConfig {
1623
1739
  }
1624
1740
  const json = JSON.stringify(input);
1625
1741
  this.ensure(json.length * 3);
1626
- const { written } = encoder.encodeInto(json, this.json.subarray(this.i));
1627
- this.i += written;
1742
+ this.i += encoder.encodeInto(json, this.json.subarray(this.i)).written;
1628
1743
  return;
1629
1744
  }
1630
1745
  }
@@ -0,0 +1,103 @@
1
+ import { toUtf8 } from "@smithy/core/serde";
2
+ export class JsonBytesStringAdapter extends Uint8Array {
3
+ string = null;
4
+ static allocUnsafe(bytes) {
5
+ if (typeof Buffer === "function") {
6
+ const buffer = Buffer.allocUnsafe(bytes);
7
+ return new JsonBytesStringAdapter(buffer.buffer, buffer.byteOffset, buffer.byteLength);
8
+ }
9
+ return new JsonBytesStringAdapter(bytes);
10
+ }
11
+ toString() {
12
+ return this.s();
13
+ }
14
+ valueOf() {
15
+ return this.s();
16
+ }
17
+ includes(searchString, position) {
18
+ if (typeof searchString === "string") {
19
+ return this.s().includes(searchString, position);
20
+ }
21
+ return Uint8Array.prototype.includes.call(this, searchString, position);
22
+ }
23
+ indexOf(searchString, position) {
24
+ if (typeof searchString === "string") {
25
+ return this.s().indexOf(searchString, position);
26
+ }
27
+ return Uint8Array.prototype.indexOf.call(this, searchString, position);
28
+ }
29
+ lastIndexOf(searchString, position) {
30
+ if (typeof searchString === "string") {
31
+ return this.s().lastIndexOf(searchString, position);
32
+ }
33
+ const fn = Uint8Array.prototype.lastIndexOf;
34
+ if (position !== undefined) {
35
+ return fn.call(this, searchString, position);
36
+ }
37
+ return fn.call(this, searchString);
38
+ }
39
+ startsWith(searchString, position) {
40
+ return this.s().startsWith(searchString, position);
41
+ }
42
+ endsWith(searchString, endPosition) {
43
+ return this.s().endsWith(searchString, endPosition);
44
+ }
45
+ match(regexp) {
46
+ return this.s().match(regexp);
47
+ }
48
+ replace(searchValue, replaceValue) {
49
+ return this.s().replace(searchValue, replaceValue);
50
+ }
51
+ search(regexp) {
52
+ return this.s().search(regexp);
53
+ }
54
+ split(separator, limit) {
55
+ return this.s().split(separator, limit);
56
+ }
57
+ substring(start, end) {
58
+ return this.s().substring(start, end);
59
+ }
60
+ trim() {
61
+ return this.s().trim();
62
+ }
63
+ trimStart() {
64
+ return this.s().trimStart();
65
+ }
66
+ trimEnd() {
67
+ return this.s().trimEnd();
68
+ }
69
+ charAt(pos) {
70
+ return this.s().charAt(pos);
71
+ }
72
+ charCodeAt(index) {
73
+ return this.s().charCodeAt(index);
74
+ }
75
+ padStart(maxLength, fillString) {
76
+ return this.s().padStart(maxLength, fillString);
77
+ }
78
+ padEnd(maxLength, fillString) {
79
+ return this.s().padEnd(maxLength, fillString);
80
+ }
81
+ repeat(count) {
82
+ return this.s().repeat(count);
83
+ }
84
+ toUpperCase() {
85
+ return this.s().toUpperCase();
86
+ }
87
+ toLowerCase() {
88
+ return this.s().toLowerCase();
89
+ }
90
+ s() {
91
+ if (this.string == null) {
92
+ const n = Date.now();
93
+ if (n > warned + 60_000) {
94
+ console.warn("@aws-sdk/core/protocols - WARN - JsonCodec2: you have called a string method on a Uint8Array request body. " +
95
+ "It has been automatically converted to string. In a future version this will throw an error.");
96
+ warned = n;
97
+ }
98
+ this.string = toUtf8(this);
99
+ }
100
+ return this.string;
101
+ }
102
+ }
103
+ var warned = 0;
@@ -1,7 +1,6 @@
1
1
  import { determineTimestampFormat } from "@smithy/core/protocols";
2
2
  import { NormalizedSchema } from "@smithy/core/schema";
3
- import { LazyJsonString, NumericValue, parseEpochTimestamp, parseRfc3339DateTimeWithOffset, parseRfc7231DateTime, } from "@smithy/core/serde";
4
- import { fromBase64 } from "@smithy/core/serde";
3
+ import { fromBase64, LazyJsonString, NumericValue, parseEpochTimestamp, parseRfc3339DateTimeWithOffset, parseRfc7231DateTime, } from "@smithy/core/serde";
5
4
  import { SerdeContextConfig } from "../../ConfigurableSerdeContext";
6
5
  import { UnionSerde } from "../../UnionSerde";
7
6
  import { detectBufferParsing } from "../detectBufferParsing";
@@ -19,14 +18,20 @@ export class JsonShapeDeserializer2 extends SerdeContextConfig {
19
18
  const reviver = needsReviver(schema) ? jsonReviver : undefined;
20
19
  let parsed;
21
20
  if (typeof data === "string") {
21
+ if (data.length === 0) {
22
+ return {};
23
+ }
22
24
  parsed = JSON.parse(data, reviver);
23
25
  }
24
26
  else if (data instanceof Uint8Array && detectBufferParsing()) {
27
+ if (data.byteLength === 0) {
28
+ return {};
29
+ }
25
30
  const buf = Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
26
31
  parsed = JSON.parse(buf, reviver);
27
32
  }
28
33
  else {
29
- parsed = await parseJsonBody(data, this.serdeContext);
34
+ parsed = await parseJsonBody(data, this.serdeContext, schema);
30
35
  }
31
36
  return this._read(schema, parsed);
32
37
  }
@@ -42,19 +47,23 @@ export class JsonShapeDeserializer2 extends SerdeContextConfig {
42
47
  }
43
48
  if (Array.isArray(value) && ns.isListSchema()) {
44
49
  const listMember = ns.getValueSchema();
45
- for (let i = 0; i < value.length; ++i) {
46
- value[i] = this._read(listMember, value[i]);
50
+ if (this.needsTransform(listMember)) {
51
+ for (let i = 0; i < value.length; ++i) {
52
+ value[i] = this._read(listMember, value[i]);
53
+ }
47
54
  }
48
55
  return value;
49
56
  }
50
57
  if (ns.isMapSchema()) {
51
58
  const mapMember = ns.getValueSchema();
52
59
  const map = value;
53
- for (const k in map) {
54
- if (k === "__proto__") {
55
- writeKey(map);
60
+ if (this.needsTransform(mapMember)) {
61
+ for (const k in map) {
62
+ if (k === "__proto__") {
63
+ writeKey(map);
64
+ }
65
+ map[k] = this._read(mapMember, map[k]);
56
66
  }
57
- map[k] = this._read(mapMember, map[k]);
58
67
  }
59
68
  return map;
60
69
  }
@@ -130,10 +139,6 @@ export class JsonShapeDeserializer2 extends SerdeContextConfig {
130
139
  }
131
140
  }
132
141
  }
133
- return value;
134
- }
135
- else {
136
- return value;
137
142
  }
138
143
  }
139
144
  return value;
@@ -141,9 +146,10 @@ export class JsonShapeDeserializer2 extends SerdeContextConfig {
141
146
  _readStruct(ns, record) {
142
147
  const union = ns.isUnionSchema();
143
148
  const out = {};
144
- let nameMap = void 0;
149
+ let nameMap;
150
+ const hasType = typeof record.__type === "string";
145
151
  const { jsonName } = this.settings;
146
- if (jsonName) {
152
+ if (jsonName && hasType) {
147
153
  nameMap = {};
148
154
  }
149
155
  let unionSerde;
@@ -154,7 +160,9 @@ export class JsonShapeDeserializer2 extends SerdeContextConfig {
154
160
  let fromKey = memberName;
155
161
  if (jsonName) {
156
162
  fromKey = memberSchema.getMergedTraits().jsonName ?? fromKey;
157
- nameMap[fromKey] = memberName;
163
+ if (hasType) {
164
+ nameMap[fromKey] = memberName;
165
+ }
158
166
  }
159
167
  if (union) {
160
168
  unionSerde.mark(fromKey);
@@ -166,7 +174,7 @@ export class JsonShapeDeserializer2 extends SerdeContextConfig {
166
174
  if (union) {
167
175
  unionSerde.writeUnknown();
168
176
  }
169
- else if (typeof record.__type === "string") {
177
+ else if (hasType) {
170
178
  for (const k in record) {
171
179
  const v = record[k];
172
180
  const t = jsonName ? (nameMap[k] ?? k) : k;
@@ -177,4 +185,16 @@ export class JsonShapeDeserializer2 extends SerdeContextConfig {
177
185
  }
178
186
  return out;
179
187
  }
188
+ needsTransform(ns) {
189
+ if (ns.isBlobSchema() || ns.isTimestampSchema() || ns.isBigIntegerSchema() || ns.isBigDecimalSchema()) {
190
+ return true;
191
+ }
192
+ if (ns.isDocumentSchema() || ns.isStructSchema() || ns.isListSchema() || ns.isMapSchema()) {
193
+ return true;
194
+ }
195
+ if (ns.isStringSchema() && ns.getMergedTraits().mediaType) {
196
+ return true;
197
+ }
198
+ return false;
199
+ }
180
200
  }
@@ -3,6 +3,7 @@ import { NormalizedSchema } from "@smithy/core/schema";
3
3
  import { dateToUtcString, generateIdempotencyToken, LazyJsonString, NumericValue, toBase64 } from "@smithy/core/serde";
4
4
  import { SerdeContextConfig } from "../../ConfigurableSerdeContext";
5
5
  import { writeKey } from "../../writeKey";
6
+ import { JsonBytesStringAdapter } from "./JsonBytesStringAdapter";
6
7
  const encoder = new TextEncoder();
7
8
  const OPEN_BRACE = 0x7b;
8
9
  const CLOSE_BRACE = 0x7d;
@@ -30,7 +31,7 @@ for (let i = 0; i < 0x20; i++) {
30
31
  }
31
32
  const INITIAL_BUFFER_SIZE = 2048;
32
33
  function alloc(size) {
33
- return typeof Buffer !== "undefined" ? Buffer.allocUnsafe(size) : new Uint8Array(size);
34
+ return JsonBytesStringAdapter.allocUnsafe(size);
34
35
  }
35
36
  export class JsonShapeSerializer2 extends SerdeContextConfig {
36
37
  settings;
@@ -48,10 +49,7 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
48
49
  this.i = 0;
49
50
  this.rawValue = value;
50
51
  this.rootSchema = NormalizedSchema.of(schema);
51
- this.passthrough =
52
- !this.rootSchema.isStructSchema() &&
53
- !this.rootSchema.isDocumentSchema() &&
54
- (this.rootSchema.isBlobSchema() || this.rootSchema.isStringSchema());
52
+ this.passthrough = this.rootSchema.isBlobSchema() || this.rootSchema.isStringSchema();
55
53
  if (!this.passthrough) {
56
54
  this.writeValue(this.rootSchema, value, undefined);
57
55
  }
@@ -61,30 +59,13 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
61
59
  this.rootSchema = NormalizedSchema.of(schema);
62
60
  const ns = this.rootSchema;
63
61
  if (ns.isStructSchema() && value != null && typeof value === "object") {
64
- this.ensure(2);
65
- this.json[this.i++] = OPEN_BRACE;
66
- this.writeAsciiQuoted("__type");
67
- this.json[this.i++] = COLON;
68
- this.writeAsciiQuoted(ns.getName(true) ?? "Unknown");
69
- let wroteAny = true;
70
- const { jsonName } = this.settings;
71
- for (const [memberName, memberSchema] of ns.structIterator()) {
72
- const item = value[memberName];
73
- if (item == null && !memberSchema.isIdempotencyToken()) {
74
- continue;
75
- }
76
- if (wroteAny) {
77
- this.ensure(1);
78
- this.json[this.i++] = COMMA;
79
- }
80
- const targetKey = jsonName ? (memberSchema.getMergedTraits().jsonName ?? memberName) : memberName;
81
- this.writeAsciiQuoted(targetKey);
82
- this.json[this.i++] = COLON;
83
- this.writeValue(memberSchema, item, ns);
84
- wroteAny = true;
85
- }
86
- this.ensure(1);
87
- this.json[this.i++] = CLOSE_BRACE;
62
+ this.writeValue(ns, value, undefined);
63
+ const prefix = `"__type":"${ns.getName(true) ?? "Unknown"}",`;
64
+ const z = prefix.length;
65
+ this.ensure(z);
66
+ this.json.copyWithin(1 + z, 1, this.i);
67
+ encoder.encodeInto(prefix, this.json.subarray(1));
68
+ this.i += z;
88
69
  }
89
70
  else {
90
71
  this.writeValue(ns, value, undefined);
@@ -137,7 +118,7 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
137
118
  this.i = i;
138
119
  }
139
120
  writeJsonString(s) {
140
- this.ensure(s.length * 2 + 2);
121
+ this.ensure(s.length * 3 + 2);
141
122
  this.json[this.i++] = QUOTE;
142
123
  const z = s.length;
143
124
  for (let j = 0; j < z; ++j) {
@@ -164,7 +145,7 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
164
145
  this.ensure(4);
165
146
  const { written } = encoder.encodeInto(s.substring(j, j + 2), this.json.subarray(this.i));
166
147
  this.i += written;
167
- j++;
148
+ ++j;
168
149
  }
169
150
  else {
170
151
  this.ensure(6);
@@ -204,8 +185,9 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
204
185
  static B64 = (() => {
205
186
  const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
206
187
  const table = new Uint8Array(64);
207
- for (let i = 0; i < 64; i++)
188
+ for (let i = 0; i < 64; ++i) {
208
189
  table[i] = chars.charCodeAt(i);
190
+ }
209
191
  return table;
210
192
  })();
211
193
  writeBase64(data) {
@@ -332,14 +314,16 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
332
314
  }
333
315
  if (typeof value === "boolean") {
334
316
  this.ensure(5);
317
+ let { i, json } = this;
335
318
  if (value) {
336
- this.json.set(TRUE, this.i);
337
- this.i += 4;
319
+ json.set(TRUE, i);
320
+ i += 4;
338
321
  }
339
322
  else {
340
- this.json.set(FALSE, this.i);
341
- this.i += 5;
323
+ json.set(FALSE, i);
324
+ i += 5;
342
325
  }
326
+ this.i = i;
343
327
  return;
344
328
  }
345
329
  if (typeof value === "bigint") {
@@ -351,7 +335,6 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
351
335
  writeStruct(ns, value) {
352
336
  this.ensure(2);
353
337
  this.json[this.i++] = OPEN_BRACE;
354
- let first = true;
355
338
  let wroteAny = false;
356
339
  const hasType = typeof value.__type === "string";
357
340
  let writtenKeys;
@@ -360,13 +343,13 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
360
343
  }
361
344
  for (const [memberName, memberSchema] of ns.structIterator()) {
362
345
  const item = value[memberName];
363
- if (item == null && !memberSchema.isIdempotencyToken())
346
+ if (item == null && !memberSchema.isIdempotencyToken()) {
364
347
  continue;
365
- if (!first) {
348
+ }
349
+ if (wroteAny) {
366
350
  this.ensure(1);
367
351
  this.json[this.i++] = COMMA;
368
352
  }
369
- first = false;
370
353
  wroteAny = true;
371
354
  const targetKey = this.settings.jsonName ? (memberSchema.getMergedTraits().jsonName ?? memberName) : memberName;
372
355
  if (writtenKeys) {
@@ -389,17 +372,17 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
389
372
  }
390
373
  else if (hasType) {
391
374
  for (const k in value) {
392
- const targetKey = this.settings.jsonName ? (writtenKeys.has(k) ? k : k) : k;
393
- if (writtenKeys.has(targetKey))
375
+ if (writtenKeys.has(k)) {
394
376
  continue;
395
- writtenKeys.add(targetKey);
377
+ }
378
+ writtenKeys.add(k);
396
379
  const v = value[k];
397
- if (!first) {
380
+ if (wroteAny) {
398
381
  this.ensure(1);
399
382
  this.json[this.i++] = COMMA;
400
383
  }
401
- first = false;
402
- this.writeAsciiQuoted(targetKey);
384
+ wroteAny = true;
385
+ this.writeAsciiQuoted(k);
403
386
  this.ensure(1);
404
387
  this.json[this.i++] = COLON;
405
388
  this.writeValue(15, v, undefined);
@@ -409,20 +392,30 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
409
392
  this.json[this.i++] = CLOSE_BRACE;
410
393
  }
411
394
  writeList(ns, value, isDocument) {
412
- this.ensure(2);
413
- this.json[this.i++] = OPEN_BRACKET;
414
395
  const sparse = !!ns.getMergedTraits().sparse;
415
396
  const valueSchema = ns.getValueSchema();
397
+ if (!isDocument) {
398
+ if (valueSchema.isStringSchema() || valueSchema.isNumericSchema() || valueSchema.isBooleanSchema()) {
399
+ const json = sparse ? JSON.stringify(value) : JSON.stringify(value.filter((_) => _ != null));
400
+ this.ensure(json.length * 3);
401
+ this.i += encoder.encodeInto(json, this.json.subarray(this.i)).written;
402
+ return;
403
+ }
404
+ }
405
+ this.ensure(2);
406
+ this.json[this.i++] = OPEN_BRACKET;
407
+ let wroteFirstItem = false;
416
408
  for (let i = 0; i < value.length; ++i) {
417
409
  const item = value[i];
418
410
  if (isDocument ? item === undefined : item == null && !sparse) {
419
411
  continue;
420
412
  }
421
- if (i !== 0) {
413
+ if (wroteFirstItem) {
422
414
  this.ensure(1);
423
415
  this.json[this.i++] = COMMA;
424
416
  }
425
417
  this.writeValue(valueSchema, item, undefined);
418
+ wroteFirstItem = true;
426
419
  }
427
420
  this.ensure(1);
428
421
  this.json[this.i++] = CLOSE_BRACKET;
@@ -444,8 +437,7 @@ export class JsonShapeSerializer2 extends SerdeContextConfig {
444
437
  }
445
438
  const json = JSON.stringify(input);
446
439
  this.ensure(json.length * 3);
447
- const { written } = encoder.encodeInto(json, this.json.subarray(this.i));
448
- this.i += written;
440
+ this.i += encoder.encodeInto(json, this.json.subarray(this.i)).written;
449
441
  return;
450
442
  }
451
443
  }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * A Uint8Array subclass holding serialized JSON bytes that provides
3
+ * string method compatibility for customer middleware.
4
+ *
5
+ * Middleware historically observed `request.body` as a string for JSON
6
+ * protocol services. This class preserves that contract: string methods
7
+ * and coercion (template literals, `+` operator) lazily decode the bytes
8
+ * to a cached string. The HTTP transport layer still sees a Uint8Array
9
+ * and sends raw bytes without conversion.
10
+ *
11
+ * @internal
12
+ * @deprecated this adapter will be removed in a future version.
13
+ */
14
+ export declare class JsonBytesStringAdapter extends Uint8Array {
15
+ private string;
16
+ static allocUnsafe(bytes: number): JsonBytesStringAdapter;
17
+ /**
18
+ * Enables string coercion via template literals and `+` operator.
19
+ */
20
+ toString(): string;
21
+ /**
22
+ * Enables string coercion in comparison and arithmetic contexts.
23
+ * @returns a string. The signature is set to avoid incompatibility with extending Uint8Array.
24
+ */
25
+ valueOf(): any;
26
+ includes(searchString: string | number, position?: number): boolean;
27
+ indexOf(searchString: string | number, position?: number): number;
28
+ lastIndexOf(searchString: string | number, position?: number): number;
29
+ startsWith(searchString: string, position?: number): boolean;
30
+ endsWith(searchString: string, endPosition?: number): boolean;
31
+ match(regexp: string | RegExp): RegExpMatchArray | null;
32
+ replace(searchValue: string | RegExp, replaceValue: string): string;
33
+ search(regexp: string | RegExp): number;
34
+ split(separator: string | RegExp, limit?: number): string[];
35
+ substring(start: number, end?: number): string;
36
+ trim(): string;
37
+ trimStart(): string;
38
+ trimEnd(): string;
39
+ charAt(pos: number): string;
40
+ charCodeAt(index: number): number;
41
+ padStart(maxLength: number, fillString?: string): string;
42
+ padEnd(maxLength: number, fillString?: string): string;
43
+ repeat(count: number): string;
44
+ toUpperCase(): string;
45
+ toLowerCase(): string;
46
+ /**
47
+ * Decodes the bytes to a UTF-8 string on first access, then caches.
48
+ * Subsequent calls return the cached string with zero cost.
49
+ */
50
+ private s;
51
+ }
@@ -2,6 +2,7 @@ import type { $ShapeSerializer, $Codec, $ShapeDeserializer } from "@smithy/types
2
2
  import { SerdeContextConfig } from "../../ConfigurableSerdeContext";
3
3
  import type { JsonSettings } from "../JsonSettings";
4
4
  /**
5
+ * Codec grouping the v2 serializer and deserializer.
5
6
  * @public
6
7
  */
7
8
  export declare class JsonCodec2 extends SerdeContextConfig implements $Codec<Uint8Array, string> {
@@ -26,4 +26,5 @@ export declare class JsonShapeDeserializer2 extends SerdeContextConfig implement
26
26
  readObject(schema: Schema, data: DocumentType): any;
27
27
  protected _read(schema: Schema, value: unknown): any;
28
28
  private _readStruct;
29
+ private needsTransform;
29
30
  }
@@ -0,0 +1,27 @@
1
+ export declare class JsonBytesStringAdapter extends Uint8Array {
2
+ private string;
3
+ static allocUnsafe(bytes: number): JsonBytesStringAdapter;
4
+ toString(): string;
5
+ valueOf(): any;
6
+ includes(searchString: string | number, position?: number): boolean;
7
+ indexOf(searchString: string | number, position?: number): number;
8
+ lastIndexOf(searchString: string | number, position?: number): number;
9
+ startsWith(searchString: string, position?: number): boolean;
10
+ endsWith(searchString: string, endPosition?: number): boolean;
11
+ match(regexp: string | RegExp): RegExpMatchArray | null;
12
+ replace(searchValue: string | RegExp, replaceValue: string): string;
13
+ search(regexp: string | RegExp): number;
14
+ split(separator: string | RegExp, limit?: number): string[];
15
+ substring(start: number, end?: number): string;
16
+ trim(): string;
17
+ trimStart(): string;
18
+ trimEnd(): string;
19
+ charAt(pos: number): string;
20
+ charCodeAt(index: number): number;
21
+ padStart(maxLength: number, fillString?: string): string;
22
+ padEnd(maxLength: number, fillString?: string): string;
23
+ repeat(count: number): string;
24
+ toUpperCase(): string;
25
+ toLowerCase(): string;
26
+ private s;
27
+ }
@@ -11,4 +11,5 @@ export declare class JsonShapeDeserializer2
11
11
  readObject(schema: Schema, data: DocumentType): any;
12
12
  protected _read(schema: Schema, value: unknown): any;
13
13
  private _readStruct;
14
+ private needsTransform;
14
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-sdk/core",
3
- "version": "3.977.3",
3
+ "version": "3.977.4",
4
4
  "description": "Core functions & classes shared by multiple AWS SDK clients.",
5
5
  "homepage": "https://github.com/aws/aws-sdk-js-v3/tree/main/packages-internal/core",
6
6
  "license": "Apache-2.0",