// Copyright (c) Cratis. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. import { PropertyAccessor, PropertyPathResolverProxyHandler } from '@cratis/fundamentals'; import { AllSetBuilder } from './AllSetBuilder.js'; import type { IAllSetBuilder } from './IAllSetBuilder.js'; import type { IFromAllBuilder } from './IFromAllBuilder.js'; /** Accumulates all-event mappings without restricting the event subscription to known types. */ export class FromAllBuilder implements IFromAllBuilder { readonly properties: Record = {}; /** @inheritdoc */ set(readModelPropertyAccessor: PropertyAccessor): IAllSetBuilder> { return new AllSetBuilder>( this.targetProperty(readModelPropertyAccessor), (property, expression) => { this.properties[property] = expression; }, this ); } /** @inheritdoc */ count(readModelPropertyAccessor: PropertyAccessor, contextPropertyName?: string): IFromAllBuilder { return this.operation(readModelPropertyAccessor, '$count', contextPropertyName); } /** @inheritdoc */ increment(readModelPropertyAccessor: PropertyAccessor, contextPropertyName?: string): IFromAllBuilder { return this.operation(readModelPropertyAccessor, '$increment', contextPropertyName); } /** @inheritdoc */ decrement(readModelPropertyAccessor: PropertyAccessor, contextPropertyName?: string): IFromAllBuilder { return this.operation(readModelPropertyAccessor, '$decrement', contextPropertyName); } private operation(accessor: PropertyAccessor, expression: string, contextPropertyName?: string): this { const property = this.targetProperty(accessor); const target = contextPropertyName === undefined ? property : `${property}.$eventContext.${contextPropertyName}`; this.properties[target] = expression; return this; } private targetProperty(accessor: PropertyAccessor): string { const handler = new PropertyPathResolverProxyHandler(); accessor(new Proxy({}, handler) as TReadModel); return handler.property; } }