From 21eacc19d9ddaf6b00266e9b22279132791c5935 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Tue, 5 Nov 2024 12:14:59 +0400 Subject: [PATCH 1/2] Improve DataSource TS --- .../src/data_sources/model/DataRecords.ts | 2 +- .../core/src/data_sources/model/DataSource.ts | 23 +++++++++---------- packages/core/src/data_sources/types.ts | 7 ++++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/packages/core/src/data_sources/model/DataRecords.ts b/packages/core/src/data_sources/model/DataRecords.ts index 87a172dae3..1eadfcc220 100644 --- a/packages/core/src/data_sources/model/DataRecords.ts +++ b/packages/core/src/data_sources/model/DataRecords.ts @@ -3,7 +3,7 @@ import { DataRecordProps } from '../types'; import DataRecord from './DataRecord'; import DataSource from './DataSource'; -export default class DataRecords extends Collection { +export default class DataRecords extends Collection> { dataSource: DataSource; constructor(models: DataRecord[] | DataRecordProps[], options: { dataSource: DataSource }) { diff --git a/packages/core/src/data_sources/model/DataSource.ts b/packages/core/src/data_sources/model/DataSource.ts index 858758be5b..a585558e9b 100644 --- a/packages/core/src/data_sources/model/DataSource.ts +++ b/packages/core/src/data_sources/model/DataSource.ts @@ -38,7 +38,7 @@ import DataSources from './DataSources'; interface DataSourceOptions extends CombinedModelConstructorOptions<{ em: EditorModel }, DataSource> {} -export default class DataSource extends Model { +export default class DataSource extends Model { transformers: DataSourceTransformers; /** @@ -52,7 +52,7 @@ export default class DataSource extends Model { return { records: [], transformers: {}, - }; + } as unknown as Partial; } /** @@ -64,13 +64,13 @@ export default class DataSource extends Model { * @param {DataSourceOptions} opts - Options to initialize the data source. * @name constructor */ - constructor(props: DataSourceProps, opts: DataSourceOptions) { + constructor(props: DS, opts: DataSourceOptions) { super(props, opts); const { records, transformers } = props; this.transformers = transformers || {}; if (!(records instanceof DataRecords)) { - this.set({ records: new DataRecords(records!, { dataSource: this }) }); + this.set({ records: new DataRecords(records!, { dataSource: this }) } as Partial); } this.listenTo(this.records, 'add', this.onAdd); @@ -84,7 +84,7 @@ export default class DataSource extends Model { * @name records */ get records() { - return this.attributes.records as DataRecords; + return this.attributes.records as NonNullable; } /** @@ -117,7 +117,7 @@ export default class DataSource extends Model { * @returns {DataRecord} The added data record. * @name addRecord */ - addRecord(record: DataRecordProps, opts?: AddOptions) { + addRecord(record: T, opts?: AddOptions) { return this.records.add(record, opts); } @@ -128,9 +128,8 @@ export default class DataSource extends Model { * @returns {DataRecord | undefined} The data record, or `undefined` if no record is found with the given ID. * @name getRecord */ - getRecord(id: string | number): DataRecord | undefined { - const record = this.records.get(id); - return record; + getRecord(id: string | number) { + return this.records.get(id) as DataRecord | undefined; } /** @@ -140,8 +139,8 @@ export default class DataSource extends Model { * @returns {Array} An array of data records. * @name getRecords */ - getRecords() { - return [...this.records.models].map((record) => this.getRecord(record.id)); + getRecords() { + return [...this.records.models].map((record) => this.getRecord(record.id)!); } /** @@ -168,7 +167,7 @@ export default class DataSource extends Model { * @returns {Array} An array of the added data records. * @name setRecords */ - setRecords(records: Array) { + setRecords(records: T[]) { this.records.reset([], { silent: true }); records.forEach((record) => { diff --git a/packages/core/src/data_sources/types.ts b/packages/core/src/data_sources/types.ts index f1873fd3ec..57f358adea 100644 --- a/packages/core/src/data_sources/types.ts +++ b/packages/core/src/data_sources/types.ts @@ -24,7 +24,7 @@ export interface DataVariableListener { event: string; } -export interface DataSourceProps { +export interface DataSourceProps { /** * DataSource id. */ @@ -33,7 +33,7 @@ export interface DataSourceProps { /** * DataSource records. */ - records?: DataRecords | DataRecord[] | DataRecordProps[]; + records?: DataRecords | DataRecord[] | DR[]; /** * DataSource validation and transformation factories. @@ -44,6 +44,9 @@ export interface DataSourceProps { * If true will store the data source in the GrapesJS project.json file. */ skipFromStorage?: boolean; + + // for TS + _records?: DataRecords; } export interface DataSourceTransformers { From 1ebf65157a7f4f2db43572060f8ed8dfa2e10921 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Tue, 5 Nov 2024 18:03:17 +0400 Subject: [PATCH 2/2] Datasource types (#6295) * Add datasource types * Refactor types * Remove unused type --------- Co-authored-by: mohamedsalem401 --- .../core/src/data_sources/model/DataSource.ts | 32 ++++++++++++------- packages/core/src/data_sources/types.ts | 20 ++++++------ 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/packages/core/src/data_sources/model/DataSource.ts b/packages/core/src/data_sources/model/DataSource.ts index a585558e9b..618ee30688 100644 --- a/packages/core/src/data_sources/model/DataSource.ts +++ b/packages/core/src/data_sources/model/DataSource.ts @@ -31,14 +31,18 @@ import { AddOptions, collectionEvents, CombinedModelConstructorOptions, Model, RemoveOptions } from '../../common'; import EditorModel from '../../editor/model/Editor'; -import { DataRecordProps, DataSourceProps, DataSourceTransformers } from '../types'; +import { DataSourceProps } from '../types'; +import { DataSourceTransformers, DataSourceType, SingleRecordType } from '../types'; import DataRecord from './DataRecord'; import DataRecords from './DataRecords'; import DataSources from './DataSources'; interface DataSourceOptions extends CombinedModelConstructorOptions<{ em: EditorModel }, DataSource> {} -export default class DataSource extends Model { +export default class DataSource< + DS extends DataSourceType = DataSourceType, + DR extends SingleRecordType = SingleRecordType, +> extends Model { transformers: DataSourceTransformers; /** @@ -64,8 +68,14 @@ export default class DataSource ex * @param {DataSourceOptions} opts - Options to initialize the data source. * @name constructor */ - constructor(props: DS, opts: DataSourceOptions) { - super(props, opts); + constructor(props: DataSourceProps, opts: DataSourceOptions) { + super( + { + ...props, + records: [], + } as unknown as DS, + opts, + ); const { records, transformers } = props; this.transformers = transformers || {}; @@ -84,7 +94,7 @@ export default class DataSource ex * @name records */ get records() { - return this.attributes.records as NonNullable; + return this.attributes.records as NonNullable; } /** @@ -117,7 +127,7 @@ export default class DataSource ex * @returns {DataRecord} The added data record. * @name addRecord */ - addRecord(record: T, opts?: AddOptions) { + addRecord(record: DR, opts?: AddOptions) { return this.records.add(record, opts); } @@ -128,8 +138,8 @@ export default class DataSource ex * @returns {DataRecord | undefined} The data record, or `undefined` if no record is found with the given ID. * @name getRecord */ - getRecord(id: string | number) { - return this.records.get(id) as DataRecord | undefined; + getRecord(id: string | number) { + return this.records.get(id) as DR | undefined; } /** @@ -139,8 +149,8 @@ export default class DataSource ex * @returns {Array} An array of data records. * @name getRecords */ - getRecords() { - return [...this.records.models].map((record) => this.getRecord(record.id)!); + getRecords() { + return [...this.records.models].map((record) => this.getRecord(record.id)!); } /** @@ -167,7 +177,7 @@ export default class DataSource ex * @returns {Array} An array of the added data records. * @name setRecords */ - setRecords(records: T[]) { + setRecords(records: DR[]) { this.records.reset([], { silent: true }); records.forEach((record) => { diff --git a/packages/core/src/data_sources/types.ts b/packages/core/src/data_sources/types.ts index 57f358adea..ec9508c7a9 100644 --- a/packages/core/src/data_sources/types.ts +++ b/packages/core/src/data_sources/types.ts @@ -1,4 +1,4 @@ -import { ObjectAny } from '../common'; +import { Collection, ObjectAny } from '../common'; import ComponentDataVariable from './model/ComponentDataVariable'; import DataRecord from './model/DataRecord'; import DataRecords from './model/DataRecords'; @@ -24,17 +24,12 @@ export interface DataVariableListener { event: string; } -export interface DataSourceProps { +interface BaseDataSource { /** * DataSource id. */ id: string; - /** - * DataSource records. - */ - records?: DataRecords | DataRecord[] | DR[]; - /** * DataSource validation and transformation factories. */ @@ -44,10 +39,15 @@ export interface DataSourceProps { * If true will store the data source in the GrapesJS project.json file. */ skipFromStorage?: boolean; - - // for TS - _records?: DataRecords; } +export interface DataSourceType extends BaseDataSource { + records: DataRecords; +} +export interface DataSourceProps extends BaseDataSource { + records?: DataRecords> | DataRecord>[] | ExtractRecordType[]; +} +export type ExtractRecordType = T extends { records: DataRecords } ? DR : never; +export type SingleRecordType = T extends Collection ? U : never; export interface DataSourceTransformers { onRecordSetValue?: (args: { id: string | number; key: string; value: any }) => any;