import { PropertiesBuilder } from './PropertiesBuilder'; import { PropertyOperation } from './PropertyOperation'; export class PropertyOperationsBuilder { private operations: Map = new Map(); set(key: string, value: any): PropertyOperationsBuilder { return this.add(PropertyOperation.SET, key, value); } setOnce(key: string, value: any): PropertyOperationsBuilder { return this.add(PropertyOperation.SET_ONCE, key, value); } unset(key: string): PropertyOperationsBuilder { return this.add(PropertyOperation.UNSET, key, '-'); } increment(key: string, value: any): PropertyOperationsBuilder { return this.add(PropertyOperation.INCREMENT, key, value); } append(key: string, value: any): PropertyOperationsBuilder { return this.add(PropertyOperation.APPEND, key, value); } appendOnce(key: string, value: any): PropertyOperationsBuilder { return this.add(PropertyOperation.APPEND_ONCE, key, value); } prepend(key: string, value: any): PropertyOperationsBuilder { return this.add(PropertyOperation.PREPEND, key, value); } prependOnce(key: string, value: any): PropertyOperationsBuilder { return this.add(PropertyOperation.PREPEND_ONCE, key, value); } remove(key: string, value: any): PropertyOperationsBuilder { return this.add(PropertyOperation.REMOVE, key, value); } clearAll(): PropertyOperationsBuilder { return this.add(PropertyOperation.CLEAR_ALL, 'clearAll', '-'); } build(): PropertyOperations { const builderPropertyOperation = Array.from(this.operations.entries()).map< [PropertyOperation, Map] >(([operation, builder]) => [operation, builder.build()]); return new PropertyOperations(new Map(builderPropertyOperation)); } private containsKey(key: string) { return Array.from(this.operations.entries()).some(([_operation, builder]) => builder.contains(key) ); } private add( operation: PropertyOperation, key: string, value: any ): PropertyOperationsBuilder { if (this.containsKey(key)) return this; if (!this.operations.has(operation)) { this.operations.set(operation, new PropertiesBuilder()); } const _builder = this.operations.get(operation); _builder?.add(key, value); return this; } } type PropertyOperationsRecord = Map>; export class PropertyOperations { private _operations: PropertyOperationsRecord; constructor(operations?: PropertyOperationsRecord) { this._operations = operations ?? new Map(); } toRecord(): Record> { const converted: Record> = {}; this._operations.forEach((properties, operation) => { converted[operation] = Object.fromEntries(properties); }); return converted; } }