@aws-sdk/core 3.977.4 → 3.977.6

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.
@@ -2,7 +2,7 @@ const { SmithyRpcV2CborProtocol, loadSmithyRpcV2CborErrorCode } = require("@smit
2
2
  const { TypeRegistry, NormalizedSchema, deref } = require("@smithy/core/schema");
3
3
  const { decorateServiceException, getValueFromTextNode } = require("@smithy/core/client");
4
4
  const { collectBody, determineTimestampFormat, RpcProtocol, HttpBindingProtocol, HttpInterceptingShapeSerializer, HttpInterceptingShapeDeserializer, FromStringShapeDeserializer, extendedEncodeURIComponent } = require("@smithy/core/protocols");
5
- const { NumericValue, toUtf8, fromBase64, LazyJsonString, parseEpochTimestamp, parseRfc7231DateTime, parseRfc3339DateTimeWithOffset, toBase64, dateToUtcString, generateIdempotencyToken, expectUnion } = require("@smithy/core/serde");
5
+ const { NumericValue, toUtf8, fromBase64, LazyJsonString, parseEpochTimestamp, parseRfc7231DateTime, parseRfc3339DateTimeWithOffset, generateIdempotencyToken, toBase64, dateToUtcString, expectUnion } = require("@smithy/core/serde");
6
6
  const { parseXML, XmlNode, XmlText } = require("@aws-sdk/xml-builder");
7
7
 
8
8
  class ProtocolLib {
@@ -227,30 +227,50 @@ class UnionSerde {
227
227
  }
228
228
  }
229
229
 
230
+ let canParseBuffer;
231
+ function detectBufferParsing() {
232
+ if (canParseBuffer === undefined) {
233
+ try {
234
+ if (typeof Buffer !== "function") {
235
+ canParseBuffer = false;
236
+ }
237
+ else {
238
+ const result = JSON.parse(Buffer.from([0x7b, 0x7d]));
239
+ canParseBuffer = result !== null && typeof result === "object";
240
+ }
241
+ }
242
+ catch {
243
+ canParseBuffer = false;
244
+ }
245
+ }
246
+ return canParseBuffer;
247
+ }
248
+
230
249
  function jsonReviver(key, value, context) {
231
250
  if (context?.source) {
232
251
  const numericString = context.source;
233
252
  if (typeof value === "number") {
234
253
  const inSafeRange = value <= Number.MAX_SAFE_INTEGER && value >= Number.MIN_SAFE_INTEGER;
235
- if (!inSafeRange || numericString !== String(value)) {
236
- if (inSafeRange && /[eE]/.test(numericString) && String(Number(numericString)) === String(value)) {
254
+ if (inSafeRange) {
255
+ if (isRepresentable(numericString, value)) {
237
256
  return value;
238
257
  }
239
- if (isFractionalNumeric(numericString)) {
258
+ return new NumericValue(numericString, "bigDecimal");
259
+ }
260
+ else {
261
+ if (isFractionalBigNumeric(numericString)) {
240
262
  return new NumericValue(numericString, "bigDecimal");
241
263
  }
242
- else {
243
- if (/[eE]/.test(numericString)) {
244
- return BigInt(Number(numericString));
245
- }
246
- return BigInt(numericString);
264
+ if (/[eE]/.test(numericString)) {
265
+ return expandExponentToBigInt(numericString);
247
266
  }
267
+ return BigInt(numericString);
248
268
  }
249
269
  }
250
270
  }
251
271
  return value;
252
272
  }
253
- function isFractionalNumeric(s) {
273
+ function isFractionalBigNumeric(s) {
254
274
  const dotIndex = s.indexOf(".");
255
275
  if (dotIndex === -1) {
256
276
  return false;
@@ -263,6 +283,89 @@ function isFractionalNumeric(s) {
263
283
  const exp = parseInt(s.slice(eIndex + 1), 10);
264
284
  return exp < fracDigits;
265
285
  }
286
+ function isRepresentable(numericString, value) {
287
+ if (numericString === String(value)) {
288
+ return true;
289
+ }
290
+ if (Object.is(value, -0)) {
291
+ return true;
292
+ }
293
+ if (/[eE]/.test(numericString)) {
294
+ return expandToDecimal(numericString) === expandToDecimal(String(value));
295
+ }
296
+ const normalized = numericString.replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "");
297
+ const canonical = String(value);
298
+ if (normalized === canonical) {
299
+ return true;
300
+ }
301
+ if (/[eE]/.test(canonical)) {
302
+ return normalized === expandToDecimal(canonical);
303
+ }
304
+ return false;
305
+ }
306
+ function expandToDecimal(s) {
307
+ const negative = s.startsWith("-");
308
+ const abs = negative ? s.slice(1) : s;
309
+ const eIndex = abs.search(/[eE]/);
310
+ let result;
311
+ if (eIndex === -1) {
312
+ result = abs;
313
+ }
314
+ else {
315
+ const exp = parseInt(abs.slice(eIndex + 1), 10);
316
+ const mantissa = abs.slice(0, eIndex);
317
+ const dotIndex = mantissa.indexOf(".");
318
+ let digits;
319
+ let intLen;
320
+ if (dotIndex === -1) {
321
+ digits = mantissa;
322
+ intLen = mantissa.length;
323
+ }
324
+ else {
325
+ digits = mantissa.slice(0, dotIndex) + mantissa.slice(dotIndex + 1);
326
+ intLen = dotIndex;
327
+ }
328
+ digits = digits.replace(/0+$/, "") || "0";
329
+ const newDotPos = intLen + exp;
330
+ if (digits === "0") {
331
+ result = "0";
332
+ }
333
+ else if (newDotPos <= 0) {
334
+ result = "0." + "0".repeat(-newDotPos) + digits;
335
+ }
336
+ else if (newDotPos >= digits.length) {
337
+ result = digits + "0".repeat(newDotPos - digits.length);
338
+ }
339
+ else {
340
+ result = digits.slice(0, newDotPos) + "." + digits.slice(newDotPos);
341
+ }
342
+ }
343
+ if (result.includes(".")) {
344
+ result = result.replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "");
345
+ }
346
+ return (negative ? "-" : "") + result;
347
+ }
348
+ function expandExponentToBigInt(s) {
349
+ const eIndex = s.search(/[eE]/);
350
+ const exp = parseInt(s.slice(eIndex + 1), 10);
351
+ const negative = s.startsWith("-");
352
+ const mantissa = s.slice(negative ? 1 : 0, eIndex);
353
+ const dotIndex = mantissa.indexOf(".");
354
+ let digits;
355
+ let shift;
356
+ if (dotIndex === -1) {
357
+ digits = mantissa;
358
+ shift = exp;
359
+ }
360
+ else {
361
+ digits = mantissa.slice(0, dotIndex) + mantissa.slice(dotIndex + 1);
362
+ const fracDigits = mantissa.length - dotIndex - 1;
363
+ shift = exp - fracDigits;
364
+ }
365
+ digits = digits.replace(/0+$/, "") || "0";
366
+ const result = BigInt(digits) * 10n ** BigInt(shift + (mantissa.replace(".", "").length - digits.length));
367
+ return negative ? -result : result;
368
+ }
266
369
 
267
370
  const REVIVER_SYMBOL = Symbol.for("@aws-sdk/reviver");
268
371
  function needsReviver(schema) {
@@ -307,25 +410,6 @@ function _check(ns, seen) {
307
410
 
308
411
  const collectBodyString = (streamBody, context) => collectBody(streamBody, context).then((body) => (context?.utf8Encoder ?? toUtf8)(body));
309
412
 
310
- let canParseBuffer;
311
- function detectBufferParsing() {
312
- if (canParseBuffer === undefined) {
313
- try {
314
- if (typeof Buffer !== "function") {
315
- canParseBuffer = false;
316
- }
317
- else {
318
- const result = JSON.parse(Buffer.from([0x7b, 0x7d]));
319
- canParseBuffer = result !== null && typeof result === "object";
320
- }
321
- }
322
- catch {
323
- canParseBuffer = false;
324
- }
325
- }
326
- return canParseBuffer;
327
- }
328
-
329
413
  async function parseJsonBody(streamBody, context, schema) {
330
414
  let parsingInput;
331
415
  if (detectBufferParsing() && typeof streamBody?.[Symbol.asyncIterator] === "function") {
@@ -415,7 +499,7 @@ function writeKey(obj) {
415
499
  Object.defineProperty(obj, "__proto__", { value: undefined, writable: true, enumerable: true, configurable: true });
416
500
  }
417
501
 
418
- class JsonShapeDeserializer extends SerdeContextConfig {
502
+ class JsonShapeDeserializer2 extends SerdeContextConfig {
419
503
  settings;
420
504
  constructor(settings) {
421
505
  super();
@@ -423,7 +507,24 @@ class JsonShapeDeserializer extends SerdeContextConfig {
423
507
  }
424
508
  async read(schema, data) {
425
509
  const reviver = needsReviver(schema) ? jsonReviver : undefined;
426
- return this._read(schema, typeof data === "string" ? JSON.parse(data, reviver) : await parseJsonBody(data, this.serdeContext, schema));
510
+ let parsed;
511
+ if (typeof data === "string") {
512
+ if (data.length === 0) {
513
+ return {};
514
+ }
515
+ parsed = JSON.parse(data, reviver);
516
+ }
517
+ else if (data instanceof Uint8Array && detectBufferParsing()) {
518
+ if (data.byteLength === 0) {
519
+ return {};
520
+ }
521
+ const buf = Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
522
+ parsed = JSON.parse(buf, reviver);
523
+ }
524
+ else {
525
+ parsed = await parseJsonBody(data, this.serdeContext, schema);
526
+ }
527
+ return this._read(schema, parsed);
427
528
  }
428
529
  readObject(schema, data) {
429
530
  return this._read(schema, data);
@@ -433,63 +534,29 @@ class JsonShapeDeserializer extends SerdeContextConfig {
433
534
  const ns = NormalizedSchema.of(schema);
434
535
  if (isObject) {
435
536
  if (ns.isStructSchema()) {
436
- const record = value;
437
- const union = ns.isUnionSchema();
438
- const out = {};
439
- let nameMap = void 0;
440
- const { jsonName } = this.settings;
441
- if (jsonName) {
442
- nameMap = {};
443
- }
444
- let unionSerde;
445
- if (union) {
446
- unionSerde = new UnionSerde(record, out);
447
- }
448
- for (const [memberName, memberSchema] of ns.structIterator()) {
449
- let fromKey = memberName;
450
- if (jsonName) {
451
- fromKey = memberSchema.getMergedTraits().jsonName ?? fromKey;
452
- nameMap[fromKey] = memberName;
453
- }
454
- if (union) {
455
- unionSerde.mark(fromKey);
456
- }
457
- if (record[fromKey] != null) {
458
- out[memberName] = this._read(memberSchema, record[fromKey]);
459
- }
460
- }
461
- if (union) {
462
- unionSerde.writeUnknown();
463
- }
464
- else if (typeof record.__type === "string") {
465
- for (const k in record) {
466
- const v = record[k];
467
- const t = jsonName ? (nameMap[k] ?? k) : k;
468
- if (!(t in out)) {
469
- out[t] = v;
470
- }
471
- }
472
- }
473
- return out;
537
+ return this._readStruct(ns, value);
474
538
  }
475
539
  if (Array.isArray(value) && ns.isListSchema()) {
476
540
  const listMember = ns.getValueSchema();
477
- const out = [];
478
- for (const item of value) {
479
- out.push(this._read(listMember, item));
541
+ if (this.needsTransform(listMember)) {
542
+ for (let i = 0; i < value.length; ++i) {
543
+ value[i] = this._read(listMember, value[i]);
544
+ }
480
545
  }
481
- return out;
546
+ return value;
482
547
  }
483
548
  if (ns.isMapSchema()) {
484
549
  const mapMember = ns.getValueSchema();
485
- const out = {};
486
- for (const _k in value) {
487
- if (_k === "__proto__") {
488
- writeKey(out);
550
+ const map = value;
551
+ if (this.needsTransform(mapMember)) {
552
+ for (const k in map) {
553
+ if (k === "__proto__") {
554
+ writeKey(map);
555
+ }
556
+ map[k] = this._read(mapMember, map[k]);
489
557
  }
490
- out[_k] = this._read(mapMember, value[_k]);
491
558
  }
492
- return out;
559
+ return map;
493
560
  }
494
561
  }
495
562
  if (ns.isBlobSchema() && typeof value === "string") {
@@ -543,273 +610,717 @@ class JsonShapeDeserializer extends SerdeContextConfig {
543
610
  }
544
611
  if (ns.isDocumentSchema()) {
545
612
  if (isObject) {
546
- const out = Array.isArray(value) ? [] : {};
547
- for (const k in value) {
548
- if (k === "__proto__") {
549
- writeKey(out);
550
- }
551
- const v = value[k];
552
- if (v instanceof NumericValue) {
553
- out[k] = v;
613
+ if (Array.isArray(value)) {
614
+ for (let i = 0; i < value.length; ++i) {
615
+ const v = value[i];
616
+ if (!(v instanceof NumericValue)) {
617
+ value[i] = this._read(ns, v);
618
+ }
554
619
  }
555
- else {
556
- out[k] = this._read(ns, v);
620
+ }
621
+ else {
622
+ const doc = value;
623
+ for (const k in doc) {
624
+ if (k === "__proto__") {
625
+ writeKey(doc);
626
+ }
627
+ const v = doc[k];
628
+ if (!(v instanceof NumericValue)) {
629
+ doc[k] = this._read(ns, v);
630
+ }
557
631
  }
558
632
  }
559
- return out;
560
- }
561
- else {
562
- return structuredClone(value);
563
633
  }
564
634
  }
565
635
  return value;
566
636
  }
567
- }
568
-
569
- const NUMERIC_CONTROL_CHAR = String.fromCharCode(925);
570
- class JsonReplacer {
571
- values = new Map();
572
- counter = 0;
573
- stage = 0;
574
- createReplacer() {
575
- if (this.stage === 1) {
576
- throw new Error("@aws-sdk/core/protocols - JsonReplacer already created.");
637
+ _readStruct(ns, record) {
638
+ const union = ns.isUnionSchema();
639
+ const out = {};
640
+ let nameMap;
641
+ const hasType = typeof record.__type === "string";
642
+ const { jsonName } = this.settings;
643
+ if (jsonName && hasType) {
644
+ nameMap = {};
577
645
  }
578
- if (this.stage === 2) {
579
- throw new Error("@aws-sdk/core/protocols - JsonReplacer exhausted.");
646
+ let unionSerde;
647
+ if (union) {
648
+ unionSerde = new UnionSerde(record, out);
580
649
  }
581
- this.stage = 1;
582
- return (key, value) => {
583
- if (value instanceof NumericValue) {
584
- const v = `${NUMERIC_CONTROL_CHAR + "nv" + this.counter++}_` + value.string;
585
- this.values.set(`"${v}"`, value.string);
586
- return v;
650
+ for (const [memberName, memberSchema] of ns.structIterator()) {
651
+ let fromKey = memberName;
652
+ if (jsonName) {
653
+ fromKey = memberSchema.getMergedTraits().jsonName ?? fromKey;
654
+ if (hasType) {
655
+ nameMap[fromKey] = memberName;
656
+ }
587
657
  }
588
- if (typeof value === "bigint") {
589
- const s = value.toString();
590
- const v = `${NUMERIC_CONTROL_CHAR + "b" + this.counter++}_` + s;
591
- this.values.set(`"${v}"`, s);
592
- return v;
658
+ if (union) {
659
+ unionSerde.mark(fromKey);
660
+ }
661
+ if (record[fromKey] != null) {
662
+ out[memberName] = this._read(memberSchema, record[fromKey]);
593
663
  }
594
- return value;
595
- };
596
- }
597
- replaceInJson(json) {
598
- if (this.stage === 0) {
599
- throw new Error("@aws-sdk/core/protocols - JsonReplacer not created yet.");
600
- }
601
- if (this.stage === 2) {
602
- throw new Error("@aws-sdk/core/protocols - JsonReplacer exhausted.");
603
664
  }
604
- this.stage = 2;
605
- if (this.counter === 0) {
606
- return json;
665
+ if (union) {
666
+ unionSerde.writeUnknown();
607
667
  }
608
- for (const [key, value] of this.values) {
609
- json = json.replace(key, value);
668
+ else if (hasType) {
669
+ for (const k in record) {
670
+ const v = record[k];
671
+ const t = jsonName ? (nameMap[k] ?? k) : k;
672
+ if (!(t in out)) {
673
+ out[t] = v;
674
+ }
675
+ }
610
676
  }
611
- return json;
677
+ return out;
678
+ }
679
+ needsTransform(ns) {
680
+ if (ns.isBlobSchema() || ns.isTimestampSchema() || ns.isBigIntegerSchema() || ns.isBigDecimalSchema()) {
681
+ return true;
682
+ }
683
+ if (ns.isDocumentSchema() || ns.isStructSchema() || ns.isListSchema() || ns.isMapSchema()) {
684
+ return true;
685
+ }
686
+ if (ns.isStringSchema() && ns.getMergedTraits().mediaType) {
687
+ return true;
688
+ }
689
+ return false;
612
690
  }
613
691
  }
614
692
 
615
- class JsonShapeSerializer extends SerdeContextConfig {
693
+ class JsonBytesStringAdapter extends Uint8Array {
694
+ string = null;
695
+ static allocUnsafe(bytes) {
696
+ if (typeof Buffer === "function") {
697
+ const buffer = Buffer.allocUnsafe(bytes);
698
+ return new JsonBytesStringAdapter(buffer.buffer, buffer.byteOffset, buffer.byteLength);
699
+ }
700
+ return new JsonBytesStringAdapter(bytes);
701
+ }
702
+ toString() {
703
+ return this.s();
704
+ }
705
+ valueOf() {
706
+ return this.s();
707
+ }
708
+ includes(searchString, position) {
709
+ if (typeof searchString === "string") {
710
+ return this.s().includes(searchString, position);
711
+ }
712
+ return Uint8Array.prototype.includes.call(this, searchString, position);
713
+ }
714
+ indexOf(searchString, position) {
715
+ if (typeof searchString === "string") {
716
+ return this.s().indexOf(searchString, position);
717
+ }
718
+ return Uint8Array.prototype.indexOf.call(this, searchString, position);
719
+ }
720
+ lastIndexOf(searchString, position) {
721
+ if (typeof searchString === "string") {
722
+ return this.s().lastIndexOf(searchString, position);
723
+ }
724
+ const fn = Uint8Array.prototype.lastIndexOf;
725
+ if (position !== undefined) {
726
+ return fn.call(this, searchString, position);
727
+ }
728
+ return fn.call(this, searchString);
729
+ }
730
+ startsWith(searchString, position) {
731
+ return this.s().startsWith(searchString, position);
732
+ }
733
+ endsWith(searchString, endPosition) {
734
+ return this.s().endsWith(searchString, endPosition);
735
+ }
736
+ match(regexp) {
737
+ return this.s().match(regexp);
738
+ }
739
+ replace(searchValue, replaceValue) {
740
+ return this.s().replace(searchValue, replaceValue);
741
+ }
742
+ search(regexp) {
743
+ return this.s().search(regexp);
744
+ }
745
+ split(separator, limit) {
746
+ return this.s().split(separator, limit);
747
+ }
748
+ substring(start, end) {
749
+ return this.s().substring(start, end);
750
+ }
751
+ trim() {
752
+ return this.s().trim();
753
+ }
754
+ trimStart() {
755
+ return this.s().trimStart();
756
+ }
757
+ trimEnd() {
758
+ return this.s().trimEnd();
759
+ }
760
+ charAt(pos) {
761
+ return this.s().charAt(pos);
762
+ }
763
+ charCodeAt(index) {
764
+ return this.s().charCodeAt(index);
765
+ }
766
+ padStart(maxLength, fillString) {
767
+ return this.s().padStart(maxLength, fillString);
768
+ }
769
+ padEnd(maxLength, fillString) {
770
+ return this.s().padEnd(maxLength, fillString);
771
+ }
772
+ repeat(count) {
773
+ return this.s().repeat(count);
774
+ }
775
+ toUpperCase() {
776
+ return this.s().toUpperCase();
777
+ }
778
+ toLowerCase() {
779
+ return this.s().toLowerCase();
780
+ }
781
+ s() {
782
+ if (this.string == null) {
783
+ const n = Date.now();
784
+ if (n > warned + 60_000) {
785
+ console.warn("@aws-sdk/core/protocols - WARN - JsonCodec2: you have called a string method on a Uint8Array request body. " +
786
+ "It has been automatically converted to string. In a future version this will throw an error.");
787
+ warned = n;
788
+ }
789
+ this.string = toUtf8(this);
790
+ }
791
+ return this.string;
792
+ }
793
+ }
794
+ var warned = 0;
795
+
796
+ const encoder = new TextEncoder();
797
+ const OPEN_BRACE = 0x7b;
798
+ const CLOSE_BRACE = 0x7d;
799
+ const OPEN_BRACKET = 0x5b;
800
+ const CLOSE_BRACKET = 0x5d;
801
+ const QUOTE = 0x22;
802
+ const COLON = 0x3a;
803
+ const COMMA = 0x2c;
804
+ const BACKSLASH = 0x5c;
805
+ const TRUE = new Uint8Array([0x74, 0x72, 0x75, 0x65]);
806
+ const FALSE = new Uint8Array([0x66, 0x61, 0x6c, 0x73, 0x65]);
807
+ const NULL = new Uint8Array([0x6e, 0x75, 0x6c, 0x6c]);
808
+ const ESCAPE_TABLE = new Array(128).fill(null);
809
+ ESCAPE_TABLE[0x08] = "b";
810
+ ESCAPE_TABLE[0x09] = "t";
811
+ ESCAPE_TABLE[0x0a] = "n";
812
+ ESCAPE_TABLE[0x0c] = "f";
813
+ ESCAPE_TABLE[0x0d] = "r";
814
+ ESCAPE_TABLE[0x22] = '"';
815
+ ESCAPE_TABLE[0x5c] = "\\";
816
+ for (let i = 0; i < 0x20; i++) {
817
+ if (ESCAPE_TABLE[i] === null) {
818
+ ESCAPE_TABLE[i] = "u00" + i.toString(16).padStart(2, "0");
819
+ }
820
+ }
821
+ const INITIAL_BUFFER_SIZE = 2048;
822
+ function alloc(size) {
823
+ return JsonBytesStringAdapter.allocUnsafe(size);
824
+ }
825
+ class JsonShapeSerializer2 extends SerdeContextConfig {
616
826
  settings;
617
- buffer;
618
- useReplacer = false;
827
+ json;
828
+ i = 0;
619
829
  rootSchema;
830
+ rawValue;
831
+ passthrough = false;
620
832
  constructor(settings) {
621
833
  super();
622
834
  this.settings = settings;
835
+ this.json = alloc(INITIAL_BUFFER_SIZE);
623
836
  }
624
837
  write(schema, value) {
838
+ this.i = 0;
839
+ this.rawValue = value;
625
840
  this.rootSchema = NormalizedSchema.of(schema);
626
- this.buffer = this._write(this.rootSchema, value);
841
+ this.passthrough = this.rootSchema.isBlobSchema() || this.rootSchema.isStringSchema();
842
+ if (!this.passthrough) {
843
+ this.writeValue(this.rootSchema, value, undefined);
844
+ }
845
+ }
846
+ writeDiscriminatedDocument(schema, value) {
847
+ this.i = 0;
848
+ this.rootSchema = NormalizedSchema.of(schema);
849
+ const ns = this.rootSchema;
850
+ if (ns.isStructSchema() && value != null && typeof value === "object") {
851
+ this.writeValue(ns, value, undefined);
852
+ const prefix = `"__type":"${ns.getName(true) ?? "Unknown"}",`;
853
+ const z = prefix.length;
854
+ this.ensure(z);
855
+ this.json.copyWithin(1 + z, 1, this.i);
856
+ encoder.encodeInto(prefix, this.json.subarray(1));
857
+ this.i += z;
858
+ }
859
+ else {
860
+ this.writeValue(ns, value, undefined);
861
+ }
627
862
  }
628
863
  flush() {
629
- const { rootSchema, useReplacer } = this;
630
864
  this.rootSchema = undefined;
631
- this.useReplacer = false;
632
- if (rootSchema?.isStructSchema() || rootSchema?.isDocumentSchema()) {
633
- if (!useReplacer) {
634
- return JSON.stringify(this.buffer);
865
+ const finalPosition = this.i;
866
+ this.i = 0;
867
+ const raw = this.rawValue;
868
+ this.rawValue = undefined;
869
+ if (finalPosition === 0) {
870
+ return raw;
871
+ }
872
+ const result = this.json.subarray(0, finalPosition);
873
+ this.json = alloc(INITIAL_BUFFER_SIZE);
874
+ return result;
875
+ }
876
+ ensure(byteCount) {
877
+ const { i, json } = this;
878
+ if (i + byteCount > json.length) {
879
+ let newSize = json.length * 2;
880
+ while (newSize < i + byteCount) {
881
+ newSize *= 2;
635
882
  }
636
- const replacer = new JsonReplacer();
637
- return replacer.replaceInJson(JSON.stringify(this.buffer, replacer.createReplacer(), 0));
883
+ const next = alloc(newSize);
884
+ next.set(this.json);
885
+ this.json = next;
638
886
  }
639
- return this.buffer;
640
887
  }
641
- writeDiscriminatedDocument(schema, value) {
642
- this.write(schema, value);
643
- if (typeof this.buffer === "object") {
644
- this.buffer.__type = NormalizedSchema.of(schema).getName(true);
888
+ writeAscii(s) {
889
+ const z = s.length;
890
+ this.ensure(z);
891
+ let { i, json } = this;
892
+ for (let j = 0; j < z; ++j) {
893
+ json[i] = s.charCodeAt(j);
894
+ i += 1;
645
895
  }
896
+ this.i = i;
646
897
  }
647
- _write(schema, value, container) {
648
- const isObject = value !== null && typeof value === "object";
649
- const ns = NormalizedSchema.of(schema);
650
- if (isObject) {
651
- if (ns.isStructSchema()) {
652
- const record = value;
653
- const out = {};
654
- const { jsonName } = this.settings;
655
- let nameMap = void 0;
656
- if (jsonName) {
657
- nameMap = {};
898
+ writeAsciiQuoted(s) {
899
+ const z = s.length;
900
+ this.ensure(z + 4);
901
+ let { json, i } = this;
902
+ json[i++] = QUOTE;
903
+ for (let j = 0; j < z; ++j) {
904
+ json[i++] = s.charCodeAt(j);
905
+ }
906
+ json[i++] = QUOTE;
907
+ this.i = i;
908
+ }
909
+ writeJsonString(s) {
910
+ this.ensure(s.length * 3 + 2);
911
+ this.json[this.i++] = QUOTE;
912
+ const z = s.length;
913
+ for (let j = 0; j < z; ++j) {
914
+ const c = s.charCodeAt(j);
915
+ if (c > 0x22 && c < 0x5c) {
916
+ this.json[this.i++] = c;
917
+ }
918
+ else if (c < 0x80) {
919
+ const esc = ESCAPE_TABLE[c];
920
+ if (esc !== null) {
921
+ this.ensure(esc.length + 1);
922
+ this.json[this.i++] = BACKSLASH;
923
+ for (let k = 0; k < esc.length; k++) {
924
+ this.json[this.i++] = esc.charCodeAt(k);
925
+ }
658
926
  }
659
- let outCount = 0;
660
- for (const [memberName, memberSchema] of ns.structIterator()) {
661
- const serializableValue = this._write(memberSchema, record[memberName], ns);
662
- if (serializableValue !== undefined) {
663
- let targetKey = memberName;
664
- if (jsonName) {
665
- targetKey = memberSchema.getMergedTraits().jsonName ?? memberName;
666
- nameMap[memberName] = targetKey;
667
- }
668
- out[targetKey] = serializableValue;
669
- outCount++;
670
- }
927
+ else {
928
+ this.json[this.i++] = c;
671
929
  }
672
- if (ns.isUnionSchema() && outCount === 0) {
673
- const { $unknown } = record;
674
- if (Array.isArray($unknown)) {
675
- const [k, v] = $unknown;
676
- if (k === "__proto__") {
677
- writeKey(out);
678
- }
679
- out[k] = this._write(15, v);
680
- }
930
+ }
931
+ else if (c >= 0xd800 && c <= 0xdbff) {
932
+ const next = j + 1 < z ? s.charCodeAt(j + 1) : 0;
933
+ if (next >= 0xdc00 && next <= 0xdfff) {
934
+ this.ensure(4);
935
+ const { written } = encoder.encodeInto(s.substring(j, j + 2), this.json.subarray(this.i));
936
+ this.i += written;
937
+ ++j;
681
938
  }
682
- else if (typeof record.__type === "string") {
683
- for (const k in record) {
684
- const v = record[k];
685
- const targetKey = jsonName ? (nameMap[k] ?? k) : k;
686
- if (!(targetKey in out)) {
687
- out[targetKey] = this._write(15, v);
688
- }
689
- }
939
+ else {
940
+ this.ensure(6);
941
+ this.writeUnicodeEscape(c);
690
942
  }
691
- return out;
692
943
  }
693
- if (Array.isArray(value) && ns.isListSchema()) {
694
- const listMember = ns.getValueSchema();
695
- const out = [];
696
- const sparse = !!ns.getMergedTraits().sparse;
697
- for (const item of value) {
698
- if (sparse || item != null) {
699
- out.push(this._write(listMember, item));
700
- }
701
- }
702
- return out;
944
+ else if (c >= 0xdc00 && c <= 0xdfff) {
945
+ this.ensure(6);
946
+ this.writeUnicodeEscape(c);
703
947
  }
704
- if (ns.isMapSchema()) {
705
- const mapMember = ns.getValueSchema();
706
- const out = {};
707
- const sparse = !!ns.getMergedTraits().sparse;
708
- for (const _k in value) {
709
- const _v = value[_k];
710
- if (sparse || _v != null) {
711
- if (_k === "__proto__") {
712
- writeKey(out);
713
- }
714
- out[_k] = this._write(mapMember, _v);
715
- }
948
+ else {
949
+ let { i, json } = this;
950
+ if (c < 0x800) {
951
+ json[i++] = 0xc0 | (c >> 6);
952
+ json[i++] = 0x80 | (c & 0x3f);
716
953
  }
717
- return out;
718
- }
719
- if (value instanceof Uint8Array && (ns.isBlobSchema() || ns.isDocumentSchema())) {
720
- if (ns === this.rootSchema) {
721
- return value;
954
+ else {
955
+ json[i++] = 0xe0 | (c >> 12);
956
+ json[i++] = 0x80 | ((c >> 6) & 0x3f);
957
+ json[i++] = 0x80 | (c & 0x3f);
722
958
  }
723
- return (this.serdeContext?.base64Encoder ?? toBase64)(value);
959
+ this.i = i;
724
960
  }
725
- if (value instanceof Date && (ns.isTimestampSchema() || ns.isDocumentSchema())) {
726
- const format = determineTimestampFormat(ns, this.settings);
727
- switch (format) {
728
- case 5:
729
- return value.toISOString().replace(".000Z", "Z");
730
- case 6:
731
- return dateToUtcString(value);
732
- case 7:
733
- return value.getTime() / 1000;
734
- default:
735
- console.warn("Missing timestamp format, using epoch seconds", value);
736
- return value.getTime() / 1000;
961
+ }
962
+ this.json[this.i++] = QUOTE;
963
+ }
964
+ writeUnicodeEscape(code) {
965
+ let { json, i } = this;
966
+ json[i++] = BACKSLASH;
967
+ json[i++] = 0x75;
968
+ const hex = code.toString(16).padStart(4, "0");
969
+ for (let j = 0; j < 4; ++j) {
970
+ json[i++] = hex.charCodeAt(j);
971
+ }
972
+ this.i = i;
973
+ }
974
+ static B64 = (() => {
975
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
976
+ const table = new Uint8Array(64);
977
+ for (let i = 0; i < 64; ++i) {
978
+ table[i] = chars.charCodeAt(i);
979
+ }
980
+ return table;
981
+ })();
982
+ writeBase64(data) {
983
+ const b64Len = Math.ceil(data.length / 3) * 4;
984
+ this.ensure(b64Len + 2);
985
+ const json = this.json;
986
+ const B64 = JsonShapeSerializer2.B64;
987
+ let i = this.i;
988
+ json[i++] = QUOTE;
989
+ const len = data.length;
990
+ const remainder = len % 3;
991
+ const mainLen = len - remainder;
992
+ for (let j = 0; j < mainLen; j += 3) {
993
+ const a = data[j];
994
+ const b = data[j + 1];
995
+ const c = data[j + 2];
996
+ json[i++] = B64[a >> 2];
997
+ json[i++] = B64[((a & 0x03) << 4) | (b >> 4)];
998
+ json[i++] = B64[((b & 0x0f) << 2) | (c >> 6)];
999
+ json[i++] = B64[c & 0x3f];
1000
+ }
1001
+ if (remainder === 2) {
1002
+ const a = data[mainLen];
1003
+ const b = data[mainLen + 1];
1004
+ json[i++] = B64[a >> 2];
1005
+ json[i++] = B64[((a & 0x03) << 4) | (b >> 4)];
1006
+ json[i++] = B64[(b & 0x0f) << 2];
1007
+ json[i++] = 0x3d;
1008
+ }
1009
+ else if (remainder === 1) {
1010
+ const a = data[mainLen];
1011
+ json[i++] = B64[a >> 2];
1012
+ json[i++] = B64[(a & 0x03) << 4];
1013
+ json[i++] = 0x3d;
1014
+ json[i++] = 0x3d;
1015
+ }
1016
+ json[i++] = QUOTE;
1017
+ this.i = i;
1018
+ }
1019
+ writeValue(schema, value, container) {
1020
+ if (value == null) {
1021
+ if (container?.isStructSchema()) {
1022
+ if (value === undefined) {
1023
+ const ns = NormalizedSchema.of(schema);
1024
+ if (ns.isIdempotencyToken()) {
1025
+ this.writeAsciiQuoted(generateIdempotencyToken());
1026
+ return;
1027
+ }
737
1028
  }
1029
+ return;
738
1030
  }
739
- if (value instanceof NumericValue) {
740
- this.useReplacer = true;
741
- }
742
- }
743
- if (value === null && container?.isStructSchema()) {
744
- return void 0;
1031
+ this.ensure(4);
1032
+ this.json.set(NULL, this.i);
1033
+ this.i += 4;
1034
+ return;
745
1035
  }
1036
+ const ns = NormalizedSchema.of(schema);
1037
+ const isObject = typeof value === "object";
746
1038
  if (ns.isStringSchema()) {
747
- if (typeof value === "undefined" && ns.isIdempotencyToken()) {
748
- return generateIdempotencyToken();
749
- }
750
1039
  const mediaType = ns.getMergedTraits().mediaType;
751
- if (value != null && mediaType) {
1040
+ if (mediaType) {
752
1041
  const isJson = mediaType === "application/json" || mediaType.endsWith("+json");
753
1042
  if (isJson) {
754
- return LazyJsonString.from(value);
1043
+ this.writeJsonString(LazyJsonString.from(value).toString());
1044
+ return;
755
1045
  }
756
1046
  }
757
- return value;
758
1047
  }
759
- if (typeof value === "number" && ns.isNumericSchema()) {
760
- if (Math.abs(value) === Infinity || isNaN(value)) {
761
- return String(value);
1048
+ if (isObject) {
1049
+ if (ns.isStructSchema()) {
1050
+ this.writeStruct(ns, value);
1051
+ return;
762
1052
  }
763
- return value;
764
- }
765
- if (typeof value === "string" && ns.isBlobSchema()) {
766
- if (ns === this.rootSchema) {
767
- return value;
1053
+ if (Array.isArray(value) && (ns.isListSchema() || ns.isDocumentSchema())) {
1054
+ this.writeList(ns, value, ns.isDocumentSchema());
1055
+ return;
768
1056
  }
769
- return (this.serdeContext?.base64Encoder ?? toBase64)(value);
770
- }
771
- if (typeof value === "bigint") {
772
- this.useReplacer = true;
773
- }
774
- if (ns.isDocumentSchema()) {
775
- if (isObject) {
776
- const out = Array.isArray(value) ? [] : {};
777
- for (const k in value) {
778
- const v = value[k];
779
- if (k === "__proto__") {
780
- writeKey(out);
781
- }
782
- if (v instanceof NumericValue) {
783
- this.useReplacer = true;
784
- out[k] = v;
785
- }
786
- else {
787
- out[k] = this._write(ns, v);
788
- }
1057
+ if (ns.isMapSchema()) {
1058
+ this.writeMap(ns, value, false);
1059
+ return;
1060
+ }
1061
+ if (value instanceof Uint8Array && (ns.isBlobSchema() || ns.isDocumentSchema())) {
1062
+ this.writeBase64(value);
1063
+ return;
1064
+ }
1065
+ if (value instanceof Date && (ns.isTimestampSchema() || ns.isDocumentSchema())) {
1066
+ this.writeTimestamp(ns, value);
1067
+ return;
1068
+ }
1069
+ if (value instanceof NumericValue) {
1070
+ this.writeAscii(value.string);
1071
+ return;
1072
+ }
1073
+ if (ns.isDocumentSchema()) {
1074
+ if (Array.isArray(value)) {
1075
+ this.writeList(ns, value, true);
789
1076
  }
790
- return out;
1077
+ else {
1078
+ this.writeMap(ns, value, true);
1079
+ }
1080
+ return;
791
1081
  }
792
- else {
793
- return structuredClone(value);
1082
+ const json = JSON.stringify(value);
1083
+ this.writeAscii(json);
1084
+ return;
1085
+ }
1086
+ if (typeof value === "string") {
1087
+ if (ns.isBlobSchema()) {
1088
+ const b64 = (this.serdeContext?.base64Encoder ?? toBase64)(value);
1089
+ this.writeAsciiQuoted(b64);
1090
+ return;
1091
+ }
1092
+ this.writeJsonString(value);
1093
+ return;
1094
+ }
1095
+ if (typeof value === "number") {
1096
+ if (Math.abs(value) === Infinity || Number.isNaN(value)) {
1097
+ this.writeAsciiQuoted(String(value));
1098
+ return;
1099
+ }
1100
+ const numStr = String(value);
1101
+ this.writeAscii(numStr);
1102
+ return;
1103
+ }
1104
+ if (typeof value === "boolean") {
1105
+ this.ensure(5);
1106
+ let { i, json } = this;
1107
+ if (value) {
1108
+ json.set(TRUE, i);
1109
+ i += 4;
1110
+ }
1111
+ else {
1112
+ json.set(FALSE, i);
1113
+ i += 5;
1114
+ }
1115
+ this.i = i;
1116
+ return;
1117
+ }
1118
+ if (typeof value === "bigint") {
1119
+ this.writeAscii(value.toString());
1120
+ return;
1121
+ }
1122
+ this.writeAscii(String(value));
1123
+ }
1124
+ writeStruct(ns, value) {
1125
+ this.ensure(2);
1126
+ this.json[this.i++] = OPEN_BRACE;
1127
+ let wroteAny = false;
1128
+ const hasType = typeof value.__type === "string";
1129
+ let writtenKeys;
1130
+ if (hasType) {
1131
+ writtenKeys = new Set();
1132
+ }
1133
+ for (const [memberName, memberSchema] of ns.structIterator()) {
1134
+ const item = value[memberName];
1135
+ if (item == null && !memberSchema.isIdempotencyToken()) {
1136
+ continue;
1137
+ }
1138
+ if (wroteAny) {
1139
+ this.ensure(1);
1140
+ this.json[this.i++] = COMMA;
1141
+ }
1142
+ wroteAny = true;
1143
+ const targetKey = this.settings.jsonName ? (memberSchema.getMergedTraits().jsonName ?? memberName) : memberName;
1144
+ if (writtenKeys) {
1145
+ writtenKeys.add(memberName);
1146
+ writtenKeys.add(targetKey);
1147
+ }
1148
+ this.writeAsciiQuoted(targetKey);
1149
+ this.json[this.i++] = COLON;
1150
+ this.writeValue(memberSchema, item, ns);
1151
+ }
1152
+ if (!wroteAny && ns.isUnionSchema()) {
1153
+ const { $unknown } = value;
1154
+ if (Array.isArray($unknown)) {
1155
+ const [k, v] = $unknown;
1156
+ this.writeAsciiQuoted(k);
1157
+ this.ensure(1);
1158
+ this.json[this.i++] = COLON;
1159
+ this.writeValue(15, v, ns);
1160
+ }
1161
+ }
1162
+ else if (hasType) {
1163
+ for (const k in value) {
1164
+ if (writtenKeys.has(k)) {
1165
+ continue;
1166
+ }
1167
+ writtenKeys.add(k);
1168
+ const v = value[k];
1169
+ if (wroteAny) {
1170
+ this.ensure(1);
1171
+ this.json[this.i++] = COMMA;
1172
+ }
1173
+ wroteAny = true;
1174
+ this.writeAsciiQuoted(k);
1175
+ this.ensure(1);
1176
+ this.json[this.i++] = COLON;
1177
+ this.writeValue(15, v, undefined);
1178
+ }
1179
+ }
1180
+ this.ensure(1);
1181
+ this.json[this.i++] = CLOSE_BRACE;
1182
+ }
1183
+ writeList(ns, value, isDocument) {
1184
+ const sparse = !!ns.getMergedTraits().sparse;
1185
+ const valueSchema = ns.getValueSchema();
1186
+ if (!isDocument) {
1187
+ if (valueSchema.isStringSchema() || valueSchema.isNumericSchema() || valueSchema.isBooleanSchema()) {
1188
+ let hasSpecials = false;
1189
+ for (let i = 0; i < value.length; ++i) {
1190
+ const v = value[i];
1191
+ if (Number.isNaN(v) || v === Infinity || v === -Infinity || (v == null && !sparse)) {
1192
+ hasSpecials = true;
1193
+ break;
1194
+ }
1195
+ }
1196
+ let json;
1197
+ if (!hasSpecials) {
1198
+ json = JSON.stringify(value);
1199
+ }
1200
+ else {
1201
+ const out = [];
1202
+ for (let i = 0; i < value.length; ++i) {
1203
+ const v = value[i];
1204
+ if (v == null && !sparse)
1205
+ continue;
1206
+ if (Number.isNaN(v) || v === Infinity || v === -Infinity) {
1207
+ out.push(String(v));
1208
+ }
1209
+ else {
1210
+ out.push(v);
1211
+ }
1212
+ }
1213
+ json = JSON.stringify(out);
1214
+ }
1215
+ this.ensure(json.length * 3);
1216
+ this.i += encoder.encodeInto(json, this.json.subarray(this.i)).written;
1217
+ return;
1218
+ }
1219
+ }
1220
+ this.ensure(2);
1221
+ this.json[this.i++] = OPEN_BRACKET;
1222
+ let wroteFirstItem = false;
1223
+ for (let i = 0; i < value.length; ++i) {
1224
+ const item = value[i];
1225
+ if (isDocument ? item === undefined : item == null && !sparse) {
1226
+ continue;
1227
+ }
1228
+ if (wroteFirstItem) {
1229
+ this.ensure(1);
1230
+ this.json[this.i++] = COMMA;
1231
+ }
1232
+ this.writeValue(valueSchema, item, undefined);
1233
+ wroteFirstItem = true;
1234
+ }
1235
+ this.ensure(1);
1236
+ this.json[this.i++] = CLOSE_BRACKET;
1237
+ }
1238
+ writeMap(ns, value, isDocument) {
1239
+ const sparse = !!ns.getMergedTraits().sparse;
1240
+ const valueSchema = ns.getValueSchema();
1241
+ if (!isDocument) {
1242
+ if (valueSchema.isStringSchema() || valueSchema.isNumericSchema() || valueSchema.isBooleanSchema()) {
1243
+ let modifications;
1244
+ for (const k in value) {
1245
+ const v = value[k];
1246
+ if (Number.isNaN(v) || v === Infinity || v === -Infinity) {
1247
+ (modifications ??= {})[k] = v;
1248
+ value[k] = String(v);
1249
+ }
1250
+ else if (v === null && !sparse) {
1251
+ (modifications ??= {})[k] = null;
1252
+ value[k] = undefined;
1253
+ }
1254
+ }
1255
+ const json = JSON.stringify(value);
1256
+ if (modifications) {
1257
+ Object.assign(value, modifications);
1258
+ }
1259
+ this.ensure(json.length * 3);
1260
+ this.i += encoder.encodeInto(json, this.json.subarray(this.i)).written;
1261
+ return;
1262
+ }
1263
+ }
1264
+ this.ensure(2);
1265
+ this.json[this.i++] = OPEN_BRACE;
1266
+ let first = true;
1267
+ for (const k in value) {
1268
+ const v = value[k];
1269
+ if (isDocument ? v === undefined : v == null && !sparse) {
1270
+ continue;
1271
+ }
1272
+ if (!first) {
1273
+ this.ensure(1);
1274
+ this.json[this.i++] = COMMA;
1275
+ }
1276
+ first = false;
1277
+ this.writeJsonString(k);
1278
+ this.ensure(1);
1279
+ this.json[this.i++] = COLON;
1280
+ this.writeValue(valueSchema, v, undefined);
1281
+ }
1282
+ this.ensure(1);
1283
+ this.json[this.i++] = CLOSE_BRACE;
1284
+ }
1285
+ writeTimestamp(ns, value) {
1286
+ const format = determineTimestampFormat(ns, this.settings);
1287
+ switch (format) {
1288
+ case 5: {
1289
+ const iso = value.toISOString().replace(".000Z", "Z");
1290
+ this.writeAsciiQuoted(iso);
1291
+ return;
1292
+ }
1293
+ case 6: {
1294
+ this.writeAsciiQuoted(dateToUtcString(value));
1295
+ return;
1296
+ }
1297
+ case 7: {
1298
+ const epochSecs = String(value.getTime() / 1000);
1299
+ this.writeAscii(epochSecs);
1300
+ return;
1301
+ }
1302
+ default: {
1303
+ const epochSecs = String(value.getTime() / 1000);
1304
+ this.writeAscii(epochSecs);
1305
+ return;
794
1306
  }
795
1307
  }
796
- return value;
797
1308
  }
798
1309
  }
799
1310
 
800
- class JsonCodec extends SerdeContextConfig {
1311
+ class JsonCodec2 extends SerdeContextConfig {
801
1312
  settings;
802
1313
  constructor(settings) {
803
1314
  super();
804
1315
  this.settings = settings;
805
1316
  }
806
1317
  createSerializer() {
807
- const serializer = new JsonShapeSerializer(this.settings);
1318
+ const serializer = new JsonShapeSerializer2(this.settings);
808
1319
  serializer.setSerdeContext(this.serdeContext);
809
1320
  return serializer;
810
1321
  }
811
1322
  createDeserializer() {
812
- const deserializer = new JsonShapeDeserializer(this.settings);
1323
+ const deserializer = new JsonShapeDeserializer2(this.settings);
813
1324
  deserializer.setSerdeContext(this.serdeContext);
814
1325
  return deserializer;
815
1326
  }
@@ -830,7 +1341,7 @@ class AwsJsonRpcProtocol extends RpcProtocol {
830
1341
  this.serviceTarget = serviceTarget;
831
1342
  this.codec =
832
1343
  jsonCodec ??
833
- new JsonCodec({
1344
+ new JsonCodec2({
834
1345
  timestampFormat: {
835
1346
  useTrait: true,
836
1347
  default: 7,
@@ -936,7 +1447,7 @@ class AwsRestJsonProtocol extends HttpBindingProtocol {
936
1447
  deserializer;
937
1448
  codec;
938
1449
  mixin = new ProtocolLib();
939
- constructor({ defaultNamespace, errorTypeRegistries, }) {
1450
+ constructor({ defaultNamespace, errorTypeRegistries, jsonCodec, }) {
940
1451
  super({
941
1452
  defaultNamespace,
942
1453
  errorTypeRegistries,
@@ -949,7 +1460,7 @@ class AwsRestJsonProtocol extends HttpBindingProtocol {
949
1460
  httpBindings: true,
950
1461
  jsonName: true,
951
1462
  };
952
- this.codec = new JsonCodec(settings);
1463
+ this.codec = jsonCodec ?? new JsonCodec2(settings);
953
1464
  this.serializer = new HttpInterceptingShapeSerializer(this.codec.createSerializer(), settings);
954
1465
  this.deserializer = new HttpInterceptingShapeDeserializer(this.codec.createDeserializer(), settings);
955
1466
  }
@@ -1012,7 +1523,7 @@ class AwsRestJsonProtocol extends HttpBindingProtocol {
1012
1523
  }
1013
1524
  }
1014
1525
 
1015
- class JsonShapeDeserializer2 extends SerdeContextConfig {
1526
+ class JsonShapeDeserializer extends SerdeContextConfig {
1016
1527
  settings;
1017
1528
  constructor(settings) {
1018
1529
  super();
@@ -1020,24 +1531,7 @@ class JsonShapeDeserializer2 extends SerdeContextConfig {
1020
1531
  }
1021
1532
  async read(schema, data) {
1022
1533
  const reviver = needsReviver(schema) ? jsonReviver : undefined;
1023
- let parsed;
1024
- if (typeof data === "string") {
1025
- if (data.length === 0) {
1026
- return {};
1027
- }
1028
- parsed = JSON.parse(data, reviver);
1029
- }
1030
- else if (data instanceof Uint8Array && detectBufferParsing()) {
1031
- if (data.byteLength === 0) {
1032
- return {};
1033
- }
1034
- const buf = Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
1035
- parsed = JSON.parse(buf, reviver);
1036
- }
1037
- else {
1038
- parsed = await parseJsonBody(data, this.serdeContext, schema);
1039
- }
1040
- return this._read(schema, parsed);
1534
+ return this._read(schema, typeof data === "string" ? JSON.parse(data, reviver) : await parseJsonBody(data, this.serdeContext, schema));
1041
1535
  }
1042
1536
  readObject(schema, data) {
1043
1537
  return this._read(schema, data);
@@ -1047,29 +1541,63 @@ class JsonShapeDeserializer2 extends SerdeContextConfig {
1047
1541
  const ns = NormalizedSchema.of(schema);
1048
1542
  if (isObject) {
1049
1543
  if (ns.isStructSchema()) {
1050
- return this._readStruct(ns, value);
1051
- }
1052
- if (Array.isArray(value) && ns.isListSchema()) {
1053
- const listMember = ns.getValueSchema();
1054
- if (this.needsTransform(listMember)) {
1055
- for (let i = 0; i < value.length; ++i) {
1056
- value[i] = this._read(listMember, value[i]);
1057
- }
1544
+ const record = value;
1545
+ const union = ns.isUnionSchema();
1546
+ const out = {};
1547
+ let nameMap = void 0;
1548
+ const { jsonName } = this.settings;
1549
+ if (jsonName) {
1550
+ nameMap = {};
1058
1551
  }
1059
- return value;
1060
- }
1061
- if (ns.isMapSchema()) {
1062
- const mapMember = ns.getValueSchema();
1063
- const map = value;
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]);
1552
+ let unionSerde;
1553
+ if (union) {
1554
+ unionSerde = new UnionSerde(record, out);
1555
+ }
1556
+ for (const [memberName, memberSchema] of ns.structIterator()) {
1557
+ let fromKey = memberName;
1558
+ if (jsonName) {
1559
+ fromKey = memberSchema.getMergedTraits().jsonName ?? fromKey;
1560
+ nameMap[fromKey] = memberName;
1561
+ }
1562
+ if (union) {
1563
+ unionSerde.mark(fromKey);
1564
+ }
1565
+ if (record[fromKey] != null) {
1566
+ out[memberName] = this._read(memberSchema, record[fromKey]);
1070
1567
  }
1071
1568
  }
1072
- return map;
1569
+ if (union) {
1570
+ unionSerde.writeUnknown();
1571
+ }
1572
+ else if (typeof record.__type === "string") {
1573
+ for (const k in record) {
1574
+ const v = record[k];
1575
+ const t = jsonName ? (nameMap[k] ?? k) : k;
1576
+ if (!(t in out)) {
1577
+ out[t] = v;
1578
+ }
1579
+ }
1580
+ }
1581
+ return out;
1582
+ }
1583
+ if (Array.isArray(value) && ns.isListSchema()) {
1584
+ const listMember = ns.getValueSchema();
1585
+ const out = [];
1586
+ for (const item of value) {
1587
+ out.push(this._read(listMember, item));
1588
+ }
1589
+ return out;
1590
+ }
1591
+ if (ns.isMapSchema()) {
1592
+ const mapMember = ns.getValueSchema();
1593
+ const out = {};
1594
+ for (const _k in value) {
1595
+ if (_k === "__proto__") {
1596
+ writeKey(out);
1597
+ }
1598
+ out[_k] = this._read(mapMember, value[_k]);
1599
+ }
1600
+ return out;
1073
1601
  }
1074
1602
  }
1075
1603
  if (ns.isBlobSchema() && typeof value === "string") {
@@ -1119,690 +1647,280 @@ class JsonShapeDeserializer2 extends SerdeContextConfig {
1119
1647
  case "NaN":
1120
1648
  return NaN;
1121
1649
  }
1122
- return value;
1123
- }
1124
- if (ns.isDocumentSchema()) {
1125
- if (isObject) {
1126
- if (Array.isArray(value)) {
1127
- for (let i = 0; i < value.length; ++i) {
1128
- const v = value[i];
1129
- if (!(v instanceof NumericValue)) {
1130
- value[i] = this._read(ns, v);
1131
- }
1132
- }
1133
- }
1134
- else {
1135
- const doc = value;
1136
- for (const k in doc) {
1137
- if (k === "__proto__") {
1138
- writeKey(doc);
1139
- }
1140
- const v = doc[k];
1141
- if (!(v instanceof NumericValue)) {
1142
- doc[k] = this._read(ns, v);
1143
- }
1144
- }
1145
- }
1146
- }
1147
- }
1148
- return value;
1149
- }
1150
- _readStruct(ns, record) {
1151
- const union = ns.isUnionSchema();
1152
- const out = {};
1153
- let nameMap;
1154
- const hasType = typeof record.__type === "string";
1155
- const { jsonName } = this.settings;
1156
- if (jsonName && hasType) {
1157
- nameMap = {};
1158
- }
1159
- let unionSerde;
1160
- if (union) {
1161
- unionSerde = new UnionSerde(record, out);
1162
- }
1163
- for (const [memberName, memberSchema] of ns.structIterator()) {
1164
- let fromKey = memberName;
1165
- if (jsonName) {
1166
- fromKey = memberSchema.getMergedTraits().jsonName ?? fromKey;
1167
- if (hasType) {
1168
- nameMap[fromKey] = memberName;
1169
- }
1170
- }
1171
- if (union) {
1172
- unionSerde.mark(fromKey);
1173
- }
1174
- if (record[fromKey] != null) {
1175
- out[memberName] = this._read(memberSchema, record[fromKey]);
1176
- }
1177
- }
1178
- if (union) {
1179
- unionSerde.writeUnknown();
1180
- }
1181
- else if (hasType) {
1182
- for (const k in record) {
1183
- const v = record[k];
1184
- const t = jsonName ? (nameMap[k] ?? k) : k;
1185
- if (!(t in out)) {
1186
- out[t] = v;
1187
- }
1188
- }
1189
- }
1190
- return out;
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
- }
1204
- }
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
-
1309
- const encoder = new TextEncoder();
1310
- const OPEN_BRACE = 0x7b;
1311
- const CLOSE_BRACE = 0x7d;
1312
- const OPEN_BRACKET = 0x5b;
1313
- const CLOSE_BRACKET = 0x5d;
1314
- const QUOTE = 0x22;
1315
- const COLON = 0x3a;
1316
- const COMMA = 0x2c;
1317
- const BACKSLASH = 0x5c;
1318
- const TRUE = new Uint8Array([0x74, 0x72, 0x75, 0x65]);
1319
- const FALSE = new Uint8Array([0x66, 0x61, 0x6c, 0x73, 0x65]);
1320
- const NULL = new Uint8Array([0x6e, 0x75, 0x6c, 0x6c]);
1321
- const ESCAPE_TABLE = new Array(128).fill(null);
1322
- ESCAPE_TABLE[0x08] = "b";
1323
- ESCAPE_TABLE[0x09] = "t";
1324
- ESCAPE_TABLE[0x0a] = "n";
1325
- ESCAPE_TABLE[0x0c] = "f";
1326
- ESCAPE_TABLE[0x0d] = "r";
1327
- ESCAPE_TABLE[0x22] = '"';
1328
- ESCAPE_TABLE[0x5c] = "\\";
1329
- for (let i = 0; i < 0x20; i++) {
1330
- if (ESCAPE_TABLE[i] === null) {
1331
- ESCAPE_TABLE[i] = "u00" + i.toString(16).padStart(2, "0");
1332
- }
1333
- }
1334
- const INITIAL_BUFFER_SIZE = 2048;
1335
- function alloc(size) {
1336
- return JsonBytesStringAdapter.allocUnsafe(size);
1337
- }
1338
- class JsonShapeSerializer2 extends SerdeContextConfig {
1339
- settings;
1340
- json;
1341
- i = 0;
1342
- rootSchema;
1343
- rawValue;
1344
- passthrough = false;
1345
- constructor(settings) {
1346
- super();
1347
- this.settings = settings;
1348
- this.json = alloc(INITIAL_BUFFER_SIZE);
1349
- }
1350
- write(schema, value) {
1351
- this.i = 0;
1352
- this.rawValue = value;
1353
- this.rootSchema = NormalizedSchema.of(schema);
1354
- this.passthrough = this.rootSchema.isBlobSchema() || this.rootSchema.isStringSchema();
1355
- if (!this.passthrough) {
1356
- this.writeValue(this.rootSchema, value, undefined);
1357
- }
1358
- }
1359
- writeDiscriminatedDocument(schema, value) {
1360
- this.i = 0;
1361
- this.rootSchema = NormalizedSchema.of(schema);
1362
- const ns = this.rootSchema;
1363
- if (ns.isStructSchema() && value != null && typeof value === "object") {
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;
1371
- }
1372
- else {
1373
- this.writeValue(ns, value, undefined);
1374
- }
1375
- }
1376
- flush() {
1377
- this.rootSchema = undefined;
1378
- const finalPosition = this.i;
1379
- this.i = 0;
1380
- const raw = this.rawValue;
1381
- this.rawValue = undefined;
1382
- if (finalPosition === 0) {
1383
- return raw;
1384
- }
1385
- const result = this.json.subarray(0, finalPosition);
1386
- this.json = alloc(INITIAL_BUFFER_SIZE);
1387
- return result;
1388
- }
1389
- ensure(byteCount) {
1390
- const { i, json } = this;
1391
- if (i + byteCount > json.length) {
1392
- let newSize = json.length * 2;
1393
- while (newSize < i + byteCount) {
1394
- newSize *= 2;
1395
- }
1396
- const next = alloc(newSize);
1397
- next.set(this.json);
1398
- this.json = next;
1399
- }
1400
- }
1401
- writeAscii(s) {
1402
- const z = s.length;
1403
- this.ensure(z);
1404
- let { i, json } = this;
1405
- for (let j = 0; j < z; ++j) {
1406
- json[i] = s.charCodeAt(j);
1407
- i += 1;
1408
- }
1409
- this.i = i;
1410
- }
1411
- writeAsciiQuoted(s) {
1412
- const z = s.length;
1413
- this.ensure(z + 4);
1414
- let { json, i } = this;
1415
- json[i++] = QUOTE;
1416
- for (let j = 0; j < z; ++j) {
1417
- json[i++] = s.charCodeAt(j);
1418
- }
1419
- json[i++] = QUOTE;
1420
- this.i = i;
1421
- }
1422
- writeJsonString(s) {
1423
- this.ensure(s.length * 3 + 2);
1424
- this.json[this.i++] = QUOTE;
1425
- const z = s.length;
1426
- for (let j = 0; j < z; ++j) {
1427
- const c = s.charCodeAt(j);
1428
- if (c > 0x22 && c < 0x5c) {
1429
- this.json[this.i++] = c;
1430
- }
1431
- else if (c < 0x80) {
1432
- const esc = ESCAPE_TABLE[c];
1433
- if (esc !== null) {
1434
- this.ensure(esc.length + 1);
1435
- this.json[this.i++] = BACKSLASH;
1436
- for (let k = 0; k < esc.length; k++) {
1437
- this.json[this.i++] = esc.charCodeAt(k);
1438
- }
1439
- }
1440
- else {
1441
- this.json[this.i++] = c;
1442
- }
1443
- }
1444
- else if (c >= 0xd800 && c <= 0xdbff) {
1445
- const next = j + 1 < z ? s.charCodeAt(j + 1) : 0;
1446
- if (next >= 0xdc00 && next <= 0xdfff) {
1447
- this.ensure(4);
1448
- const { written } = encoder.encodeInto(s.substring(j, j + 2), this.json.subarray(this.i));
1449
- this.i += written;
1450
- ++j;
1451
- }
1452
- else {
1453
- this.ensure(6);
1454
- this.writeUnicodeEscape(c);
1650
+ return value;
1651
+ }
1652
+ if (ns.isDocumentSchema()) {
1653
+ if (isObject) {
1654
+ const out = Array.isArray(value) ? [] : {};
1655
+ for (const k in value) {
1656
+ if (k === "__proto__") {
1657
+ writeKey(out);
1658
+ }
1659
+ const v = value[k];
1660
+ if (v instanceof NumericValue) {
1661
+ out[k] = v;
1662
+ }
1663
+ else {
1664
+ out[k] = this._read(ns, v);
1665
+ }
1455
1666
  }
1456
- }
1457
- else if (c >= 0xdc00 && c <= 0xdfff) {
1458
- this.ensure(6);
1459
- this.writeUnicodeEscape(c);
1667
+ return out;
1460
1668
  }
1461
1669
  else {
1462
- let { i, json } = this;
1463
- if (c < 0x800) {
1464
- json[i++] = 0xc0 | (c >> 6);
1465
- json[i++] = 0x80 | (c & 0x3f);
1466
- }
1467
- else {
1468
- json[i++] = 0xe0 | (c >> 12);
1469
- json[i++] = 0x80 | ((c >> 6) & 0x3f);
1470
- json[i++] = 0x80 | (c & 0x3f);
1471
- }
1472
- this.i = i;
1670
+ return structuredClone(value);
1473
1671
  }
1474
1672
  }
1475
- this.json[this.i++] = QUOTE;
1673
+ return value;
1476
1674
  }
1477
- writeUnicodeEscape(code) {
1478
- let { json, i } = this;
1479
- json[i++] = BACKSLASH;
1480
- json[i++] = 0x75;
1481
- const hex = code.toString(16).padStart(4, "0");
1482
- for (let j = 0; j < 4; ++j) {
1483
- json[i++] = hex.charCodeAt(j);
1675
+ }
1676
+
1677
+ const NUMERIC_CONTROL_CHAR = String.fromCharCode(925);
1678
+ class JsonReplacer {
1679
+ values = new Map();
1680
+ counter = 0;
1681
+ stage = 0;
1682
+ createReplacer() {
1683
+ if (this.stage === 1) {
1684
+ throw new Error("@aws-sdk/core/protocols - JsonReplacer already created.");
1484
1685
  }
1485
- this.i = i;
1686
+ if (this.stage === 2) {
1687
+ throw new Error("@aws-sdk/core/protocols - JsonReplacer exhausted.");
1688
+ }
1689
+ this.stage = 1;
1690
+ return (key, value) => {
1691
+ if (value instanceof NumericValue) {
1692
+ const v = `${NUMERIC_CONTROL_CHAR + "nv" + this.counter++}_` + value.string;
1693
+ this.values.set(`"${v}"`, value.string);
1694
+ return v;
1695
+ }
1696
+ if (typeof value === "bigint") {
1697
+ const s = value.toString();
1698
+ const v = `${NUMERIC_CONTROL_CHAR + "b" + this.counter++}_` + s;
1699
+ this.values.set(`"${v}"`, s);
1700
+ return v;
1701
+ }
1702
+ return value;
1703
+ };
1486
1704
  }
1487
- static B64 = (() => {
1488
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1489
- const table = new Uint8Array(64);
1490
- for (let i = 0; i < 64; ++i) {
1491
- table[i] = chars.charCodeAt(i);
1705
+ replaceInJson(json) {
1706
+ if (this.stage === 0) {
1707
+ throw new Error("@aws-sdk/core/protocols - JsonReplacer not created yet.");
1492
1708
  }
1493
- return table;
1494
- })();
1495
- writeBase64(data) {
1496
- const b64Len = Math.ceil(data.length / 3) * 4;
1497
- this.ensure(b64Len + 2);
1498
- const json = this.json;
1499
- const B64 = JsonShapeSerializer2.B64;
1500
- let i = this.i;
1501
- json[i++] = QUOTE;
1502
- const len = data.length;
1503
- const remainder = len % 3;
1504
- const mainLen = len - remainder;
1505
- for (let j = 0; j < mainLen; j += 3) {
1506
- const a = data[j];
1507
- const b = data[j + 1];
1508
- const c = data[j + 2];
1509
- json[i++] = B64[a >> 2];
1510
- json[i++] = B64[((a & 0x03) << 4) | (b >> 4)];
1511
- json[i++] = B64[((b & 0x0f) << 2) | (c >> 6)];
1512
- json[i++] = B64[c & 0x3f];
1709
+ if (this.stage === 2) {
1710
+ throw new Error("@aws-sdk/core/protocols - JsonReplacer exhausted.");
1513
1711
  }
1514
- if (remainder === 2) {
1515
- const a = data[mainLen];
1516
- const b = data[mainLen + 1];
1517
- json[i++] = B64[a >> 2];
1518
- json[i++] = B64[((a & 0x03) << 4) | (b >> 4)];
1519
- json[i++] = B64[(b & 0x0f) << 2];
1520
- json[i++] = 0x3d;
1712
+ this.stage = 2;
1713
+ if (this.counter === 0) {
1714
+ return json;
1521
1715
  }
1522
- else if (remainder === 1) {
1523
- const a = data[mainLen];
1524
- json[i++] = B64[a >> 2];
1525
- json[i++] = B64[(a & 0x03) << 4];
1526
- json[i++] = 0x3d;
1527
- json[i++] = 0x3d;
1716
+ for (const [key, value] of this.values) {
1717
+ json = json.replace(key, value);
1528
1718
  }
1529
- json[i++] = QUOTE;
1530
- this.i = i;
1719
+ return json;
1531
1720
  }
1532
- writeValue(schema, value, container) {
1533
- if (value == null) {
1534
- if (container?.isStructSchema()) {
1535
- if (value === undefined) {
1536
- const ns = NormalizedSchema.of(schema);
1537
- if (ns.isIdempotencyToken()) {
1538
- this.writeAsciiQuoted(generateIdempotencyToken());
1539
- return;
1540
- }
1541
- }
1542
- return;
1721
+ }
1722
+
1723
+ class JsonShapeSerializer extends SerdeContextConfig {
1724
+ settings;
1725
+ buffer;
1726
+ useReplacer = false;
1727
+ rootSchema;
1728
+ constructor(settings) {
1729
+ super();
1730
+ this.settings = settings;
1731
+ }
1732
+ write(schema, value) {
1733
+ this.rootSchema = NormalizedSchema.of(schema);
1734
+ this.buffer = this._write(this.rootSchema, value);
1735
+ }
1736
+ flush() {
1737
+ const { rootSchema, useReplacer } = this;
1738
+ this.rootSchema = undefined;
1739
+ this.useReplacer = false;
1740
+ if (rootSchema?.isStructSchema() || rootSchema?.isDocumentSchema()) {
1741
+ if (!useReplacer) {
1742
+ return JSON.stringify(this.buffer);
1543
1743
  }
1544
- this.ensure(4);
1545
- this.json.set(NULL, this.i);
1546
- this.i += 4;
1547
- return;
1744
+ const replacer = new JsonReplacer();
1745
+ return replacer.replaceInJson(JSON.stringify(this.buffer, replacer.createReplacer(), 0));
1548
1746
  }
1549
- const ns = NormalizedSchema.of(schema);
1550
- const isObject = typeof value === "object";
1551
- if (ns.isStringSchema()) {
1552
- const mediaType = ns.getMergedTraits().mediaType;
1553
- if (mediaType) {
1554
- const isJson = mediaType === "application/json" || mediaType.endsWith("+json");
1555
- if (isJson) {
1556
- this.writeJsonString(LazyJsonString.from(value).toString());
1557
- return;
1558
- }
1559
- }
1747
+ return this.buffer;
1748
+ }
1749
+ writeDiscriminatedDocument(schema, value) {
1750
+ this.write(schema, value);
1751
+ if (typeof this.buffer === "object") {
1752
+ this.buffer.__type = NormalizedSchema.of(schema).getName(true);
1560
1753
  }
1754
+ }
1755
+ _write(schema, value, container) {
1756
+ const isObject = value !== null && typeof value === "object";
1757
+ const ns = NormalizedSchema.of(schema);
1561
1758
  if (isObject) {
1562
1759
  if (ns.isStructSchema()) {
1563
- this.writeStruct(ns, value);
1564
- return;
1760
+ const record = value;
1761
+ const out = {};
1762
+ const { jsonName } = this.settings;
1763
+ let nameMap = void 0;
1764
+ if (jsonName) {
1765
+ nameMap = {};
1766
+ }
1767
+ let outCount = 0;
1768
+ for (const [memberName, memberSchema] of ns.structIterator()) {
1769
+ const serializableValue = this._write(memberSchema, record[memberName], ns);
1770
+ if (serializableValue !== undefined) {
1771
+ let targetKey = memberName;
1772
+ if (jsonName) {
1773
+ targetKey = memberSchema.getMergedTraits().jsonName ?? memberName;
1774
+ nameMap[memberName] = targetKey;
1775
+ }
1776
+ out[targetKey] = serializableValue;
1777
+ outCount++;
1778
+ }
1779
+ }
1780
+ if (ns.isUnionSchema() && outCount === 0) {
1781
+ const { $unknown } = record;
1782
+ if (Array.isArray($unknown)) {
1783
+ const [k, v] = $unknown;
1784
+ if (k === "__proto__") {
1785
+ writeKey(out);
1786
+ }
1787
+ out[k] = this._write(15, v);
1788
+ }
1789
+ }
1790
+ else if (typeof record.__type === "string") {
1791
+ for (const k in record) {
1792
+ const v = record[k];
1793
+ const targetKey = jsonName ? (nameMap[k] ?? k) : k;
1794
+ if (!(targetKey in out)) {
1795
+ out[targetKey] = this._write(15, v);
1796
+ }
1797
+ }
1798
+ }
1799
+ return out;
1565
1800
  }
1566
- if (Array.isArray(value) && (ns.isListSchema() || ns.isDocumentSchema())) {
1567
- this.writeList(ns, value, ns.isDocumentSchema());
1568
- return;
1801
+ if (Array.isArray(value) && ns.isListSchema()) {
1802
+ const listMember = ns.getValueSchema();
1803
+ const out = [];
1804
+ const sparse = !!ns.getMergedTraits().sparse;
1805
+ for (const item of value) {
1806
+ if (sparse || item != null) {
1807
+ out.push(this._write(listMember, item));
1808
+ }
1809
+ }
1810
+ return out;
1569
1811
  }
1570
1812
  if (ns.isMapSchema()) {
1571
- this.writeMap(ns, value, false);
1572
- return;
1813
+ const mapMember = ns.getValueSchema();
1814
+ const out = {};
1815
+ const sparse = !!ns.getMergedTraits().sparse;
1816
+ for (const _k in value) {
1817
+ const _v = value[_k];
1818
+ if (sparse || _v != null) {
1819
+ if (_k === "__proto__") {
1820
+ writeKey(out);
1821
+ }
1822
+ out[_k] = this._write(mapMember, _v);
1823
+ }
1824
+ }
1825
+ return out;
1573
1826
  }
1574
- if (value instanceof Uint8Array && (ns.isBlobSchema() || ns.isDocumentSchema())) {
1575
- this.writeBase64(value);
1576
- return;
1827
+ if (value instanceof Uint8Array && ns.isBlobSchema()) {
1828
+ if (ns === this.rootSchema) {
1829
+ return value;
1830
+ }
1831
+ return (this.serdeContext?.base64Encoder ?? toBase64)(value);
1577
1832
  }
1578
1833
  if (value instanceof Date && (ns.isTimestampSchema() || ns.isDocumentSchema())) {
1579
- this.writeTimestamp(ns, value);
1580
- return;
1834
+ const format = determineTimestampFormat(ns, this.settings);
1835
+ switch (format) {
1836
+ case 5:
1837
+ return value.toISOString().replace(".000Z", "Z");
1838
+ case 6:
1839
+ return dateToUtcString(value);
1840
+ case 7:
1841
+ return value.getTime() / 1000;
1842
+ default:
1843
+ console.warn("Missing timestamp format, using epoch seconds", value);
1844
+ return value.getTime() / 1000;
1845
+ }
1581
1846
  }
1582
1847
  if (value instanceof NumericValue) {
1583
- this.writeAscii(value.string);
1584
- return;
1585
- }
1586
- if (ns.isDocumentSchema()) {
1587
- if (Array.isArray(value)) {
1588
- this.writeList(ns, value, true);
1589
- }
1590
- else {
1591
- this.writeMap(ns, value, true);
1592
- }
1593
- return;
1848
+ this.useReplacer = true;
1594
1849
  }
1595
- const json = JSON.stringify(value);
1596
- this.writeAscii(json);
1597
- return;
1598
1850
  }
1599
- if (typeof value === "string") {
1600
- if (ns.isBlobSchema()) {
1601
- const b64 = (this.serdeContext?.base64Encoder ?? toBase64)(value);
1602
- this.writeAsciiQuoted(b64);
1603
- return;
1851
+ if (value === null && container?.isStructSchema()) {
1852
+ return void 0;
1853
+ }
1854
+ if (ns.isStringSchema()) {
1855
+ if (typeof value === "undefined" && ns.isIdempotencyToken()) {
1856
+ return generateIdempotencyToken();
1604
1857
  }
1605
- this.writeJsonString(value);
1606
- return;
1858
+ const mediaType = ns.getMergedTraits().mediaType;
1859
+ if (value != null && mediaType) {
1860
+ const isJson = mediaType === "application/json" || mediaType.endsWith("+json");
1861
+ if (isJson) {
1862
+ return LazyJsonString.from(value);
1863
+ }
1864
+ }
1865
+ return value;
1607
1866
  }
1608
1867
  if (typeof value === "number") {
1609
- if (ns.isNumericSchema() && (Math.abs(value) === Infinity || isNaN(value))) {
1610
- this.writeAsciiQuoted(String(value));
1611
- return;
1868
+ if (Math.abs(value) === Infinity || isNaN(value)) {
1869
+ return String(value);
1612
1870
  }
1613
- const numStr = String(value);
1614
- this.writeAscii(numStr);
1615
- return;
1871
+ return value;
1616
1872
  }
1617
- if (typeof value === "boolean") {
1618
- this.ensure(5);
1619
- let { i, json } = this;
1620
- if (value) {
1621
- json.set(TRUE, i);
1622
- i += 4;
1623
- }
1624
- else {
1625
- json.set(FALSE, i);
1626
- i += 5;
1873
+ if (typeof value === "string" && ns.isBlobSchema()) {
1874
+ if (ns === this.rootSchema) {
1875
+ return value;
1627
1876
  }
1628
- this.i = i;
1629
- return;
1877
+ return (this.serdeContext?.base64Encoder ?? toBase64)(value);
1630
1878
  }
1631
1879
  if (typeof value === "bigint") {
1632
- this.writeAscii(value.toString());
1633
- return;
1634
- }
1635
- this.writeAscii(String(value));
1636
- }
1637
- writeStruct(ns, value) {
1638
- this.ensure(2);
1639
- this.json[this.i++] = OPEN_BRACE;
1640
- let wroteAny = false;
1641
- const hasType = typeof value.__type === "string";
1642
- let writtenKeys;
1643
- if (hasType) {
1644
- writtenKeys = new Set();
1645
- }
1646
- for (const [memberName, memberSchema] of ns.structIterator()) {
1647
- const item = value[memberName];
1648
- if (item == null && !memberSchema.isIdempotencyToken()) {
1649
- continue;
1650
- }
1651
- if (wroteAny) {
1652
- this.ensure(1);
1653
- this.json[this.i++] = COMMA;
1654
- }
1655
- wroteAny = true;
1656
- const targetKey = this.settings.jsonName ? (memberSchema.getMergedTraits().jsonName ?? memberName) : memberName;
1657
- if (writtenKeys) {
1658
- writtenKeys.add(memberName);
1659
- writtenKeys.add(targetKey);
1660
- }
1661
- this.writeAsciiQuoted(targetKey);
1662
- this.json[this.i++] = COLON;
1663
- this.writeValue(memberSchema, item, ns);
1664
- }
1665
- if (!wroteAny && ns.isUnionSchema()) {
1666
- const { $unknown } = value;
1667
- if (Array.isArray($unknown)) {
1668
- const [k, v] = $unknown;
1669
- this.writeAsciiQuoted(k);
1670
- this.ensure(1);
1671
- this.json[this.i++] = COLON;
1672
- this.writeValue(15, v, ns);
1673
- }
1880
+ this.useReplacer = true;
1674
1881
  }
1675
- else if (hasType) {
1676
- for (const k in value) {
1677
- if (writtenKeys.has(k)) {
1678
- continue;
1679
- }
1680
- writtenKeys.add(k);
1681
- const v = value[k];
1682
- if (wroteAny) {
1683
- this.ensure(1);
1684
- this.json[this.i++] = COMMA;
1882
+ if (ns.isDocumentSchema()) {
1883
+ if (isObject) {
1884
+ if (value instanceof Uint8Array) {
1885
+ return (this.serdeContext?.base64Encoder ?? toBase64)(value);
1685
1886
  }
1686
- wroteAny = true;
1687
- this.writeAsciiQuoted(k);
1688
- this.ensure(1);
1689
- this.json[this.i++] = COLON;
1690
- this.writeValue(15, v, undefined);
1691
- }
1692
- }
1693
- this.ensure(1);
1694
- this.json[this.i++] = CLOSE_BRACE;
1695
- }
1696
- writeList(ns, value, isDocument) {
1697
- const sparse = !!ns.getMergedTraits().sparse;
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;
1710
- for (let i = 0; i < value.length; ++i) {
1711
- const item = value[i];
1712
- if (isDocument ? item === undefined : item == null && !sparse) {
1713
- continue;
1714
- }
1715
- if (wroteFirstItem) {
1716
- this.ensure(1);
1717
- this.json[this.i++] = COMMA;
1718
- }
1719
- this.writeValue(valueSchema, item, undefined);
1720
- wroteFirstItem = true;
1721
- }
1722
- this.ensure(1);
1723
- this.json[this.i++] = CLOSE_BRACKET;
1724
- }
1725
- writeMap(ns, value, isDocument) {
1726
- const sparse = !!ns.getMergedTraits().sparse;
1727
- const valueSchema = ns.getValueSchema();
1728
- if (!isDocument) {
1729
- if (valueSchema.isStringSchema() || valueSchema.isNumericSchema() || valueSchema.isBooleanSchema()) {
1730
- let input = value;
1731
- if (sparse) {
1732
- input = {};
1733
- for (const k in value) {
1734
- if (k === "__proto__") {
1735
- writeKey(input);
1736
- }
1737
- input[k] = value[k] ?? null;
1887
+ const out = Array.isArray(value) ? [] : {};
1888
+ for (const k in value) {
1889
+ const v = value[k];
1890
+ if (k === "__proto__") {
1891
+ writeKey(out);
1892
+ }
1893
+ if (v instanceof NumericValue) {
1894
+ this.useReplacer = true;
1895
+ out[k] = v;
1896
+ }
1897
+ else {
1898
+ out[k] = this._write(ns, v);
1738
1899
  }
1739
1900
  }
1740
- const json = JSON.stringify(input);
1741
- this.ensure(json.length * 3);
1742
- this.i += encoder.encodeInto(json, this.json.subarray(this.i)).written;
1743
- return;
1744
- }
1745
- }
1746
- this.ensure(2);
1747
- this.json[this.i++] = OPEN_BRACE;
1748
- let first = true;
1749
- for (const k in value) {
1750
- const v = value[k];
1751
- if (isDocument ? v === undefined : v == null && !sparse) {
1752
- continue;
1753
- }
1754
- if (!first) {
1755
- this.ensure(1);
1756
- this.json[this.i++] = COMMA;
1757
- }
1758
- first = false;
1759
- this.writeJsonString(k);
1760
- this.ensure(1);
1761
- this.json[this.i++] = COLON;
1762
- this.writeValue(valueSchema, v, undefined);
1763
- }
1764
- this.ensure(1);
1765
- this.json[this.i++] = CLOSE_BRACE;
1766
- }
1767
- writeTimestamp(ns, value) {
1768
- const format = determineTimestampFormat(ns, this.settings);
1769
- switch (format) {
1770
- case 5: {
1771
- const iso = value.toISOString().replace(".000Z", "Z");
1772
- this.writeAsciiQuoted(iso);
1773
- return;
1774
- }
1775
- case 6: {
1776
- this.writeAsciiQuoted(dateToUtcString(value));
1777
- return;
1778
- }
1779
- case 7: {
1780
- const epochSecs = String(value.getTime() / 1000);
1781
- this.writeAscii(epochSecs);
1782
- return;
1901
+ return out;
1783
1902
  }
1784
- default: {
1785
- const epochSecs = String(value.getTime() / 1000);
1786
- this.writeAscii(epochSecs);
1787
- return;
1903
+ else {
1904
+ return structuredClone(value);
1788
1905
  }
1789
1906
  }
1907
+ return value;
1790
1908
  }
1791
1909
  }
1792
1910
 
1793
- class JsonCodec2 extends SerdeContextConfig {
1911
+ class JsonCodec extends SerdeContextConfig {
1794
1912
  settings;
1795
1913
  constructor(settings) {
1796
1914
  super();
1797
1915
  this.settings = settings;
1798
1916
  }
1799
1917
  createSerializer() {
1800
- const serializer = new JsonShapeSerializer2(this.settings);
1918
+ const serializer = new JsonShapeSerializer(this.settings);
1801
1919
  serializer.setSerdeContext(this.serdeContext);
1802
1920
  return serializer;
1803
1921
  }
1804
1922
  createDeserializer() {
1805
- const deserializer = new JsonShapeDeserializer2(this.settings);
1923
+ const deserializer = new JsonShapeDeserializer(this.settings);
1806
1924
  deserializer.setSerdeContext(this.serdeContext);
1807
1925
  return deserializer;
1808
1926
  }