No Description

YAMLMap.js 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. 'use strict';
  2. var stringifyCollection = require('../stringify/stringifyCollection.js');
  3. var addPairToJSMap = require('./addPairToJSMap.js');
  4. var Collection = require('./Collection.js');
  5. var Node = require('./Node.js');
  6. var Pair = require('./Pair.js');
  7. var Scalar = require('./Scalar.js');
  8. function findPair(items, key) {
  9. const k = Node.isScalar(key) ? key.value : key;
  10. for (const it of items) {
  11. if (Node.isPair(it)) {
  12. if (it.key === key || it.key === k)
  13. return it;
  14. if (Node.isScalar(it.key) && it.key.value === k)
  15. return it;
  16. }
  17. }
  18. return undefined;
  19. }
  20. class YAMLMap extends Collection.Collection {
  21. static get tagName() {
  22. return 'tag:yaml.org,2002:map';
  23. }
  24. constructor(schema) {
  25. super(Node.MAP, schema);
  26. this.items = [];
  27. }
  28. /**
  29. * Adds a value to the collection.
  30. *
  31. * @param overwrite - If not set `true`, using a key that is already in the
  32. * collection will throw. Otherwise, overwrites the previous value.
  33. */
  34. add(pair, overwrite) {
  35. let _pair;
  36. if (Node.isPair(pair))
  37. _pair = pair;
  38. else if (!pair || typeof pair !== 'object' || !('key' in pair)) {
  39. // In TypeScript, this never happens.
  40. _pair = new Pair.Pair(pair, pair?.value);
  41. }
  42. else
  43. _pair = new Pair.Pair(pair.key, pair.value);
  44. const prev = findPair(this.items, _pair.key);
  45. const sortEntries = this.schema?.sortMapEntries;
  46. if (prev) {
  47. if (!overwrite)
  48. throw new Error(`Key ${_pair.key} already set`);
  49. // For scalars, keep the old node & its comments and anchors
  50. if (Node.isScalar(prev.value) && Scalar.isScalarValue(_pair.value))
  51. prev.value.value = _pair.value;
  52. else
  53. prev.value = _pair.value;
  54. }
  55. else if (sortEntries) {
  56. const i = this.items.findIndex(item => sortEntries(_pair, item) < 0);
  57. if (i === -1)
  58. this.items.push(_pair);
  59. else
  60. this.items.splice(i, 0, _pair);
  61. }
  62. else {
  63. this.items.push(_pair);
  64. }
  65. }
  66. delete(key) {
  67. const it = findPair(this.items, key);
  68. if (!it)
  69. return false;
  70. const del = this.items.splice(this.items.indexOf(it), 1);
  71. return del.length > 0;
  72. }
  73. get(key, keepScalar) {
  74. const it = findPair(this.items, key);
  75. const node = it?.value;
  76. return (!keepScalar && Node.isScalar(node) ? node.value : node) ?? undefined;
  77. }
  78. has(key) {
  79. return !!findPair(this.items, key);
  80. }
  81. set(key, value) {
  82. this.add(new Pair.Pair(key, value), true);
  83. }
  84. /**
  85. * @param ctx - Conversion context, originally set in Document#toJS()
  86. * @param {Class} Type - If set, forces the returned collection type
  87. * @returns Instance of Type, Map, or Object
  88. */
  89. toJSON(_, ctx, Type) {
  90. const map = Type ? new Type() : ctx?.mapAsMap ? new Map() : {};
  91. if (ctx?.onCreate)
  92. ctx.onCreate(map);
  93. for (const item of this.items)
  94. addPairToJSMap.addPairToJSMap(ctx, map, item);
  95. return map;
  96. }
  97. toString(ctx, onComment, onChompKeep) {
  98. if (!ctx)
  99. return JSON.stringify(this);
  100. for (const item of this.items) {
  101. if (!Node.isPair(item))
  102. throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`);
  103. }
  104. if (!ctx.allNullValues && this.hasAllNullValues(false))
  105. ctx = Object.assign({}, ctx, { allNullValues: true });
  106. return stringifyCollection.stringifyCollection(this, ctx, {
  107. blockItemPrefix: '',
  108. flowChars: { start: '{', end: '}' },
  109. itemIndent: ctx.indent || '',
  110. onChompKeep,
  111. onComment
  112. });
  113. }
  114. }
  115. exports.YAMLMap = YAMLMap;
  116. exports.findPair = findPair;