Skip to content

Commit

Permalink
feat(data-source,editor,schema): 数据源mock新增在编辑器中使用的配置
Browse files Browse the repository at this point in the history
  • Loading branch information
roymondchen committed Oct 17, 2023
1 parent 588ec68 commit 83ab94f
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 58 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ class App extends EventEmitter implements AppCore {

if (!dataSource) return;

const methods = dataSource.getMethods() || [];
const methods = dataSource.methods || [];

const method = methods.find((item) => item.name === methodName);

Expand Down
21 changes: 12 additions & 9 deletions packages/data-source/src/DataSourceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,24 @@ class DataSourceManager extends EventEmitter {
public dataSourceMap = new Map<string, DataSource>();

public data: DataSourceManagerData = {};
public useMock?: boolean = false;

constructor({ app, useMock }: DataSourceManagerOptions) {
super();

this.app = app;
this.useMock = useMock;

app.dsl?.dataSources?.forEach((config) => {
this.addDataSource(config, useMock);
this.addDataSource(config);
});
}

public get(id: string) {
return this.dataSourceMap.get(id);
}

public async addDataSource(config?: DataSourceSchema, useMock?: boolean) {
public async addDataSource(config?: DataSourceSchema) {
if (!config) return;

let ds: DataSource;
Expand All @@ -66,7 +68,7 @@ class DataSourceManager extends EventEmitter {
app: this.app,
schema: config as HttpDataSourceSchema,
request: this.app.request,
useMock,
useMock: this.useMock,
});
} else {
// eslint-disable-next-line @typescript-eslint/naming-convention
Expand All @@ -75,7 +77,7 @@ class DataSourceManager extends EventEmitter {
ds = new DataSourceClass({
app: this.app,
schema: config,
useMock,
useMock: this.useMock,
});
}

Expand All @@ -90,7 +92,7 @@ class DataSourceManager extends EventEmitter {
const beforeInit: ((...args: any[]) => any)[] = [];
const afterInit: ((...args: any[]) => any)[] = [];

ds.getMethods().forEach((method) => {
ds.methods.forEach((method) => {
if (typeof method.content !== 'function') return;
if (method.timing === 'beforeInit') {
beforeInit.push(method.content);
Expand Down Expand Up @@ -128,9 +130,10 @@ class DataSourceManager extends EventEmitter {
if (!ds) {
return;
}
ds.setFields(schema.fields);
ds.updateDefaultData();
this.data[ds.id] = ds.data;

this.removeDataSource(schema.id);

this.addDataSource(schema);
});
}

Expand Down Expand Up @@ -191,7 +194,7 @@ class DataSourceManager extends EventEmitter {
this.dataSourceMap.forEach((ds) => {
ds.destroy();
});
this.dataSourceMap = new Map();
this.dataSourceMap.clear();
}
}

Expand Down
64 changes: 37 additions & 27 deletions packages/data-source/src/data-sources/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/
import EventEmitter from 'events';

import type { AppCore, CodeBlockContent, DataSchema, MockSchema } from '@tmagic/schema';
import type { AppCore, CodeBlockContent, DataSchema } from '@tmagic/schema';
import { getDefaultValueFromFields } from '@tmagic/utils';

import type { DataSourceOptions } from '@data-source/types';
Expand All @@ -26,50 +26,64 @@ import type { DataSourceOptions } from '@data-source/types';
* 静态数据源
*/
export default class DataSource extends EventEmitter {
public type = 'base';

public id: string;

public isInit = false;

public data: Record<string, any> = {};

/** @tmagic/core 实例 */
public app: AppCore;

protected mockData?: MockSchema;
protected mockData?: Record<string | number, any>;

private fields: DataSchema[] = [];
private methods: CodeBlockContent[] = [];
#type = 'base';
#id: string;

/** 数据源自定义字段配置 */
#fields: DataSchema[] = [];
/** 数据源自定义方法配置 */
#methods: CodeBlockContent[] = [];

constructor(options: DataSourceOptions) {
super();

this.app = options.app;
this.id = options.schema.id;
this.#id = options.schema.id;
this.setFields(options.schema.fields);
this.setMethods(options.schema.methods || []);

if (typeof options.useMock === 'boolean' && options.useMock) {
this.mockData = options.schema.mocks?.find((mock) => mock.enable);
const defaultData = this.getDefaultData();

if (this.app.platform === 'editor') {
this.mockData = options.schema.mocks?.find((mock) => mock.useInEditor)?.data || defaultData;
} else if (typeof options.useMock === 'boolean' && options.useMock) {
this.mockData = options.schema.mocks?.find((mock) => mock.enable)?.data;
}

this.updateDefaultData();
this.setData(this.mockData || defaultData);
}

if (this.mockData) {
this.setData(this.mockData.data);
}
public get id() {
return this.#id;
}

public setFields(fields: DataSchema[]) {
this.fields = fields;
public get type() {
return this.#type;
}

public setMethods(methods: CodeBlockContent[]) {
this.methods = methods;
public get fields() {
return this.#fields;
}

public getMethods() {
return this.methods;
public get methods() {
return this.#methods;
}

public setFields(fields: DataSchema[]) {
this.#fields = fields;
}

public setMethods(methods: CodeBlockContent[]) {
this.#methods = methods;
}

public setData(data: Record<string, any>) {
Expand All @@ -79,11 +93,7 @@ export default class DataSource extends EventEmitter {
}

public getDefaultData() {
return getDefaultValueFromFields(this.fields);
}

public updateDefaultData() {
this.setData(this.getDefaultData());
return getDefaultValueFromFields(this.#fields);
}

public async init() {
Expand All @@ -92,7 +102,7 @@ export default class DataSource extends EventEmitter {

public destroy() {
this.data = {};
this.fields = [];
this.#fields = [];
this.removeAllListeners();
}
}
44 changes: 29 additions & 15 deletions packages/data-source/src/data-sources/Http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,24 @@ const webRequest = async (options: HttpOptions) => {
* @description 通过 http 请求获取数据
*/
export default class HttpDataSource extends DataSource {
public type = 'http';

/** 是否正在发起请求 */
public isLoading = false;
public error?: {
msg?: string;
code?: string | number;
};
public schema: HttpDataSourceSchema;
/** 请求配置 */
public httpOptions: HttpOptions;

private fetch?: RequestFunction;
private beforeRequest: ((...args: any[]) => any)[] = [];
private afterRequest: ((...args: any[]) => any)[] = [];
/** 请求函数 */
#fetch?: RequestFunction;
/** 请求前需要执行的函数队列 */
#beforeRequest: ((...args: any[]) => any)[] = [];
/** 请求后需要执行的函数队列 */
#afterRequest: ((...args: any[]) => any)[] = [];

#type = 'http';

constructor(options: HttpDataSourceOptions) {
const { options: httpOptions, ...dataSourceOptions } = options.schema;
Expand All @@ -93,22 +98,26 @@ export default class HttpDataSource extends DataSource {
this.httpOptions = httpOptions;

if (typeof options.request === 'function') {
this.fetch = options.request;
this.#fetch = options.request;
} else if (typeof globalThis.fetch === 'function') {
this.fetch = webRequest;
this.#fetch = webRequest;
}

this.getMethods().forEach((method) => {
this.methods.forEach((method) => {
if (typeof method.content !== 'function') return;
if (method.timing === 'beforeRequest') {
this.beforeRequest.push(method.content);
this.#beforeRequest.push(method.content);
}
if (method.timing === 'afterRequest') {
this.afterRequest.push(method.content);
this.#afterRequest.push(method.content);
}
});
}

public get type() {
return this.#type;
}

public async init() {
if (this.schema.autoFetch) {
await this.request(this.httpOptions);
Expand All @@ -117,20 +126,23 @@ export default class HttpDataSource extends DataSource {
super.init();
}

public async request(options: HttpOptions) {
public async request(options: Partial<HttpOptions> = {}) {
this.isLoading = true;

try {
for (const method of this.beforeRequest) {
for (const method of this.#beforeRequest) {
await method({ options, params: {}, dataSource: this, app: this.app });
}

// 注意:在编辑器中mockData不会为空,至少是默认值,不会发起请求
const res = this.mockData
? this.mockData.data
: await this.fetch?.({
? this.mockData
: await this.#fetch?.({
...this.httpOptions,
...options,
});

for (const method of this.afterRequest) {
for (const method of this.#afterRequest) {
await method({ res, options, params: {}, dataSource: this, app: this.app });
}

Expand All @@ -149,6 +161,8 @@ export default class HttpDataSource extends DataSource {

this.emit('error', error);
}

this.isLoading = false;
}

public get(options: Partial<HttpOptions> & { url: string }) {
Expand Down
4 changes: 4 additions & 0 deletions packages/data-source/tests/DataSource.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ describe('DataSource', () => {
type: 'base',
id: '1',
fields: [{ name: 'name' }],
methods: [],
},
app: {},
});

expect(ds).toBeInstanceOf(DataSource);
Expand All @@ -22,7 +24,9 @@ describe('DataSource', () => {
type: 'base',
id: '1',
fields: [{ name: 'name' }],
methods: [],
},
app: {},
});

ds.init();
Expand Down
Loading

0 comments on commit 83ab94f

Please sign in to comment.