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