UNPKG

@orbit/records

Version:

A flexible data access and synchronization layer.

230 lines (209 loc) 6.17 kB
import { Orbit } from '@orbit/core'; import { TransformBuilderFunc } from '@orbit/data'; import { StandardValidator, ValidatorForFn } from '@orbit/validators'; import { InitializedRecord, RecordIdentity, RecordInitializer, UninitializedRecord } from './record'; import { RecordNormalizer } from './record-normalizer'; import { RecordOperation } from './record-operation'; import { AddRecordTerm, AddToRelatedRecordsTerm, RemoveFromRelatedRecordsTerm, RemoveRecordTerm, ReplaceAttributeTerm, ReplaceKeyTerm, ReplaceRelatedRecordsTerm, ReplaceRelatedRecordTerm, UpdateRecordTerm } from './record-operation-term'; import { RecordSchema } from './record-schema'; import { StandardRecordValidator } from './record-validators/standard-record-validators'; const { assert, deprecate } = Orbit; export type RecordTransformBuilderFunc = TransformBuilderFunc< RecordOperation, RecordTransformBuilder >; export interface RecordTransformBuilderSettings< RT = string, RI = RecordIdentity, R = UninitializedRecord > { /** * @deprecated since v0.17, replaced by `recordNormalizer` */ recordInitializer?: RecordInitializer; schema?: RecordSchema; normalizer?: RecordNormalizer<RT, RI, R>; validatorFor?: ValidatorForFn<StandardValidator | StandardRecordValidator>; } export class RecordTransformBuilder< RT = string, RI = RecordIdentity, R = UninitializedRecord > { $schema?: RecordSchema; $normalizer?: RecordNormalizer<RT, RI, R>; $validatorFor?: ValidatorForFn<StandardValidator | StandardRecordValidator>; constructor(settings: RecordTransformBuilderSettings<RT, RI, R> = {}) { const { schema, normalizer, validatorFor, recordInitializer } = settings; if (validatorFor) { assert( 'A RecordTransformBuilder that has been assigned a `validatorFor` requires a `schema`', schema !== undefined ); } this.$schema = schema; this.$normalizer = normalizer; this.$validatorFor = validatorFor; if (recordInitializer) { if (this.$normalizer !== undefined) { deprecate( 'A `normalizer` and `recordInitializer` have both been assigned to the `TransformBuilder`. Only the `normalizer` will be used.' ); } else { deprecate( 'A `recordInitializer` has been assigned to the `TransformBuilder`. The `recordInitializer` setting has been deprecated in favor of `normalizer`, and will be treated as if it were a `RecordNormalizer`.' ); this.$normalizer = { normalizeRecordType(type: RT): string { return (type as unknown) as string; }, normalizeRecord(record: R) { return recordInitializer.initializeRecord( (record as unknown) as UninitializedRecord ); }, normalizeRecordIdentity(recordIdentity: RI) { return (recordIdentity as unknown) as RecordIdentity; } }; } } } /** * Instantiate a new `addRecord` operation. */ addRecord(record: R): AddRecordTerm<RT, RI, R> { return new AddRecordTerm(this, this.$normalizeRecord(record)); } /** * Instantiate a new `updateRecord` operation. */ updateRecord(record: R): UpdateRecordTerm<RT, RI, R> { return new UpdateRecordTerm(this, this.$normalizeRecord(record)); } /** * Instantiate a new `removeRecord` operation. */ removeRecord(record: RI): RemoveRecordTerm<RT, RI, R> { return new RemoveRecordTerm(this, this.$normalizeRecordIdentity(record)); } /** * Instantiate a new `replaceKey` operation. */ replaceKey( record: RI, key: string, value: string ): ReplaceKeyTerm<RT, RI, R> { return new ReplaceKeyTerm( this, this.$normalizeRecordIdentity(record), key, value ); } /** * Instantiate a new `replaceAttribute` operation. */ replaceAttribute( record: RI, attribute: string, value: unknown ): ReplaceAttributeTerm<RT, RI, R> { return new ReplaceAttributeTerm( this, this.$normalizeRecordIdentity(record), attribute, value ); } /** * Instantiate a new `addToRelatedRecords` operation. */ addToRelatedRecords( record: RI, relationship: string, relatedRecord: RI ): AddToRelatedRecordsTerm<RT, RI, R> { return new AddToRelatedRecordsTerm( this, this.$normalizeRecordIdentity(record), relationship, this.$normalizeRecordIdentity(relatedRecord) ); } /** * Instantiate a new `removeFromRelatedRecords` operation. */ removeFromRelatedRecords( record: RI, relationship: string, relatedRecord: RI ): RemoveFromRelatedRecordsTerm<RT, RI, R> { return new RemoveFromRelatedRecordsTerm( this, this.$normalizeRecordIdentity(record), relationship, this.$normalizeRecordIdentity(relatedRecord) ); } /** * Instantiate a new `replaceRelatedRecords` operation. */ replaceRelatedRecords( record: RI, relationship: string, relatedRecords: RI[] ): ReplaceRelatedRecordsTerm<RT, RI, R> { return new ReplaceRelatedRecordsTerm( this, this.$normalizeRecordIdentity(record), relationship, relatedRecords.map((ri) => this.$normalizeRecordIdentity(ri)) ); } /** * Instantiate a new `replaceRelatedRecord` operation. */ replaceRelatedRecord( record: RI, relationship: string, relatedRecord: RI | null ): ReplaceRelatedRecordTerm<RT, RI, R> { return new ReplaceRelatedRecordTerm( this, this.$normalizeRecordIdentity(record), relationship, relatedRecord ? this.$normalizeRecordIdentity(relatedRecord) : null ); } $normalizeRecord(r: R): InitializedRecord { if (this.$normalizer) { return this.$normalizer.normalizeRecord(r); } else { return (r as unknown) as InitializedRecord; } } $normalizeRecordIdentity(ri: RI): RecordIdentity { if (this.$normalizer !== undefined) { return this.$normalizer.normalizeRecordIdentity(ri); } else { return (ri as unknown) as RecordIdentity; } } }