Browse Source

feat: add onRecordSet methoda

ci/dependabot
danstarns 2 years ago
parent
commit
40c48b4379
  1. 34
      src/data_sources/model/DataRecord.ts
  2. 6
      src/data_sources/model/DataRecords.ts
  3. 6
      src/data_sources/model/DataSource.ts
  4. 8
      src/data_sources/types.ts
  5. 50
      test/specs/data_sources/index.ts

34
src/data_sources/model/DataRecord.ts

@ -1,9 +1,10 @@
import { keys } from 'underscore'; import { keys } from 'underscore';
import { Model } from '../../common'; import { Model, SetOptions } from '../../common';
import { DataRecordProps, DataSourcesEvents } from '../types'; import { DataRecordProps, DataSourcesEvents } from '../types';
import DataRecords from './DataRecords'; import DataRecords from './DataRecords';
import DataSource from './DataSource'; import DataSource from './DataSource';
import EditorModel from '../../editor/model/Editor'; import EditorModel from '../../editor/model/Editor';
import { _StringKey } from 'backbone';
export default class DataRecord<T extends DataRecordProps = DataRecordProps> extends Model<T> { export default class DataRecord<T extends DataRecordProps = DataRecordProps> extends Model<T> {
constructor(props: T, opts = {}) { constructor(props: T, opts = {}) {
@ -59,4 +60,35 @@ export default class DataRecord<T extends DataRecordProps = DataRecordProps> ext
const paths = this.getPaths(prop); const paths = this.getPaths(prop);
paths.forEach(path => em.trigger(`${DataSourcesEvents.path}:${path}`, { ...data, path })); paths.forEach(path => em.trigger(`${DataSourcesEvents.path}:${path}`, { ...data, path }));
} }
set<A extends _StringKey<T>>(
attributeName: Partial<T> | A,
value?: SetOptions | T[A] | undefined,
options?: SetOptions | undefined
): this;
set(attributeName: unknown, value?: unknown, options?: SetOptions): DataRecord {
const onRecordSet = this.dataSource?.transformers?.onRecordSet;
if (options?.avoidTransformers) {
// @ts-ignore
super.set(attributeName, value, options);
return this;
}
if (onRecordSet) {
const newValue = onRecordSet({
id: this.id,
key: attributeName as string,
value,
});
// @ts-ignore
super.set(attributeName, newValue, options);
return this;
} else {
// @ts-ignore
super.set(attributeName, value, options);
return this;
}
}
} }

6
src/data_sources/model/DataRecords.ts

@ -16,14 +16,14 @@ export default class DataRecords extends Collection<DataRecord> {
add(model: {} | DataRecord<DataRecordProps>, options?: AddRecordOptions): DataRecord<DataRecordProps>; add(model: {} | DataRecord<DataRecordProps>, options?: AddRecordOptions): DataRecord<DataRecordProps>;
add(models: ({} | DataRecord<DataRecordProps>)[], options?: AddRecordOptions): DataRecord<DataRecordProps>[]; add(models: ({} | DataRecord<DataRecordProps>)[], options?: AddRecordOptions): DataRecord<DataRecordProps>[];
add(models: unknown, options?: AddRecordOptions): DataRecord<DataRecordProps> | DataRecord<DataRecordProps>[] { add(models: unknown, options?: AddRecordOptions): DataRecord<DataRecordProps> | DataRecord<DataRecordProps>[] {
const onRecordInsert = this.dataSource?.transformers?.onRecordInsert; const onRecordAdd = this.dataSource?.transformers?.onRecordAdd;
if (options?.avoidTransformers) { if (options?.avoidTransformers) {
return super.add(models as DataRecord<DataRecordProps>, options); return super.add(models as DataRecord<DataRecordProps>, options);
} }
if (onRecordInsert) { if (onRecordAdd) {
const m = (Array.isArray(models) ? models : [models]).map(onRecordInsert); const m = (Array.isArray(models) ? models : [models]).map(model => onRecordAdd({ record: model }));
return super.add(m, options); return super.add(m, options);
} else { } else {

6
src/data_sources/model/DataSource.ts

@ -42,9 +42,9 @@ export default class DataSource extends Model<DataSourceProps> {
} }
addRecord(record: DataRecordProps, opts?: AddOptions) { addRecord(record: DataRecordProps, opts?: AddOptions) {
const onRecordInsert = this.transformers.onRecordInsert; const onRecordAdd = this.transformers.onRecordAdd;
if (onRecordInsert) { if (onRecordAdd) {
record = onRecordInsert(record); record = onRecordAdd({ record });
} }
return this.records.add(record, opts); return this.records.add(record, opts);

8
src/data_sources/types.ts

@ -21,10 +21,10 @@ export interface DataSourceProps {
} }
export interface DataSourceTransformers { export interface DataSourceTransformers {
onRecordInsert?: (record: DataRecordProps) => DataRecordProps; onRecordAdd?: (args: { record: DataRecordProps }) => DataRecordProps;
onRecordUpdate?: (record: DataRecord) => DataRecord; onRecordSet?: (args: { id: string | number; key: string; value: any }) => any;
onRecordDelete?: (record: DataRecord) => DataRecord; onRecordDelete?: (args: { record: DataRecord }) => DataRecord;
onRecordRead?: (record: DataRecord) => DataRecord; onRecordRead?: (args: { record: DataRecord }) => DataRecord;
} }
export interface DataRecordProps extends ObjectAny { export interface DataRecordProps extends ObjectAny {

50
test/specs/data_sources/index.ts

@ -145,12 +145,12 @@ describe('DataSourceManager', () => {
fixtures.appendChild(wrapperEl.el); fixtures.appendChild(wrapperEl.el);
}); });
test('onRecordInsert', () => { test('onRecordAdd', () => {
const testDataSource: DataSourceProps = { const testDataSource: DataSourceProps = {
id: 'test-data-source', id: 'test-data-source',
records: [], records: [],
transformers: { transformers: {
onRecordInsert: record => { onRecordAdd: ({ record }) => {
record.content = record.content.toUpperCase(); record.content = record.content.toUpperCase();
return record; return record;
}, },
@ -179,6 +179,52 @@ describe('DataSourceManager', () => {
const result = ds.getRecord('id1')?.get('content'); const result = ds.getRecord('id1')?.get('content');
expect(result).toBe('I LOVE GRAPES'); expect(result).toBe('I LOVE GRAPES');
}); });
test('onRecordSet', () => {
const testDataSource: DataSourceProps = {
id: 'test-data-source',
records: [],
transformers: {
onRecordSet: ({ id, key, value }) => {
if (key !== 'content') {
return value;
}
if (typeof value !== 'string') {
throw new Error('Value must be a string');
}
return value.toUpperCase();
},
},
};
dsm.add(testDataSource);
const cmp = cmpRoot.append({
tagName: 'h1',
type: 'text',
components: [
{
type: 'data-variable',
value: 'default',
path: 'test-data-source.id1.content',
},
],
})[0];
const ds = dsm.get('test-data-source');
const dr = ds.addRecord({ id: 'id1', content: 'i love grapes' });
expect(() => dr.set('content', 123)).toThrowError('Value must be a string');
dr.set('content', 'I LOVE GRAPES');
const el = cmp.getEl();
expect(el?.innerHTML).toContain('I LOVE GRAPES');
const result = ds.getRecord('id1')?.get('content');
expect(result).toBe('I LOVE GRAPES');
});
}); });
test('add DataSource with records', () => { test('add DataSource with records', () => {

Loading…
Cancel
Save