From 1391fcfd724e05c85ee299b788d7769fd1fca39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E5=AE=89=E5=B9=B3?= Date: Tue, 22 Nov 2022 01:12:50 +0800 Subject: [PATCH] feat: each table can be configured with a different api_host --- lib/config.interface.ts | 14 +++++-- lib/generator.class.ts | 87 ++++++++++++++++++++++++++++------------- lib/index.ts | 13 +++--- lib/transfomer.class.ts | 17 ++++---- 4 files changed, 87 insertions(+), 44 deletions(-) diff --git a/lib/config.interface.ts b/lib/config.interface.ts index cc7eda9..43691ba 100644 --- a/lib/config.interface.ts +++ b/lib/config.interface.ts @@ -1,9 +1,9 @@ import { IGetRecordsReqParams } from "apitable"; export enum Format { - Array = "array", - Rows = "rows", - Columns = "columns", + Array = "array", + Rows = "rows", + Columns = "columns", } export interface ITableConfig { @@ -12,10 +12,18 @@ export interface ITableConfig { format: Format; id?: boolean; params?: IGetRecordsReqParams; + create?: boolean; + _api_client_config: _IApiClientConfig; } export interface IConfig { dirName: string; fileName: string; + create?: boolean; tables: ITableConfig[]; } + +export interface _IApiClientConfig { + _host: string, + _token: string +} diff --git a/lib/generator.class.ts b/lib/generator.class.ts index 66cc236..5072765 100644 --- a/lib/generator.class.ts +++ b/lib/generator.class.ts @@ -1,15 +1,11 @@ - -import { - APITable, - IRecord, - IGetRecordsReqParams, -} from "apitable"; +import { APITable, IGetRecordsReqParams, IRecord, } from "apitable"; +import dot from "dot-object"; import * as fs from "fs"; import { resolve } from "path"; -import { IConfig } from "./config.interface"; +import { IConfig, ITableConfig } from "./config.interface"; import { Transformer } from "./transfomer.class"; -export type RequestDataMap = {[datasheetId: string]: IRecord[]}; +export type RequestDataMap = { [datasheetId: string]: IRecord[] }; /** * The main settings generator @@ -18,8 +14,11 @@ export class Generator { private _api: APITable; private _configs: IConfig[]; + // private _transformer: Transformer; + private _currentHandleTableConfig: ITableConfig | undefined; + constructor(configs: IConfig[], token: string, host: string = 'https://apitable.com/fusion/v1') { // APITable API client @@ -29,15 +28,18 @@ export class Generator { }); this._configs = configs; - + + this._tableCustomizeApiClientConfig(); } - public async generate() { - const requestDatas: RequestDataMap = {} + public async generate() { + const requestDatas: RequestDataMap = {}; for (const config of this._configs) { // process multi table configs for (const tableConfig of config.tables) { + this._currentHandleTableConfig = tableConfig; + // request data const records = await this.requestData( tableConfig.datasheetId, @@ -50,7 +52,7 @@ export class Generator { const tf = new Transformer(this._configs, requestDatas); const resultMap = tf.generateSettings(); for (const fileName in resultMap) { - const result = resultMap[fileName] + const result = resultMap[fileName]; this.writeJsonFile(result.config, result.data); } @@ -59,6 +61,7 @@ export class Generator { /** * write to JSON file * @param config config + * @param tableData output data */ private async writeJsonFile(config: IConfig, tableData: object) { const rootDir = process.cwd(); @@ -71,37 +74,67 @@ export class Generator { console.log("Start writting file: %s", outputPath); const begin = +new Date(); - - // write into file - const outputJson = JSON.stringify(tableData, null, 4); - fs.writeFile(outputPath, outputJson, (err) => { - if (err !== null) { - console.error("Write failed"); - console.error(err); - return; - } - }); - const end = +new Date(); - console.log("Write finished,Time: %d seconds", (end - begin) / 1000); - console.log("==========End============"); + if ((config.create ?? true)) { + // Filter out the keys that do not need to be generated + const removeKeys = config.tables.reduce((pre, cur) => { + if (!(cur.create ?? true)) { + pre.push(cur.datasheetName); + } + return pre; + }, []) as string[]; + console.log('Key to be deleted: %s', removeKeys); + const filterData = removeKeys.length > 0 ? dot.remove(removeKeys, tableData) : tableData; + + // write into file + const outputJson = JSON.stringify(filterData, null, 4); + fs.writeFile(outputPath, outputJson, (err) => { + if (err !== null) { + console.error("Write failed"); + console.error(err); + return; + } + }); + const end = +new Date(); + console.log("Write finished,Time: %d seconds", (end - begin) / 1000); + console.log("==========End============"); + } else { + console.log('No need to generate file: %s ', config.fileName); + console.log('==========End============'); + } } /** * requiest data by APITable API Client * @param datasheetId Datasheet ID + * @param reqParams */ async requestData( datasheetId: string, - setting?: IGetRecordsReqParams + reqParams?: IGetRecordsReqParams ): Promise { let records: IRecord[] = []; for await (const eachPageRecords of this._api .datasheet(datasheetId) - .records.queryAll({ ...setting })) { + .records.queryAll({ ...reqParams })) { records = [...records, ...eachPageRecords]; } return records; } + private _tableCustomizeApiClientConfig() { + this._api.axios.interceptors.request.use(config => { + const _tableConfig = this._currentHandleTableConfig; + const _host = _tableConfig?._api_client_config?._host || this._api.config.host; + const _token = _tableConfig?._api_client_config?._token || this._api.config.token; + + config.baseURL = _host; + config.headers = { + ...config.headers, + Authorization: 'Bearer ' + _token + }; + return config; + }); + } + } diff --git a/lib/index.ts b/lib/index.ts index 5344240..22689a3 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,8 +1,9 @@ -import { Generator } from "./generator.class"; import { createCommand } from "commander"; -const program = createCommand(); -import { name, version, description, homepage } from "../package.json"; +import { description, homepage, name, version } from "../package.json"; import { IConfig } from "./config.interface"; +import { Generator } from "./generator.class"; + +const program = createCommand(); const fs = require("fs"); program @@ -30,7 +31,7 @@ program.parse(); /** * generate, do it. */ - (async function main() { +(async function main() { const options = program.opts(); @@ -38,10 +39,10 @@ program.parse(); const token = options.token; const host = options.host || undefined; - const fileContent: string = await fs.readFileSync(configFilePath, 'utf-8'); + const fileContent: string = fs.readFileSync(configFilePath, 'utf-8'); const settings: IConfig[] = JSON.parse(fileContent) as IConfig[]; - const gen = new Generator(settings, token, host); + const gen = new Generator(settings, token, host); await gen.generate(); })(); diff --git a/lib/transfomer.class.ts b/lib/transfomer.class.ts index ce79b96..9280e8e 100644 --- a/lib/transfomer.class.ts +++ b/lib/transfomer.class.ts @@ -1,13 +1,14 @@ import { IFieldValueMap, IRecord } from "apitable"; import * as dot from "dot-object"; import { isArray, isString } from "lodash"; -import { Format } from "./config.interface"; +import { Format, IConfig, ITableConfig } from "./config.interface"; import { RequestDataMap } from "./generator.class"; -import { IConfig, ITableConfig } from "./config.interface"; + interface CacheRecord { id: string; dottedObject: object; } + interface SettingsResult { data: object; config: IConfig; @@ -20,20 +21,21 @@ interface SettingsResult { export type SettingsResultMap = { [fileName: string]: SettingsResult }; type CacheRecordsMap = { [key: string]: CacheRecord }; + /** * Data transformer, from requested data (IRecord) and configs (IConfig) to settings result (JSON). */ export class Transformer { private _requestedData: RequestDataMap; private _configs: IConfig[]; - private _recordsCache: CacheRecordsMap = {}; + private _recordsCache: CacheRecordsMap = {}; generateSettings(): SettingsResultMap { const resultMap: SettingsResultMap = {}; for (const config of this._configs) { - const result = this.parseTables(config.tables) + const result = this.parseTables(config.tables); resultMap[config.fileName] = { data: result, config: config @@ -46,13 +48,12 @@ export class Transformer { return resultMap; } - /** * parse multi tables - * + * * @param tableConfigs configs */ - public parseTables(tableConfigs: ITableConfig[]): object { + public parseTables(tableConfigs: ITableConfig[]): object { const tableObjects: { [key: string]: any } = {}; // multi table process @@ -146,7 +147,7 @@ export class Transformer { if (recordKey == 'id') continue; // ignore `id` - if (!retObj[recordKey]) retObj[recordKey] = {} + if (!retObj[recordKey]) retObj[recordKey] = {}; const valObj = retObj[recordKey]; const rowPrimaryKey = rObj['id'];