fast-json-stringify 4.0.0 → 5.0.0

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/test/ref.test.js CHANGED
@@ -431,10 +431,215 @@ test('ref external - plain name fragment', (t) => {
431
431
  type: 'object',
432
432
  properties: {
433
433
  first: {
434
- $ref: '#first-schema'
434
+ $ref: 'first#first-schema'
435
435
  },
436
436
  second: {
437
- $ref: '#second-schema'
437
+ $ref: 'second#second-schema'
438
+ }
439
+ }
440
+ }
441
+
442
+ const object = {
443
+ first: {
444
+ str: 'test'
445
+ },
446
+ second: {
447
+ int: 42
448
+ }
449
+ }
450
+
451
+ const stringify = build(schema, { schema: externalSchema })
452
+ const output = stringify(object)
453
+
454
+ JSON.parse(output)
455
+ t.pass()
456
+
457
+ t.equal(output, '{"first":{"str":"test"},"second":{"int":42}}')
458
+ })
459
+
460
+ test('external reference to $id', (t) => {
461
+ t.plan(2)
462
+
463
+ const externalSchema = {
464
+ first: {
465
+ $id: 'external-reference',
466
+ type: 'object',
467
+ properties: {
468
+ str: {
469
+ type: 'string'
470
+ }
471
+ }
472
+ }
473
+ }
474
+
475
+ const schema = {
476
+ type: 'object',
477
+ properties: {
478
+ first: {
479
+ $ref: 'external-reference'
480
+ }
481
+ }
482
+ }
483
+
484
+ const object = { first: { str: 'test' } }
485
+
486
+ const stringify = build(schema, { schema: externalSchema })
487
+ const output = stringify(object)
488
+
489
+ JSON.parse(output)
490
+ t.pass()
491
+
492
+ t.equal(output, '{"first":{"str":"test"}}')
493
+ })
494
+
495
+ test('external reference to key#id', (t) => {
496
+ t.plan(2)
497
+
498
+ const externalSchema = {
499
+ first: {
500
+ $id: '#external-reference',
501
+ type: 'object',
502
+ properties: {
503
+ str: {
504
+ type: 'string'
505
+ }
506
+ }
507
+ }
508
+ }
509
+
510
+ const schema = {
511
+ type: 'object',
512
+ properties: {
513
+ first: {
514
+ $ref: 'first#external-reference'
515
+ }
516
+ }
517
+ }
518
+
519
+ const object = { first: { str: 'test' } }
520
+
521
+ const stringify = build(schema, { schema: externalSchema })
522
+ const output = stringify(object)
523
+
524
+ JSON.parse(output)
525
+ t.pass()
526
+
527
+ t.equal(output, '{"first":{"str":"test"}}')
528
+ })
529
+
530
+ test('external and inner reference', (t) => {
531
+ t.plan(2)
532
+
533
+ const externalSchema = {
534
+ first: {
535
+ $id: 'reference',
536
+ $ref: '#reference',
537
+ definitions: {
538
+ inner: {
539
+ $id: '#reference',
540
+ type: 'object',
541
+ properties: {
542
+ str: {
543
+ type: 'string'
544
+ }
545
+ }
546
+ }
547
+ }
548
+ }
549
+ }
550
+
551
+ const schema = {
552
+ type: 'object',
553
+ properties: {
554
+ first: {
555
+ $ref: 'reference'
556
+ }
557
+ }
558
+ }
559
+
560
+ const object = { first: { str: 'test' } }
561
+
562
+ const stringify = build(schema, { schema: externalSchema })
563
+ const output = stringify(object)
564
+
565
+ JSON.parse(output)
566
+ t.pass()
567
+
568
+ t.equal(output, '{"first":{"str":"test"}}')
569
+ })
570
+
571
+ test('external reference to key', (t) => {
572
+ t.plan(2)
573
+
574
+ const externalSchema = {
575
+ first: {
576
+ $id: 'external-reference',
577
+ type: 'object',
578
+ properties: {
579
+ str: {
580
+ type: 'string'
581
+ }
582
+ }
583
+ }
584
+ }
585
+
586
+ const schema = {
587
+ type: 'object',
588
+ properties: {
589
+ first: {
590
+ $ref: 'external-reference'
591
+ }
592
+ }
593
+ }
594
+
595
+ const object = { first: { str: 'test' } }
596
+
597
+ const stringify = build(schema, { schema: externalSchema })
598
+ const output = stringify(object)
599
+
600
+ JSON.parse(output)
601
+ t.pass()
602
+
603
+ t.equal(output, '{"first":{"str":"test"}}')
604
+ })
605
+
606
+ test('ref external - plain name fragment', (t) => {
607
+ t.plan(2)
608
+
609
+ const externalSchema = {
610
+ first: {
611
+ $id: 'first-schema',
612
+ type: 'object',
613
+ properties: {
614
+ str: {
615
+ type: 'string'
616
+ }
617
+ }
618
+ },
619
+ second: {
620
+ definitions: {
621
+ second: {
622
+ $id: 'second-schema',
623
+ type: 'object',
624
+ properties: {
625
+ int: {
626
+ type: 'integer'
627
+ }
628
+ }
629
+ }
630
+ }
631
+ }
632
+ }
633
+
634
+ const schema = {
635
+ title: 'object with $ref to external plain name fragment',
636
+ type: 'object',
637
+ properties: {
638
+ first: {
639
+ $ref: 'first-schema'
640
+ },
641
+ second: {
642
+ $ref: 'second-schema'
438
643
  }
439
644
  }
440
645
  }
@@ -503,7 +708,7 @@ test('ref external - duplicate plain name fragment', (t) => {
503
708
  $ref: 'external#duplicateSchema'
504
709
  },
505
710
  other: {
506
- $ref: '#otherSchema'
711
+ $ref: 'other#otherSchema'
507
712
  }
508
713
  }
509
714
  }
@@ -893,7 +1098,7 @@ test('ref in root external multiple times', (t) => {
893
1098
  const schema = {
894
1099
  title: 'object with $ref in root schema',
895
1100
  type: 'object',
896
- $ref: 'numbers#/definitions/num'
1101
+ $ref: 'numbers'
897
1102
  }
898
1103
 
899
1104
  const object = { int: 42 }
@@ -978,32 +1183,6 @@ test('ref to nested ref definition', (t) => {
978
1183
  t.equal(output, '{"foo":"foo"}')
979
1184
  })
980
1185
 
981
- test('ref in definition with exact match', (t) => {
982
- t.plan(2)
983
-
984
- const externalSchema = {
985
- '#/definitions/foo': {
986
- type: 'string'
987
- }
988
- }
989
-
990
- const schema = {
991
- type: 'object',
992
- properties: {
993
- foo: { $ref: '#/definitions/foo' }
994
- }
995
- }
996
-
997
- const object = { foo: 'foo' }
998
- const stringify = build(schema, { schema: externalSchema })
999
- const output = stringify(object)
1000
-
1001
- JSON.parse(output)
1002
- t.pass()
1003
-
1004
- t.equal(output, '{"foo":"foo"}')
1005
- })
1006
-
1007
1186
  test('Bad key', t => {
1008
1187
  t.test('Find match', t => {
1009
1188
  t.plan(1)
@@ -1026,7 +1205,7 @@ test('Bad key', t => {
1026
1205
  })
1027
1206
  t.fail('Should throw')
1028
1207
  } catch (err) {
1029
- t.equal(err.message, 'Cannot find reference "porjectId", did you mean "projectId"?')
1208
+ t.equal(err.message, 'Cannot find reference "#/definitions/porjectId"')
1030
1209
  }
1031
1210
  })
1032
1211
 
@@ -1051,7 +1230,7 @@ test('Bad key', t => {
1051
1230
  })
1052
1231
  t.fail('Should throw')
1053
1232
  } catch (err) {
1054
- t.equal(err.message, 'Cannot find reference "foobar"')
1233
+ t.equal(err.message, 'Cannot find reference "#/definitions/foobar"')
1055
1234
  }
1056
1235
  })
1057
1236
 
@@ -1081,7 +1260,7 @@ test('Bad key', t => {
1081
1260
  })
1082
1261
  t.fail('Should throw')
1083
1262
  } catch (err) {
1084
- t.equal(err.message, 'Cannot find reference "porjectId", did you mean "projectId"?')
1263
+ t.equal(err.message, 'Cannot find reference "external#/definitions/porjectId"')
1085
1264
  }
1086
1265
  })
1087
1266
 
@@ -1111,7 +1290,7 @@ test('Bad key', t => {
1111
1290
  })
1112
1291
  t.fail('Should throw')
1113
1292
  } catch (err) {
1114
- t.equal(err.message, 'Cannot find reference "foobar"')
1293
+ t.equal(err.message, 'Cannot find reference "external#/definitions/foobar"')
1115
1294
  }
1116
1295
  })
1117
1296
 
@@ -1141,7 +1320,7 @@ test('Bad key', t => {
1141
1320
  })
1142
1321
  t.fail('Should throw')
1143
1322
  } catch (err) {
1144
- t.equal(err.message, 'Cannot find reference "deifnitions", did you mean "definitions"?')
1323
+ t.equal(err.message, 'Cannot find reference "external#/deifnitions/projectId"')
1145
1324
  }
1146
1325
  })
1147
1326
 
@@ -1166,7 +1345,7 @@ test('Bad key', t => {
1166
1345
  })
1167
1346
  t.fail('Should throw')
1168
1347
  } catch (err) {
1169
- t.equal(err.message, 'Cannot find reference "deifnitions", did you mean "definitions"?')
1348
+ t.equal(err.message, 'Cannot find reference "#/deifnitions/projectId"')
1170
1349
  }
1171
1350
  })
1172
1351
 
@@ -1196,7 +1375,7 @@ test('Bad key', t => {
1196
1375
  })
1197
1376
  t.fail('Should throw')
1198
1377
  } catch (err) {
1199
- t.equal(err.message, 'Cannot find reference "extrenal", did you mean "external"?')
1378
+ t.equal(err.message, 'Cannot find reference "extrenal#/definitions/projectId"')
1200
1379
  }
1201
1380
  })
1202
1381
 
@@ -1249,3 +1428,397 @@ test('Regression 2.5.2', t => {
1249
1428
 
1250
1429
  t.equal(output, '[{"field":"parent","sub":{"field":"joined"}}]')
1251
1430
  })
1431
+
1432
+ test('Reference through multiple definitions', (t) => {
1433
+ t.plan(2)
1434
+
1435
+ const schema = {
1436
+ $ref: '#/definitions/A',
1437
+ definitions: {
1438
+ A: {
1439
+ type: 'object',
1440
+ additionalProperties: false,
1441
+ properties: { a: { anyOf: [{ $ref: '#/definitions/B' }] } },
1442
+ required: ['a']
1443
+ },
1444
+ B: {
1445
+ type: 'object',
1446
+ properties: { b: { anyOf: [{ $ref: '#/definitions/C' }] } },
1447
+ required: ['b'],
1448
+ additionalProperties: false
1449
+ },
1450
+ C: {
1451
+ type: 'object',
1452
+ properties: { c: { type: 'string', const: 'd' } },
1453
+ required: ['c'],
1454
+ additionalProperties: false
1455
+ }
1456
+ }
1457
+ }
1458
+
1459
+ const object = { a: { b: { c: 'd' } } }
1460
+
1461
+ const stringify = build(schema)
1462
+ const output = stringify(object)
1463
+
1464
+ JSON.parse(output)
1465
+ t.pass()
1466
+
1467
+ t.equal(output, JSON.stringify(object))
1468
+ })
1469
+
1470
+ test('issue #350', (t) => {
1471
+ t.plan(2)
1472
+
1473
+ const schema = {
1474
+ title: 'Example Schema',
1475
+ type: 'object',
1476
+ properties: {
1477
+ firstName: { $ref: '#foo' },
1478
+ lastName: { $ref: '#foo' },
1479
+ nested: {
1480
+ type: 'object',
1481
+ properties: {
1482
+ firstName: { $ref: '#foo' },
1483
+ lastName: { $ref: '#foo' }
1484
+ }
1485
+ }
1486
+ },
1487
+ definitions: {
1488
+ foo: {
1489
+ $id: '#foo',
1490
+ type: 'string'
1491
+ }
1492
+ }
1493
+ }
1494
+
1495
+ const object = {
1496
+ firstName: 'Matteo',
1497
+ lastName: 'Collina',
1498
+ nested: {
1499
+ firstName: 'Matteo',
1500
+ lastName: 'Collina'
1501
+ }
1502
+ }
1503
+
1504
+ const stringify = build(schema)
1505
+ const output = stringify(object)
1506
+
1507
+ JSON.parse(output)
1508
+ t.pass()
1509
+
1510
+ t.equal(output, JSON.stringify(object))
1511
+ })
1512
+
1513
+ test('deep union type', (t) => {
1514
+ t.plan(1)
1515
+
1516
+ const stringify = build({
1517
+ schema: {
1518
+ type: 'array',
1519
+ items: {
1520
+ oneOf: [
1521
+ {
1522
+ $ref: 'components#/schemas/IDirectory'
1523
+ },
1524
+ {
1525
+ $ref: 'components#/schemas/IImageFile'
1526
+ },
1527
+ {
1528
+ $ref: 'components#/schemas/ITextFile'
1529
+ },
1530
+ {
1531
+ $ref: 'components#/schemas/IZipFile'
1532
+ }
1533
+ ]
1534
+ },
1535
+ nullable: false
1536
+ },
1537
+ components: {
1538
+ schemas: {
1539
+ IDirectory: {
1540
+ $id: 'IDirectory',
1541
+ $recursiveAnchor: true,
1542
+ type: 'object',
1543
+ properties: {
1544
+ children: {
1545
+ type: 'array',
1546
+ items: {
1547
+ oneOf: [
1548
+ {
1549
+ $recursiveRef: '#'
1550
+ },
1551
+ {
1552
+ $ref: 'components#/schemas/IImageFile'
1553
+ },
1554
+ {
1555
+ $ref: 'components#/schemas/ITextFile'
1556
+ },
1557
+ {
1558
+ $ref: 'components#/schemas/IZipFile'
1559
+ }
1560
+ ]
1561
+ },
1562
+ nullable: false
1563
+ },
1564
+ type: {
1565
+ type: 'string',
1566
+ nullable: false
1567
+ },
1568
+ id: {
1569
+ type: 'string',
1570
+ nullable: false
1571
+ },
1572
+ name: {
1573
+ type: 'string',
1574
+ nullable: false
1575
+ }
1576
+ },
1577
+ nullable: false,
1578
+ required: [
1579
+ 'children',
1580
+ 'type',
1581
+ 'id',
1582
+ 'name'
1583
+ ]
1584
+ },
1585
+ IImageFile: {
1586
+ $id: 'IImageFile',
1587
+ type: 'object',
1588
+ properties: {
1589
+ width: {
1590
+ type: 'number',
1591
+ nullable: false
1592
+ },
1593
+ height: {
1594
+ type: 'number',
1595
+ nullable: false
1596
+ },
1597
+ url: {
1598
+ type: 'string',
1599
+ nullable: false
1600
+ },
1601
+ extension: {
1602
+ type: 'string',
1603
+ nullable: false
1604
+ },
1605
+ size: {
1606
+ type: 'number',
1607
+ nullable: false
1608
+ },
1609
+ type: {
1610
+ type: 'string',
1611
+ nullable: false
1612
+ },
1613
+ id: {
1614
+ type: 'string',
1615
+ nullable: false
1616
+ },
1617
+ name: {
1618
+ type: 'string',
1619
+ nullable: false
1620
+ }
1621
+ },
1622
+ nullable: false,
1623
+ required: [
1624
+ 'width',
1625
+ 'height',
1626
+ 'url',
1627
+ 'extension',
1628
+ 'size',
1629
+ 'type',
1630
+ 'id',
1631
+ 'name'
1632
+ ]
1633
+ },
1634
+ ITextFile: {
1635
+ $id: 'ITextFile',
1636
+ type: 'object',
1637
+ properties: {
1638
+ content: {
1639
+ type: 'string',
1640
+ nullable: false
1641
+ },
1642
+ extension: {
1643
+ type: 'string',
1644
+ nullable: false
1645
+ },
1646
+ size: {
1647
+ type: 'number',
1648
+ nullable: false
1649
+ },
1650
+ type: {
1651
+ type: 'string',
1652
+ nullable: false
1653
+ },
1654
+ id: {
1655
+ type: 'string',
1656
+ nullable: false
1657
+ },
1658
+ name: {
1659
+ type: 'string',
1660
+ nullable: false
1661
+ }
1662
+ },
1663
+ nullable: false,
1664
+ required: [
1665
+ 'content',
1666
+ 'extension',
1667
+ 'size',
1668
+ 'type',
1669
+ 'id',
1670
+ 'name'
1671
+ ]
1672
+ },
1673
+ IZipFile: {
1674
+ $id: 'IZipFile',
1675
+ type: 'object',
1676
+ properties: {
1677
+ files: {
1678
+ type: 'number',
1679
+ nullable: false
1680
+ },
1681
+ extension: {
1682
+ type: 'string',
1683
+ nullable: false
1684
+ },
1685
+ size: {
1686
+ type: 'number',
1687
+ nullable: false
1688
+ },
1689
+ type: {
1690
+ type: 'string',
1691
+ nullable: false
1692
+ },
1693
+ id: {
1694
+ type: 'string',
1695
+ nullable: false
1696
+ },
1697
+ name: {
1698
+ type: 'string',
1699
+ nullable: false
1700
+ }
1701
+ },
1702
+ nullable: false,
1703
+ required: [
1704
+ 'files',
1705
+ 'extension',
1706
+ 'size',
1707
+ 'type',
1708
+ 'id',
1709
+ 'name'
1710
+ ]
1711
+ }
1712
+ }
1713
+ }
1714
+ })
1715
+
1716
+ const obj = [
1717
+ {
1718
+ type: 'directory',
1719
+ id: '7b1068a4-dd6e-474a-8d85-09a2d77639cb',
1720
+ name: 'ixcWGOKI',
1721
+ children: [
1722
+ {
1723
+ type: 'directory',
1724
+ id: '5883e17c-b207-46d4-ad2d-be72249711ce',
1725
+ name: 'vecQwFGS',
1726
+ children: []
1727
+ },
1728
+ {
1729
+ type: 'file',
1730
+ id: '670b6556-a610-4a48-8a16-9c2da97a0d18',
1731
+ name: 'eStFddzX',
1732
+ extension: 'jpg',
1733
+ size: 7,
1734
+ width: 300,
1735
+ height: 1200,
1736
+ url: 'https://github.com/samchon/typescript-json'
1737
+ },
1738
+ {
1739
+ type: 'file',
1740
+ id: '85dc796d-9593-4833-b1a1-addc8ebf74ea',
1741
+ name: 'kTdUfwRJ',
1742
+ extension: 'ts',
1743
+ size: 86,
1744
+ content: 'console.log("Hello world");'
1745
+ },
1746
+ {
1747
+ type: 'file',
1748
+ id: '8933c86a-7a1e-4d4a-b0a6-17d6896fdf89',
1749
+ name: 'NBPkefUG',
1750
+ extension: 'zip',
1751
+ size: 22,
1752
+ files: 20
1753
+ }
1754
+ ]
1755
+ }
1756
+ ]
1757
+ t.equal(JSON.stringify(obj), stringify(obj))
1758
+ })
1759
+
1760
+ test('ref with same id in properties', (t) => {
1761
+ t.plan(2)
1762
+
1763
+ const externalSchema = {
1764
+ ObjectId: {
1765
+ $id: 'ObjectId',
1766
+ type: 'string'
1767
+ },
1768
+ File: {
1769
+ $id: 'File',
1770
+ type: 'object',
1771
+ properties: {
1772
+ _id: { $ref: 'ObjectId' },
1773
+ name: { type: 'string' },
1774
+ owner: { $ref: 'ObjectId' }
1775
+ }
1776
+ }
1777
+ }
1778
+
1779
+ t.test('anyOf', (t) => {
1780
+ t.plan(1)
1781
+
1782
+ const schema = {
1783
+ $id: 'Article',
1784
+ type: 'object',
1785
+ properties: {
1786
+ _id: { $ref: 'ObjectId' },
1787
+ image: {
1788
+ anyOf: [
1789
+ { $ref: 'File' },
1790
+ { type: 'null' }
1791
+ ]
1792
+ }
1793
+ }
1794
+ }
1795
+
1796
+ const stringify = build(schema, { schema: externalSchema })
1797
+ const output = stringify({ _id: 'foo', image: { _id: 'bar', name: 'hello', owner: 'baz' } })
1798
+
1799
+ t.equal(output, '{"_id":"foo","image":{"_id":"bar","name":"hello","owner":"baz"}}')
1800
+ })
1801
+
1802
+ t.test('oneOf', (t) => {
1803
+ t.plan(1)
1804
+
1805
+ const schema = {
1806
+ $id: 'Article',
1807
+ type: 'object',
1808
+ properties: {
1809
+ _id: { $ref: 'ObjectId' },
1810
+ image: {
1811
+ oneOf: [
1812
+ { $ref: 'File' },
1813
+ { type: 'null' }
1814
+ ]
1815
+ }
1816
+ }
1817
+ }
1818
+
1819
+ const stringify = build(schema, { schema: externalSchema })
1820
+ const output = stringify({ _id: 'foo', image: { _id: 'bar', name: 'hello', owner: 'baz' } })
1821
+
1822
+ t.equal(output, '{"_id":"foo","image":{"_id":"bar","name":"hello","owner":"baz"}}')
1823
+ })
1824
+ })