Skip to content

Commit

Permalink
feat: add configApi method (#874)
Browse files Browse the repository at this point in the history
* feat: add configApi method

* chore: publish 1.4.0 release

* test: skip export in sqlite
  • Loading branch information
tea-artist authored Sep 2, 2024
1 parent b39c912 commit 03d273a
Show file tree
Hide file tree
Showing 13 changed files with 119 additions and 70 deletions.
2 changes: 1 addition & 1 deletion apps/nestjs-backend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/backend",
"version": "1.3.2",
"version": "1.4.0",
"license": "AGPL-3.0",
"private": true,
"main": "dist/index.js",
Expand Down
119 changes: 62 additions & 57 deletions apps/nestjs-backend/test/table-export.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import os from 'node:os';
import path from 'path';
import type { INestApplication } from '@nestjs/common';
import type { IFieldVo } from '@teable/core';
import { FieldType, Colors, Relationship, ViewType } from '@teable/core';
import { FieldType, Colors, Relationship, ViewType, DriverClient } from '@teable/core';
import type { INotifyVo } from '@teable/openapi';
import {
exportCsvFromTable as apiExportCsvFromTable,
Expand Down Expand Up @@ -257,70 +257,75 @@ const createRecordsWithLink = async (mainTableId: string, subTableId: string) =>
});
};

describe('/export/${tableId} OpenAPI ExportController (e2e) Get csv stream from table (Get) ', () => {
it(`should return a csv stream from table and compatible all fields`, async () => {
const { mainTable, subTable } = await createTables();

const exportRes = await apiExportCsvFromTable(mainTable.id);
const disposition = exportRes?.headers[contentDispositionKey];
const contentType = exportRes?.headers[contentTypeKey];
const { data: csvData } = exportRes;

await apiDeleteTable(baseId, mainTable.id);
await apiDeleteTable(baseId, subTable.id);

expect(disposition).toBe(`attachment; filename=${encodeURIComponent(mainTable.name)}.csv`);
expect(contentType).toBe('text/csv');
expect(csvData).toBe(
`Text field,Number field,Checkbox field,Select field,Date field,Attachment field,User Field,Link field,Link field from lookups sub_Name,Link field from lookups sub_Number,Link field from lookups sub_Checkbox,Link field from lookups sub_SingleSelect\r\ntxt1,1.00,true,x,2022-11-28,test.txt ${txtFileData.presignedUrl},,Name1,Name1,1.00,true,sub_y\r\ntxt2,,,y,2022-11-28,,test,,,,,\r\n,,true,z,,,,,,,,`
);
});
describe.skipIf(globalThis.testConfig.driver === DriverClient.Sqlite)(
'/export/${tableId} OpenAPI ExportController (e2e) Get csv stream from table (Get) ',
() => {
it(`should return a csv stream from table and compatible all fields`, async () => {
const { mainTable, subTable } = await createTables();

const exportRes = await apiExportCsvFromTable(mainTable.id);
const disposition = exportRes?.headers[contentDispositionKey];
const contentType = exportRes?.headers[contentTypeKey];
const { data: csvData } = exportRes;

await apiDeleteTable(baseId, mainTable.id);
await apiDeleteTable(baseId, subTable.id);

expect(disposition).toBe(`attachment; filename=${encodeURIComponent(mainTable.name)}.csv`);
expect(contentType).toBe('text/csv');
expect(csvData).toBe(
`Text field,Number field,Checkbox field,Select field,Date field,Attachment field,User Field,Link field,Link field from lookups sub_Name,Link field from lookups sub_Number,Link field from lookups sub_Checkbox,Link field from lookups sub_SingleSelect\r\ntxt1,1.00,true,x,2022-11-28,test.txt ${txtFileData.presignedUrl},,Name1,Name1,1.00,true,sub_y\r\ntxt2,,,y,2022-11-28,,test,,,,,\r\n,,true,z,,,,,,,,`
);
});

it(`should return a csv stream from table with special character table name`, async () => {
const { mainTable, subTable } = await createTables('测试😄', 'subTable');
it(`should return a csv stream from table with special character table name`, async () => {
const { mainTable, subTable } = await createTables('测试😄', 'subTable');

const exportRes = await apiExportCsvFromTable(mainTable.id);
const disposition = exportRes?.headers['content-disposition'];
const contentType = exportRes?.headers['content-type'];
const { data: csvData } = exportRes;
const exportRes = await apiExportCsvFromTable(mainTable.id);
const disposition = exportRes?.headers['content-disposition'];
const contentType = exportRes?.headers['content-type'];
const { data: csvData } = exportRes;

await apiDeleteTable(baseId, mainTable.id);
await apiDeleteTable(baseId, subTable.id);
await apiDeleteTable(baseId, mainTable.id);
await apiDeleteTable(baseId, subTable.id);

expect(disposition).toBe(`attachment; filename=${encodeURIComponent(mainTable.name)}.csv`);
expect(contentType).toBe('text/csv');
expect(csvData).toBe(
`Text field,Number field,Checkbox field,Select field,Date field,Attachment field,User Field,Link field,Link field from lookups sub_Name,Link field from lookups sub_Number,Link field from lookups sub_Checkbox,Link field from lookups sub_SingleSelect\r\ntxt1,1.00,true,x,2022-11-28,test.txt ${txtFileData.presignedUrl},,Name1,Name1,1.00,true,sub_y\r\ntxt2,,,y,2022-11-28,,test,,,,,\r\n,,true,z,,,,,,,,`
);
});
expect(disposition).toBe(`attachment; filename=${encodeURIComponent(mainTable.name)}.csv`);
expect(contentType).toBe('text/csv');
expect(csvData).toBe(
`Text field,Number field,Checkbox field,Select field,Date field,Attachment field,User Field,Link field,Link field from lookups sub_Name,Link field from lookups sub_Number,Link field from lookups sub_Checkbox,Link field from lookups sub_SingleSelect\r\ntxt1,1.00,true,x,2022-11-28,test.txt ${txtFileData.presignedUrl},,Name1,Name1,1.00,true,sub_y\r\ntxt2,,,y,2022-11-28,,test,,,,,\r\n,,true,z,,,,,,,,`
);
});

it(`should return a csv stream from a particular view`, async () => {
const { mainTable, subTable } = await createTables();
it(`should return a csv stream from a particular view`, async () => {
const { mainTable, subTable } = await createTables();

const numberField = mainTable?.fields?.find(
(field) => field.name === 'Number field'
) as IFieldVo;
const numberField = mainTable?.fields?.find(
(field) => field.name === 'Number field'
) as IFieldVo;

const oldColumnMeta = mainTable?.views?.[0]?.columnMeta;
const view2 = await createView(mainTable.id, {
columnMeta: {
...oldColumnMeta,
[numberField.id]: {
...oldColumnMeta?.[numberField.id],
order: 0.5,
const oldColumnMeta = mainTable?.views?.[0]?.columnMeta;
const view2 = await createView(mainTable.id, {
columnMeta: {
...oldColumnMeta,
[numberField.id]: {
...oldColumnMeta?.[numberField.id],
order: 0.5,
},
},
},
type: ViewType.Grid,
});
type: ViewType.Grid,
});

const exportRes = await apiExportCsvFromTable(mainTable.id, view2.id);
const { data: csvData } = exportRes;
const exportRes = await apiExportCsvFromTable(mainTable.id, view2.id);
const { data: csvData } = exportRes;

await apiDeleteTable(baseId, mainTable.id);
await apiDeleteTable(baseId, subTable.id);
console.log('exportRes', csvData);

expect(csvData).toBe(
`Text field,Number field,Checkbox field,Select field,Date field,Attachment field,User Field,Link field,Link field from lookups sub_Name,Link field from lookups sub_Number,Link field from lookups sub_Checkbox,Link field from lookups sub_SingleSelect\r\ntxt1,1.00,true,x,2022-11-28,test.txt ${txtFileData.presignedUrl},,Name1,Name1,1.00,true,sub_y\r\ntxt2,,,y,2022-11-28,,test,,,,,\r\n,,true,z,,,,,,,,`
);
});
});
await apiDeleteTable(baseId, mainTable.id);
await apiDeleteTable(baseId, subTable.id);

expect(csvData).toBe(
`Text field,Number field,Checkbox field,Select field,Date field,Attachment field,User Field,Link field,Link field from lookups sub_Name,Link field from lookups sub_Number,Link field from lookups sub_Checkbox,Link field from lookups sub_SingleSelect\r\ntxt1,1.00,true,x,2022-11-28,test.txt ${txtFileData.presignedUrl},,Name1,Name1,1.00,true,sub_y\r\ntxt2,,,y,2022-11-28,,test,,,,,\r\n,,true,z,,,,,,,,`
);
});
}
);
2 changes: 1 addition & 1 deletion apps/nextjs-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/app",
"version": "1.3.2",
"version": "1.4.0",
"license": "AGPL-3.0",
"private": true,
"main": "main/index.js",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/teable",
"version": "1.3.2",
"version": "1.4.0",
"license": "AGPL-3.0",
"private": true,
"homepage": "https://github.com/teableio/teable",
Expand Down
2 changes: 1 addition & 1 deletion packages/common-i18n/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/common-i18n",
"version": "1.3.2",
"version": "1.4.0",
"license": "MIT",
"homepage": "https://github.com/teableio/teable",
"private": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/core",
"version": "1.3.2",
"version": "1.4.0",
"license": "MIT",
"homepage": "https://github.com/teableio/teable",
"publishConfig": {
Expand Down
2 changes: 1 addition & 1 deletion packages/db-main-prisma/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/db-main-prisma",
"version": "1.3.2",
"version": "1.4.0",
"license": "MIT",
"homepage": "https://github.com/teableio/teable",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-config-bases/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/eslint-config-bases",
"version": "1.3.2",
"version": "1.4.0",
"license": "MIT",
"private": true,
"homepage": "https://github.com/teableio/teable",
Expand Down
2 changes: 1 addition & 1 deletion packages/icons/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/icons",
"version": "1.3.2",
"version": "1.4.0",
"license": "MIT",
"homepage": "https://github.com/teableio/teable",
"publishConfig": {
Expand Down
2 changes: 1 addition & 1 deletion packages/openapi/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/openapi",
"version": "1.3.2",
"version": "1.4.0",
"license": "MIT",
"homepage": "https://github.com/teableio/teable",
"publishConfig": {
Expand Down
48 changes: 46 additions & 2 deletions packages/openapi/src/axios.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { HttpError } from '@teable/core';
import { generateWindowId, HttpError } from '@teable/core';
import axiosInstance from 'axios';

export const createAxios = () => {
Expand All @@ -20,4 +20,48 @@ export const createAxios = () => {
return axios;
};

export const axios = createAxios();
const axios = createAxios();

/**
* Configuration options for the Axios instance.
*/
export interface IAPIRequestConfig {
/**
* API endpoint, defaults to 'https://app.teable.io'.
*/
endpoint?: string;
/**
* Bearer token for authentication.
*/
token: string;
/**
* Enable undo/redo functionality for API calls related to record, field, and view mutations
*/
enableUndoRedo?: boolean;
}

/**
* Configures the Axios instance with the provided options.
* @param config - Configuration options
*/
export const configApi = (config: IAPIRequestConfig) => {
const { token, enableUndoRedo, endpoint = 'https://app.teable.io' } = config;
if (!token) {
throw new Error(
`token is required, visit ${endpoint}/setting/personal-access-token to get one`
);
}

axios.defaults.baseURL = `${endpoint}/api`;
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;

// Add windowId for undo/redo functionality if enabled
if (enableUndoRedo) {
const windowId = generateWindowId();
axios.defaults.headers.common['X-Window-Id'] = windowId;
}

return axios;
};

export { axios };
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/sdk",
"version": "1.3.2",
"version": "1.4.0",
"license": "MIT",
"homepage": "https://github.com/teableio/teable",
"publishConfig": {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@teable/ui-lib",
"version": "1.3.2",
"version": "1.4.0",
"license": "MIT",
"homepage": "https://github.com/teableio/teable",
"publishConfig": {
Expand Down

0 comments on commit 03d273a

Please sign in to comment.