@abyss-project/tools 3.0.0 → 3.1.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/.eslintrc.js +1 -1
- package/README.md +1 -1
- package/dist/api/atlas-document.api.d.ts +2 -1
- package/dist/api/atlas-document.api.js +5 -1
- package/dist/api/atlas-document.api.js.map +1 -1
- package/dist/api/atlas-group.api.js.map +1 -1
- package/dist/api/atlas-page.api.js.map +1 -1
- package/dist/api/atlas.api.js +3 -3
- package/dist/api/atlas.api.js.map +1 -1
- package/dist/api/atlas.public.api.js.map +1 -1
- package/dist/api/board-card.api.js.map +1 -1
- package/dist/api/board-column.api.js.map +1 -1
- package/dist/api/board-label.api.js +1 -2
- package/dist/api/board-label.api.js.map +1 -1
- package/dist/api/board.api.js +7 -5
- package/dist/api/board.api.js.map +1 -1
- package/dist/api/draw.api.js +1 -2
- package/dist/api/draw.api.js.map +1 -1
- package/dist/api/draw.public.api.js.map +1 -1
- package/dist/api/extraction-plan-preset.api.js +19 -6
- package/dist/api/extraction-plan-preset.api.js.map +1 -1
- package/dist/api/extraction-settings.api.js.map +1 -1
- package/dist/api/extraction.api.d.ts +2 -1
- package/dist/api/extraction.api.js +43 -82
- package/dist/api/extraction.api.js.map +1 -1
- package/dist/api/extraction.application.api.d.ts +4 -0
- package/dist/api/extraction.application.api.js +23 -0
- package/dist/api/extraction.application.api.js.map +1 -0
- package/dist/api/extraction.application.api.test.d.ts +1 -0
- package/dist/api/extraction.application.api.test.js +59 -0
- package/dist/api/extraction.application.api.test.js.map +1 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/probe-scan.api.d.ts +2 -9
- package/dist/api/probe-scan.api.js +16 -26
- package/dist/api/probe-scan.api.js.map +1 -1
- package/dist/api/probe-scan.api.test.js +10 -0
- package/dist/api/probe-scan.api.test.js.map +1 -1
- package/dist/api/probe-scan.application.api.js +2 -2
- package/dist/api/probe-scan.application.api.js.map +1 -1
- package/dist/api/probe-scan.application.api.test.js +4 -0
- package/dist/api/probe-scan.application.api.test.js.map +1 -1
- package/dist/api/retrospective.api.js +2 -1
- package/dist/api/retrospective.api.js.map +1 -1
- package/dist/api/short-link.admin.api.js.map +1 -1
- package/dist/api/short-link.api.js.map +1 -1
- package/dist/api/short-link.public.api.js.map +1 -1
- package/dist/api/tag.api.js.map +1 -1
- package/dist/constants/atlas.constants.js +1 -1
- package/dist/constants/atlas.constants.js.map +1 -1
- package/dist/constants/extract.constants.d.ts +4 -0
- package/dist/constants/extract.constants.js +91 -0
- package/dist/constants/extract.constants.js.map +1 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/constants/index.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/server-sent-events/server-sent-events.manager.d.ts +1 -2
- package/dist/server-sent-events/server-sent-events.manager.js +1 -2
- package/dist/server-sent-events/server-sent-events.manager.js.map +1 -1
- package/dist/types/enum/document-type.enum.d.ts +1 -0
- package/dist/types/enum/document-type.enum.js +1 -0
- package/dist/types/enum/document-type.enum.js.map +1 -1
- package/dist/types/enum/extract-field-format.enum.d.ts +7 -0
- package/dist/types/enum/extract-field-format.enum.js +12 -0
- package/dist/types/enum/extract-field-format.enum.js.map +1 -0
- package/dist/types/enum/extract-field-key.enum.d.ts +59 -0
- package/dist/types/enum/extract-field-key.enum.js +64 -0
- package/dist/types/enum/extract-field-key.enum.js.map +1 -0
- package/dist/types/enum/extraction-warning.enum.d.ts +4 -1
- package/dist/types/enum/extraction-warning.enum.js +3 -0
- package/dist/types/enum/extraction-warning.enum.js.map +1 -1
- package/dist/types/enum/index.d.ts +2 -0
- package/dist/types/enum/index.js +2 -0
- package/dist/types/enum/index.js.map +1 -1
- package/dist/types/enum/rcb-bank.enum.js +252 -36
- package/dist/types/enum/rcb-bank.enum.js.map +1 -1
- package/dist/types/interface/api/requests/abyss.admin.request.d.ts +1 -1
- package/dist/types/interface/api/requests/atlas-document.request.d.ts +6 -0
- package/dist/types/interface/api/requests/board-card-document.request.d.ts +1 -0
- package/dist/types/interface/api/requests/extraction.request.d.ts +12 -0
- package/dist/types/interface/api/responses/atlas-document.response.d.ts +6 -4
- package/dist/types/interface/api/responses/board-card-document.response.d.ts +2 -4
- package/dist/types/interface/models/extraction-fetched-provenance.dto.test.js +8 -2
- package/dist/types/interface/models/extraction-fetched-provenance.dto.test.js.map +1 -1
- package/dist/types/interface/models/extraction-plan.dto.test.js +6 -1
- package/dist/types/interface/models/extraction-plan.dto.test.js.map +1 -1
- package/dist/types/interface/models/extraction-spatial-template.dto.test.js +20 -3
- package/dist/types/interface/models/extraction-spatial-template.dto.test.js.map +1 -1
- package/dist/types/interface/models/extraction.dto.d.ts +13 -0
- package/dist/types/interface/models/extraction.dto.js.map +1 -1
- package/dist/types/interface/models/index.d.ts +1 -0
- package/dist/types/interface/models/index.js +1 -0
- package/dist/types/interface/models/index.js.map +1 -1
- package/dist/types/interface/models/project.dto.d.ts +1 -1
- package/dist/types/interface/models/short-link.dto.d.ts +8 -0
- package/dist/types/interface/models/upload-session.dto.d.ts +8 -0
- package/dist/types/interface/models/upload-session.dto.js +3 -0
- package/dist/types/interface/models/upload-session.dto.js.map +1 -0
- package/dist/types/interface/models/user.dto.d.ts +1 -0
- package/package.json +12 -14
- package/src/api/atlas-document.api.ts +20 -3
- package/src/api/atlas-group.api.ts +4 -1
- package/src/api/atlas-page.api.ts +12 -6
- package/src/api/atlas.api.ts +12 -7
- package/src/api/atlas.public.api.ts +3 -1
- package/src/api/board-card.api.ts +6 -3
- package/src/api/board-column.api.ts +4 -1
- package/src/api/board-label.api.ts +7 -3
- package/src/api/board.api.ts +19 -10
- package/src/api/draw.api.ts +16 -12
- package/src/api/draw.public.api.ts +3 -1
- package/src/api/extraction-plan-preset.api.ts +64 -18
- package/src/api/extraction-settings.api.ts +2 -8
- package/src/api/extraction.api.ts +82 -84
- package/src/api/extraction.application.api.test.ts +55 -0
- package/src/api/extraction.application.api.ts +73 -0
- package/src/api/index.ts +1 -0
- package/src/api/probe-scan.api.test.ts +26 -0
- package/src/api/probe-scan.api.ts +66 -54
- package/src/api/probe-scan.application.api.test.ts +14 -0
- package/src/api/probe-scan.application.api.ts +5 -5
- package/src/api/retrospective.api.ts +8 -5
- package/src/api/short-link.admin.api.ts +14 -4
- package/src/api/short-link.api.ts +39 -17
- package/src/api/short-link.public.api.ts +25 -11
- package/src/api/tag.api.ts +3 -1
- package/src/constants/atlas.constants.ts +1 -1
- package/src/constants/extract.constants.ts +109 -0
- package/src/constants/index.ts +1 -0
- package/src/index.ts +19 -0
- package/src/server-sent-events/server-sent-events.manager.ts +5 -3
- package/src/types/enum/document-type.enum.ts +1 -0
- package/src/types/enum/extract-field-format.enum.ts +16 -0
- package/src/types/enum/extract-field-key.enum.ts +77 -0
- package/src/types/enum/extraction-warning.enum.ts +57 -0
- package/src/types/enum/index.ts +2 -0
- package/src/types/enum/rcb-bank.enum.ts +255 -41
- package/src/types/interface/api/requests/abyss.admin.request.ts +2 -1
- package/src/types/interface/api/requests/atlas-document.request.ts +14 -0
- package/src/types/interface/api/requests/board-card-document.request.ts +5 -0
- package/src/types/interface/api/requests/extraction.request.ts +22 -0
- package/src/types/interface/api/requests/probe-scan.request.ts +5 -1
- package/src/types/interface/api/responses/atlas-document.response.ts +11 -4
- package/src/types/interface/api/responses/board-card-document.response.ts +5 -4
- package/src/types/interface/api/responses/retrospective.response.ts +2 -1
- package/src/types/interface/models/content-share.dto.ts +5 -1
- package/src/types/interface/models/extraction-fetched-provenance.dto.test.ts +20 -9
- package/src/types/interface/models/extraction-plan.dto.test.ts +17 -4
- package/src/types/interface/models/extraction-spatial-template.dto.test.ts +26 -5
- package/src/types/interface/models/extraction.dto.ts +35 -0
- package/src/types/interface/models/index.ts +1 -0
- package/src/types/interface/models/probe-webhook.dto.ts +3 -4
- package/src/types/interface/models/project.dto.ts +2 -1
- package/src/types/interface/models/short-link.dto.ts +2 -0
- package/src/types/interface/models/upload-session.dto.ts +24 -0
- package/src/types/interface/models/user.dto.ts +3 -0
- package/tsconfig.check.json +15 -0
package/src/api/board.api.ts
CHANGED
|
@@ -31,7 +31,8 @@ export const getBoard = async (params: IGetBoardParams): Promise<IGetBoardRespon
|
|
|
31
31
|
export const getBySlugBoard = async (
|
|
32
32
|
params: IGetBySlugBoardParams,
|
|
33
33
|
): Promise<IGetBySlugBoardResponse> => {
|
|
34
|
-
return (await AbyssToolsCore.axios.get<IGetBySlugBoardResponse>(`board/slug/${params.slug}`))
|
|
34
|
+
return (await AbyssToolsCore.axios.get<IGetBySlugBoardResponse>(`board/slug/${params.slug}`))
|
|
35
|
+
.data;
|
|
35
36
|
};
|
|
36
37
|
|
|
37
38
|
export const deleteBoard = async (params: IDeleteBoardParams): Promise<IDeleteBoardResponse> => {
|
|
@@ -42,7 +43,8 @@ export const updateBoard = async (
|
|
|
42
43
|
params: IUpdateBoardParams,
|
|
43
44
|
body: IUpdateBoardBody,
|
|
44
45
|
): Promise<IUpdateBoardResponse> => {
|
|
45
|
-
return (await AbyssToolsCore.axios.put<IUpdateBoardResponse>(`board/${params.boardId}`, body))
|
|
46
|
+
return (await AbyssToolsCore.axios.put<IUpdateBoardResponse>(`board/${params.boardId}`, body))
|
|
47
|
+
.data;
|
|
46
48
|
};
|
|
47
49
|
|
|
48
50
|
export const createBoard = async (body: ICreateBoardBody): Promise<ICreateBoardResponse> => {
|
|
@@ -54,12 +56,18 @@ export const createForOrganizationBoard = async (
|
|
|
54
56
|
body: ICreateBoardBody,
|
|
55
57
|
): Promise<ICreateBoardResponse> => {
|
|
56
58
|
return (
|
|
57
|
-
await AbyssToolsCore.axios.post<ICreateBoardResponse>(
|
|
59
|
+
await AbyssToolsCore.axios.post<ICreateBoardResponse>(
|
|
60
|
+
`board/organization/${params.organizationId}`,
|
|
61
|
+
body,
|
|
62
|
+
)
|
|
58
63
|
).data;
|
|
59
64
|
};
|
|
60
65
|
|
|
61
|
-
export const listBoard = async (query?: {
|
|
62
|
-
|
|
66
|
+
export const listBoard = async (query?: {
|
|
67
|
+
sharedWithMe?: boolean;
|
|
68
|
+
}): Promise<IListBoardUserResponse> => {
|
|
69
|
+
return (await AbyssToolsCore.axios.get<IListBoardUserResponse>('board/list', { params: query }))
|
|
70
|
+
.data;
|
|
63
71
|
};
|
|
64
72
|
|
|
65
73
|
export const listBoardProject = async (params: {
|
|
@@ -71,8 +79,9 @@ export const listBoardProject = async (params: {
|
|
|
71
79
|
};
|
|
72
80
|
|
|
73
81
|
export const getNextCardPreviewBoard = async (): Promise<IGetNextCardPreviewBoardResponse> => {
|
|
74
|
-
return (
|
|
75
|
-
.
|
|
82
|
+
return (
|
|
83
|
+
await AbyssToolsCore.axios.post<IGetNextCardPreviewBoardResponse>(`board/next-card-preview`)
|
|
84
|
+
).data;
|
|
76
85
|
};
|
|
77
86
|
|
|
78
87
|
export const listBoardOrganization = async (
|
|
@@ -111,9 +120,9 @@ export const transferBoard = async (
|
|
|
111
120
|
).data;
|
|
112
121
|
};
|
|
113
122
|
|
|
114
|
-
export const countOrganizationBoard = async (
|
|
115
|
-
|
|
116
|
-
): Promise<ICountOrganizationResponse> => {
|
|
123
|
+
export const countOrganizationBoard = async (params: {
|
|
124
|
+
organizationId: string;
|
|
125
|
+
}): Promise<ICountOrganizationResponse> => {
|
|
117
126
|
return (
|
|
118
127
|
await AbyssToolsCore.axios.get<ICountOrganizationResponse>(
|
|
119
128
|
`board/organization/${params.organizationId}/count`,
|
package/src/api/draw.api.ts
CHANGED
|
@@ -29,9 +29,12 @@ export const paginateProjectDraw = async (
|
|
|
29
29
|
query: IPaginateDrawQuery,
|
|
30
30
|
): Promise<IPaginateDrawResponse> => {
|
|
31
31
|
return (
|
|
32
|
-
await AbyssToolsCore.axios.get<IPaginateDrawResponse>(
|
|
33
|
-
params
|
|
34
|
-
|
|
32
|
+
await AbyssToolsCore.axios.get<IPaginateDrawResponse>(
|
|
33
|
+
`project/${params.projectId}/draw/paginate`,
|
|
34
|
+
{
|
|
35
|
+
params: query,
|
|
36
|
+
},
|
|
37
|
+
)
|
|
35
38
|
).data;
|
|
36
39
|
};
|
|
37
40
|
|
|
@@ -58,8 +61,12 @@ export const createForOrganizationDraw = async (
|
|
|
58
61
|
params: ICreateForOrganizationDrawParams,
|
|
59
62
|
body: ICreateDrawBody,
|
|
60
63
|
): Promise<ICreateDrawResponse> => {
|
|
61
|
-
return (
|
|
62
|
-
.
|
|
64
|
+
return (
|
|
65
|
+
await AbyssToolsCore.axios.post<ICreateDrawResponse>(
|
|
66
|
+
`draw/organization/${params.organizationId}`,
|
|
67
|
+
body,
|
|
68
|
+
)
|
|
69
|
+
).data;
|
|
63
70
|
};
|
|
64
71
|
|
|
65
72
|
export const paginateOrganizationDraw = async (
|
|
@@ -79,16 +86,13 @@ export const transferDraw = async (
|
|
|
79
86
|
body: ITransferContentBody,
|
|
80
87
|
): Promise<ITransferDrawResponse> => {
|
|
81
88
|
return (
|
|
82
|
-
await AbyssToolsCore.axios.post<ITransferDrawResponse>(
|
|
83
|
-
`draw/${params.drawId}/transfer`,
|
|
84
|
-
body,
|
|
85
|
-
)
|
|
89
|
+
await AbyssToolsCore.axios.post<ITransferDrawResponse>(`draw/${params.drawId}/transfer`, body)
|
|
86
90
|
).data;
|
|
87
91
|
};
|
|
88
92
|
|
|
89
|
-
export const countOrganizationDraw = async (
|
|
90
|
-
|
|
91
|
-
): Promise<ICountOrganizationResponse> => {
|
|
93
|
+
export const countOrganizationDraw = async (params: {
|
|
94
|
+
organizationId: string;
|
|
95
|
+
}): Promise<ICountOrganizationResponse> => {
|
|
92
96
|
return (
|
|
93
97
|
await AbyssToolsCore.axios.get<ICountOrganizationResponse>(
|
|
94
98
|
`draw/organization/${params.organizationId}/count`,
|
|
@@ -15,7 +15,9 @@ export const getDrawPublic = async (
|
|
|
15
15
|
params: IGetDrawPublicParams,
|
|
16
16
|
): Promise<IGetDrawPublicResponse> => {
|
|
17
17
|
return (
|
|
18
|
-
await AbyssToolsCore.axios.get<IGetDrawPublicResponse>(
|
|
18
|
+
await AbyssToolsCore.axios.get<IGetDrawPublicResponse>(
|
|
19
|
+
`draw/public/${params.publicAccessToken}`,
|
|
20
|
+
)
|
|
19
21
|
).data;
|
|
20
22
|
};
|
|
21
23
|
|
|
@@ -11,11 +11,7 @@
|
|
|
11
11
|
// ──────────────────────────────────────────────
|
|
12
12
|
|
|
13
13
|
import { AbyssToolsCore } from '..';
|
|
14
|
-
import type {
|
|
15
|
-
ICreatePlanPresetBody,
|
|
16
|
-
IUpdatePlanPresetBody,
|
|
17
|
-
IListPlanPresetQuery,
|
|
18
|
-
} from '../types';
|
|
14
|
+
import type { ICreatePlanPresetBody, IUpdatePlanPresetBody, IListPlanPresetQuery } from '../types';
|
|
19
15
|
import type {
|
|
20
16
|
IListModesResponse,
|
|
21
17
|
IListPlanPresetsResponse,
|
|
@@ -30,22 +26,72 @@ function authHeader(apiKey?: string): Record<string, string> {
|
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
export const listModes = async (apiKey?: string): Promise<IListModesResponse> =>
|
|
33
|
-
(
|
|
29
|
+
(
|
|
30
|
+
await AbyssToolsCore.axios.get<IListModesResponse>(`extract/modes`, {
|
|
31
|
+
headers: authHeader(apiKey),
|
|
32
|
+
})
|
|
33
|
+
).data;
|
|
34
34
|
|
|
35
|
-
export const listExtractionPlanPresets = async (
|
|
36
|
-
|
|
35
|
+
export const listExtractionPlanPresets = async (
|
|
36
|
+
query: IListPlanPresetQuery = {},
|
|
37
|
+
apiKey?: string,
|
|
38
|
+
): Promise<IListPlanPresetsResponse> =>
|
|
39
|
+
(
|
|
40
|
+
await AbyssToolsCore.axios.get<IListPlanPresetsResponse>(`extract/plans`, {
|
|
41
|
+
params: query,
|
|
42
|
+
headers: authHeader(apiKey),
|
|
43
|
+
})
|
|
44
|
+
).data;
|
|
37
45
|
|
|
38
|
-
export const getExtractionPlanPreset = async (
|
|
39
|
-
|
|
46
|
+
export const getExtractionPlanPreset = async (
|
|
47
|
+
id: string,
|
|
48
|
+
apiKey?: string,
|
|
49
|
+
): Promise<IGetPlanPresetResponse> =>
|
|
50
|
+
(
|
|
51
|
+
await AbyssToolsCore.axios.get<IGetPlanPresetResponse>(`extract/plans/${id}`, {
|
|
52
|
+
headers: authHeader(apiKey),
|
|
53
|
+
})
|
|
54
|
+
).data;
|
|
40
55
|
|
|
41
|
-
export const createExtractionPlanPreset = async (
|
|
42
|
-
|
|
56
|
+
export const createExtractionPlanPreset = async (
|
|
57
|
+
body: ICreatePlanPresetBody,
|
|
58
|
+
apiKey?: string,
|
|
59
|
+
): Promise<IGetPlanPresetResponse> =>
|
|
60
|
+
(
|
|
61
|
+
await AbyssToolsCore.axios.post<IGetPlanPresetResponse>(`extract/plans`, body, {
|
|
62
|
+
headers: authHeader(apiKey),
|
|
63
|
+
})
|
|
64
|
+
).data;
|
|
43
65
|
|
|
44
|
-
export const updateExtractionPlanPreset = async (
|
|
45
|
-
|
|
66
|
+
export const updateExtractionPlanPreset = async (
|
|
67
|
+
id: string,
|
|
68
|
+
body: IUpdatePlanPresetBody,
|
|
69
|
+
apiKey?: string,
|
|
70
|
+
): Promise<IGetPlanPresetResponse> =>
|
|
71
|
+
(
|
|
72
|
+
await AbyssToolsCore.axios.put<IGetPlanPresetResponse>(`extract/plans/${id}`, body, {
|
|
73
|
+
headers: authHeader(apiKey),
|
|
74
|
+
})
|
|
75
|
+
).data;
|
|
46
76
|
|
|
47
|
-
export const deleteExtractionPlanPreset = async (
|
|
48
|
-
|
|
77
|
+
export const deleteExtractionPlanPreset = async (
|
|
78
|
+
id: string,
|
|
79
|
+
apiKey?: string,
|
|
80
|
+
): Promise<IDeletePlanPresetResponse> =>
|
|
81
|
+
(
|
|
82
|
+
await AbyssToolsCore.axios.delete<IDeletePlanPresetResponse>(`extract/plans/${id}`, {
|
|
83
|
+
headers: authHeader(apiKey),
|
|
84
|
+
})
|
|
85
|
+
).data;
|
|
49
86
|
|
|
50
|
-
export const setDefaultExtractionPlanPreset = async (
|
|
51
|
-
|
|
87
|
+
export const setDefaultExtractionPlanPreset = async (
|
|
88
|
+
id: string,
|
|
89
|
+
apiKey?: string,
|
|
90
|
+
): Promise<IGetPlanPresetResponse> =>
|
|
91
|
+
(
|
|
92
|
+
await AbyssToolsCore.axios.post<IGetPlanPresetResponse>(
|
|
93
|
+
`extract/plans/${id}/default`,
|
|
94
|
+
{},
|
|
95
|
+
{ headers: authHeader(apiKey) },
|
|
96
|
+
)
|
|
97
|
+
).data;
|
|
@@ -9,14 +9,8 @@
|
|
|
9
9
|
// ──────────────────────────────────────────────
|
|
10
10
|
|
|
11
11
|
import { AbyssToolsCore } from '..';
|
|
12
|
-
import type {
|
|
13
|
-
|
|
14
|
-
IUpsertExtractionSettingsBody,
|
|
15
|
-
} from '../types';
|
|
16
|
-
import type {
|
|
17
|
-
IGetExtractionSettingsResponse,
|
|
18
|
-
IUpsertExtractionSettingsResponse,
|
|
19
|
-
} from '../types';
|
|
12
|
+
import type { IGetExtractionSettingsQuery, IUpsertExtractionSettingsBody } from '../types';
|
|
13
|
+
import type { IGetExtractionSettingsResponse, IUpsertExtractionSettingsResponse } from '../types';
|
|
20
14
|
|
|
21
15
|
const DEFAULT_API_KEY_HEADER = 'abyss-api-key';
|
|
22
16
|
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
//
|
|
4
4
|
// Sync helper accepts an inline PDF buffer (multipart) or a storage_file_id.
|
|
5
5
|
// Queue helper enqueues for async processing + webhook delivery.
|
|
6
|
+
//
|
|
7
|
+
// Multipart bodies are built with the global `FormData` + `Blob` — the same
|
|
8
|
+
// code in a browser and on Node (>= 18, see package.json `engines`). axios
|
|
9
|
+
// serializes a spec-compliant FormData on both and sets the multipart
|
|
10
|
+
// boundary itself, so no content-type header is ever set by hand.
|
|
6
11
|
// ──────────────────────────────────────────────
|
|
7
12
|
|
|
8
13
|
import { AbyssToolsCore } from '..';
|
|
@@ -92,16 +97,9 @@ function authHeader(apiKey?: string): Record<string, string> {
|
|
|
92
97
|
return apiKey ? { [DEFAULT_API_KEY_HEADER]: apiKey } : {};
|
|
93
98
|
}
|
|
94
99
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
// Use indirect eval so bundlers (esbuild/vite/webpack) do not try to
|
|
100
|
-
// resolve the Node-only "form-data" package when this file is included
|
|
101
|
-
// in a browser bundle. The require only runs at runtime on Node.
|
|
102
|
-
// eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func
|
|
103
|
-
const nodeRequire: NodeRequire = new Function('return require')();
|
|
104
|
-
return nodeRequire('form-data');
|
|
100
|
+
/** The PDF bytes as a multipart file part: filename kept, `application/pdf` type. */
|
|
101
|
+
function appendPdfPart(form: FormData, pdf: Buffer | Uint8Array, filename: string): void {
|
|
102
|
+
form.append('file', new Blob([pdf], { type: 'application/pdf' }), filename);
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
function serializeParams<T extends object>(o: T): Record<string, unknown> {
|
|
@@ -119,23 +117,41 @@ function serializeParams<T extends object>(o: T): Record<string, unknown> {
|
|
|
119
117
|
* Optional per-call extras for extract endpoints. `idempotencyKey` is a
|
|
120
118
|
* Stripe-style replay key (24h window) sent as the `Idempotency-Key` header —
|
|
121
119
|
* not part of the request body.
|
|
120
|
+
*
|
|
121
|
+
* The key identifies ONE request, not just the caller: the server records a
|
|
122
|
+
* fingerprint of the run it answered (route, principal, ownership scope, the
|
|
123
|
+
* document, `processing`, `mode`, plan/preset and the rest of the body).
|
|
124
|
+
* - same key + identical request → the recorded response is replayed;
|
|
125
|
+
* - same key + different request → HTTP 422 `IDEMPOTENCY_KEY_REUSED`, and
|
|
126
|
+
* nothing is run.
|
|
127
|
+
*
|
|
128
|
+
* `extractSync` and `extractQueue` are the SAME endpoint, told apart only by
|
|
129
|
+
* `processing`, so a key used for one of them cannot be reused for the other:
|
|
130
|
+
* that is a different request and answers 422. Use one key per run.
|
|
131
|
+
*
|
|
132
|
+
* Responses cached before this behaviour shipped (API 1.10) carry no
|
|
133
|
+
* fingerprint and replay as they always did until their 24h TTL expires.
|
|
122
134
|
*/
|
|
123
135
|
export interface ExtractCallOptions {
|
|
124
136
|
idempotencyKey?: string;
|
|
125
137
|
}
|
|
126
138
|
|
|
139
|
+
/**
|
|
140
|
+
* `POST /extract/extract` with `processing: 'sync'`. The route still moves an
|
|
141
|
+
* async plan (an OCR pass, or more than one pass — inline or reached through
|
|
142
|
+
* `plan_preset_id`) onto the queue and answers 202 with the queue body, so the
|
|
143
|
+
* call resolves either the extraction (`extraction_id`) or the queued job
|
|
144
|
+
* (`job_id`); narrow on `'job_id' in response.data`.
|
|
145
|
+
*/
|
|
127
146
|
export const extractSync = async (
|
|
128
147
|
body: IExtractBody,
|
|
129
148
|
scope: IExtractionContentScopeQuery = {},
|
|
130
149
|
apiKey?: string,
|
|
131
150
|
opts: ExtractCallOptions = {},
|
|
132
|
-
): Promise<IExtractSyncResponse> => {
|
|
133
|
-
return postExtract(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
apiKey,
|
|
137
|
-
opts,
|
|
138
|
-
) as Promise<IExtractSyncResponse>;
|
|
151
|
+
): Promise<IExtractSyncResponse | IExtractQueueResponse> => {
|
|
152
|
+
return postExtract({ ...body, processing: 'sync' }, scope, apiKey, opts) as Promise<
|
|
153
|
+
IExtractSyncResponse | IExtractQueueResponse
|
|
154
|
+
>;
|
|
139
155
|
};
|
|
140
156
|
|
|
141
157
|
export const extractQueue = async (
|
|
@@ -164,54 +180,11 @@ const postExtract = async (
|
|
|
164
180
|
}
|
|
165
181
|
const params = serializeParams(scope);
|
|
166
182
|
if (body.pdf) {
|
|
167
|
-
const
|
|
168
|
-
const filename = body.pdf_filename ?? 'document.pdf';
|
|
169
|
-
if (isBrowser) {
|
|
170
|
-
const form = new FormData();
|
|
171
|
-
const blob = new Blob([body.pdf as Uint8Array], { type: 'application/pdf' });
|
|
172
|
-
form.append('file', blob, filename);
|
|
173
|
-
appendIf(form, 'mode', body.mode);
|
|
174
|
-
if (body.hint) form.append('hint', JSON.stringify(body.hint));
|
|
175
|
-
appendIf(form, 'template_id', body.template_id);
|
|
176
|
-
if (body.template) form.append('template', JSON.stringify(body.template));
|
|
177
|
-
appendIf(form, 'user_external_id', body.user_external_id);
|
|
178
|
-
if (body.user_metadata) form.append('user_metadata', JSON.stringify(body.user_metadata));
|
|
179
|
-
if (typeof body.archive === 'boolean') form.append('archive', String(body.archive));
|
|
180
|
-
if (typeof body.force === 'boolean') form.append('force', String(body.force));
|
|
181
|
-
if (body.processing) form.append('processing', body.processing);
|
|
182
|
-
return (
|
|
183
|
-
await AbyssToolsCore.axios.post(`extract/extract`, form, {
|
|
184
|
-
params,
|
|
185
|
-
headers: { ...authHeader(apiKey), ...extraHeaders },
|
|
186
|
-
maxBodyLength: Infinity,
|
|
187
|
-
maxContentLength: Infinity,
|
|
188
|
-
})
|
|
189
|
-
).data;
|
|
190
|
-
}
|
|
191
|
-
const FormDataCtor = await loadFormData();
|
|
192
|
-
const form = new FormDataCtor();
|
|
193
|
-
const buf = Buffer.isBuffer(body.pdf) ? body.pdf : Buffer.from(body.pdf);
|
|
194
|
-
form.append('file', buf, {
|
|
195
|
-
filename,
|
|
196
|
-
contentType: 'application/pdf',
|
|
197
|
-
});
|
|
198
|
-
appendIf(form, 'mode', body.mode);
|
|
199
|
-
if (body.hint) form.append('hint', JSON.stringify(body.hint));
|
|
200
|
-
appendIf(form, 'template_id', body.template_id);
|
|
201
|
-
if (body.template) form.append('template', JSON.stringify(body.template));
|
|
202
|
-
appendIf(form, 'user_external_id', body.user_external_id);
|
|
203
|
-
if (body.user_metadata) form.append('user_metadata', JSON.stringify(body.user_metadata));
|
|
204
|
-
if (typeof body.archive === 'boolean') form.append('archive', String(body.archive));
|
|
205
|
-
if (typeof body.force === 'boolean') form.append('force', String(body.force));
|
|
206
|
-
if (body.processing) form.append('processing', body.processing);
|
|
183
|
+
const form = buildExtractMultipart(body);
|
|
207
184
|
return (
|
|
208
185
|
await AbyssToolsCore.axios.post(`extract/extract`, form, {
|
|
209
186
|
params,
|
|
210
|
-
headers: {
|
|
211
|
-
...(typeof form.getHeaders === 'function' ? form.getHeaders() : {}),
|
|
212
|
-
...authHeader(apiKey),
|
|
213
|
-
...extraHeaders,
|
|
214
|
-
},
|
|
187
|
+
headers: { ...authHeader(apiKey), ...extraHeaders },
|
|
215
188
|
maxBodyLength: Infinity,
|
|
216
189
|
maxContentLength: Infinity,
|
|
217
190
|
})
|
|
@@ -228,11 +201,54 @@ const postExtract = async (
|
|
|
228
201
|
).data;
|
|
229
202
|
};
|
|
230
203
|
|
|
231
|
-
function appendIf(form:
|
|
204
|
+
function appendIf(form: FormData, key: string, value: unknown): void {
|
|
232
205
|
if (value === undefined || value === null) return;
|
|
233
206
|
form.append(key, String(value));
|
|
234
207
|
}
|
|
235
208
|
|
|
209
|
+
/** Append the shared extract text fields (all optional) onto a multipart form. */
|
|
210
|
+
function appendExtractFields(form: FormData, body: IExtractBody): void {
|
|
211
|
+
appendIf(form, 'mode', body.mode);
|
|
212
|
+
if (body.hint) form.append('hint', JSON.stringify(body.hint));
|
|
213
|
+
appendIf(form, 'template_id', body.template_id);
|
|
214
|
+
if (body.template) form.append('template', JSON.stringify(body.template));
|
|
215
|
+
appendIf(form, 'user_external_id', body.user_external_id);
|
|
216
|
+
if (body.user_metadata) form.append('user_metadata', JSON.stringify(body.user_metadata));
|
|
217
|
+
if (typeof body.archive === 'boolean') form.append('archive', String(body.archive));
|
|
218
|
+
if (typeof body.force === 'boolean') form.append('force', String(body.force));
|
|
219
|
+
if (body.processing) form.append('processing', body.processing);
|
|
220
|
+
if (body.plan) form.append('plan', JSON.stringify(body.plan));
|
|
221
|
+
appendIf(form, 'plan_preset_id', body.plan_preset_id);
|
|
222
|
+
// Wire name read by the API's parseExtractRequest ('true' / 'false').
|
|
223
|
+
if (typeof body.improvementConsent === 'boolean') {
|
|
224
|
+
form.append('improvement_consent', String(body.improvementConsent));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Build the multipart form for an extract upload, shared by the personal and
|
|
230
|
+
* application extract clients: the PDF as the `file` part (filename from
|
|
231
|
+
* `body.pdf_filename`, default `document.pdf`) plus the extract text fields.
|
|
232
|
+
* Scope params + auth headers are added by the caller; axios sets the
|
|
233
|
+
* multipart content type. Requires `body.pdf` to be set.
|
|
234
|
+
*/
|
|
235
|
+
export function buildExtractMultipart(body: IExtractBody): FormData {
|
|
236
|
+
const pdf = body.pdf;
|
|
237
|
+
if (!pdf) {
|
|
238
|
+
// Precondition: only the multipart-upload path calls this. `postExtract`
|
|
239
|
+
// guards on `body.pdf` itself and falls back to a JSON body otherwise;
|
|
240
|
+
// the application client (extraction.application.api.ts) has no JSON
|
|
241
|
+
// fallback and relies entirely on this throw, since its narrower
|
|
242
|
+
// `IExtractApplicationBody` type requires `pdf` in the first place
|
|
243
|
+
// (#581). Enforced here so the helper is self-contained either way.
|
|
244
|
+
throw new Error('buildExtractMultipart requires body.pdf');
|
|
245
|
+
}
|
|
246
|
+
const form = new FormData();
|
|
247
|
+
appendPdfPart(form, pdf, body.pdf_filename ?? 'document.pdf');
|
|
248
|
+
appendExtractFields(form, body);
|
|
249
|
+
return form;
|
|
250
|
+
}
|
|
251
|
+
|
|
236
252
|
export const extractBulk = async (
|
|
237
253
|
body: IExtractBulkBody,
|
|
238
254
|
scope: IExtractionContentScopeQuery = {},
|
|
@@ -253,29 +269,11 @@ export const detect = async (
|
|
|
253
269
|
pdfFilename = 'document.pdf',
|
|
254
270
|
apiKey?: string,
|
|
255
271
|
): Promise<IDetectResponse> => {
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
const form = new FormData();
|
|
259
|
-
const blob = new Blob([pdf as Uint8Array], { type: 'application/pdf' });
|
|
260
|
-
form.append('file', blob, pdfFilename);
|
|
261
|
-
return (
|
|
262
|
-
await AbyssToolsCore.axios.post<IDetectResponse>(`extract/detect`, form, {
|
|
263
|
-
headers: authHeader(apiKey),
|
|
264
|
-
maxBodyLength: Infinity,
|
|
265
|
-
maxContentLength: Infinity,
|
|
266
|
-
})
|
|
267
|
-
).data;
|
|
268
|
-
}
|
|
269
|
-
const FormDataCtor = await loadFormData();
|
|
270
|
-
const form = new FormDataCtor();
|
|
271
|
-
const buf = Buffer.isBuffer(pdf) ? pdf : Buffer.from(pdf);
|
|
272
|
-
form.append('file', buf, { filename: pdfFilename, contentType: 'application/pdf' });
|
|
272
|
+
const form = new FormData();
|
|
273
|
+
appendPdfPart(form, pdf, pdfFilename);
|
|
273
274
|
return (
|
|
274
275
|
await AbyssToolsCore.axios.post<IDetectResponse>(`extract/detect`, form, {
|
|
275
|
-
headers:
|
|
276
|
-
...(typeof form.getHeaders === 'function' ? form.getHeaders() : {}),
|
|
277
|
-
...authHeader(apiKey),
|
|
278
|
-
},
|
|
276
|
+
headers: authHeader(apiKey),
|
|
279
277
|
maxBodyLength: Infinity,
|
|
280
278
|
maxContentLength: Infinity,
|
|
281
279
|
})
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Type-level compile test for the APPLICATION extract client (#581).
|
|
2
|
+
// No jest runner in this SDK package; compile guard only (mirrors
|
|
3
|
+
// probe-scan.application.api.test.ts). Run: npx tsc --noEmit, or `npm run build`.
|
|
4
|
+
|
|
5
|
+
import * as api from './extraction.application.api';
|
|
6
|
+
import type { IExtractApplicationBody } from '../types';
|
|
7
|
+
|
|
8
|
+
const _run: typeof api.runExtractionApplication = api.runExtractionApplication;
|
|
9
|
+
void _run;
|
|
10
|
+
|
|
11
|
+
type Body = Parameters<typeof api.runExtractionApplication>[1];
|
|
12
|
+
declare const pdf: Buffer;
|
|
13
|
+
|
|
14
|
+
// What the route accepts: a PDF, mode auto|hint, and the optional fields.
|
|
15
|
+
const _minimal: Body = { pdf, mode: 'auto' };
|
|
16
|
+
const _full: Body = {
|
|
17
|
+
pdf,
|
|
18
|
+
mode: 'hint',
|
|
19
|
+
hint: { bank: 'bnp' },
|
|
20
|
+
pdf_filename: 'invoice.pdf',
|
|
21
|
+
user_external_id: 'u-1',
|
|
22
|
+
user_metadata: { a: 1 },
|
|
23
|
+
archive: true,
|
|
24
|
+
force: false,
|
|
25
|
+
improvementConsent: true,
|
|
26
|
+
};
|
|
27
|
+
const _named: IExtractApplicationBody = _minimal;
|
|
28
|
+
void _minimal;
|
|
29
|
+
void _full;
|
|
30
|
+
void _named;
|
|
31
|
+
|
|
32
|
+
// What the route refuses with a 4xx must not compile.
|
|
33
|
+
// @ts-expect-error the route only accepts a multipart PDF
|
|
34
|
+
const _noPdf: Body = { mode: 'auto' };
|
|
35
|
+
// @ts-expect-error storage_file_id is refused by the application route
|
|
36
|
+
const _storage: Body = { pdf, mode: 'auto', storage_file_id: 'f' };
|
|
37
|
+
// @ts-expect-error template_id is refused by the application route
|
|
38
|
+
const _templateId: Body = { pdf, mode: 'auto', template_id: 't' };
|
|
39
|
+
// @ts-expect-error template is refused by the application route
|
|
40
|
+
const _template: Body = { pdf, mode: 'auto', template: {} };
|
|
41
|
+
// @ts-expect-error plan_preset_id is refused by the application route
|
|
42
|
+
const _preset: Body = { pdf, mode: 'auto', plan_preset_id: 'p' };
|
|
43
|
+
// @ts-expect-error mode template is refused by the application route
|
|
44
|
+
const _modeTemplate: Body = { pdf, mode: 'template' };
|
|
45
|
+
// @ts-expect-error the application route is synchronous only
|
|
46
|
+
const _processing: Body = { pdf, mode: 'auto', processing: 'queue' };
|
|
47
|
+
void _noPdf;
|
|
48
|
+
void _storage;
|
|
49
|
+
void _templateId;
|
|
50
|
+
void _template;
|
|
51
|
+
void _preset;
|
|
52
|
+
void _modeTemplate;
|
|
53
|
+
void _processing;
|
|
54
|
+
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// ──────────────────────────────────────────────
|
|
2
|
+
// AbyssExtract APPLICATION extract API — POST
|
|
3
|
+
// /extract/application/:applicationId/extract. Mirrors
|
|
4
|
+
// apps/api/src/api/controllers/extraction-extract-application.controller.ts
|
|
5
|
+
// EXACTLY — the application counterpart of extraction.api.ts's `extractSync`,
|
|
6
|
+
// for inter-service callers (e.g. AbyssBanking) authenticating with a project
|
|
7
|
+
// API key instead of a personal/org session.
|
|
8
|
+
//
|
|
9
|
+
// Reuses extraction.api.ts's `buildExtractMultipart` (the same global
|
|
10
|
+
// `FormData` + `Blob` multipart body as the personal client) and the
|
|
11
|
+
// response TYPE verbatim (`IExtractSyncResponse`) — never redefined here.
|
|
12
|
+
// The request body is `IExtractApplicationBody`, a narrower type than the
|
|
13
|
+
// personal client's `IExtractBody`: it types exactly what this route accepts
|
|
14
|
+
// (#581) — see extraction.request.ts. There is NO scope query param: unlike
|
|
15
|
+
// the personal/org route's `?organization_id=`, an application caller's scope
|
|
16
|
+
// is entirely its `:applicationId` URL segment, resolved server-side by
|
|
17
|
+
// ApplicationMiddleware (round-trips to abyss-main).
|
|
18
|
+
//
|
|
19
|
+
// `authHeaderApplication` is kept LOCAL and unexported, same convention as the
|
|
20
|
+
// personal client's own `authHeader` — it sends `API_KEY_APPLICATION_HEADER`
|
|
21
|
+
// (`abyss-api-key-application`) instead of the personal `abyss-api-key`.
|
|
22
|
+
//
|
|
23
|
+
// The endpoint is SYNCHRONOUS (the machine caller gets the extraction inline —
|
|
24
|
+
// no queue), so the return is always the `IExtractSyncResponse` shape.
|
|
25
|
+
// ──────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
import { AbyssToolsCore, API_KEY_APPLICATION_HEADER } from '..';
|
|
28
|
+
import type { IExtractApplicationBody } from '../types';
|
|
29
|
+
import type { IExtractSyncResponse } from '../types';
|
|
30
|
+
import { buildExtractMultipart, ExtractCallOptions } from './extraction.api';
|
|
31
|
+
|
|
32
|
+
function authHeaderApplication(applicationApiKey?: string): Record<string, string> {
|
|
33
|
+
return applicationApiKey ? { [API_KEY_APPLICATION_HEADER]: applicationApiKey } : {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* `POST /extract/application/:applicationId/extract` — run one synchronous
|
|
38
|
+
* extraction OWNED by `applicationId` and BILLED to its resolved owning
|
|
39
|
+
* organization. The route accepts only a multipart PDF upload: send
|
|
40
|
+
* `body.pdf`, with `body.mode` `auto` or `hint`; `body.plan` (inline, single
|
|
41
|
+
* pass, no OCR, no template pass) and `body.improvementConsent` travel as
|
|
42
|
+
* multipart fields. The route refuses `storage_file_id`, `plan_preset_id`,
|
|
43
|
+
* `template_id` and `template` with a 4xx. A body without `pdf` never reaches
|
|
44
|
+
* the route at all: `IExtractApplicationBody` requires it, and this client's
|
|
45
|
+
* `buildExtractMultipart` throws locally ("buildExtractMultipart requires
|
|
46
|
+
* body.pdf") before any request is sent (#581). The memory watchdog may still
|
|
47
|
+
* answer 503 on a well-formed call, before the route reads the body.
|
|
48
|
+
* `options` forwards a Stripe-style
|
|
49
|
+
* `Idempotency-Key` header (24h replay window) when set — replayed only for
|
|
50
|
+
* the IDENTICAL request; the same key sent with another document or another
|
|
51
|
+
* body answers 422 `IDEMPOTENCY_KEY_REUSED` (see `ExtractCallOptions`).
|
|
52
|
+
*/
|
|
53
|
+
export const runExtractionApplication = async (
|
|
54
|
+
applicationId: string,
|
|
55
|
+
body: IExtractApplicationBody,
|
|
56
|
+
options: ExtractCallOptions = {},
|
|
57
|
+
applicationApiKey?: string,
|
|
58
|
+
): Promise<IExtractSyncResponse> => {
|
|
59
|
+
const extraHeaders: Record<string, string> = {};
|
|
60
|
+
if (options.idempotencyKey) {
|
|
61
|
+
extraHeaders['Idempotency-Key'] = options.idempotencyKey;
|
|
62
|
+
}
|
|
63
|
+
const url = `extract/application/${applicationId}/extract`;
|
|
64
|
+
|
|
65
|
+
const form = buildExtractMultipart(body);
|
|
66
|
+
return (
|
|
67
|
+
await AbyssToolsCore.axios.post<IExtractSyncResponse>(url, form, {
|
|
68
|
+
headers: { ...authHeaderApplication(applicationApiKey), ...extraHeaders },
|
|
69
|
+
maxBodyLength: Infinity,
|
|
70
|
+
maxContentLength: Infinity,
|
|
71
|
+
})
|
|
72
|
+
).data;
|
|
73
|
+
};
|
package/src/api/index.ts
CHANGED
|
@@ -18,4 +18,30 @@ void _scanAsync;
|
|
|
18
18
|
void _getScan;
|
|
19
19
|
void _listScans;
|
|
20
20
|
|
|
21
|
+
// The accepted file inputs (#519). A Blob covers the browser's File and Node's
|
|
22
|
+
// file-backed fs.openAsBlob(path); raw bytes are accepted as a Uint8Array (and
|
|
23
|
+
// therefore a Buffer). A Node stream is refused AT COMPILE TIME: the body is a
|
|
24
|
+
// spec FormData, whose parts need a known length, so honouring a stream would
|
|
25
|
+
// mean buffering up to 2 GiB in memory.
|
|
26
|
+
declare const blob: Blob;
|
|
27
|
+
declare const bytes: Uint8Array;
|
|
28
|
+
declare const buffer: Buffer;
|
|
29
|
+
declare const stream: NodeJS.ReadableStream;
|
|
30
|
+
|
|
31
|
+
const _fromBlob: api.ProbeScanFileInput = blob;
|
|
32
|
+
const _fromBytes: api.ProbeScanFileInput = bytes;
|
|
33
|
+
const _fromBuffer: api.ProbeScanFileInput = buffer;
|
|
34
|
+
// @ts-expect-error a Readable stream is not an accepted scan input since 2.12.0
|
|
35
|
+
const _fromStream: api.ProbeScanFileInput = stream;
|
|
36
|
+
|
|
37
|
+
void _fromBlob;
|
|
38
|
+
void _fromBytes;
|
|
39
|
+
void _fromBuffer;
|
|
40
|
+
void _fromStream;
|
|
41
|
+
|
|
42
|
+
// buildScanForm returns the FormData alone — axios sets the multipart
|
|
43
|
+
// content type and boundary, so there are no headers to merge in.
|
|
44
|
+
const _form: FormData = api.buildScanForm(blob, { filename: 'f.bin' });
|
|
45
|
+
void _form;
|
|
46
|
+
|
|
21
47
|
export {};
|