Brak opisu

YAMLSeq.js 2.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import { stringifyCollection } from '../stringify/stringifyCollection.js';
  2. import { Collection } from './Collection.js';
  3. import { SEQ, isScalar } from './Node.js';
  4. import { isScalarValue } from './Scalar.js';
  5. import { toJS } from './toJS.js';
  6. class YAMLSeq extends Collection {
  7. static get tagName() {
  8. return 'tag:yaml.org,2002:seq';
  9. }
  10. constructor(schema) {
  11. super(SEQ, schema);
  12. this.items = [];
  13. }
  14. add(value) {
  15. this.items.push(value);
  16. }
  17. /**
  18. * Removes a value from the collection.
  19. *
  20. * `key` must contain a representation of an integer for this to succeed.
  21. * It may be wrapped in a `Scalar`.
  22. *
  23. * @returns `true` if the item was found and removed.
  24. */
  25. delete(key) {
  26. const idx = asItemIndex(key);
  27. if (typeof idx !== 'number')
  28. return false;
  29. const del = this.items.splice(idx, 1);
  30. return del.length > 0;
  31. }
  32. get(key, keepScalar) {
  33. const idx = asItemIndex(key);
  34. if (typeof idx !== 'number')
  35. return undefined;
  36. const it = this.items[idx];
  37. return !keepScalar && isScalar(it) ? it.value : it;
  38. }
  39. /**
  40. * Checks if the collection includes a value with the key `key`.
  41. *
  42. * `key` must contain a representation of an integer for this to succeed.
  43. * It may be wrapped in a `Scalar`.
  44. */
  45. has(key) {
  46. const idx = asItemIndex(key);
  47. return typeof idx === 'number' && idx < this.items.length;
  48. }
  49. /**
  50. * Sets a value in this collection. For `!!set`, `value` needs to be a
  51. * boolean to add/remove the item from the set.
  52. *
  53. * If `key` does not contain a representation of an integer, this will throw.
  54. * It may be wrapped in a `Scalar`.
  55. */
  56. set(key, value) {
  57. const idx = asItemIndex(key);
  58. if (typeof idx !== 'number')
  59. throw new Error(`Expected a valid index, not ${key}.`);
  60. const prev = this.items[idx];
  61. if (isScalar(prev) && isScalarValue(value))
  62. prev.value = value;
  63. else
  64. this.items[idx] = value;
  65. }
  66. toJSON(_, ctx) {
  67. const seq = [];
  68. if (ctx?.onCreate)
  69. ctx.onCreate(seq);
  70. let i = 0;
  71. for (const item of this.items)
  72. seq.push(toJS(item, String(i++), ctx));
  73. return seq;
  74. }
  75. toString(ctx, onComment, onChompKeep) {
  76. if (!ctx)
  77. return JSON.stringify(this);
  78. return stringifyCollection(this, ctx, {
  79. blockItemPrefix: '- ',
  80. flowChars: { start: '[', end: ']' },
  81. itemIndent: (ctx.indent || '') + ' ',
  82. onChompKeep,
  83. onComment
  84. });
  85. }
  86. }
  87. function asItemIndex(key) {
  88. let idx = isScalar(key) ? key.value : key;
  89. if (idx && typeof idx === 'string')
  90. idx = Number(idx);
  91. return typeof idx === 'number' && Number.isInteger(idx) && idx >= 0
  92. ? idx
  93. : null;
  94. }
  95. export { YAMLSeq };