mobx-lark 2.1.1 → 2.2.0
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.
- package/LICENSE +165 -165
- package/ReadMe.md +39 -39
- package/dist/Lark.d.ts +7 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/module/BITable/index.d.ts +14 -4
- package/package.json +5 -5
- package/src/Lark.ts +242 -226
- package/src/index.ts +3 -3
- package/src/module/BITable/index.ts +294 -283
- package/src/module/BITable/type.ts +120 -120
- package/src/module/BITable/utility.ts +57 -57
- package/src/module/InstantMessenger/index.ts +82 -82
- package/src/module/InstantMessenger/type/index.ts +60 -60
- package/src/module/InstantMessenger/type/message.ts +141 -141
- package/src/module/SpreadSheet/index.ts +78 -78
- package/src/module/SpreadSheet/type.ts +31 -31
- package/src/module/Task/index.ts +278 -278
- package/src/module/Task/type.ts +168 -168
- package/src/module/Wiki/type.ts +16 -16
- package/src/module/base.ts +34 -34
- package/src/module/index.ts +6 -6
- package/src/type.ts +75 -75
- package/tsconfig.json +21 -21
|
@@ -1,283 +1,294 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DataObject,
|
|
3
|
-
Filter,
|
|
4
|
-
ListModel,
|
|
5
|
-
PageData,
|
|
6
|
-
RESTClient,
|
|
7
|
-
Stream,
|
|
8
|
-
toggle
|
|
9
|
-
} from 'mobx-restful';
|
|
10
|
-
import { buildURLData, Constructor, isEmpty } from 'web-utility';
|
|
11
|
-
|
|
12
|
-
import { UserIdType } from '../../type';
|
|
13
|
-
import { createPageStream } from '../base';
|
|
14
|
-
import {
|
|
15
|
-
BITable,
|
|
16
|
-
LarkFormData,
|
|
17
|
-
TableFormView,
|
|
18
|
-
TableRecord,
|
|
19
|
-
TableRecordData,
|
|
20
|
-
TableRecordFields,
|
|
21
|
-
TableView
|
|
22
|
-
} from './type';
|
|
23
|
-
import { makeSimpleFilter } from './utility';
|
|
24
|
-
|
|
25
|
-
export * from './type';
|
|
26
|
-
export * from './utility';
|
|
27
|
-
|
|
28
|
-
export type BiBaseData = Omit<
|
|
29
|
-
TableRecord<{}>,
|
|
30
|
-
`record_${'id' | 'url'}` | 'fields'
|
|
31
|
-
>;
|
|
32
|
-
|
|
33
|
-
export interface BiDataQueryOptions {
|
|
34
|
-
text_field_as_array?: boolean;
|
|
35
|
-
automatic_fields?: boolean;
|
|
36
|
-
display_formula_ref?: boolean;
|
|
37
|
-
with_shared_url?: boolean;
|
|
38
|
-
user_id_type?: UserIdType;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* @see {@link https://open.feishu.cn/document/ukTMukTMukTM/uUDN04SN0QjL1QDN/bitable-overview}
|
|
43
|
-
*/
|
|
44
|
-
export function BiDataTable<
|
|
45
|
-
T extends DataObject,
|
|
46
|
-
F extends Filter<T> = Filter<T>
|
|
47
|
-
>(Base = ListModel) {
|
|
48
|
-
abstract class BiDataTableModel extends Stream<T, F>(Base) {
|
|
49
|
-
requiredKeys: readonly (keyof T)[] = [];
|
|
50
|
-
|
|
51
|
-
sort: Partial<Record<keyof T, 'ASC' | 'DESC'>> = {};
|
|
52
|
-
|
|
53
|
-
queryOptions: BiDataQueryOptions = {
|
|
54
|
-
text_field_as_array: true,
|
|
55
|
-
automatic_fields: true
|
|
56
|
-
};
|
|
57
|
-
currentViewId?: string;
|
|
58
|
-
|
|
59
|
-
constructor(appId: string, tableId: string) {
|
|
60
|
-
super();
|
|
61
|
-
this.baseURI = `bitable/v1/apps/${appId}/tables/${tableId}/records`;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return { ...meta, ...fields };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* @
|
|
70
|
-
*/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
this.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
this.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
)
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
1
|
+
import {
|
|
2
|
+
DataObject,
|
|
3
|
+
Filter,
|
|
4
|
+
ListModel,
|
|
5
|
+
PageData,
|
|
6
|
+
RESTClient,
|
|
7
|
+
Stream,
|
|
8
|
+
toggle
|
|
9
|
+
} from 'mobx-restful';
|
|
10
|
+
import { buildURLData, Constructor, isEmpty } from 'web-utility';
|
|
11
|
+
|
|
12
|
+
import { UserIdType } from '../../type';
|
|
13
|
+
import { createPageStream } from '../base';
|
|
14
|
+
import {
|
|
15
|
+
BITable,
|
|
16
|
+
LarkFormData,
|
|
17
|
+
TableFormView,
|
|
18
|
+
TableRecord,
|
|
19
|
+
TableRecordData,
|
|
20
|
+
TableRecordFields,
|
|
21
|
+
TableView
|
|
22
|
+
} from './type';
|
|
23
|
+
import { makeSimpleFilter } from './utility';
|
|
24
|
+
|
|
25
|
+
export * from './type';
|
|
26
|
+
export * from './utility';
|
|
27
|
+
|
|
28
|
+
export type BiBaseData = Omit<
|
|
29
|
+
TableRecord<{}>,
|
|
30
|
+
`record_${'id' | 'url'}` | 'fields'
|
|
31
|
+
>;
|
|
32
|
+
|
|
33
|
+
export interface BiDataQueryOptions {
|
|
34
|
+
text_field_as_array?: boolean;
|
|
35
|
+
automatic_fields?: boolean;
|
|
36
|
+
display_formula_ref?: boolean;
|
|
37
|
+
with_shared_url?: boolean;
|
|
38
|
+
user_id_type?: UserIdType;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @see {@link https://open.feishu.cn/document/ukTMukTMukTM/uUDN04SN0QjL1QDN/bitable-overview}
|
|
43
|
+
*/
|
|
44
|
+
export function BiDataTable<
|
|
45
|
+
T extends DataObject,
|
|
46
|
+
F extends Filter<T> = Filter<T>
|
|
47
|
+
>(Base = ListModel) {
|
|
48
|
+
abstract class BiDataTableModel extends Stream<T, F>(Base) {
|
|
49
|
+
requiredKeys: readonly (keyof T)[] = [];
|
|
50
|
+
|
|
51
|
+
sort: Partial<Record<keyof T, 'ASC' | 'DESC'>> = {};
|
|
52
|
+
|
|
53
|
+
queryOptions: BiDataQueryOptions = {
|
|
54
|
+
text_field_as_array: true,
|
|
55
|
+
automatic_fields: true
|
|
56
|
+
};
|
|
57
|
+
currentViewId?: string;
|
|
58
|
+
|
|
59
|
+
constructor(appId: string, tableId: string) {
|
|
60
|
+
super();
|
|
61
|
+
this.baseURI = `bitable/v1/apps/${appId}/tables/${tableId}/records`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
extractFields({ fields, ...meta }: TableRecord<T>): T {
|
|
65
|
+
return { ...meta, ...fields };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @deprecated
|
|
70
|
+
*/
|
|
71
|
+
normalize = this.extractFields;
|
|
72
|
+
|
|
73
|
+
wrapFields(fields: F) {
|
|
74
|
+
return fields as unknown as T;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/get}
|
|
79
|
+
*/
|
|
80
|
+
@toggle('downloading')
|
|
81
|
+
async getOne(id: string) {
|
|
82
|
+
const { body } = await this.client.get<TableRecordData<T>>(
|
|
83
|
+
`${this.baseURI}/${id}?${buildURLData(this.queryOptions)}`
|
|
84
|
+
);
|
|
85
|
+
return (this.currentOne = this.normalize(body!.data!.record));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/create}
|
|
90
|
+
* @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/update}
|
|
91
|
+
*/
|
|
92
|
+
@toggle('uploading')
|
|
93
|
+
async updateOne(data: F, id?: string) {
|
|
94
|
+
const fields = this.wrapFields(data);
|
|
95
|
+
|
|
96
|
+
const { body } = await (id
|
|
97
|
+
? this.client.put<TableRecordData<T>>(`${this.baseURI}/${id}`, {
|
|
98
|
+
fields
|
|
99
|
+
})
|
|
100
|
+
: this.client.post<TableRecordData<T>>(this.baseURI, {
|
|
101
|
+
fields
|
|
102
|
+
}));
|
|
103
|
+
return (this.currentOne = this.normalize(body!.data!.record));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
makeFilter(filter: F) {
|
|
107
|
+
return [
|
|
108
|
+
this.requiredKeys[0] &&
|
|
109
|
+
makeSimpleFilter(
|
|
110
|
+
Object.fromEntries(
|
|
111
|
+
this.requiredKeys.map(key => [key, ''])
|
|
112
|
+
),
|
|
113
|
+
'!='
|
|
114
|
+
),
|
|
115
|
+
!isEmpty(filter) && makeSimpleFilter(filter)
|
|
116
|
+
]
|
|
117
|
+
.filter(Boolean)
|
|
118
|
+
.join('&&');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/list}
|
|
123
|
+
*/
|
|
124
|
+
async *openStream(filter: F) {
|
|
125
|
+
const view_id = this.currentViewId;
|
|
126
|
+
const searchParams = view_id
|
|
127
|
+
? { view_id }
|
|
128
|
+
: {
|
|
129
|
+
filter: this.makeFilter(filter),
|
|
130
|
+
sort: JSON.stringify(
|
|
131
|
+
Object.entries(this.sort).map(
|
|
132
|
+
([key, order]) => `${key} ${order}`
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
};
|
|
136
|
+
const stream = createPageStream<TableRecord<T>>(
|
|
137
|
+
this.client,
|
|
138
|
+
this.baseURI,
|
|
139
|
+
total => (this.totalCount = total),
|
|
140
|
+
{ ...searchParams, ...this.queryOptions }
|
|
141
|
+
);
|
|
142
|
+
for await (const item of stream) yield this.normalize(item);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async getViewList(
|
|
146
|
+
viewId: string,
|
|
147
|
+
pageIndex = this.pageIndex + 1,
|
|
148
|
+
pageSize = this.pageSize
|
|
149
|
+
) {
|
|
150
|
+
try {
|
|
151
|
+
this.currentViewId = viewId;
|
|
152
|
+
|
|
153
|
+
return await this.getList({} as F, pageIndex, pageSize);
|
|
154
|
+
} finally {
|
|
155
|
+
this.currentViewId = undefined;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async getViewAll(viewId: string, pageSize = this.pageSize) {
|
|
160
|
+
this.clearList();
|
|
161
|
+
|
|
162
|
+
while (!this.noMore)
|
|
163
|
+
await this.getViewList(viewId, undefined, pageSize);
|
|
164
|
+
|
|
165
|
+
return this.allItems;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return BiDataTableModel;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function BiSearch<D extends DataObject, F extends Filter<D> = Filter<D>>(
|
|
172
|
+
Model: Constructor<ListModel<D, F>>
|
|
173
|
+
) {
|
|
174
|
+
abstract class BiSearchModel extends Model {
|
|
175
|
+
declare baseURI: string;
|
|
176
|
+
declare client: RESTClient;
|
|
177
|
+
declare loadPage: (
|
|
178
|
+
pageIndex: number,
|
|
179
|
+
pageSize: number,
|
|
180
|
+
filter: F
|
|
181
|
+
) => Promise<PageData<D>>;
|
|
182
|
+
|
|
183
|
+
abstract searchKeys: readonly (keyof TableRecordFields)[];
|
|
184
|
+
|
|
185
|
+
makeFilter(filter: F) {
|
|
186
|
+
return isEmpty(filter)
|
|
187
|
+
? ''
|
|
188
|
+
: makeSimpleFilter(filter, 'contains', 'OR');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async getSearchList(
|
|
192
|
+
keywords: string,
|
|
193
|
+
pageIndex = this.pageIndex + 1,
|
|
194
|
+
pageSize = this.pageSize
|
|
195
|
+
) {
|
|
196
|
+
const wordList = keywords.split(/[\s,]+/);
|
|
197
|
+
const filterList = this.searchKeys.map(key => [key, wordList]);
|
|
198
|
+
|
|
199
|
+
return this.getList(
|
|
200
|
+
Object.fromEntries(filterList),
|
|
201
|
+
pageIndex,
|
|
202
|
+
pageSize
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return BiSearchModel;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
interface BiSearchModel
|
|
210
|
+
extends InstanceType<ReturnType<typeof BiSearch<TableRecordFields, any>>> {}
|
|
211
|
+
|
|
212
|
+
export type BiSearchModelClass = Constructor<BiSearchModel>;
|
|
213
|
+
|
|
214
|
+
export function BiTableView<
|
|
215
|
+
T extends TableView['view_type'],
|
|
216
|
+
D extends T extends 'form' ? TableFormView : TableView
|
|
217
|
+
>(type = 'grid' as T) {
|
|
218
|
+
abstract class BiTableViewModel extends Stream<D>(ListModel) {
|
|
219
|
+
constructor(appId: string, tableId: string) {
|
|
220
|
+
super();
|
|
221
|
+
this.baseURI = `bitable/v1/apps/${appId}/tables/${tableId}/views`;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-view/list}
|
|
226
|
+
* @see {@link https://open.feishu.cn/document/server-docs/docs/bitable-v1/form/get}
|
|
227
|
+
*/
|
|
228
|
+
async *openStream() {
|
|
229
|
+
for await (const item of createPageStream<TableView>(
|
|
230
|
+
this.client,
|
|
231
|
+
this.baseURI,
|
|
232
|
+
total => (this.totalCount = total)
|
|
233
|
+
))
|
|
234
|
+
if (type !== 'form') {
|
|
235
|
+
if (item.view_type === type) yield item as D;
|
|
236
|
+
} else if (item.view_type === 'form') {
|
|
237
|
+
const { body } = await this.client.get<LarkFormData>(
|
|
238
|
+
this.baseURI.replace(/views$/, `forms/${item.view_id}`)
|
|
239
|
+
);
|
|
240
|
+
yield body!.data!.form as D;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return BiTableViewModel;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export type BiDataTableClass<
|
|
248
|
+
T extends DataObject,
|
|
249
|
+
F extends Filter<T> = Filter<T>
|
|
250
|
+
> = ReturnType<typeof BiDataTable<T, F>>;
|
|
251
|
+
|
|
252
|
+
export function BiTable() {
|
|
253
|
+
abstract class BiTableModel extends Stream<BITable>(ListModel) {
|
|
254
|
+
constructor(public id: string) {
|
|
255
|
+
super();
|
|
256
|
+
this.baseURI = `bitable/v1/apps/${id}/tables`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
currentDataTable?: ListModel<any>;
|
|
260
|
+
|
|
261
|
+
async getOne<T extends DataObject, F extends Filter<T>>(
|
|
262
|
+
tableName: string,
|
|
263
|
+
DataTableClass?: BiDataTableClass<T, F>
|
|
264
|
+
) {
|
|
265
|
+
const { allItems } = this;
|
|
266
|
+
|
|
267
|
+
const list = allItems[0] ? allItems : await this.getAll();
|
|
268
|
+
|
|
269
|
+
const table = list.find(({ name }) => name === tableName);
|
|
270
|
+
|
|
271
|
+
if (!table) throw new URIError(`Table "${tableName}" is not found`);
|
|
272
|
+
|
|
273
|
+
if (DataTableClass instanceof Function)
|
|
274
|
+
this.currentDataTable = Reflect.construct(DataTableClass, [
|
|
275
|
+
this.id,
|
|
276
|
+
table.table_id
|
|
277
|
+
]);
|
|
278
|
+
return (this.currentOne = table);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table/list}
|
|
283
|
+
*/
|
|
284
|
+
async *openStream() {
|
|
285
|
+
for await (const item of createPageStream<BITable>(
|
|
286
|
+
this.client,
|
|
287
|
+
this.baseURI,
|
|
288
|
+
total => (this.totalCount = total)
|
|
289
|
+
))
|
|
290
|
+
yield item;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return BiTableModel;
|
|
294
|
+
}
|