diff --git a/packages/data-source/src/DataSourceManager.ts b/packages/data-source/src/DataSourceManager.ts index b413e968..426d6e27 100644 --- a/packages/data-source/src/DataSourceManager.ts +++ b/packages/data-source/src/DataSourceManager.ts @@ -64,6 +64,7 @@ class DataSourceManager extends EventEmitter { let ds: DataSource; if (config.type === 'http') { ds = new HttpDataSource({ + app: this.app, schema: config as HttpDataSourceSchema, request: this.app.request, }); @@ -72,6 +73,7 @@ class DataSourceManager extends EventEmitter { const DataSourceClass = DataSourceManager.dataSourceClassMap.get(config.type) || DataSource; ds = new DataSourceClass({ + app: this.app, schema: config, }); } diff --git a/packages/data-source/src/data-sources/Base.ts b/packages/data-source/src/data-sources/Base.ts index 29fa06e8..01d29450 100644 --- a/packages/data-source/src/data-sources/Base.ts +++ b/packages/data-source/src/data-sources/Base.ts @@ -17,6 +17,7 @@ */ import EventEmitter from 'events'; +import type Core from '@tmagic/core'; import type { CodeBlockContent, DataSchema } from '@tmagic/schema'; import type { DataSourceOptions } from '@data-source/types'; @@ -34,12 +35,15 @@ export default class DataSource extends EventEmitter { public data: Record = {}; + public app: Core; + private fields: DataSchema[] = []; private methods: CodeBlockContent[] = []; constructor(options: DataSourceOptions) { super(); + this.app = options.app; this.id = options.schema.id; this.setFields(options.schema.fields); this.setMethods(options.schema.methods || []); diff --git a/packages/data-source/src/data-sources/Http.ts b/packages/data-source/src/data-sources/Http.ts index 64c4f423..5bfefec8 100644 --- a/packages/data-source/src/data-sources/Http.ts +++ b/packages/data-source/src/data-sources/Http.ts @@ -74,12 +74,15 @@ export default class HttpDataSource extends DataSource { public httpOptions: HttpOptions; private fetch?: RequestFunction; + private beforeRequest: ((...args: any[]) => any)[] = []; + private afterRequest: ((...args: any[]) => any)[] = []; constructor(options: HttpDataSourceOptions) { const { options: httpOptions, ...dataSourceOptions } = options.schema; super({ schema: dataSourceOptions, + app: options.app, }); this.schema = options.schema; @@ -90,6 +93,16 @@ export default class HttpDataSource extends DataSource { } else if (typeof globalThis.fetch === 'function') { this.fetch = webRequest; } + + this.getMethods().forEach((method) => { + if (typeof method.content !== 'function') return; + if (method.timing === 'beforeRequest') { + this.beforeRequest.push(method.content); + } + if (method.timing === 'afterRequest') { + this.afterRequest.push(method.content); + } + }); } public async init() { @@ -101,11 +114,19 @@ export default class HttpDataSource extends DataSource { } public async request(options: HttpOptions) { + await Promise.all( + this.beforeRequest.map((method) => method({ options, params: {}, dataSource: this, app: this.app })), + ); + const res = await this.fetch?.({ ...this.httpOptions, ...options, }); + await Promise.all( + this.afterRequest.map((method) => method({ res, options, params: {}, dataSource: this, app: this.app })), + ); + if (this.schema.responseOptions?.dataPath) { const data = getValueByKeyPath(this.schema.responseOptions.dataPath, res); this.setData(data); diff --git a/packages/data-source/src/types.ts b/packages/data-source/src/types.ts index 565ca834..33d0ef6c 100644 --- a/packages/data-source/src/types.ts +++ b/packages/data-source/src/types.ts @@ -3,6 +3,7 @@ import type { DataSourceSchema } from '@tmagic/schema'; export interface DataSourceOptions { schema: DataSourceSchema; + app: Core; } export type Method = 'get' | 'GET' | 'delete' | 'DELETE' | 'post' | 'POST' | 'put' | 'PUT'; @@ -28,6 +29,7 @@ export interface HttpDataSourceSchema extends DataSourceSchema { export interface HttpDataSourceOptions { schema: HttpDataSourceSchema; + app: Core; request?: RequestFunction; }