Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions lib/config.interface.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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
}
87 changes: 60 additions & 27 deletions lib/generator.class.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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,
Expand All @@ -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);
}
Expand All @@ -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();
Expand All @@ -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<string[]>((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<IRecord[]> {
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;
});
}

}
13 changes: 7 additions & 6 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -30,18 +31,18 @@ program.parse();
/**
* generate, do it.
*/
(async function main() {
(async function main() {

const options = program.opts();

const configFilePath = options.config;
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();
})();
Expand Down
17 changes: 9 additions & 8 deletions lib/transfomer.class.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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'];
Expand Down