mobx-lark 2.8.1 → 2.10.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.
@@ -97,7 +97,7 @@ export declare function BiDataTable<D extends DataObject, F extends Filter<D> =
97
97
  export type BiSearchFilter<D extends DataObject> = Filter<D> & {
98
98
  keywords?: string;
99
99
  };
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) => {
100
+ export declare function BiSearch<D extends DataObject, F extends BiSearchFilter<D> = BiSearchFilter<D>, M extends ReturnType<typeof BiDataTable<D, F>> = ReturnType<typeof BiDataTable<D, F>>>(Model: M): abstract new (appId: string, tableId: string) => {
101
101
  baseURI: string;
102
102
  client: RESTClient;
103
103
  searchKeys: readonly (keyof TableRecordFields)[];
@@ -6,4 +6,4 @@ export declare function registerBlocks<T extends Block<any, any, any>>(blocks: T
6
6
  export declare const ChildrenRenderer: FC<{
7
7
  children?: string[];
8
8
  }>;
9
- export declare function renderBlocks(blocks: Block<any, any, any>[]): import("react/jsx-runtime").JSX.Element;
9
+ export declare function renderBlocks(blocks: Block<any, any, any>[]): import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { BaseModel, RESTClient } from 'mobx-restful';
2
- import { TaxiInvoice, TrainInvoice, VatInvoice, VehicleInvoice } from './type';
2
+ import { BankCardEntity, BusinessCard, BusinessLicense, Contract, IDCard, Resume, TaxiInvoice, TrainInvoice, VatInvoice, VehicleInvoice } from './type';
3
3
  export * from './type';
4
4
  export declare abstract class DocumentAIModel extends BaseModel {
5
5
  baseURI: string;
@@ -28,4 +28,32 @@ export declare abstract class DocumentAIModel extends BaseModel {
28
28
  recognizeVehicleInvoice(file: File): Promise<{
29
29
  entities: VehicleInvoice[];
30
30
  }>;
31
+ /**
32
+ * @see {@link https://open.feishu.cn/document/server-docs/ai/optical_char_recognition-v1/basic_recognize}
33
+ */
34
+ recognizeText(image: File): Promise<string[]>;
35
+ /**
36
+ * @see {@link https://open.feishu.cn/document/ai/document_ai-v1/bank_card/recognize}
37
+ */
38
+ recognizeBankCard(file: File): Promise<BankCardEntity[]>;
39
+ /**
40
+ * @see {@link https://open.feishu.cn/document/ai/document_ai-v1/id_card/recognize}
41
+ */
42
+ recognizeIDCard(file: File): Promise<IDCard>;
43
+ /**
44
+ * @see {@link https://open.feishu.cn/document/server-docs/ai/document_ai-v1/business_card/recognize}
45
+ */
46
+ recognizeBusinessCard(file: File): Promise<BusinessCard[]>;
47
+ /**
48
+ * @see {@link https://open.feishu.cn/document/ai/document_ai-v1/business_license/recognize}
49
+ */
50
+ recognizeBusinessLicense(file: File): Promise<BusinessLicense>;
51
+ /**
52
+ * @see {@link https://open.feishu.cn/document/ai/document_ai-v1/resume/parse}
53
+ */
54
+ parseResume(file: File): Promise<Resume[]>;
55
+ /**
56
+ * @see {@link https://open.feishu.cn/document/server-docs/ai/document_ai-v1/contract/field_extraction}
57
+ */
58
+ extractContract(file: File, ocr_mode?: 'unused' | 'force' | 'auto', pdf_page_limit?: number): Promise<Contract>;
31
59
  }
@@ -1,3 +1,4 @@
1
+ import { Gender } from '../User/type';
1
2
  export type InvoiceEntityType = `invoice_${'code' | 'no' | 'special_seal'}` | `seller_${'name' | 'taxpayer_no'}_in_seal`;
2
3
  export type TrafficInvoiceEntityType = 'total_amount' | 'price';
3
4
  export interface VatInvoice {
@@ -17,3 +18,110 @@ export interface VehicleInvoice {
17
18
  type: 'date' | `invoice_${'code' | 'num'}` | `print_${'code' | 'num'}` | `buyer_${'name' | 'id'}` | `saler_${'name' | 'id' | 'addr'}` | 'vehicle_type' | 'product_model' | `${'certificate' | 'machine' | 'engine'}_num` | 'vin' | `tax${'' | '_rate'}` | 'price' | `total_price${'' | '_little'}`;
18
19
  value: string;
19
20
  }
21
+ export interface BankCardEntity {
22
+ type: 'card_number' | 'date_of_expiry';
23
+ value: string;
24
+ }
25
+ export interface IDCardEntity {
26
+ type: `identity_${'code' | 'name'}` | 'birth' | 'gender' | 'race' | 'address' | 'issued_by' | `valid_date_${'start' | 'end'}`;
27
+ value: string;
28
+ }
29
+ export declare enum IDCardSide {
30
+ Cover = 0,
31
+ Profile = 1
32
+ }
33
+ export interface IDCard {
34
+ entities: IDCardEntity[];
35
+ side: IDCardSide;
36
+ corners: number[];
37
+ }
38
+ export interface BusinessCardEntity {
39
+ type: `${'contact' | 'company'}_names` | 'departments' | 'job_titles' | 'emails' | 'websites' | 'addresses' | `${'mobile' | 'work' | 'other'}_phones` | 'faxes';
40
+ value: string;
41
+ }
42
+ export interface BusinessCard {
43
+ entities: BusinessCardEntity[];
44
+ }
45
+ export interface BusinessLicenseEntity {
46
+ type: 'certificate_type' | 'unified_social_credit_code' | `company_${'name' | 'type'}` | 'domicile' | 'legal_representative' | 'registered_capital' | `established_${'time' | 'date'}` | 'business_scope' | 'approval_date' | 'website';
47
+ value: string;
48
+ }
49
+ export interface BusinessLicense {
50
+ entities: BusinessLicenseEntity[];
51
+ }
52
+ export type ResumePeriod = Record<`${'start' | 'end'}_${'date' | 'time'}`, string>;
53
+ export declare enum EducationQualification {
54
+ PrimarySchool = 1,
55
+ JuniorHighSchool = 2,
56
+ VocationalHighSchool = 3,
57
+ HighSchool = 4,
58
+ AssociateDegree = 5,
59
+ BachelorDegree = 6,
60
+ MasterDegree = 7,
61
+ Doctorate = 8,
62
+ Other = 9
63
+ }
64
+ export interface ResumeEducation extends ResumePeriod, Record<'school' | 'major' | 'degree', string> {
65
+ qualification: EducationQualification;
66
+ }
67
+ export declare enum CareerType {
68
+ Internship = 1,
69
+ FullTime = 2
70
+ }
71
+ export interface ResumeCareer extends ResumePeriod, Record<'company' | 'title' | 'type_str' | 'job_description', string> {
72
+ type: CareerType;
73
+ }
74
+ export type ResumeProject = ResumePeriod & Record<'name' | 'title' | 'description', string>;
75
+ export interface ResumeLanguage {
76
+ level: number;
77
+ description: string;
78
+ }
79
+ export type ResumeAward = Record<'award' | 'date' | 'description', string>;
80
+ export type ResumeCertificate = Record<'name' | 'desc', string>;
81
+ export type ResumeCompetition = ResumeCertificate;
82
+ export interface Resume extends Record<'file_md5' | `${'' | 'new_'}content` | 'name' | 'email' | 'mobile' | 'country_code' | 'date_of_birth' | `${'current' | 'home'}_location` | 'self_evaluation', string>, Record<`willing_${'positions' | 'locations'}` | 'urls' | 'social_links', string[]> {
83
+ mobile_is_virtual: boolean;
84
+ educations: ResumeEducation[];
85
+ careers: ResumeCareer[];
86
+ projects: ResumeProject[];
87
+ work_year: number | null;
88
+ gender: Gender;
89
+ languages: ResumeLanguage[];
90
+ awards: ResumeAward[];
91
+ certificates: ResumeCertificate[];
92
+ competitions: ResumeCompetition[];
93
+ }
94
+ export interface ContractPrice {
95
+ contract_price: number;
96
+ contract_price_original: string;
97
+ text: string;
98
+ }
99
+ export type ContractInitialTerm = Record<`initial_${'time' | 'unit'}`, string>;
100
+ export interface ContractTime extends Record<`${'' | 'original_'}time_${'start' | 'end'}` | `text_${'start' | 'end' | 'initial_term'}`, string> {
101
+ initial_term: ContractInitialTerm;
102
+ }
103
+ export interface ContractCopy extends Record<'original_copy' | 'key' | 'text', string> {
104
+ copy_num: number;
105
+ }
106
+ export type ContractCurrency = Record<`currency_${'name' | 'text'}`, string>;
107
+ export type ContractBodyType = 'buy' | 'sell' | 'third';
108
+ export type ContractContact = Record<'contacts' | 'id_number' | 'phone' | 'email' | 'address', string>;
109
+ export type ContractBodyEntity = ContractContact & Record<'legal_representative' | 'party', string>;
110
+ export interface ContractBodyInfo {
111
+ body_type: ContractBodyType;
112
+ value: ContractBodyEntity;
113
+ }
114
+ export type ContractBankType = `${'buy' | 'sell' | 'third' | 'uncertain'}_bank`;
115
+ export type ContractBankEntity = ContractContact & Record<'bank_name' | `account_${'name' | 'number'}` | 'tax_number', string>;
116
+ export interface ContractBankInfo {
117
+ bank_type: ContractBankType;
118
+ value: ContractBankEntity;
119
+ }
120
+ export interface Contract extends Record<'file_id' | 'header', string> {
121
+ price: ContractPrice;
122
+ time: ContractTime;
123
+ copy: ContractCopy;
124
+ currency: ContractCurrency;
125
+ body_info: ContractBodyInfo[];
126
+ bank_info: ContractBankInfo[];
127
+ }
@@ -1,7 +1,7 @@
1
1
  import { BaseListModel, RESTClient } from 'mobx-restful';
2
2
  import { LarkDocumentType, UploadTargetType } from '../../type';
3
3
  import { UserIdType } from '../User/type';
4
- import { CopiedFile, DriveFile, DriveFileType, TransferOwner, TransferOption } from './type';
4
+ import { CopiedFile, DriveFile, DriveFileType, PublicFileType, PublicPermission, PublicPermissionPatch, TransferOption, TransferOwner } from './type';
5
5
  export * from './type';
6
6
  export declare abstract class DriveFileModel extends BaseListModel<DriveFile> {
7
7
  baseURI: string;
@@ -29,6 +29,14 @@ export declare abstract class DriveFileModel extends BaseListModel<DriveFile> {
29
29
  * @see {@link https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/drive-v1/file/copy}
30
30
  */
31
31
  copyOne(type: LarkDocumentType, file_token: string, name?: string, folder_token?: string, user_id_type?: UserIdType): Promise<CopiedFile>;
32
+ /**
33
+ * @see {@link https://open.feishu.cn/document/server-docs/docs/permission/permission-public/patch-2}
34
+ */
35
+ updatePublicPermission(type: PublicFileType, token: string, permission: PublicPermissionPatch): Promise<PublicPermission>;
36
+ /**
37
+ * @see {@link https://open.feishu.cn/document/server-docs/docs/permission/permission-public/permission-public-password/create}
38
+ */
39
+ createPublicPassword(type: PublicFileType, token: string): Promise<string>;
32
40
  /**
33
41
  * @see {@link https://open.feishu.cn/document/server-docs/docs/permission/permission-member/transfer_owner}
34
42
  */
@@ -2,6 +2,31 @@ import { LarkDocumentType } from '../../type';
2
2
  export type DriveFile = Record<`doc_${'token' | 'type'}` | 'title' | 'owner_id' | 'create_time' | `latest_modify_${'user' | 'time'}` | 'url' | 'sec_label_name', string>;
3
3
  export type CopiedFile = Record<'type' | `${'parent_' | ''}token` | 'name' | 'url', string>;
4
4
  export type DriveFileType = LarkDocumentType | 'minutes' | 'folder' | 'wiki';
5
+ export type PublicFileType = Exclude<DriveFileType, 'folder'>;
6
+ type PublicEditableLevel = 'view' | 'edit';
7
+ type PublicLinkAccessLevel = 'readable' | 'editable';
8
+ type PublicLinkShareScope = `${'' | 'partner_'}tenant` | 'anyone';
9
+ export type PublicCommentEntity = `anyone_can_${PublicEditableLevel}`;
10
+ export type PublicPermissionLevel = PublicCommentEntity | 'only_full_access';
11
+ export type PublicShareEntity = 'anyone' | 'same_tenant';
12
+ export type PublicCollaboratorEntity = `collaborator_can_${PublicEditableLevel}` | 'collaborator_full_access';
13
+ export type PublicExternalAccessEntity = 'open' | 'closed' | 'allow_share_partner_tenant';
14
+ export type PublicLinkShareEntity = `${PublicLinkShareScope}_${PublicLinkAccessLevel}` | 'closed';
15
+ export interface PublicPermission {
16
+ external_access_entity: PublicExternalAccessEntity;
17
+ security_entity: PublicPermissionLevel;
18
+ comment_entity: PublicCommentEntity;
19
+ share_entity: PublicShareEntity;
20
+ manage_collaborator_entity: PublicCollaboratorEntity;
21
+ link_share_entity: PublicLinkShareEntity;
22
+ copy_entity: PublicPermissionLevel;
23
+ lock_switch: boolean;
24
+ }
25
+ export type PublicPermissionPatch = Partial<Omit<PublicPermission, 'lock_switch'>>;
26
+ export interface PublishedFile {
27
+ permission: PublicPermission;
28
+ password?: string;
29
+ }
5
30
  export interface TransferOwner {
6
31
  member_type: 'email' | 'userid' | 'openid';
7
32
  member_id: string;
@@ -12,3 +37,4 @@ export interface TransferOption {
12
37
  stay_put?: boolean;
13
38
  old_owner_perm?: 'view' | 'edit' | 'full_access';
14
39
  }
40
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobx-lark",
3
- "version": "2.8.1",
3
+ "version": "2.10.0",
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.21",
29
- "@types/react": "^19.2.14",
28
+ "@swc/helpers": "^0.5.23",
29
+ "@types/react": "^19.2.17",
30
30
  "koajax": "^3.3.0",
31
31
  "lodash.memoize": "^4.1.2",
32
- "mobx": "^6.15.0",
32
+ "mobx": "^6.16.1",
33
33
  "mobx-restful": "^2.1.4",
34
34
  "regenerator-runtime": "^0.14.1",
35
- "web-utility": "^4.6.5"
35
+ "web-utility": "^4.6.6"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": ">=16"
@@ -42,31 +42,23 @@
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.2",
45
+ "@types/node": "^24.13.2",
46
46
  "@types/react-dom": "^19.2.3",
47
47
  "@types/turndown": "^5.0.6",
48
- "dotenv": "^17.4.0",
49
- "fs-extra": "^11.3.4",
48
+ "dotenv": "^17.4.2",
49
+ "fs-extra": "^11.3.5",
50
50
  "husky": "^9.1.7",
51
- "lint-staged": "^16.4.0",
51
+ "lint-staged": "^17.0.8",
52
52
  "parcel": "~2.16.4",
53
- "prettier": "^3.8.1",
54
- "react": "^19.2.4",
55
- "react-dom": "^19.2.4",
53
+ "prettier": "^3.8.4",
54
+ "react": "^19.2.7",
55
+ "react-dom": "^19.2.7",
56
56
  "ts-node": "^10.9.2",
57
57
  "turndown": "^7.2.4",
58
- "typedoc": "^0.28.18",
58
+ "typedoc": "^0.28.19",
59
59
  "typedoc-plugin-mdn-links": "^5.1.1",
60
60
  "typescript": "~5.8.3"
61
61
  },
62
- "pnpm": {
63
- "onlyBuiltDependencies": [
64
- "@parcel/watcher",
65
- "@swc/core",
66
- "lmdb",
67
- "msgpackr-extract"
68
- ]
69
- },
70
62
  "prettier": {
71
63
  "singleQuote": true,
72
64
  "trailingComma": "none",
@@ -0,0 +1,9 @@
1
+ packages:
2
+ - .
3
+ autoInstallPeers: false
4
+ allowBuilds:
5
+ '@parcel/watcher': true
6
+ '@swc/core': true
7
+ core-js: true
8
+ lmdb: true
9
+ msgpackr-extract: true
package/src/Lark.ts CHANGED
@@ -9,6 +9,8 @@ import {
9
9
  DocumentAIModel,
10
10
  DocumentModel,
11
11
  DriveFileModel,
12
+ PublicFileType,
13
+ PublishedFile,
12
14
  TableFormView,
13
15
  UserIdType,
14
16
  WikiNode,
@@ -39,7 +41,7 @@ export interface LarkAppClientOption extends LarkAppBaseOption {
39
41
  accessToken: string;
40
42
  }
41
43
 
42
- export interface LarkAppOption extends LarkAppServerOption, LarkAppClientOption {}
44
+ export type LarkAppOption = LarkAppServerOption & LarkAppClientOption;
43
45
 
44
46
  export class LarkApp implements LarkAppOption {
45
47
  host = 'https://open.feishu.cn/open-apis/';
@@ -291,6 +293,31 @@ export class LarkApp implements LarkAppOption {
291
293
  return this.documentStore.getOneContent(doc_token, 'markdown');
292
294
  }
293
295
 
296
+ /**
297
+ * @see {@link DriveFileModel#updatePublicPermission}
298
+ * @see {@link DriveFileModel#createPublicPassword}
299
+ */
300
+ async publishFile(URI: string, enablePassword = false, editable = false) {
301
+ await this.getAccessToken();
302
+
303
+ const [[pathType, token]] = DriveFileModel.parseURI(URI);
304
+ const type: PublicFileType =
305
+ pathType === 'wiki' ? pathType : getLarkDocumentType(pathType as LarkDocumentPathType);
306
+
307
+ const permission = await this.driveFileStore.updatePublicPermission(type, token, {
308
+ external_access_entity: 'open',
309
+ link_share_entity: editable ? 'anyone_editable' : 'anyone_readable',
310
+ copy_entity: 'anyone_can_view',
311
+ security_entity: 'anyone_can_view',
312
+ comment_entity: 'anyone_can_view'
313
+ }),
314
+ password = enablePassword
315
+ ? await this.driveFileStore.createPublicPassword(type, token)
316
+ : undefined;
317
+
318
+ return { permission, password } as PublishedFile;
319
+ }
320
+
294
321
  async getBiTableSchema(appId: string): Promise<BiTableSchema> {
295
322
  const { client } = this;
296
323
 
@@ -177,10 +177,12 @@ export type BiSearchFilter<D extends DataObject> = Filter<D> & {
177
177
  keywords?: string;
178
178
  };
179
179
 
180
- export function BiSearch<D extends DataObject, F extends BiSearchFilter<D> = BiSearchFilter<D>>(
181
- Model: ReturnType<typeof BiDataTable<D, F>>
182
- ) {
183
- abstract class BiSearchModel extends Model {
180
+ export function BiSearch<
181
+ D extends DataObject,
182
+ F extends BiSearchFilter<D> = BiSearchFilter<D>,
183
+ M extends ReturnType<typeof BiDataTable<D, F>> = ReturnType<typeof BiDataTable<D, F>>
184
+ >(Model: M) {
185
+ abstract class BiSearchModel extends (Model as ReturnType<typeof BiDataTable<D, F>>) {
184
186
  declare baseURI: string;
185
187
  declare client: RESTClient;
186
188
 
@@ -1,8 +1,19 @@
1
- import { makeFormData } from 'koajax';
1
+ import { makeFormData, readAs } from 'koajax';
2
2
  import { BaseModel, RESTClient, toggle } from 'mobx-restful';
3
3
 
4
4
  import { LarkData } from '../../type';
5
- import { TaxiInvoice, TrainInvoice, VatInvoice, VehicleInvoice } from './type';
5
+ import {
6
+ BankCardEntity,
7
+ BusinessCard,
8
+ BusinessLicense,
9
+ Contract,
10
+ IDCard,
11
+ Resume,
12
+ TaxiInvoice,
13
+ TrainInvoice,
14
+ VatInvoice,
15
+ VehicleInvoice
16
+ } from './type';
6
17
 
7
18
  export * from './type';
8
19
 
@@ -58,4 +69,100 @@ export abstract class DocumentAIModel extends BaseModel {
58
69
 
59
70
  return body!.data!.vehicle_invoice;
60
71
  }
72
+
73
+ /**
74
+ * @see {@link https://open.feishu.cn/document/server-docs/ai/optical_char_recognition-v1/basic_recognize}
75
+ */
76
+ @toggle('uploading')
77
+ async recognizeText(image: File) {
78
+ const URI = (await readAs(image, 'dataURL').result) as string;
79
+
80
+ const [, base64] = URI.split(',');
81
+
82
+ const { body } = await this.client.post<LarkData<{ text_list: string[] }>>(
83
+ 'optical_char_recognition/v1/image/basic_recognize',
84
+ { image: base64 }
85
+ );
86
+ return body!.data!.text_list;
87
+ }
88
+
89
+ /**
90
+ * @see {@link https://open.feishu.cn/document/ai/document_ai-v1/bank_card/recognize}
91
+ */
92
+ @toggle('uploading')
93
+ async recognizeBankCard(file: File) {
94
+ const { body } = await this.client.post<
95
+ LarkData<{ bank_card: { entities: BankCardEntity[] } }>
96
+ >(`${this.baseURI}/bank_card/recognize`, makeFormData({ file }));
97
+
98
+ return body!.data!.bank_card.entities;
99
+ }
100
+
101
+ /**
102
+ * @see {@link https://open.feishu.cn/document/ai/document_ai-v1/id_card/recognize}
103
+ */
104
+ @toggle('uploading')
105
+ async recognizeIDCard(file: File) {
106
+ type IDCardTypo = Omit<IDCard, 'corners'> & { conners: number[] };
107
+
108
+ const { body } = await this.client.post<LarkData<{ id_card: IDCardTypo }>>(
109
+ `${this.baseURI}/id_card/recognize`,
110
+ makeFormData({ file })
111
+ );
112
+ const { conners: corners, ...idCard } = body!.data!.id_card;
113
+
114
+ return { ...idCard, corners } as IDCard;
115
+ }
116
+
117
+ /**
118
+ * @see {@link https://open.feishu.cn/document/server-docs/ai/document_ai-v1/business_card/recognize}
119
+ */
120
+ @toggle('uploading')
121
+ async recognizeBusinessCard(file: File) {
122
+ const { body } = await this.client.post<LarkData<{ business_cards: BusinessCard[] }>>(
123
+ `${this.baseURI}/business_card/recognize`,
124
+ makeFormData({ file })
125
+ );
126
+ return body!.data!.business_cards;
127
+ }
128
+
129
+ /**
130
+ * @see {@link https://open.feishu.cn/document/ai/document_ai-v1/business_license/recognize}
131
+ */
132
+ @toggle('uploading')
133
+ async recognizeBusinessLicense(file: File) {
134
+ const { body } = await this.client.post<LarkData<{ business_license: BusinessLicense }>>(
135
+ `${this.baseURI}/business_license/recognize`,
136
+ makeFormData({ file })
137
+ );
138
+ return body!.data!.business_license;
139
+ }
140
+
141
+ /**
142
+ * @see {@link https://open.feishu.cn/document/ai/document_ai-v1/resume/parse}
143
+ */
144
+ @toggle('uploading')
145
+ async parseResume(file: File) {
146
+ const { body } = await this.client.post<LarkData<{ resumes: Resume[] }>>(
147
+ `${this.baseURI}/resume/parse`,
148
+ makeFormData({ file })
149
+ );
150
+ return body!.data!.resumes;
151
+ }
152
+
153
+ /**
154
+ * @see {@link https://open.feishu.cn/document/server-docs/ai/document_ai-v1/contract/field_extraction}
155
+ */
156
+ @toggle('uploading')
157
+ async extractContract(
158
+ file: File,
159
+ ocr_mode: 'unused' | 'force' | 'auto' = 'auto',
160
+ pdf_page_limit = 100
161
+ ) {
162
+ const { body } = await this.client.post<LarkData<Contract>>(
163
+ `${this.baseURI}/contract/field_extraction`,
164
+ makeFormData({ file, ocr_mode, pdf_page_limit })
165
+ );
166
+ return body!.data!;
167
+ }
61
168
  }