@baruchiro/paperless-mcp 0.0.3 → 0.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/README.md +156 -7
- package/build/api/PaperlessAPI.d.ts +10 -3
- package/build/api/PaperlessAPI.js +60 -3
- package/build/api/documentEnhancer.d.ts +18 -0
- package/build/api/documentEnhancer.js +88 -0
- package/build/api/types.d.ts +76 -7
- package/build/api/types.js +13 -0
- package/build/api/utils.d.ts +15 -0
- package/build/api/utils.js +13 -0
- package/build/index.js +11 -2
- package/build/tools/correspondents.d.ts +2 -1
- package/build/tools/correspondents.js +66 -22
- package/build/tools/customFields.d.ts +3 -0
- package/build/tools/customFields.js +142 -0
- package/build/tools/documentTypes.d.ts +3 -1
- package/build/tools/documentTypes.js +58 -20
- package/build/tools/documents.js +117 -71
- package/build/tools/tags.js +42 -12
- package/build/tools/utils/empty.d.ts +2 -0
- package/build/tools/utils/empty.js +7 -0
- package/build/tools/utils/middlewares.d.ts +1 -1
- package/build/tools/utils/middlewares.js +12 -13
- package/package.json +6 -3
- package/paperless-mcp.dxt +0 -0
package/README.md
CHANGED
|
@@ -206,6 +206,15 @@ bulk_edit_documents({
|
|
|
206
206
|
add_tags: [1, 2],
|
|
207
207
|
remove_tags: [3, 4]
|
|
208
208
|
})
|
|
209
|
+
|
|
210
|
+
// Modify custom fields
|
|
211
|
+
bulk_edit_documents({
|
|
212
|
+
documents: [12, 13],
|
|
213
|
+
method: "modify_custom_fields",
|
|
214
|
+
add_custom_fields: {
|
|
215
|
+
"2": "שנה"
|
|
216
|
+
}
|
|
217
|
+
})
|
|
209
218
|
```
|
|
210
219
|
|
|
211
220
|
#### post_document
|
|
@@ -232,7 +241,8 @@ post_document({
|
|
|
232
241
|
correspondent: 1,
|
|
233
242
|
document_type: 2,
|
|
234
243
|
tags: [1, 3],
|
|
235
|
-
archive_serial_number: "2024-001"
|
|
244
|
+
archive_serial_number: "2024-001",
|
|
245
|
+
custom_fields: [1, 2]
|
|
236
246
|
})
|
|
237
247
|
```
|
|
238
248
|
|
|
@@ -252,14 +262,21 @@ Parameters:
|
|
|
252
262
|
- name: Tag name
|
|
253
263
|
- color (optional): Hex color code (e.g. "#ff0000")
|
|
254
264
|
- match (optional): Text pattern to match
|
|
255
|
-
- matching_algorithm (optional):
|
|
265
|
+
- matching_algorithm (optional): Number between 0 and 6:
|
|
266
|
+
0 - None
|
|
267
|
+
1 - Any word
|
|
268
|
+
2 - All words
|
|
269
|
+
3 - Exact match
|
|
270
|
+
4 - Regular expression
|
|
271
|
+
5 - Fuzzy word
|
|
272
|
+
6 - Automatic
|
|
256
273
|
|
|
257
274
|
```typescript
|
|
258
275
|
create_tag({
|
|
259
276
|
name: "Invoice",
|
|
260
277
|
color: "#ff0000",
|
|
261
278
|
match: "invoice",
|
|
262
|
-
matching_algorithm:
|
|
279
|
+
matching_algorithm: 5
|
|
263
280
|
})
|
|
264
281
|
```
|
|
265
282
|
|
|
@@ -278,13 +295,20 @@ Create a new correspondent.
|
|
|
278
295
|
Parameters:
|
|
279
296
|
- name: Correspondent name
|
|
280
297
|
- match (optional): Text pattern to match
|
|
281
|
-
- matching_algorithm (optional):
|
|
298
|
+
- matching_algorithm (optional): Number between 0 and 6:
|
|
299
|
+
0 - None
|
|
300
|
+
1 - Any word
|
|
301
|
+
2 - All words
|
|
302
|
+
3 - Exact match
|
|
303
|
+
4 - Regular expression
|
|
304
|
+
5 - Fuzzy word
|
|
305
|
+
6 - Automatic
|
|
282
306
|
|
|
283
307
|
```typescript
|
|
284
308
|
create_correspondent({
|
|
285
309
|
name: "ACME Corp",
|
|
286
310
|
match: "ACME",
|
|
287
|
-
matching_algorithm:
|
|
311
|
+
matching_algorithm: 5
|
|
288
312
|
})
|
|
289
313
|
```
|
|
290
314
|
|
|
@@ -303,13 +327,99 @@ Create a new document type.
|
|
|
303
327
|
Parameters:
|
|
304
328
|
- name: Document type name
|
|
305
329
|
- match (optional): Text pattern to match
|
|
306
|
-
- matching_algorithm (optional):
|
|
330
|
+
- matching_algorithm (optional): Number between 0 and 6:
|
|
331
|
+
0 - None
|
|
332
|
+
1 - Any word
|
|
333
|
+
2 - All words
|
|
334
|
+
3 - Exact match
|
|
335
|
+
4 - Regular expression
|
|
336
|
+
5 - Fuzzy word
|
|
337
|
+
6 - Automatic
|
|
307
338
|
|
|
308
339
|
```typescript
|
|
309
340
|
create_document_type({
|
|
310
341
|
name: "Invoice",
|
|
311
342
|
match: "invoice total amount due",
|
|
312
|
-
matching_algorithm:
|
|
343
|
+
matching_algorithm: 1
|
|
344
|
+
})
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Custom Field Operations
|
|
348
|
+
|
|
349
|
+
#### list_custom_fields
|
|
350
|
+
Get all custom fields.
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
list_custom_fields()
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
#### get_custom_field
|
|
357
|
+
Get a specific custom field by ID.
|
|
358
|
+
|
|
359
|
+
Parameters:
|
|
360
|
+
- id: Custom field ID
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
get_custom_field({
|
|
364
|
+
id: 1
|
|
365
|
+
})
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
#### create_custom_field
|
|
369
|
+
Create a new custom field.
|
|
370
|
+
|
|
371
|
+
Parameters:
|
|
372
|
+
- name: Custom field name
|
|
373
|
+
- data_type: One of "string", "url", "date", "boolean", "integer", "float", "monetary", "documentlink", "select"
|
|
374
|
+
- extra_data (optional): Extra data for the custom field, such as select options
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
create_custom_field({
|
|
378
|
+
name: "Invoice Number",
|
|
379
|
+
data_type: "string"
|
|
380
|
+
})
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
#### update_custom_field
|
|
384
|
+
Update an existing custom field.
|
|
385
|
+
|
|
386
|
+
Parameters:
|
|
387
|
+
- id: Custom field ID
|
|
388
|
+
- name (optional): New custom field name
|
|
389
|
+
- data_type (optional): New data type
|
|
390
|
+
- extra_data (optional): Extra data for the custom field
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
update_custom_field({
|
|
394
|
+
id: 1,
|
|
395
|
+
name: "Updated Invoice Number",
|
|
396
|
+
data_type: "string"
|
|
397
|
+
})
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
#### delete_custom_field
|
|
401
|
+
Delete a custom field.
|
|
402
|
+
|
|
403
|
+
Parameters:
|
|
404
|
+
- id: Custom field ID
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
delete_custom_field({
|
|
408
|
+
id: 1
|
|
409
|
+
})
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
#### bulk_edit_custom_fields
|
|
413
|
+
Perform bulk operations on multiple custom fields.
|
|
414
|
+
|
|
415
|
+
Parameters:
|
|
416
|
+
- custom_fields: Array of custom field IDs
|
|
417
|
+
- operation: One of "delete"
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
bulk_edit_custom_fields({
|
|
421
|
+
custom_fields: [1, 2, 3],
|
|
422
|
+
operation: "delete"
|
|
313
423
|
})
|
|
314
424
|
```
|
|
315
425
|
|
|
@@ -372,3 +482,42 @@ npm run start -- <baseUrl> <token> --http --port 3000
|
|
|
372
482
|
# Credits
|
|
373
483
|
|
|
374
484
|
This project is a fork of [nloui/paperless-mcp](https://github.com/nloui/paperless-mcp). Many thanks to the original author for their work. Contributions and improvements may be returned upstream.
|
|
485
|
+
|
|
486
|
+
## Debugging
|
|
487
|
+
|
|
488
|
+
To debug the MCP server in VS Code, use the following launch configuration:
|
|
489
|
+
|
|
490
|
+
```json
|
|
491
|
+
{
|
|
492
|
+
"type": "node",
|
|
493
|
+
"request": "launch",
|
|
494
|
+
"name": "Debug Paperless MCP (HTTP, ts-node ESM)",
|
|
495
|
+
"program": "${workspaceFolder}/node_modules/ts-node/dist/bin.js",
|
|
496
|
+
"args": [
|
|
497
|
+
"--esm",
|
|
498
|
+
"src/index.ts",
|
|
499
|
+
"--http",
|
|
500
|
+
"--baseUrl",
|
|
501
|
+
"http://your-paperless-instance:8000",
|
|
502
|
+
"--token",
|
|
503
|
+
"your-api-token",
|
|
504
|
+
"--port",
|
|
505
|
+
"3002"
|
|
506
|
+
],
|
|
507
|
+
"env": {
|
|
508
|
+
"NODE_OPTIONS": "--loader ts-node/esm",
|
|
509
|
+
},
|
|
510
|
+
"console": "integratedTerminal",
|
|
511
|
+
"skipFiles": [
|
|
512
|
+
"<node_internals>/**"
|
|
513
|
+
]
|
|
514
|
+
}
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**Important:** Before debugging, uncomment the following line in `src/index.ts` (around line 175):
|
|
518
|
+
|
|
519
|
+
```typescript
|
|
520
|
+
// await new Promise((resolve) => setTimeout(resolve, 1000000));
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
This prevents the server from exiting immediately and allows you to set breakpoints and debug the code.
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { BulkEditDocumentsResult, Correspondent, Document, DocumentsResponse, DocumentType, GetCorrespondentsResponse, GetDocumentTypesResponse, GetTagsResponse, Tag } from "./types";
|
|
1
|
+
import { BulkEditDocumentsResult, BulkEditParameters, Correspondent, CustomField, Document, DocumentsResponse, DocumentType, GetCorrespondentsResponse, GetCustomFieldsResponse, GetDocumentTypesResponse, GetTagsResponse, Tag } from "./types";
|
|
2
2
|
export declare class PaperlessAPI {
|
|
3
3
|
private readonly baseUrl;
|
|
4
4
|
private readonly token;
|
|
5
5
|
constructor(baseUrl: string, token: string);
|
|
6
6
|
request<T = any>(path: string, options?: RequestInit): Promise<T>;
|
|
7
|
-
bulkEditDocuments(documents: number[], method: string, parameters?:
|
|
7
|
+
bulkEditDocuments(documents: number[], method: string, parameters?: BulkEditParameters): Promise<BulkEditDocumentsResult>;
|
|
8
8
|
postDocument(file: File, metadata?: Record<string, string | string[] | number | number[]>): Promise<string>;
|
|
9
9
|
getDocuments(query?: string): Promise<DocumentsResponse>;
|
|
10
10
|
getDocument(id: number): Promise<Document>;
|
|
11
|
+
updateDocument(id: number, data: Partial<Document>): Promise<Document>;
|
|
11
12
|
searchDocuments(query: string): Promise<DocumentsResponse>;
|
|
12
13
|
downloadDocument(id: number, asOriginal?: boolean): Promise<import("axios").AxiosResponse<any, any>>;
|
|
13
14
|
getTags(): Promise<GetTagsResponse>;
|
|
14
15
|
createTag(data: Partial<Tag>): Promise<Tag>;
|
|
15
16
|
updateTag(id: number, data: Partial<Tag>): Promise<Tag>;
|
|
16
17
|
deleteTag(id: number): Promise<void>;
|
|
17
|
-
getCorrespondents(): Promise<GetCorrespondentsResponse>;
|
|
18
|
+
getCorrespondents(queryString?: string): Promise<GetCorrespondentsResponse>;
|
|
19
|
+
getCorrespondent(id: number): Promise<Correspondent>;
|
|
18
20
|
createCorrespondent(data: Partial<Correspondent>): Promise<Correspondent>;
|
|
19
21
|
updateCorrespondent(id: number, data: Partial<Correspondent>): Promise<Correspondent>;
|
|
20
22
|
deleteCorrespondent(id: number): Promise<void>;
|
|
@@ -22,5 +24,10 @@ export declare class PaperlessAPI {
|
|
|
22
24
|
createDocumentType(data: Partial<DocumentType>): Promise<DocumentType>;
|
|
23
25
|
updateDocumentType(id: number, data: Partial<DocumentType>): Promise<DocumentType>;
|
|
24
26
|
deleteDocumentType(id: number): Promise<void>;
|
|
27
|
+
getCustomFields(): Promise<GetCustomFieldsResponse>;
|
|
28
|
+
getCustomField(id: number): Promise<CustomField>;
|
|
29
|
+
createCustomField(data: Partial<CustomField>): Promise<CustomField>;
|
|
30
|
+
updateCustomField(id: number, data: Partial<CustomField>): Promise<CustomField>;
|
|
31
|
+
deleteCustomField(id: number): Promise<void>;
|
|
25
32
|
bulkEditObjects(objects: any, objectType: any, operation: any, parameters?: {}): Promise<any>;
|
|
26
33
|
}
|
|
@@ -25,6 +25,7 @@ class PaperlessAPI {
|
|
|
25
25
|
}
|
|
26
26
|
request(path_1) {
|
|
27
27
|
return __awaiter(this, arguments, void 0, function* (path, options = {}) {
|
|
28
|
+
var _a, _b;
|
|
28
29
|
const url = `${this.baseUrl}/api${path}`;
|
|
29
30
|
const isJson = !options.body || typeof options.body === "string";
|
|
30
31
|
const mergedHeaders = Object.assign(Object.assign({ Authorization: `Token ${this.token}`, Accept: "application/json; version=5", "Accept-Language": "en-US,en;q=0.9" }, (isJson ? { "Content-Type": "application/json" } : {})), (0, utils_1.headersToObject)(options.headers));
|
|
@@ -44,7 +45,11 @@ class PaperlessAPI {
|
|
|
44
45
|
status: response.status,
|
|
45
46
|
response: body,
|
|
46
47
|
});
|
|
47
|
-
|
|
48
|
+
const errorMessage = (body === null || body === void 0 ? void 0 : body.detail) ||
|
|
49
|
+
(body === null || body === void 0 ? void 0 : body.error) ||
|
|
50
|
+
(body === null || body === void 0 ? void 0 : body.message) ||
|
|
51
|
+
`HTTP error! status: ${response.status}`;
|
|
52
|
+
throw new Error(String(errorMessage));
|
|
48
53
|
}
|
|
49
54
|
return body;
|
|
50
55
|
}
|
|
@@ -54,6 +59,8 @@ class PaperlessAPI {
|
|
|
54
59
|
message: error instanceof Error ? error.message : String(error),
|
|
55
60
|
url,
|
|
56
61
|
options,
|
|
62
|
+
responseData: (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data,
|
|
63
|
+
status: (_b = error === null || error === void 0 ? void 0 : error.response) === null || _b === void 0 ? void 0 : _b.status,
|
|
57
64
|
});
|
|
58
65
|
throw error;
|
|
59
66
|
}
|
|
@@ -115,6 +122,14 @@ class PaperlessAPI {
|
|
|
115
122
|
return this.request(`/documents/${id}/`);
|
|
116
123
|
});
|
|
117
124
|
}
|
|
125
|
+
updateDocument(id, data) {
|
|
126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
return this.request(`/documents/${id}/`, {
|
|
128
|
+
method: "PATCH",
|
|
129
|
+
body: JSON.stringify(data),
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
118
133
|
searchDocuments(query) {
|
|
119
134
|
return __awaiter(this, void 0, void 0, function* () {
|
|
120
135
|
const response = yield this.request(`/documents/?query=${encodeURIComponent(query)}`);
|
|
@@ -163,9 +178,17 @@ class PaperlessAPI {
|
|
|
163
178
|
});
|
|
164
179
|
}
|
|
165
180
|
// Correspondent operations
|
|
166
|
-
getCorrespondents() {
|
|
181
|
+
getCorrespondents(queryString) {
|
|
182
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
183
|
+
const url = queryString
|
|
184
|
+
? `/correspondents/?${queryString}`
|
|
185
|
+
: "/correspondents/";
|
|
186
|
+
return this.request(url);
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
getCorrespondent(id) {
|
|
167
190
|
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
-
return this.request(
|
|
191
|
+
return this.request(`/correspondents/${id}/`);
|
|
169
192
|
});
|
|
170
193
|
}
|
|
171
194
|
createCorrespondent(data) {
|
|
@@ -220,6 +243,40 @@ class PaperlessAPI {
|
|
|
220
243
|
});
|
|
221
244
|
});
|
|
222
245
|
}
|
|
246
|
+
// Custom field operations
|
|
247
|
+
getCustomFields() {
|
|
248
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
249
|
+
return this.request("/custom_fields/");
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
getCustomField(id) {
|
|
253
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
254
|
+
return this.request(`/custom_fields/${id}/`);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
createCustomField(data) {
|
|
258
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
259
|
+
return this.request("/custom_fields/", {
|
|
260
|
+
method: "POST",
|
|
261
|
+
body: JSON.stringify(data),
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
updateCustomField(id, data) {
|
|
266
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
267
|
+
return this.request(`/custom_fields/${id}/`, {
|
|
268
|
+
method: "PUT",
|
|
269
|
+
body: JSON.stringify(data),
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
deleteCustomField(id) {
|
|
274
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
275
|
+
return this.request(`/custom_fields/${id}/`, {
|
|
276
|
+
method: "DELETE",
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
}
|
|
223
280
|
// Bulk object operations
|
|
224
281
|
bulkEditObjects(objects_1, objectType_1, operation_1) {
|
|
225
282
|
return __awaiter(this, arguments, void 0, function* (objects, objectType, operation, parameters = {}) {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types";
|
|
2
|
+
import { PaperlessAPI } from "./PaperlessAPI";
|
|
3
|
+
import { Document, DocumentsResponse } from "./types";
|
|
4
|
+
import { NamedItem } from "./utils";
|
|
5
|
+
interface CustomField {
|
|
6
|
+
field: number;
|
|
7
|
+
name: string;
|
|
8
|
+
value: string | number | boolean | object | null;
|
|
9
|
+
}
|
|
10
|
+
export interface EnhancedDocument extends Omit<Document, "correspondent" | "document_type" | "tags" | "custom_fields"> {
|
|
11
|
+
correspondent: NamedItem | null;
|
|
12
|
+
document_type: NamedItem | null;
|
|
13
|
+
tags: NamedItem[];
|
|
14
|
+
custom_fields: CustomField[];
|
|
15
|
+
}
|
|
16
|
+
export declare function convertDocsWithNames(document: Document, api: PaperlessAPI): Promise<CallToolResult>;
|
|
17
|
+
export declare function convertDocsWithNames(documentsResponse: DocumentsResponse, api: PaperlessAPI): Promise<CallToolResult>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.convertDocsWithNames = convertDocsWithNames;
|
|
13
|
+
function convertDocsWithNames(input, api) {
|
|
14
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
if ("results" in input) {
|
|
16
|
+
const enhancedResults = yield enhanceDocumentsArray(input.results || [], api);
|
|
17
|
+
return {
|
|
18
|
+
content: [
|
|
19
|
+
{
|
|
20
|
+
type: "text",
|
|
21
|
+
text: (enhancedResults === null || enhancedResults === void 0 ? void 0 : enhancedResults.length)
|
|
22
|
+
? JSON.stringify(Object.assign(Object.assign({}, input), { results: enhancedResults }))
|
|
23
|
+
: "No documents found",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
if (!input) {
|
|
29
|
+
return {
|
|
30
|
+
content: [
|
|
31
|
+
{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: "No document found",
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const [enhanced] = yield enhanceDocumentsArray([input], api);
|
|
39
|
+
return {
|
|
40
|
+
content: [
|
|
41
|
+
{
|
|
42
|
+
type: "text",
|
|
43
|
+
text: JSON.stringify(enhanced),
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function enhanceDocumentsArray(documents, api) {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
if (!(documents === null || documents === void 0 ? void 0 : documents.length)) {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
const [correspondents, documentTypes, tags, customFields] = yield Promise.all([
|
|
55
|
+
api.getCorrespondents(),
|
|
56
|
+
api.getDocumentTypes(),
|
|
57
|
+
api.getTags(),
|
|
58
|
+
api.getCustomFields(),
|
|
59
|
+
]);
|
|
60
|
+
const correspondentMap = new Map((correspondents.results || []).map((c) => [c.id, c.name]));
|
|
61
|
+
const documentTypeMap = new Map((documentTypes.results || []).map((dt) => [dt.id, dt.name]));
|
|
62
|
+
const tagMap = new Map((tags.results || []).map((tag) => [tag.id, tag.name]));
|
|
63
|
+
const customFieldMap = new Map((customFields.results || []).map((cf) => [cf.id, cf.name]));
|
|
64
|
+
return documents.map((doc) => (Object.assign(Object.assign({}, doc), { correspondent: doc.correspondent
|
|
65
|
+
? {
|
|
66
|
+
id: doc.correspondent,
|
|
67
|
+
name: correspondentMap.get(doc.correspondent) ||
|
|
68
|
+
String(doc.correspondent),
|
|
69
|
+
}
|
|
70
|
+
: null, document_type: doc.document_type
|
|
71
|
+
? {
|
|
72
|
+
id: doc.document_type,
|
|
73
|
+
name: documentTypeMap.get(doc.document_type) || String(doc.document_type),
|
|
74
|
+
}
|
|
75
|
+
: null, tags: Array.isArray(doc.tags)
|
|
76
|
+
? doc.tags.map((tagId) => ({
|
|
77
|
+
id: tagId,
|
|
78
|
+
name: tagMap.get(tagId) || String(tagId),
|
|
79
|
+
}))
|
|
80
|
+
: doc.tags, custom_fields: Array.isArray(doc.custom_fields)
|
|
81
|
+
? doc.custom_fields.map((field) => ({
|
|
82
|
+
field: field.field,
|
|
83
|
+
name: customFieldMap.get(field.field) || String(field.field),
|
|
84
|
+
value: field.value,
|
|
85
|
+
}))
|
|
86
|
+
: doc.custom_fields })));
|
|
87
|
+
});
|
|
88
|
+
}
|
package/build/api/types.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
export declare const MATCHING_ALGORITHM_OPTIONS: {
|
|
2
|
+
readonly 0: "None";
|
|
3
|
+
readonly 1: "Any word";
|
|
4
|
+
readonly 2: "All words";
|
|
5
|
+
readonly 3: "Exact match";
|
|
6
|
+
readonly 4: "Regular expression";
|
|
7
|
+
readonly 5: "Fuzzy word";
|
|
8
|
+
readonly 6: "Automatic";
|
|
9
|
+
};
|
|
10
|
+
export type MatchingAlgorithm = keyof typeof MATCHING_ALGORITHM_OPTIONS;
|
|
11
|
+
export declare const MATCHING_ALGORITHM_DESCRIPTION: string;
|
|
1
12
|
export interface Tag {
|
|
2
13
|
id: number;
|
|
3
14
|
slug: string;
|
|
@@ -5,13 +16,28 @@ export interface Tag {
|
|
|
5
16
|
color: string;
|
|
6
17
|
text_color: string;
|
|
7
18
|
match: string;
|
|
8
|
-
matching_algorithm:
|
|
19
|
+
matching_algorithm: MatchingAlgorithm;
|
|
9
20
|
is_insensitive: boolean;
|
|
10
21
|
is_inbox_tag: boolean;
|
|
11
22
|
document_count: number;
|
|
12
23
|
owner: number | null;
|
|
13
24
|
user_can_change: boolean;
|
|
14
25
|
}
|
|
26
|
+
export interface CustomField {
|
|
27
|
+
id: number;
|
|
28
|
+
name: string;
|
|
29
|
+
data_type: string;
|
|
30
|
+
extra_data?: Record<string, unknown> | null;
|
|
31
|
+
document_count: number;
|
|
32
|
+
}
|
|
33
|
+
export interface CustomFieldInstance {
|
|
34
|
+
field: number;
|
|
35
|
+
value: string | number | boolean | object | null;
|
|
36
|
+
}
|
|
37
|
+
export interface CustomFieldInstanceRequest {
|
|
38
|
+
field: number;
|
|
39
|
+
value: string | number | boolean | object | null;
|
|
40
|
+
}
|
|
15
41
|
export interface PaginationResponse<T> {
|
|
16
42
|
count: number;
|
|
17
43
|
next: string | null;
|
|
@@ -21,6 +47,20 @@ export interface PaginationResponse<T> {
|
|
|
21
47
|
}
|
|
22
48
|
export interface GetTagsResponse extends PaginationResponse<Tag> {
|
|
23
49
|
}
|
|
50
|
+
export interface GetCustomFieldsResponse extends PaginationResponse<CustomField> {
|
|
51
|
+
}
|
|
52
|
+
export interface BasicUser {
|
|
53
|
+
id: number;
|
|
54
|
+
username: string;
|
|
55
|
+
first_name?: string;
|
|
56
|
+
last_name?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface Note {
|
|
59
|
+
id: number;
|
|
60
|
+
note: string;
|
|
61
|
+
created: string;
|
|
62
|
+
user: BasicUser;
|
|
63
|
+
}
|
|
24
64
|
export interface DocumentsResponse extends PaginationResponse<Document> {
|
|
25
65
|
}
|
|
26
66
|
export interface Document {
|
|
@@ -42,8 +82,8 @@ export interface Document {
|
|
|
42
82
|
owner: number | null;
|
|
43
83
|
user_can_change: boolean;
|
|
44
84
|
is_shared_by_requester: boolean;
|
|
45
|
-
notes:
|
|
46
|
-
custom_fields:
|
|
85
|
+
notes: Note[];
|
|
86
|
+
custom_fields: CustomFieldInstance[];
|
|
47
87
|
page_count: number;
|
|
48
88
|
mime_type: string;
|
|
49
89
|
__search_hit__?: SearchHit;
|
|
@@ -59,12 +99,12 @@ export interface Correspondent {
|
|
|
59
99
|
slug: string;
|
|
60
100
|
name: string;
|
|
61
101
|
match: string;
|
|
62
|
-
matching_algorithm:
|
|
102
|
+
matching_algorithm: MatchingAlgorithm;
|
|
63
103
|
is_insensitive: boolean;
|
|
64
104
|
document_count: number;
|
|
65
105
|
last_correspondence: string;
|
|
66
106
|
owner: number | null;
|
|
67
|
-
permissions:
|
|
107
|
+
permissions: Record<string, unknown>;
|
|
68
108
|
user_can_change: boolean;
|
|
69
109
|
}
|
|
70
110
|
export interface GetCorrespondentsResponse extends PaginationResponse<Correspondent> {
|
|
@@ -74,12 +114,12 @@ export interface DocumentType {
|
|
|
74
114
|
slug: string;
|
|
75
115
|
name: string;
|
|
76
116
|
match: string;
|
|
77
|
-
matching_algorithm:
|
|
117
|
+
matching_algorithm: MatchingAlgorithm;
|
|
78
118
|
is_insensitive: boolean;
|
|
79
119
|
document_count: number;
|
|
80
120
|
last_correspondence: string;
|
|
81
121
|
owner: number | null;
|
|
82
|
-
permissions:
|
|
122
|
+
permissions: Record<string, unknown>;
|
|
83
123
|
user_can_change: boolean;
|
|
84
124
|
}
|
|
85
125
|
export interface GetDocumentTypesResponse extends PaginationResponse<DocumentType> {
|
|
@@ -87,3 +127,32 @@ export interface GetDocumentTypesResponse extends PaginationResponse<DocumentTyp
|
|
|
87
127
|
export interface BulkEditDocumentsResult {
|
|
88
128
|
result: string;
|
|
89
129
|
}
|
|
130
|
+
export interface BulkEditParameters {
|
|
131
|
+
assign_custom_fields?: number[];
|
|
132
|
+
assign_custom_fields_values?: CustomFieldInstanceRequest[];
|
|
133
|
+
remove_custom_fields?: number[];
|
|
134
|
+
add_tags?: number[];
|
|
135
|
+
remove_tags?: number[];
|
|
136
|
+
degrees?: number;
|
|
137
|
+
pages?: string;
|
|
138
|
+
metadata_document_id?: number;
|
|
139
|
+
delete_originals?: boolean;
|
|
140
|
+
correspondent?: number;
|
|
141
|
+
document_type?: number;
|
|
142
|
+
storage_path?: number;
|
|
143
|
+
tag?: number;
|
|
144
|
+
permissions?: {
|
|
145
|
+
owner?: number | null;
|
|
146
|
+
set_permissions?: {
|
|
147
|
+
view: {
|
|
148
|
+
users: number[];
|
|
149
|
+
groups: number[];
|
|
150
|
+
};
|
|
151
|
+
change: {
|
|
152
|
+
users: number[];
|
|
153
|
+
groups: number[];
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
merge?: boolean;
|
|
157
|
+
};
|
|
158
|
+
}
|
package/build/api/types.js
CHANGED
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MATCHING_ALGORITHM_DESCRIPTION = exports.MATCHING_ALGORITHM_OPTIONS = void 0;
|
|
4
|
+
exports.MATCHING_ALGORITHM_OPTIONS = {
|
|
5
|
+
0: "None",
|
|
6
|
+
1: "Any word",
|
|
7
|
+
2: "All words",
|
|
8
|
+
3: "Exact match",
|
|
9
|
+
4: "Regular expression",
|
|
10
|
+
5: "Fuzzy word",
|
|
11
|
+
6: "Automatic",
|
|
12
|
+
};
|
|
13
|
+
exports.MATCHING_ALGORITHM_DESCRIPTION = `Matching algorithm: ${Object.entries(exports.MATCHING_ALGORITHM_OPTIONS)
|
|
14
|
+
.map(([id, name]) => `${id}=${name}`)
|
|
15
|
+
.join(", ")}`;
|
package/build/api/utils.d.ts
CHANGED
|
@@ -1 +1,16 @@
|
|
|
1
|
+
import { MatchingAlgorithm } from "./types";
|
|
1
2
|
export declare const headersToObject: (headers: any) => Record<string, string>;
|
|
3
|
+
export interface NamedItem {
|
|
4
|
+
id: number;
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function enhanceMatchingAlgorithm<T extends {
|
|
8
|
+
matching_algorithm: MatchingAlgorithm;
|
|
9
|
+
}>(obj: T): T & {
|
|
10
|
+
matching_algorithm: NamedItem;
|
|
11
|
+
};
|
|
12
|
+
export declare function enhanceMatchingAlgorithmArray<T extends {
|
|
13
|
+
matching_algorithm: MatchingAlgorithm;
|
|
14
|
+
}>(objects: T[]): (T & {
|
|
15
|
+
matching_algorithm: NamedItem;
|
|
16
|
+
})[];
|
package/build/api/utils.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.headersToObject = void 0;
|
|
4
|
+
exports.enhanceMatchingAlgorithm = enhanceMatchingAlgorithm;
|
|
5
|
+
exports.enhanceMatchingAlgorithmArray = enhanceMatchingAlgorithmArray;
|
|
6
|
+
const types_1 = require("./types");
|
|
4
7
|
const headersToObject = (headers) => {
|
|
5
8
|
if (!headers)
|
|
6
9
|
return {};
|
|
@@ -14,3 +17,13 @@ const headersToObject = (headers) => {
|
|
|
14
17
|
return headers;
|
|
15
18
|
};
|
|
16
19
|
exports.headersToObject = headersToObject;
|
|
20
|
+
function enhanceMatchingAlgorithm(obj) {
|
|
21
|
+
return Object.assign(Object.assign({}, obj), { matching_algorithm: {
|
|
22
|
+
id: obj.matching_algorithm,
|
|
23
|
+
name: types_1.MATCHING_ALGORITHM_OPTIONS[obj.matching_algorithm] ||
|
|
24
|
+
String(obj.matching_algorithm),
|
|
25
|
+
} });
|
|
26
|
+
}
|
|
27
|
+
function enhanceMatchingAlgorithmArray(objects) {
|
|
28
|
+
return objects.map((obj) => enhanceMatchingAlgorithm(obj));
|
|
29
|
+
}
|