mirror of
				https://github.com/Theodor-Springmann-Stiftung/kgpz_web.git
				synced 2025-10-30 17:45:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			148 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| var stringifyCollection = require('../stringify/stringifyCollection.js');
 | |
| var addPairToJSMap = require('./addPairToJSMap.js');
 | |
| var Collection = require('./Collection.js');
 | |
| var identity = require('./identity.js');
 | |
| var Pair = require('./Pair.js');
 | |
| var Scalar = require('./Scalar.js');
 | |
| 
 | |
| function findPair(items, key) {
 | |
|     const k = identity.isScalar(key) ? key.value : key;
 | |
|     for (const it of items) {
 | |
|         if (identity.isPair(it)) {
 | |
|             if (it.key === key || it.key === k)
 | |
|                 return it;
 | |
|             if (identity.isScalar(it.key) && it.key.value === k)
 | |
|                 return it;
 | |
|         }
 | |
|     }
 | |
|     return undefined;
 | |
| }
 | |
| class YAMLMap extends Collection.Collection {
 | |
|     static get tagName() {
 | |
|         return 'tag:yaml.org,2002:map';
 | |
|     }
 | |
|     constructor(schema) {
 | |
|         super(identity.MAP, schema);
 | |
|         this.items = [];
 | |
|     }
 | |
|     /**
 | |
|      * A generic collection parsing method that can be extended
 | |
|      * to other node classes that inherit from YAMLMap
 | |
|      */
 | |
|     static from(schema, obj, ctx) {
 | |
|         const { keepUndefined, replacer } = ctx;
 | |
|         const map = new this(schema);
 | |
|         const add = (key, value) => {
 | |
|             if (typeof replacer === 'function')
 | |
|                 value = replacer.call(obj, key, value);
 | |
|             else if (Array.isArray(replacer) && !replacer.includes(key))
 | |
|                 return;
 | |
|             if (value !== undefined || keepUndefined)
 | |
|                 map.items.push(Pair.createPair(key, value, ctx));
 | |
|         };
 | |
|         if (obj instanceof Map) {
 | |
|             for (const [key, value] of obj)
 | |
|                 add(key, value);
 | |
|         }
 | |
|         else if (obj && typeof obj === 'object') {
 | |
|             for (const key of Object.keys(obj))
 | |
|                 add(key, obj[key]);
 | |
|         }
 | |
|         if (typeof schema.sortMapEntries === 'function') {
 | |
|             map.items.sort(schema.sortMapEntries);
 | |
|         }
 | |
|         return map;
 | |
|     }
 | |
|     /**
 | |
|      * Adds a value to the collection.
 | |
|      *
 | |
|      * @param overwrite - If not set `true`, using a key that is already in the
 | |
|      *   collection will throw. Otherwise, overwrites the previous value.
 | |
|      */
 | |
|     add(pair, overwrite) {
 | |
|         let _pair;
 | |
|         if (identity.isPair(pair))
 | |
|             _pair = pair;
 | |
|         else if (!pair || typeof pair !== 'object' || !('key' in pair)) {
 | |
|             // In TypeScript, this never happens.
 | |
|             _pair = new Pair.Pair(pair, pair?.value);
 | |
|         }
 | |
|         else
 | |
|             _pair = new Pair.Pair(pair.key, pair.value);
 | |
|         const prev = findPair(this.items, _pair.key);
 | |
|         const sortEntries = this.schema?.sortMapEntries;
 | |
|         if (prev) {
 | |
|             if (!overwrite)
 | |
|                 throw new Error(`Key ${_pair.key} already set`);
 | |
|             // For scalars, keep the old node & its comments and anchors
 | |
|             if (identity.isScalar(prev.value) && Scalar.isScalarValue(_pair.value))
 | |
|                 prev.value.value = _pair.value;
 | |
|             else
 | |
|                 prev.value = _pair.value;
 | |
|         }
 | |
|         else if (sortEntries) {
 | |
|             const i = this.items.findIndex(item => sortEntries(_pair, item) < 0);
 | |
|             if (i === -1)
 | |
|                 this.items.push(_pair);
 | |
|             else
 | |
|                 this.items.splice(i, 0, _pair);
 | |
|         }
 | |
|         else {
 | |
|             this.items.push(_pair);
 | |
|         }
 | |
|     }
 | |
|     delete(key) {
 | |
|         const it = findPair(this.items, key);
 | |
|         if (!it)
 | |
|             return false;
 | |
|         const del = this.items.splice(this.items.indexOf(it), 1);
 | |
|         return del.length > 0;
 | |
|     }
 | |
|     get(key, keepScalar) {
 | |
|         const it = findPair(this.items, key);
 | |
|         const node = it?.value;
 | |
|         return (!keepScalar && identity.isScalar(node) ? node.value : node) ?? undefined;
 | |
|     }
 | |
|     has(key) {
 | |
|         return !!findPair(this.items, key);
 | |
|     }
 | |
|     set(key, value) {
 | |
|         this.add(new Pair.Pair(key, value), true);
 | |
|     }
 | |
|     /**
 | |
|      * @param ctx - Conversion context, originally set in Document#toJS()
 | |
|      * @param {Class} Type - If set, forces the returned collection type
 | |
|      * @returns Instance of Type, Map, or Object
 | |
|      */
 | |
|     toJSON(_, ctx, Type) {
 | |
|         const map = Type ? new Type() : ctx?.mapAsMap ? new Map() : {};
 | |
|         if (ctx?.onCreate)
 | |
|             ctx.onCreate(map);
 | |
|         for (const item of this.items)
 | |
|             addPairToJSMap.addPairToJSMap(ctx, map, item);
 | |
|         return map;
 | |
|     }
 | |
|     toString(ctx, onComment, onChompKeep) {
 | |
|         if (!ctx)
 | |
|             return JSON.stringify(this);
 | |
|         for (const item of this.items) {
 | |
|             if (!identity.isPair(item))
 | |
|                 throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`);
 | |
|         }
 | |
|         if (!ctx.allNullValues && this.hasAllNullValues(false))
 | |
|             ctx = Object.assign({}, ctx, { allNullValues: true });
 | |
|         return stringifyCollection.stringifyCollection(this, ctx, {
 | |
|             blockItemPrefix: '',
 | |
|             flowChars: { start: '{', end: '}' },
 | |
|             itemIndent: ctx.indent || '',
 | |
|             onChompKeep,
 | |
|             onComment
 | |
|         });
 | |
|     }
 | |
| }
 | |
| 
 | |
| exports.YAMLMap = YAMLMap;
 | |
| exports.findPair = findPair;
 | 
