mobx-lark 2.8.0 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,85 +15,91 @@ export interface BiDataQueryOptions {
15
15
  /**
16
16
  * @see {@link https://open.feishu.cn/document/ukTMukTMukTM/uUDN04SN0QjL1QDN/bitable-overview}
17
17
  */
18
- export declare function BiDataTable<T extends DataObject, F extends Filter<T> = Filter<T>>(Base?: typeof ListModel): abstract new (appId: string, tableId: string) => {
19
- requiredKeys: readonly (keyof T)[];
20
- sort: Partial<Record<keyof T, "ASC" | "DESC">>;
18
+ export declare function BiDataTable<D extends DataObject, F extends Filter<D> = Filter<D>>(Base?: typeof ListModel): abstract new (appId: string, tableId: string) => {
19
+ requiredKeys: readonly (keyof D)[];
20
+ sort: Partial<Record<keyof D, "ASC" | "DESC">>;
21
21
  queryOptions: BiDataQueryOptions;
22
22
  currentViewId?: string;
23
- extractFields({ fields, ...meta }: TableRecord<T>): T;
23
+ keyMap?: Partial<Record<keyof D, string>>;
24
+ readonly nameMap: any;
25
+ extractFields({ fields, ...meta }: TableRecord<D>): D;
24
26
  /**
25
27
  * @deprecated
26
28
  */
27
- normalize: ({ fields, ...meta }: TableRecord<T>) => T;
28
- wrapFields(fields: F): T;
29
+ normalize: ({ fields, ...meta }: TableRecord<D>) => D;
30
+ /**
31
+ * @protected
32
+ */
33
+ mapFields({ fields, ...meta }: TableRecord<DataObject>): D;
34
+ wrapFields(fields: F): D;
29
35
  /**
30
36
  * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/get}
31
37
  */
32
- getOne(id: string): Promise<T>;
38
+ getOne(id: string): Promise<D>;
33
39
  /**
34
40
  * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/create}
35
41
  * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/update}
36
42
  */
37
- updateOne(data: F, id?: string): Promise<T>;
43
+ updateOne(data: F, id?: string): Promise<D>;
44
+ mapFilter(filter: DataObject): F;
38
45
  makeFilter(filter: F): string;
39
46
  /**
40
47
  * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/list}
41
48
  */
42
- openStream(filter: F): AsyncGenerator<T, void, unknown>;
43
- getViewList(viewId: string, pageIndex?: number, pageSize?: number): Promise<T[]>;
44
- getViewAll(viewId: string, pageSize?: number): Promise<T[]>;
45
- stream?: AsyncGenerator<T, void, any> | undefined;
49
+ openStream(filter: F): AsyncGenerator<D, void, unknown>;
50
+ getViewList(viewId: string, pageIndex?: number, pageSize?: number): Promise<D[]>;
51
+ getViewAll(viewId: string, pageSize?: number): Promise<D[]>;
52
+ stream?: AsyncGenerator<D, void, any> | undefined;
46
53
  clearList: (() => void) & (() => void);
47
54
  clear: (() => void) & (() => void);
48
- restoreList: (({ filter, pageIndex, pageSize, allItems, totalCount }?: Partial<Pick<ListModel<T, Partial<import("mobx-restful").NewData<T>>>, "filter" | "pageIndex" | "pageSize" | "allItems" | "totalCount">> | undefined) => Promise<void>) & (({ pageIndex, pageSize, allItems, totalCount }?: Partial<Pick<ListModel<T, Partial<import("mobx-restful").NewData<T>>>, "pageIndex" | "pageSize" | "allItems" | "totalCount">> | undefined) => void);
49
- loadStream(filter: F, newCount: number): Promise<T[]>;
55
+ restoreList: (({ filter, pageIndex, pageSize, allItems, totalCount }?: Partial<Pick<ListModel<D, Partial<import("mobx-restful").NewData<D>>>, "filter" | "pageIndex" | "pageSize" | "allItems" | "totalCount">> | undefined) => Promise<void>) & (({ pageIndex, pageSize, allItems, totalCount }?: Partial<Pick<ListModel<D, Partial<import("mobx-restful").NewData<D>>>, "pageIndex" | "pageSize" | "allItems" | "totalCount">> | undefined) => void);
56
+ loadStream(filter: F, newCount: number): Promise<D[]>;
50
57
  loadPage: ((pageIndex: number, pageSize: number, filter: F) => Promise<{
51
- pageData: T[];
58
+ pageData: D[];
52
59
  totalCount: number;
53
- }>) & ((pageIndex: number, pageSize: number, filter: F) => Promise<PageData<T>>);
60
+ }>) & ((pageIndex: number, pageSize: number, filter: F) => Promise<PageData<D>>);
54
61
  pageIndex: number;
55
62
  pageSize: number;
56
63
  filter: F;
57
64
  totalCount: number;
58
- pageList: T[][];
59
- readonly currentPage: T[];
65
+ pageList: D[][];
66
+ readonly currentPage: D[];
60
67
  readonly pageCount: number;
61
- readonly allItems: T[];
68
+ readonly allItems: D[];
62
69
  readonly noMore: boolean;
63
- statistic: Partial<Record<import("web-utility").TypeKeys<T, import("web-utility").IndexKey>, Record<string, number>>>;
64
- turnTo: ((pageIndex: number, pageSize?: number) => ListModel<T, F>) & ((pageIndex: number, pageSize?: number) => ListModel<T, F>);
70
+ statistic: Partial<Record<import("web-utility").TypeKeys<D, import("web-utility").IndexKey>, Record<string, number>>>;
71
+ turnTo: ((pageIndex: number, pageSize?: number) => ListModel<D, F>) & ((pageIndex: number, pageSize?: number) => ListModel<D, F>);
65
72
  loadNewPage: ((pageIndex: number, pageSize: number, filter: F) => Promise<{
66
- pageData: T[];
73
+ pageData: D[];
67
74
  totalCount: number;
68
75
  }>) & ((pageIndex: number, pageSize: number, filter: F) => Promise<{
69
- pageData: T[];
76
+ pageData: D[];
70
77
  totalCount: number;
71
78
  }>);
72
- getList: ((filter?: F | undefined, pageIndex?: number, pageSize?: number) => Promise<T[]>) & ((filter?: F | undefined, pageIndex?: number, pageSize?: number) => Promise<T[]>);
73
- refreshList: (() => Promise<T[]>) & (() => Promise<T[]>);
74
- getAllInStream: ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<T, void, unknown>) & ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<T, void, unknown>);
75
- getAll: ((filter?: F | undefined, pageSize?: number) => Promise<T[]>) & ((filter?: F | undefined, pageSize?: number) => Promise<T[]>);
76
- countAll: ((keys: import("web-utility").TypeKeys<T, import("web-utility").IndexKey>[], filter?: F | undefined, pageSize?: number) => Promise<Partial<Record<import("web-utility").TypeKeys<T, import("web-utility").IndexKey>, Record<string, number>>>>) & ((keys: import("web-utility").TypeKeys<T, import("web-utility").IndexKey>[], filter?: F | undefined, pageSize?: number) => Promise<Partial<Record<import("web-utility").TypeKeys<T, import("web-utility").IndexKey>, Record<string, number>>>>);
79
+ getList: ((filter?: F | undefined, pageIndex?: number, pageSize?: number) => Promise<D[]>) & ((filter?: F | undefined, pageIndex?: number, pageSize?: number) => Promise<D[]>);
80
+ refreshList: (() => Promise<D[]>) & (() => Promise<D[]>);
81
+ getAllInStream: ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<D, void, unknown>) & ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<D, void, unknown>);
82
+ getAll: ((filter?: F | undefined, pageSize?: number) => Promise<D[]>) & ((filter?: F | undefined, pageSize?: number) => Promise<D[]>);
83
+ countAll: ((keys: import("web-utility").TypeKeys<D, import("web-utility").IndexKey>[], filter?: F | undefined, pageSize?: number) => Promise<Partial<Record<import("web-utility").TypeKeys<D, import("web-utility").IndexKey>, Record<string, number>>>>) & ((keys: import("web-utility").TypeKeys<D, import("web-utility").IndexKey>[], filter?: F | undefined, pageSize?: number) => Promise<Partial<Record<import("web-utility").TypeKeys<D, import("web-utility").IndexKey>, Record<string, number>>>>);
77
84
  indexOf: ((id: import("mobx-restful").IDType) => number) & ((id: import("mobx-restful").IDType) => number);
78
- changeOne: ((data: Partial<T>, id: import("mobx-restful").IDType, patch?: boolean) => void) & ((data: Partial<T>, id: import("mobx-restful").IDType, patch?: boolean) => void);
85
+ changeOne: ((data: Partial<D>, id: import("mobx-restful").IDType, patch?: boolean) => void) & ((data: Partial<D>, id: import("mobx-restful").IDType, patch?: boolean) => void);
79
86
  removeOne: ((id: import("mobx-restful").IDType) => Promise<void>) & ((id: import("mobx-restful").IDType) => Promise<void>);
80
87
  deleteOne: ((id: import("mobx-restful").IDType) => Promise<void>) & ((id: import("mobx-restful").IDType) => Promise<void>);
81
88
  client: import("mobx-restful/dist/utility").RESTClient;
82
89
  baseURI: string;
83
- indexKey: keyof T;
84
- currentOne: T;
90
+ indexKey: keyof D;
91
+ currentOne: D;
85
92
  clearCurrent: (() => void) & (() => void);
86
93
  downloading: number;
87
94
  uploading: number;
88
- [Symbol.asyncIterator]: ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<T, void, unknown>) & ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<T, void, unknown>);
95
+ [Symbol.asyncIterator]: ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<D, void, unknown>) & ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<D, void, unknown>);
89
96
  };
90
97
  export type BiSearchFilter<D extends DataObject> = Filter<D> & {
91
98
  keywords?: string;
92
99
  };
93
- export declare function BiSearch<D extends DataObject, F extends BiSearchFilter<D> = BiSearchFilter<D>>(Model: Constructor<ListModel<D, F>>): abstract new (...args: any[]) => {
100
+ export declare function BiSearch<D extends DataObject, F extends BiSearchFilter<D> = BiSearchFilter<D>>(Model: ReturnType<typeof BiDataTable<D, F>>): abstract new (appId: string, tableId: string) => {
94
101
  baseURI: string;
95
102
  client: RESTClient;
96
- loadPage: (pageIndex: number, pageSize: number, filter: F) => Promise<PageData<D>>;
97
103
  searchKeys: readonly (keyof TableRecordFields)[];
98
104
  keywords: string;
99
105
  makeFilter(filter: F): string;
@@ -102,40 +108,79 @@ export declare function BiSearch<D extends DataObject, F extends BiSearchFilter<
102
108
  * @deprecated since v2.4.2, use {@link getList} instead
103
109
  */
104
110
  getSearchList(keywords: string, pageIndex?: number, pageSize?: number): Promise<D[]>;
111
+ requiredKeys: readonly (keyof D)[];
112
+ sort: Partial<Record<keyof D, "ASC" | "DESC">>;
113
+ queryOptions: BiDataQueryOptions;
114
+ currentViewId?: string;
115
+ keyMap?: Partial<Record<keyof D, string>> | undefined;
116
+ readonly nameMap: any;
117
+ extractFields({ fields, ...meta }: TableRecord<D>): D;
118
+ /**
119
+ * @deprecated
120
+ */
121
+ normalize: ({ fields, ...meta }: TableRecord<D>) => D;
122
+ /**
123
+ * @protected
124
+ */
125
+ mapFields({ fields, ...meta }: TableRecord<DataObject>): D;
126
+ wrapFields(fields: F): D;
127
+ /**
128
+ * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/get}
129
+ */
130
+ getOne(id: string): Promise<D>;
131
+ /**
132
+ * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/create}
133
+ * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/update}
134
+ */
135
+ updateOne(data: F, id?: string): Promise<D>;
136
+ mapFilter(filter: DataObject): F;
137
+ /**
138
+ * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/list}
139
+ */
140
+ openStream(filter: F): AsyncGenerator<D, void, unknown>;
141
+ getViewList(viewId: string, pageIndex?: number, pageSize?: number): Promise<D[]>;
142
+ getViewAll(viewId: string, pageSize?: number): Promise<D[]>;
143
+ stream?: AsyncGenerator<D, void, any> | undefined;
144
+ clearList: (() => void) & (() => void);
145
+ clear: (() => void) & (() => void);
146
+ restoreList: (({ filter, pageIndex, pageSize, allItems, totalCount }?: Partial<Pick<ListModel<D, Partial<import("mobx-restful").NewData<D>>>, "filter" | "pageIndex" | "pageSize" | "allItems" | "totalCount">> | undefined) => Promise<void>) & (({ pageIndex, pageSize, allItems, totalCount }?: Partial<Pick<ListModel<D, Partial<import("mobx-restful").NewData<D>>>, "pageIndex" | "pageSize" | "allItems" | "totalCount">> | undefined) => void);
147
+ loadStream(filter: F, newCount: number): Promise<D[]>;
148
+ loadPage: ((pageIndex: number, pageSize: number, filter: F) => Promise<{
149
+ pageData: D[];
150
+ totalCount: number;
151
+ }>) & ((pageIndex: number, pageSize: number, filter: F) => Promise<PageData<D>>);
105
152
  pageIndex: number;
106
153
  pageSize: number;
107
154
  filter: F;
108
- totalCount: number | undefined;
155
+ totalCount: number;
109
156
  pageList: D[][];
110
157
  readonly currentPage: D[];
111
158
  readonly pageCount: number;
112
159
  readonly allItems: D[];
113
160
  readonly noMore: boolean;
114
161
  statistic: Partial<Record<import("web-utility").TypeKeys<D, import("web-utility").IndexKey>, Record<string, number>>>;
115
- clearList(): void;
116
- clear(): void;
117
- restoreList({ pageIndex, pageSize, allItems, totalCount }?: Partial<Pick<ListModel<D, Partial<import("mobx-restful").NewData<D>>>, "pageIndex" | "pageSize" | "allItems" | "totalCount">> | undefined): void;
118
- turnTo(pageIndex: number, pageSize?: number): ListModel<D, F>;
119
- loadNewPage(pageIndex: number, pageSize: number, filter: F): Promise<{
162
+ turnTo: ((pageIndex: number, pageSize?: number) => ListModel<D, F>) & ((pageIndex: number, pageSize?: number) => ListModel<D, F>);
163
+ loadNewPage: ((pageIndex: number, pageSize: number, filter: F) => Promise<{
164
+ pageData: D[];
165
+ totalCount: number;
166
+ }>) & ((pageIndex: number, pageSize: number, filter: F) => Promise<{
120
167
  pageData: D[];
121
168
  totalCount: number;
122
- }>;
123
- refreshList(): Promise<D[]>;
124
- getAllInStream(filter?: F | undefined, pageSize?: number): AsyncGenerator<D, void, unknown>;
125
- getAll(filter?: F | undefined, pageSize?: number): Promise<D[]>;
126
- countAll(keys: import("web-utility").TypeKeys<D, import("web-utility").IndexKey>[], filter?: F | undefined, pageSize?: number): Promise<Partial<Record<import("web-utility").TypeKeys<D, import("web-utility").IndexKey>, Record<string, number>>>>;
127
- indexOf(id: import("mobx-restful").IDType): number;
128
- changeOne(data: Partial<D>, id: import("mobx-restful").IDType, patch?: boolean): void;
129
- updateOne(data: Partial<import("mobx-restful").NewData<D>>, id?: import("mobx-restful").IDType): Promise<D>;
130
- removeOne(id: import("mobx-restful").IDType): Promise<void>;
131
- deleteOne(id: import("mobx-restful").IDType): Promise<void>;
132
- [Symbol.asyncIterator]: (filter?: F | undefined, pageSize?: number) => AsyncGenerator<D, void, unknown>;
169
+ }>);
170
+ refreshList: (() => Promise<D[]>) & (() => Promise<D[]>);
171
+ getAllInStream: ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<D, void, unknown>) & ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<D, void, unknown>);
172
+ getAll: ((filter?: F | undefined, pageSize?: number) => Promise<D[]>) & ((filter?: F | undefined, pageSize?: number) => Promise<D[]>);
173
+ countAll: ((keys: import("web-utility").TypeKeys<D, import("web-utility").IndexKey>[], filter?: F | undefined, pageSize?: number) => Promise<Partial<Record<import("web-utility").TypeKeys<D, import("web-utility").IndexKey>, Record<string, number>>>>) & ((keys: import("web-utility").TypeKeys<D, import("web-utility").IndexKey>[], filter?: F | undefined, pageSize?: number) => Promise<Partial<Record<import("web-utility").TypeKeys<D, import("web-utility").IndexKey>, Record<string, number>>>>);
174
+ indexOf: ((id: import("mobx-restful").IDType) => number) & ((id: import("mobx-restful").IDType) => number);
175
+ changeOne: ((data: Partial<D>, id: import("mobx-restful").IDType, patch?: boolean) => void) & ((data: Partial<D>, id: import("mobx-restful").IDType, patch?: boolean) => void);
176
+ removeOne: ((id: import("mobx-restful").IDType) => Promise<void>) & ((id: import("mobx-restful").IDType) => Promise<void>);
177
+ deleteOne: ((id: import("mobx-restful").IDType) => Promise<void>) & ((id: import("mobx-restful").IDType) => Promise<void>);
133
178
  indexKey: keyof D;
134
179
  currentOne: D;
135
- clearCurrent(): void;
136
- getOne(id: import("mobx-restful").IDType): Promise<D>;
180
+ clearCurrent: (() => void) & (() => void);
137
181
  downloading: number;
138
182
  uploading: number;
183
+ [Symbol.asyncIterator]: ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<D, void, unknown>) & ((filter?: F | undefined, pageSize?: number) => AsyncGenerator<D, void, unknown>);
139
184
  };
140
185
  interface BiSearchModel extends InstanceType<ReturnType<typeof BiSearch<TableRecordFields, any>>> {
141
186
  }
@@ -202,11 +247,17 @@ export declare function BiTable(): abstract new (id: string) => {
202
247
  sort: Partial<Record<keyof T, "ASC" | "DESC">>;
203
248
  queryOptions: BiDataQueryOptions;
204
249
  currentViewId?: string;
250
+ keyMap?: Partial<Record<keyof T, string>> | undefined;
251
+ readonly nameMap: any;
205
252
  extractFields({ fields, ...meta }: TableRecord<T>): T;
206
253
  /**
207
254
  * @deprecated
208
255
  */
209
256
  normalize: ({ fields, ...meta }: TableRecord<T>) => T;
257
+ /**
258
+ * @protected
259
+ */
260
+ mapFields({ fields, ...meta }: TableRecord<DataObject>): T;
210
261
  wrapFields(fields: F): T;
211
262
  /**
212
263
  * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/get}
@@ -217,6 +268,7 @@ export declare function BiTable(): abstract new (id: string) => {
217
268
  * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/update}
218
269
  */
219
270
  updateOne(data: F, id?: string): Promise<T>;
271
+ mapFilter(filter: DataObject): F;
220
272
  makeFilter(filter: F): string;
221
273
  /**
222
274
  * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/list}
@@ -1,5 +1,6 @@
1
1
  import { DataObject } from 'mobx-restful';
2
2
  import { TableCellLink, TableCellLocation, TableCellRelation, TableCellText } from './type';
3
+ export declare const mapKeys: <I extends DataObject, O extends DataObject>(data: I, map: Partial<Record<keyof I, PropertyKey>>) => O;
3
4
  export type FilterOperator = '<' | '<=' | '=' | '!=' | '=>' | '>' | 'contains';
4
5
  /**
5
6
  * @see https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/filter
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobx-lark",
3
- "version": "2.8.0",
3
+ "version": "2.8.1",
4
4
  "license": "LGPL-3.0",
5
5
  "author": "shiy2008@gmail.com",
6
6
  "description": "Unofficial TypeScript SDK for FeiShu/Lark API, which is based on MobX-RESTful.",
@@ -25,14 +25,14 @@
25
25
  "url": "https://github.com/idea2app/MobX-Lark/issues"
26
26
  },
27
27
  "dependencies": {
28
- "@swc/helpers": "^0.5.20",
28
+ "@swc/helpers": "^0.5.21",
29
29
  "@types/react": "^19.2.14",
30
30
  "koajax": "^3.3.0",
31
31
  "lodash.memoize": "^4.1.2",
32
32
  "mobx": "^6.15.0",
33
33
  "mobx-restful": "^2.1.4",
34
34
  "regenerator-runtime": "^0.14.1",
35
- "web-utility": "^4.6.4"
35
+ "web-utility": "^4.6.5"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": ">=16"
@@ -42,10 +42,10 @@
42
42
  "@parcel/transformer-typescript-tsc": "~2.16.4",
43
43
  "@types/fs-extra": "^11.0.4",
44
44
  "@types/lodash.memoize": "^4.1.9",
45
- "@types/node": "^24.12.0",
45
+ "@types/node": "^24.12.2",
46
46
  "@types/react-dom": "^19.2.3",
47
47
  "@types/turndown": "^5.0.6",
48
- "dotenv": "^17.3.1",
48
+ "dotenv": "^17.4.0",
49
49
  "fs-extra": "^11.3.4",
50
50
  "husky": "^9.1.7",
51
51
  "lint-staged": "^16.4.0",
@@ -54,7 +54,7 @@
54
54
  "react": "^19.2.4",
55
55
  "react-dom": "^19.2.4",
56
56
  "ts-node": "^10.9.2",
57
- "turndown": "^7.2.2",
57
+ "turndown": "^7.2.4",
58
58
  "typedoc": "^0.28.18",
59
59
  "typedoc-plugin-mdn-links": "^5.1.1",
60
60
  "typescript": "~5.8.3"
@@ -13,7 +13,7 @@ import {
13
13
  TableRecordFields,
14
14
  TableView
15
15
  } from './type';
16
- import { makeSimpleFilter } from './utility';
16
+ import { makeSimpleFilter, mapKeys } from './utility';
17
17
 
18
18
  export * from './type';
19
19
  export * from './utility';
@@ -31,13 +31,13 @@ export interface BiDataQueryOptions {
31
31
  /**
32
32
  * @see {@link https://open.feishu.cn/document/ukTMukTMukTM/uUDN04SN0QjL1QDN/bitable-overview}
33
33
  */
34
- export function BiDataTable<T extends DataObject, F extends Filter<T> = Filter<T>>(
34
+ export function BiDataTable<D extends DataObject, F extends Filter<D> = Filter<D>>(
35
35
  Base = ListModel
36
36
  ) {
37
- abstract class BiDataTableModel extends Stream<T, F>(Base) {
38
- requiredKeys: readonly (keyof T)[] = [];
37
+ abstract class BiDataTableModel extends Stream<D, F>(Base) {
38
+ requiredKeys: readonly (keyof D)[] = [];
39
39
 
40
- sort: Partial<Record<keyof T, 'ASC' | 'DESC'>> = {};
40
+ sort: Partial<Record<keyof D, 'ASC' | 'DESC'>> = {};
41
41
 
42
42
  queryOptions: BiDataQueryOptions = {
43
43
  text_field_as_array: true,
@@ -50,7 +50,15 @@ export function BiDataTable<T extends DataObject, F extends Filter<T> = Filter<T
50
50
  this.baseURI = `bitable/v1/apps/${appId}/tables/${tableId}/records`;
51
51
  }
52
52
 
53
- extractFields({ fields, ...meta }: TableRecord<T>): T {
53
+ keyMap?: Partial<Record<keyof D, string>>;
54
+
55
+ get nameMap() {
56
+ return this.keyMap
57
+ ? Object.fromEntries(Object.entries(this.keyMap).map(([key, name]) => [name, key]))
58
+ : {};
59
+ }
60
+
61
+ extractFields({ fields, ...meta }: TableRecord<D>): D {
54
62
  return { ...meta, ...fields };
55
63
  }
56
64
 
@@ -59,8 +67,19 @@ export function BiDataTable<T extends DataObject, F extends Filter<T> = Filter<T
59
67
  */
60
68
  normalize = this.extractFields;
61
69
 
70
+ /**
71
+ * @protected
72
+ */
73
+ mapFields({ fields, ...meta }: TableRecord<DataObject>) {
74
+ const { nameMap } = this;
75
+
76
+ const mappedData = isEmpty(nameMap) ? (fields as D) : (mapKeys(fields, nameMap) as D);
77
+
78
+ return this.normalize({ fields: mappedData, ...meta });
79
+ }
80
+
62
81
  wrapFields(fields: F) {
63
- return fields as unknown as T;
82
+ return fields as unknown as D;
64
83
  }
65
84
 
66
85
  /**
@@ -68,10 +87,10 @@ export function BiDataTable<T extends DataObject, F extends Filter<T> = Filter<T
68
87
  */
69
88
  @toggle('downloading')
70
89
  async getOne(id: string) {
71
- const { body } = await this.client.get<TableRecordData<T>>(
90
+ const { body } = await this.client.get<TableRecordData<D>>(
72
91
  `${this.baseURI}/${id}?${buildURLData(this.queryOptions)}`
73
92
  );
74
- return (this.currentOne = this.normalize(body!.data!.record));
93
+ return (this.currentOne = this.mapFields(body!.data!.record));
75
94
  }
76
95
 
77
96
  /**
@@ -80,29 +99,31 @@ export function BiDataTable<T extends DataObject, F extends Filter<T> = Filter<T
80
99
  */
81
100
  @toggle('uploading')
82
101
  async updateOne(data: F, id?: string) {
83
- const fields = this.wrapFields(data);
102
+ const rawData = this.wrapFields(data);
103
+
104
+ const fields = isEmpty(this.keyMap) ? rawData : (mapKeys(rawData, this.keyMap) as D);
84
105
 
85
106
  const { body } = await (id
86
- ? this.client.put<TableRecordData<T>>(`${this.baseURI}/${id}`, {
87
- fields
88
- })
89
- : this.client.post<TableRecordData<T>>(this.baseURI, {
90
- fields
91
- }));
92
- return (this.currentOne = this.normalize(body!.data!.record));
107
+ ? this.client.put<TableRecordData<D>>(`${this.baseURI}/${id}`, { fields })
108
+ : this.client.post<TableRecordData<D>>(this.baseURI, { fields }));
109
+
110
+ return (this.currentOne = this.mapFields(body!.data!.record));
111
+ }
112
+
113
+ mapFilter(filter: DataObject) {
114
+ return isEmpty(this.keyMap) ? (filter as F) : (mapKeys(filter, this.keyMap) as F);
93
115
  }
94
116
 
95
117
  makeFilter(filter: F) {
96
- return [
118
+ const requiredFilter =
97
119
  this.requiredKeys[0] &&
98
- makeSimpleFilter(
99
- Object.fromEntries(this.requiredKeys.map(key => [key, ''])),
100
- '!='
101
- ),
102
- !isEmpty(filter) && makeSimpleFilter(filter)
103
- ]
104
- .filter(Boolean)
105
- .join('&&');
120
+ makeSimpleFilter(
121
+ this.mapFilter(Object.fromEntries(this.requiredKeys.map(key => [key, '']))),
122
+ '!='
123
+ );
124
+ const customFilter = !isEmpty(filter) && makeSimpleFilter(this.mapFilter(filter));
125
+
126
+ return [requiredFilter, customFilter].filter(Boolean).join('&&');
106
127
  }
107
128
 
108
129
  /**
@@ -118,13 +139,13 @@ export function BiDataTable<T extends DataObject, F extends Filter<T> = Filter<T
118
139
  Object.entries(this.sort).map(([key, order]) => `${key} ${order}`)
119
140
  )
120
141
  };
121
- const stream = createPageStream<TableRecord<T>>(
142
+ const stream = createPageStream<TableRecord<DataObject>>(
122
143
  this.client,
123
144
  this.baseURI,
124
145
  total => (this.totalCount = total),
125
146
  { ...searchParams, ...this.queryOptions }
126
147
  );
127
- for await (const item of stream) yield this.normalize(item);
148
+ for await (const item of stream) yield this.mapFields(item);
128
149
  }
129
150
 
130
151
  async getViewList(
@@ -157,12 +178,11 @@ export type BiSearchFilter<D extends DataObject> = Filter<D> & {
157
178
  };
158
179
 
159
180
  export function BiSearch<D extends DataObject, F extends BiSearchFilter<D> = BiSearchFilter<D>>(
160
- Model: Constructor<ListModel<D, F>>
181
+ Model: ReturnType<typeof BiDataTable<D, F>>
161
182
  ) {
162
183
  abstract class BiSearchModel extends Model {
163
184
  declare baseURI: string;
164
185
  declare client: RESTClient;
165
- declare loadPage: (pageIndex: number, pageSize: number, filter: F) => Promise<PageData<D>>;
166
186
 
167
187
  abstract searchKeys: readonly (keyof TableRecordFields)[];
168
188
 
@@ -170,7 +190,9 @@ export function BiSearch<D extends DataObject, F extends BiSearchFilter<D> = BiS
170
190
  accessor keywords = '';
171
191
 
172
192
  makeFilter(filter: F) {
173
- return isEmpty(filter) ? '' : makeSimpleFilter(filter, 'contains', 'OR');
193
+ return isEmpty(filter)
194
+ ? ''
195
+ : makeSimpleFilter(this.mapFilter(filter), 'contains', 'OR');
174
196
  }
175
197
 
176
198
  async getList(
@@ -1,10 +1,13 @@
1
1
  import { DataObject } from 'mobx-restful';
2
- import {
3
- TableCellLink,
4
- TableCellLocation,
5
- TableCellRelation,
6
- TableCellText
7
- } from './type';
2
+ import { TableCellLink, TableCellLocation, TableCellRelation, TableCellText } from './type';
3
+
4
+ export const mapKeys = <I extends DataObject, O extends DataObject>(
5
+ data: I,
6
+ map: Partial<Record<keyof I, PropertyKey>>
7
+ ) =>
8
+ Object.fromEntries(
9
+ Object.entries(data).map(([key, value]) => [map[key as keyof I] || key, value])
10
+ ) as O;
8
11
 
9
12
  export type FilterOperator = '<' | '<=' | '=' | '!=' | '=>' | '>' | 'contains';
10
13
 
@@ -34,9 +37,7 @@ export function makeSimpleFilter(
34
37
  return list[1] ? `${relation}(${list})` : list[0];
35
38
  }
36
39
 
37
- export const normalizeText = (
38
- value: TableCellText | TableCellLink | TableCellRelation
39
- ) =>
40
+ export const normalizeText = (value: TableCellText | TableCellLink | TableCellRelation) =>
40
41
  (value && typeof value === 'object' && 'text' in value && value.text) || '';
41
42
 
42
43
  export const normalizeTextArray = (list: TableCellText[]) =>
@@ -50,8 +51,7 @@ export const normalizeTextArray = (list: TableCellText[]) =>
50
51
  ['']
51
52
  );
52
53
  export function coordinateOf(location: TableCellLocation): [number, number] {
53
- const [longitude, latitude] =
54
- (location as TableCellLocation)?.location.split(',') || [];
54
+ const [longitude, latitude] = (location as TableCellLocation)?.location.split(',') || [];
55
55
 
56
56
  return [+latitude, +longitude];
57
57
  }