@abyss-project/extract 0.0.0-stage → 1.0.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.
Files changed (183) hide show
  1. package/.eslintrc.js +32 -0
  2. package/.prettierrc +5 -0
  3. package/README.md +21 -2
  4. package/dist/api/extraction-plan-preset.api.d.ts +9 -0
  5. package/dist/api/extraction-plan-preset.api.js +36 -0
  6. package/dist/api/extraction-plan-preset.api.js.map +1 -0
  7. package/dist/api/extraction-plan-preset.api.test.d.ts +1 -0
  8. package/dist/api/extraction-plan-preset.api.test.js +51 -0
  9. package/dist/api/extraction-plan-preset.api.test.js.map +1 -0
  10. package/dist/api/extraction-settings.api.d.ts +4 -0
  11. package/dist/api/extraction-settings.api.js +22 -0
  12. package/dist/api/extraction-settings.api.js.map +1 -0
  13. package/dist/api/extraction.api.d.ts +76 -0
  14. package/dist/api/extraction.api.js +414 -0
  15. package/dist/api/extraction.api.js.map +1 -0
  16. package/dist/api/extraction.application.api.d.ts +4 -0
  17. package/dist/api/extraction.application.api.js +23 -0
  18. package/dist/api/extraction.application.api.js.map +1 -0
  19. package/dist/api/extraction.application.api.test.d.ts +1 -0
  20. package/dist/api/extraction.application.api.test.js +69 -0
  21. package/dist/api/extraction.application.api.test.js.map +1 -0
  22. package/dist/api/index.d.ts +4 -0
  23. package/dist/api/index.js +21 -0
  24. package/dist/api/index.js.map +1 -0
  25. package/dist/constants/extract.constants.d.ts +4 -0
  26. package/dist/constants/extract.constants.js +91 -0
  27. package/dist/constants/extract.constants.js.map +1 -0
  28. package/dist/constants/index.d.ts +1 -0
  29. package/dist/constants/index.js +18 -0
  30. package/dist/constants/index.js.map +1 -0
  31. package/dist/index.d.ts +127 -0
  32. package/dist/index.js +210 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/types/enum/api-error.enum.d.ts +31 -0
  35. package/dist/types/enum/api-error.enum.js +37 -0
  36. package/dist/types/enum/api-error.enum.js.map +1 -0
  37. package/dist/types/enum/combine-strategy.enum.d.ts +5 -0
  38. package/dist/types/enum/combine-strategy.enum.js +10 -0
  39. package/dist/types/enum/combine-strategy.enum.js.map +1 -0
  40. package/dist/types/enum/document-type.enum.d.ts +10 -0
  41. package/dist/types/enum/document-type.enum.js +15 -0
  42. package/dist/types/enum/document-type.enum.js.map +1 -0
  43. package/dist/types/enum/extract-bank.enum.d.ts +50 -0
  44. package/dist/types/enum/extract-bank.enum.js +327 -0
  45. package/dist/types/enum/extract-bank.enum.js.map +1 -0
  46. package/dist/types/enum/extract-field-format.enum.d.ts +7 -0
  47. package/dist/types/enum/extract-field-format.enum.js +12 -0
  48. package/dist/types/enum/extract-field-format.enum.js.map +1 -0
  49. package/dist/types/enum/extract-field-key.enum.d.ts +59 -0
  50. package/dist/types/enum/extract-field-key.enum.js +64 -0
  51. package/dist/types/enum/extract-field-key.enum.js.map +1 -0
  52. package/dist/types/enum/extraction-feedback-issue-type.enum.d.ts +8 -0
  53. package/dist/types/enum/extraction-feedback-issue-type.enum.js +13 -0
  54. package/dist/types/enum/extraction-feedback-issue-type.enum.js.map +1 -0
  55. package/dist/types/enum/extraction-step-status.enum.d.ts +6 -0
  56. package/dist/types/enum/extraction-step-status.enum.js +11 -0
  57. package/dist/types/enum/extraction-step-status.enum.js.map +1 -0
  58. package/dist/types/enum/extraction-warning.enum.d.ts +10 -0
  59. package/dist/types/enum/extraction-warning.enum.js +15 -0
  60. package/dist/types/enum/extraction-warning.enum.js.map +1 -0
  61. package/dist/types/enum/file-scan-status.enum.d.ts +1 -0
  62. package/dist/types/enum/file-scan-status.enum.js +3 -0
  63. package/dist/types/enum/file-scan-status.enum.js.map +1 -0
  64. package/dist/types/enum/index.d.ts +12 -0
  65. package/dist/types/enum/index.js +29 -0
  66. package/dist/types/enum/index.js.map +1 -0
  67. package/dist/types/enum/interpreter-kind.enum.d.ts +5 -0
  68. package/dist/types/enum/interpreter-kind.enum.js +10 -0
  69. package/dist/types/enum/interpreter-kind.enum.js.map +1 -0
  70. package/dist/types/enum/provider-kind.enum.d.ts +10 -0
  71. package/dist/types/enum/provider-kind.enum.js +16 -0
  72. package/dist/types/enum/provider-kind.enum.js.map +1 -0
  73. package/dist/types/index.d.ts +2 -0
  74. package/dist/types/index.js +19 -0
  75. package/dist/types/index.js.map +1 -0
  76. package/dist/types/interface/api/index.d.ts +5 -0
  77. package/dist/types/interface/api/index.js +22 -0
  78. package/dist/types/interface/api/index.js.map +1 -0
  79. package/dist/types/interface/api/requests/extraction.request.d.ts +259 -0
  80. package/dist/types/interface/api/requests/extraction.request.js +3 -0
  81. package/dist/types/interface/api/requests/extraction.request.js.map +1 -0
  82. package/dist/types/interface/api/requests/index.d.ts +1 -0
  83. package/dist/types/interface/api/requests/index.js +18 -0
  84. package/dist/types/interface/api/requests/index.js.map +1 -0
  85. package/dist/types/interface/api/responses/extraction.response.d.ts +424 -0
  86. package/dist/types/interface/api/responses/extraction.response.js +3 -0
  87. package/dist/types/interface/api/responses/extraction.response.js.map +1 -0
  88. package/dist/types/interface/api/responses/index.d.ts +1 -0
  89. package/dist/types/interface/api/responses/index.js +18 -0
  90. package/dist/types/interface/api/responses/index.js.map +1 -0
  91. package/dist/types/interface/api/type-message/api-error.d.ts +6 -0
  92. package/dist/types/interface/api/type-message/api-error.js +3 -0
  93. package/dist/types/interface/api/type-message/api-error.js.map +1 -0
  94. package/dist/types/interface/api/type-message/base-paginate.d.ts +10 -0
  95. package/dist/types/interface/api/type-message/base-paginate.js +3 -0
  96. package/dist/types/interface/api/type-message/base-paginate.js.map +1 -0
  97. package/dist/types/interface/api/type-message/response.d.ts +5 -0
  98. package/dist/types/interface/api/type-message/response.js +3 -0
  99. package/dist/types/interface/api/type-message/response.js.map +1 -0
  100. package/dist/types/interface/index.d.ts +2 -0
  101. package/dist/types/interface/index.js +19 -0
  102. package/dist/types/interface/index.js.map +1 -0
  103. package/dist/types/interface/models/extraction-fetched-provenance.dto.test.d.ts +1 -0
  104. package/dist/types/interface/models/extraction-fetched-provenance.dto.test.js +165 -0
  105. package/dist/types/interface/models/extraction-fetched-provenance.dto.test.js.map +1 -0
  106. package/dist/types/interface/models/extraction-plan.dto.d.ts +192 -0
  107. package/dist/types/interface/models/extraction-plan.dto.js +13 -0
  108. package/dist/types/interface/models/extraction-plan.dto.js.map +1 -0
  109. package/dist/types/interface/models/extraction-plan.dto.test.d.ts +1 -0
  110. package/dist/types/interface/models/extraction-plan.dto.test.js +40 -0
  111. package/dist/types/interface/models/extraction-plan.dto.test.js.map +1 -0
  112. package/dist/types/interface/models/extraction-spatial-template.dto.d.ts +37 -0
  113. package/dist/types/interface/models/extraction-spatial-template.dto.js +3 -0
  114. package/dist/types/interface/models/extraction-spatial-template.dto.js.map +1 -0
  115. package/dist/types/interface/models/extraction-spatial-template.dto.test.d.ts +1 -0
  116. package/dist/types/interface/models/extraction-spatial-template.dto.test.js +32 -0
  117. package/dist/types/interface/models/extraction-spatial-template.dto.test.js.map +1 -0
  118. package/dist/types/interface/models/extraction.dto.d.ts +255 -0
  119. package/dist/types/interface/models/extraction.dto.js +28 -0
  120. package/dist/types/interface/models/extraction.dto.js.map +1 -0
  121. package/dist/types/interface/models/index.d.ts +3 -0
  122. package/dist/types/interface/models/index.js +20 -0
  123. package/dist/types/interface/models/index.js.map +1 -0
  124. package/dist/utils/enum.utils.d.ts +1 -0
  125. package/dist/utils/enum.utils.js +3 -0
  126. package/dist/utils/enum.utils.js.map +1 -0
  127. package/dist/utils/error.utils.d.ts +15 -0
  128. package/dist/utils/error.utils.js +25 -0
  129. package/dist/utils/error.utils.js.map +1 -0
  130. package/dist/utils/extraction-webhook.utils.d.ts +6 -0
  131. package/dist/utils/extraction-webhook.utils.js +17 -0
  132. package/dist/utils/extraction-webhook.utils.js.map +1 -0
  133. package/dist/utils/index.d.ts +3 -0
  134. package/dist/utils/index.js +20 -0
  135. package/dist/utils/index.js.map +1 -0
  136. package/package.json +58 -4
  137. package/src/api/extraction-plan-preset.api.test.ts +24 -0
  138. package/src/api/extraction-plan-preset.api.ts +97 -0
  139. package/src/api/extraction-settings.api.ts +53 -0
  140. package/src/api/extraction.api.ts +1012 -0
  141. package/src/api/extraction.application.api.test.ts +55 -0
  142. package/src/api/extraction.application.api.ts +73 -0
  143. package/src/api/index.ts +4 -0
  144. package/src/constants/extract.constants.ts +109 -0
  145. package/src/constants/index.ts +1 -0
  146. package/src/index.ts +305 -0
  147. package/src/types/enum/api-error.enum.ts +33 -0
  148. package/src/types/enum/combine-strategy.enum.ts +7 -0
  149. package/src/types/enum/document-type.enum.ts +11 -0
  150. package/src/types/enum/extract-bank.enum.ts +363 -0
  151. package/src/types/enum/extract-field-format.enum.ts +16 -0
  152. package/src/types/enum/extract-field-key.enum.ts +77 -0
  153. package/src/types/enum/extraction-feedback-issue-type.enum.ts +10 -0
  154. package/src/types/enum/extraction-step-status.enum.ts +7 -0
  155. package/src/types/enum/extraction-warning.enum.ts +78 -0
  156. package/src/types/enum/file-scan-status.enum.ts +33 -0
  157. package/src/types/enum/index.ts +12 -0
  158. package/src/types/enum/interpreter-kind.enum.ts +7 -0
  159. package/src/types/enum/provider-kind.enum.ts +13 -0
  160. package/src/types/index.ts +2 -0
  161. package/src/types/interface/api/index.ts +5 -0
  162. package/src/types/interface/api/requests/extraction.request.ts +423 -0
  163. package/src/types/interface/api/requests/index.ts +1 -0
  164. package/src/types/interface/api/responses/extraction.response.ts +488 -0
  165. package/src/types/interface/api/responses/index.ts +1 -0
  166. package/src/types/interface/api/type-message/api-error.ts +7 -0
  167. package/src/types/interface/api/type-message/base-paginate.ts +11 -0
  168. package/src/types/interface/api/type-message/response.ts +6 -0
  169. package/src/types/interface/index.ts +2 -0
  170. package/src/types/interface/models/extraction-fetched-provenance.dto.test.ts +204 -0
  171. package/src/types/interface/models/extraction-plan.dto.test.ts +60 -0
  172. package/src/types/interface/models/extraction-plan.dto.ts +280 -0
  173. package/src/types/interface/models/extraction-spatial-template.dto.test.ts +48 -0
  174. package/src/types/interface/models/extraction-spatial-template.dto.ts +48 -0
  175. package/src/types/interface/models/extraction.dto.ts +399 -0
  176. package/src/types/interface/models/index.ts +3 -0
  177. package/src/types/tests/extract-bank-catalogue.spec.ts +74 -0
  178. package/src/utils/enum.utils.ts +1 -0
  179. package/src/utils/error.utils.ts +30 -0
  180. package/src/utils/extraction-webhook.utils.ts +30 -0
  181. package/src/utils/index.ts +3 -0
  182. package/tsconfig.check.json +15 -0
  183. package/tsconfig.json +36 -0
@@ -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 { AbyssExtractCore, 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 AbyssExtractCore.axios.post<IExtractSyncResponse>(url, form, {
68
+ headers: { ...authHeaderApplication(applicationApiKey), ...extraHeaders },
69
+ maxBodyLength: Infinity,
70
+ maxContentLength: Infinity,
71
+ })
72
+ ).data;
73
+ };
@@ -0,0 +1,4 @@
1
+ export * from './extraction.api';
2
+ export * from './extraction.application.api';
3
+ export * from './extraction-settings.api';
4
+ export * from './extraction-plan-preset.api';
@@ -0,0 +1,109 @@
1
+ import { DocumentType } from '../types/enum/document-type.enum';
2
+ import { ExtractFieldFormat } from '../types/enum/extract-field-format.enum';
3
+ import { ExtractFieldKey } from '../types/enum/extract-field-key.enum';
4
+
5
+ const { AMOUNT, DATE, PERCENT, BOOLEAN, TEXT } = ExtractFieldFormat;
6
+
7
+ // ──────────────────────────────────────────────
8
+ // EXTRACT_PUBLISHABLE_FIELDS — the fields the built-in algorithmic
9
+ // interpreter of AbyssExtract can publish, per document type, with the format
10
+ // of their value. A field listed here may be absent from a given result (not
11
+ // found, or below its publish floor); a field not listed here is never
12
+ // published for that type by that interpreter. A learned template
13
+ // (spatial-template interpreter) publishes the keys its client defined, on any
14
+ // type.
15
+ //
16
+ // One exception: a valid machine-readable zone publishes its fields and
17
+ // `mrzValid` whatever the document type (listed here under `id_card` only).
18
+ //
19
+ // `generic` is absent: its fields are defined by the client. The extraction API
20
+ // tests that this list equals what its engine serves, type by type.
21
+ // ──────────────────────────────────────────────
22
+ export const EXTRACT_PUBLISHABLE_FIELDS: Readonly<
23
+ Record<
24
+ Exclude<DocumentType, DocumentType.GENERIC>,
25
+ Readonly<Partial<Record<ExtractFieldKey, ExtractFieldFormat>>>
26
+ >
27
+ > = Object.freeze({
28
+ [DocumentType.BANK_STATEMENT]: Object.freeze({
29
+ [ExtractFieldKey.IBAN]: TEXT,
30
+ [ExtractFieldKey.BIC]: TEXT,
31
+ [ExtractFieldKey.BANK_NAME]: TEXT,
32
+ [ExtractFieldKey.OPENING_BALANCE]: AMOUNT,
33
+ [ExtractFieldKey.CLOSING_BALANCE]: AMOUNT,
34
+ [ExtractFieldKey.PERIOD_START]: DATE,
35
+ [ExtractFieldKey.PERIOD_END]: DATE,
36
+ [ExtractFieldKey.CURRENCY]: TEXT,
37
+ }),
38
+ [DocumentType.INVOICE]: Object.freeze({
39
+ [ExtractFieldKey.TOTAL_TTC]: AMOUNT,
40
+ [ExtractFieldKey.TOTAL_HT]: AMOUNT,
41
+ [ExtractFieldKey.TOTAL_VAT]: AMOUNT,
42
+ [ExtractFieldKey.INVOICE_DATE]: DATE,
43
+ [ExtractFieldKey.DUE_DATE]: DATE,
44
+ [ExtractFieldKey.INVOICE_NUMBER]: TEXT,
45
+ [ExtractFieldKey.SUPPLIER]: TEXT,
46
+ [ExtractFieldKey.SUPPLIER_LEGAL_NAME]: TEXT,
47
+ [ExtractFieldKey.MARKETPLACE]: TEXT,
48
+ [ExtractFieldKey.SIRET]: TEXT,
49
+ [ExtractFieldKey.SIREN]: TEXT,
50
+ [ExtractFieldKey.VAT_NUMBER]: TEXT,
51
+ [ExtractFieldKey.IBAN]: TEXT,
52
+ [ExtractFieldKey.BIC]: TEXT,
53
+ [ExtractFieldKey.CURRENCY]: TEXT,
54
+ }),
55
+ [DocumentType.RECEIPT]: Object.freeze({
56
+ [ExtractFieldKey.TOTAL]: AMOUNT,
57
+ [ExtractFieldKey.VAT]: AMOUNT,
58
+ [ExtractFieldKey.DATE]: DATE,
59
+ [ExtractFieldKey.MERCHANT]: TEXT,
60
+ [ExtractFieldKey.CURRENCY]: TEXT,
61
+ }),
62
+ [DocumentType.ID_CARD]: Object.freeze({
63
+ [ExtractFieldKey.LAST_NAME]: TEXT,
64
+ [ExtractFieldKey.FIRST_NAMES]: TEXT,
65
+ [ExtractFieldKey.BIRTH_DATE]: DATE,
66
+ [ExtractFieldKey.EXPIRY_DATE]: DATE,
67
+ [ExtractFieldKey.ISSUE_DATE]: DATE,
68
+ [ExtractFieldKey.DOCUMENT_NUMBER]: TEXT,
69
+ [ExtractFieldKey.SEX]: TEXT,
70
+ [ExtractFieldKey.NATIONALITY]: TEXT,
71
+ [ExtractFieldKey.ISSUING_COUNTRY]: TEXT,
72
+ [ExtractFieldKey.DOCUMENT_KIND]: TEXT,
73
+ [ExtractFieldKey.MRZ_VALID]: BOOLEAN,
74
+ }),
75
+ [DocumentType.RIB]: Object.freeze({
76
+ [ExtractFieldKey.IBAN]: TEXT,
77
+ [ExtractFieldKey.BIC]: TEXT,
78
+ [ExtractFieldKey.HOLDER_NAME]: TEXT,
79
+ [ExtractFieldKey.BANK_NAME]: TEXT,
80
+ }),
81
+ [DocumentType.FINANCIAL_STATEMENT]: Object.freeze({
82
+ [ExtractFieldKey.COMPANY]: TEXT,
83
+ [ExtractFieldKey.SIREN]: TEXT,
84
+ [ExtractFieldKey.REGISTRATION_NUMBER]: TEXT,
85
+ [ExtractFieldKey.FISCAL_YEAR_END]: DATE,
86
+ [ExtractFieldKey.TOTAL_ACTIF]: AMOUNT,
87
+ [ExtractFieldKey.TOTAL_PASSIF]: AMOUNT,
88
+ [ExtractFieldKey.FIXED_ASSETS]: AMOUNT,
89
+ [ExtractFieldKey.CURRENT_ASSETS]: AMOUNT,
90
+ [ExtractFieldKey.CREDITORS_WITHIN_ONE_YEAR]: AMOUNT,
91
+ [ExtractFieldKey.NET_CURRENT_LIABILITIES]: AMOUNT,
92
+ [ExtractFieldKey.TOTAL_ASSETS_LESS_CURRENT_LIABILITIES]: AMOUNT,
93
+ [ExtractFieldKey.NET_ASSETS]: AMOUNT,
94
+ [ExtractFieldKey.CALLED_UP_SHARE_CAPITAL]: AMOUNT,
95
+ [ExtractFieldKey.PROFIT_AND_LOSS_ACCOUNT]: AMOUNT,
96
+ [ExtractFieldKey.TOTAL_SHAREHOLDERS_FUNDS]: AMOUNT,
97
+ [ExtractFieldKey.CURRENCY]: TEXT,
98
+ }),
99
+ [DocumentType.PAYSLIP]: Object.freeze({
100
+ [ExtractFieldKey.EMPLOYER]: TEXT,
101
+ [ExtractFieldKey.PERIOD]: TEXT,
102
+ [ExtractFieldKey.GROSS_CENTS]: AMOUNT,
103
+ [ExtractFieldKey.NET_CENTS]: AMOUNT,
104
+ [ExtractFieldKey.NET_TAXABLE_CENTS]: AMOUNT,
105
+ [ExtractFieldKey.PAS_AMOUNT_CENTS]: AMOUNT,
106
+ [ExtractFieldKey.PAS_RATE_PCT]: PERCENT,
107
+ [ExtractFieldKey.CURRENCY]: TEXT,
108
+ }),
109
+ });
@@ -0,0 +1 @@
1
+ export * from './extract.constants';
package/src/index.ts ADDED
@@ -0,0 +1,305 @@
1
+ import axios from 'axios';
2
+ import axiosRetry, { IAxiosRetryConfig, isNetworkOrIdempotentRequestError } from 'axios-retry';
3
+ import * as extractionApi from './api/extraction.api';
4
+ import * as extractionApplicationApi from './api/extraction.application.api';
5
+ import * as extractionSettingsApi from './api/extraction-settings.api';
6
+ import * as extractionPlanPresetApi from './api/extraction-plan-preset.api';
7
+
8
+ export * from './api';
9
+ export * from './types';
10
+ export * from './utils';
11
+ export * from './constants';
12
+
13
+ const DEFAULT_BASE_URL = 'https://extract-api.abyss-project.fr/api/';
14
+
15
+ export const API_KEY_HEADER = 'abyss-api-key';
16
+ export const API_KEY_APPLICATION_HEADER = 'abyss-api-key-application';
17
+ export const ADMIN_TOKEN_HEADER = 'abyss-admin-token';
18
+
19
+ const NUMBER_RETRY_API = 10;
20
+ const BASE_DELAY_BETWEEN_RETRY = 5000;
21
+ const RETRY_CODES = [
22
+ 502, // Bad Gateway
23
+ 503, // Service Unavailable
24
+ ];
25
+
26
+ type CoreConfig = {
27
+ token?: string;
28
+ apiKey?: string;
29
+ adminToken?: string;
30
+ baseURL?: string;
31
+ };
32
+
33
+ type AbyssExtractCoreSDK = {
34
+ extract: {
35
+ health: typeof extractionApi.health;
36
+ stats: typeof extractionApi.stats;
37
+ changelog: typeof extractionApi.changelog;
38
+ detect: typeof extractionApi.detect;
39
+ detectBulk: typeof extractionApi.detectBulk;
40
+ run: typeof extractionApi.extractSync;
41
+ runQueue: typeof extractionApi.extractQueue;
42
+ runBulk: typeof extractionApi.extractBulk;
43
+ /**
44
+ * Application/API-key-auth counterpart — for a backend satellite (e.g.
45
+ * AbyssBanking) triggering a SYNCHRONOUS extraction server-side with its
46
+ * APPLICATION api key: the run is OWNED by the application and BILLED to
47
+ * its resolved owning organization (never an end user). Hits
48
+ * `/extract/application/:applicationId/extract`, authenticated with the
49
+ * `abyss-api-key-application` header ({@link API_KEY_APPLICATION_HEADER})
50
+ * instead of the personal `abyss-api-key`. Does NOT change the personal `run`.
51
+ */
52
+ application: {
53
+ /** `POST /extract/application/:applicationId/extract` — synchronous; owned + billed to the app's org. */
54
+ run: typeof extractionApplicationApi.runExtractionApplication;
55
+ };
56
+ files: {
57
+ list: typeof extractionApi.listFiles;
58
+ listShared: typeof extractionApi.listSharedFiles;
59
+ get: typeof extractionApi.getFile;
60
+ patch: typeof extractionApi.patchFile;
61
+ listExtractions: typeof extractionApi.listFileExtractions;
62
+ downloadBundle: typeof extractionApi.downloadFileBundle;
63
+ /** Download the ORIGINAL source file (proxy-streamed; 423 while AV scan pending). */
64
+ downloadSource: typeof extractionApi.downloadFileSource;
65
+ };
66
+ extractions: {
67
+ get: typeof extractionApi.getExtraction;
68
+ patch: typeof extractionApi.patchExtraction;
69
+ searchRecords: typeof extractionApi.searchExtractionRecords;
70
+ export: typeof extractionApi.exportExtraction;
71
+ asyncExport: typeof extractionApi.asyncExportExtraction;
72
+ getExportJob: typeof extractionApi.getExportJob;
73
+ diff: typeof extractionApi.diffExtractions;
74
+ /** Opt a specific extraction in/out of the improvement-training dataset. */
75
+ toggleTraining: typeof extractionApi.toggleExtractionTraining;
76
+ /** Lazy fetch of one trace step's full IO payload (P3). */
77
+ stepIo: typeof extractionApi.getStepIo;
78
+ };
79
+ templates: {
80
+ list: typeof extractionApi.listTemplates;
81
+ get: typeof extractionApi.getTemplate;
82
+ create: typeof extractionApi.createTemplate;
83
+ update: typeof extractionApi.updateTemplate;
84
+ patchMeta: typeof extractionApi.patchTemplateMeta;
85
+ /** DESTRUCTIVE: template + versions + witness PDFs. Archive via patchMeta instead. */
86
+ delete: typeof extractionApi.deleteTemplate;
87
+ listVersions: typeof extractionApi.listTemplateVersions;
88
+ /** Presigned download URL for a version's witness PDF (404 when none). */
89
+ getWitnessUrl: typeof extractionApi.getTemplateWitnessUrl;
90
+ /** Delete a version's witness PDF and free the billed storage. */
91
+ deleteWitness: typeof extractionApi.deleteTemplateWitness;
92
+ exportCollection: typeof extractionApi.exportTemplateCollection;
93
+ importCollection: typeof extractionApi.importTemplateCollection;
94
+ };
95
+ jobs: {
96
+ get: typeof extractionApi.getJob;
97
+ retry: typeof extractionApi.retryJob;
98
+ cancel: typeof extractionApi.cancelJob;
99
+ };
100
+ feedback: {
101
+ submit: typeof extractionApi.submitFeedback;
102
+ list: typeof extractionApi.listFeedback;
103
+ get: typeof extractionApi.getFeedback;
104
+ patch: typeof extractionApi.patchFeedback;
105
+ };
106
+ usage: {
107
+ list: typeof extractionApi.listUsage;
108
+ summary: typeof extractionApi.summaryUsage;
109
+ byConfig: typeof extractionApi.usageByConfig;
110
+ };
111
+ share: {
112
+ mint: typeof extractionApi.mintShareExtraction;
113
+ revoke: typeof extractionApi.revokeShareExtraction;
114
+ public: { get: typeof extractionApi.getSharedExtractionPublic };
115
+ };
116
+ // Webhook delivery history.
117
+ webhookDeliveries: {
118
+ list: typeof extractionApi.listWebhookDeliveries;
119
+ get: typeof extractionApi.getWebhookDelivery;
120
+ replay: typeof extractionApi.replayWebhookDelivery;
121
+ };
122
+ // Webhook subscriptions (managed registrations).
123
+ webhook: {
124
+ paginate: typeof extractionApi.paginateExtractionWebhook;
125
+ get: typeof extractionApi.getExtractionWebhook;
126
+ create: typeof extractionApi.createExtractionWebhook;
127
+ update: typeof extractionApi.updateExtractionWebhook;
128
+ delete: typeof extractionApi.deleteExtractionWebhook;
129
+ resetSecret: typeof extractionApi.resetSecretExtractionWebhook;
130
+ };
131
+ // Per-scope improvement-consent settings (P4).
132
+ settings: {
133
+ get: typeof extractionSettingsApi.getExtractionSettings;
134
+ upsert: typeof extractionSettingsApi.upsertExtractionSettings;
135
+ };
136
+ // Provider/interpreter capabilities (V2-P1).
137
+ modes: { list: typeof extractionPlanPresetApi.listModes };
138
+ // Saved extraction plan presets CRUD (V2-P1).
139
+ plans: {
140
+ list: typeof extractionPlanPresetApi.listExtractionPlanPresets;
141
+ get: typeof extractionPlanPresetApi.getExtractionPlanPreset;
142
+ create: typeof extractionPlanPresetApi.createExtractionPlanPreset;
143
+ update: typeof extractionPlanPresetApi.updateExtractionPlanPreset;
144
+ delete: typeof extractionPlanPresetApi.deleteExtractionPlanPreset;
145
+ setDefault: typeof extractionPlanPresetApi.setDefaultExtractionPlanPreset;
146
+ };
147
+ };
148
+ };
149
+
150
+ export class AbyssExtractCore {
151
+ private static config = {
152
+ token: '',
153
+ apiKey: '',
154
+ adminToken: '',
155
+ baseURL: DEFAULT_BASE_URL,
156
+ };
157
+ static axios = axios.create({
158
+ baseURL: this.config.baseURL,
159
+ withCredentials: true,
160
+ });
161
+
162
+ private static _sdk: AbyssExtractCoreSDK | null = null;
163
+
164
+ public static get sdk(): AbyssExtractCoreSDK {
165
+ if (!AbyssExtractCore._sdk) {
166
+ AbyssExtractCore._sdk = AbyssExtractCore.buildSDK();
167
+ }
168
+ return AbyssExtractCore._sdk;
169
+ }
170
+
171
+ private static buildSDK(): AbyssExtractCoreSDK {
172
+ return {
173
+ extract: {
174
+ health: extractionApi.health,
175
+ stats: extractionApi.stats,
176
+ changelog: extractionApi.changelog,
177
+ detect: extractionApi.detect,
178
+ detectBulk: extractionApi.detectBulk,
179
+ run: extractionApi.extractSync,
180
+ runQueue: extractionApi.extractQueue,
181
+ runBulk: extractionApi.extractBulk,
182
+ application: {
183
+ run: extractionApplicationApi.runExtractionApplication,
184
+ },
185
+ files: {
186
+ list: extractionApi.listFiles,
187
+ listShared: extractionApi.listSharedFiles,
188
+ get: extractionApi.getFile,
189
+ patch: extractionApi.patchFile,
190
+ listExtractions: extractionApi.listFileExtractions,
191
+ downloadBundle: extractionApi.downloadFileBundle,
192
+ downloadSource: extractionApi.downloadFileSource,
193
+ },
194
+ extractions: {
195
+ get: extractionApi.getExtraction,
196
+ patch: extractionApi.patchExtraction,
197
+ searchRecords: extractionApi.searchExtractionRecords,
198
+ export: extractionApi.exportExtraction,
199
+ asyncExport: extractionApi.asyncExportExtraction,
200
+ getExportJob: extractionApi.getExportJob,
201
+ diff: extractionApi.diffExtractions,
202
+ toggleTraining: extractionApi.toggleExtractionTraining,
203
+ stepIo: extractionApi.getStepIo,
204
+ },
205
+ templates: {
206
+ list: extractionApi.listTemplates,
207
+ get: extractionApi.getTemplate,
208
+ create: extractionApi.createTemplate,
209
+ update: extractionApi.updateTemplate,
210
+ patchMeta: extractionApi.patchTemplateMeta,
211
+ delete: extractionApi.deleteTemplate,
212
+ listVersions: extractionApi.listTemplateVersions,
213
+ getWitnessUrl: extractionApi.getTemplateWitnessUrl,
214
+ deleteWitness: extractionApi.deleteTemplateWitness,
215
+ exportCollection: extractionApi.exportTemplateCollection,
216
+ importCollection: extractionApi.importTemplateCollection,
217
+ },
218
+ jobs: {
219
+ get: extractionApi.getJob,
220
+ retry: extractionApi.retryJob,
221
+ cancel: extractionApi.cancelJob,
222
+ },
223
+ feedback: {
224
+ submit: extractionApi.submitFeedback,
225
+ list: extractionApi.listFeedback,
226
+ get: extractionApi.getFeedback,
227
+ patch: extractionApi.patchFeedback,
228
+ },
229
+ usage: {
230
+ list: extractionApi.listUsage,
231
+ summary: extractionApi.summaryUsage,
232
+ byConfig: extractionApi.usageByConfig,
233
+ },
234
+ share: {
235
+ mint: extractionApi.mintShareExtraction,
236
+ revoke: extractionApi.revokeShareExtraction,
237
+ public: { get: extractionApi.getSharedExtractionPublic },
238
+ },
239
+ webhookDeliveries: {
240
+ list: extractionApi.listWebhookDeliveries,
241
+ get: extractionApi.getWebhookDelivery,
242
+ replay: extractionApi.replayWebhookDelivery,
243
+ },
244
+ webhook: {
245
+ paginate: extractionApi.paginateExtractionWebhook,
246
+ get: extractionApi.getExtractionWebhook,
247
+ create: extractionApi.createExtractionWebhook,
248
+ update: extractionApi.updateExtractionWebhook,
249
+ delete: extractionApi.deleteExtractionWebhook,
250
+ resetSecret: extractionApi.resetSecretExtractionWebhook,
251
+ },
252
+ settings: {
253
+ get: extractionSettingsApi.getExtractionSettings,
254
+ upsert: extractionSettingsApi.upsertExtractionSettings,
255
+ },
256
+ modes: { list: extractionPlanPresetApi.listModes },
257
+ plans: {
258
+ list: extractionPlanPresetApi.listExtractionPlanPresets,
259
+ get: extractionPlanPresetApi.getExtractionPlanPreset,
260
+ create: extractionPlanPresetApi.createExtractionPlanPreset,
261
+ update: extractionPlanPresetApi.updateExtractionPlanPreset,
262
+ delete: extractionPlanPresetApi.deleteExtractionPlanPreset,
263
+ setDefault: extractionPlanPresetApi.setDefaultExtractionPlanPreset,
264
+ },
265
+ },
266
+ };
267
+ }
268
+
269
+ public static enableAxiosRetry(axiosRetryConfig?: IAxiosRetryConfig): void {
270
+ axiosRetry(AbyssExtractCore.axios, {
271
+ retries: NUMBER_RETRY_API,
272
+ retryDelay: (retryCount) => retryCount * BASE_DELAY_BETWEEN_RETRY,
273
+ retryCondition: (error) =>
274
+ isNetworkOrIdempotentRequestError(error) ||
275
+ RETRY_CODES.includes(error.response?.status || 502),
276
+ ...axiosRetryConfig,
277
+ });
278
+ }
279
+
280
+ public static setConfig(config: CoreConfig): void {
281
+ AbyssExtractCore._sdk = null;
282
+
283
+ AbyssExtractCore.config = { ...AbyssExtractCore.config, ...config };
284
+
285
+ if (config.baseURL) {
286
+ AbyssExtractCore.axios.defaults.baseURL = config.baseURL;
287
+ }
288
+
289
+ if (config.token) {
290
+ AbyssExtractCore.axios.defaults.headers.common.Authorization = `Bearer ${config.token}`;
291
+ }
292
+
293
+ if (config.apiKey) {
294
+ AbyssExtractCore.axios.defaults.headers.common[API_KEY_HEADER] = `${config.apiKey}`;
295
+ }
296
+
297
+ if (config.adminToken) {
298
+ AbyssExtractCore.axios.defaults.headers.common[ADMIN_TOKEN_HEADER] = `${config.adminToken}`;
299
+ }
300
+ }
301
+
302
+ public static getConfig(): CoreConfig {
303
+ return AbyssExtractCore.config;
304
+ }
305
+ }
@@ -0,0 +1,33 @@
1
+ export enum ErrorType {
2
+ apiError = 'api_error',
3
+ authError = 'authentication_error',
4
+ resourceError = 'resource_error',
5
+ }
6
+
7
+ export enum Code {
8
+ // HTTP Error
9
+ tokenFailure = 'token_authentication_failure',
10
+ authenticationFailure = 'authentication_credentials_failure',
11
+ accessNotAllowed = 'access_not_allowed',
12
+ notFound = 'not_found',
13
+ validationError = 'resource_validation_error',
14
+ constraintError = 'resource_constraint_error',
15
+ internalServerError = 'internal_server_error',
16
+ serviceUnavailable = 'service_unavailable',
17
+ invalidData = 'invalid_data',
18
+ notImplemented = 'not_implemented',
19
+ retrospectiveCannotBeModifiedWhenCompleted = 'retrospective_cannot_be_modified_when_completed',
20
+ retrospectiveActionNotAllowedInPhase = 'retrospective_action_not_allowed_in_phase',
21
+ retrospectiveVoteBudgetExhausted = 'retrospective_vote_budget_exhausted',
22
+ retrospectiveActionLimitReached = 'retrospective_action_limit_reached',
23
+ atlasDocumentLimitReached = 'atlas_document_limit_reached',
24
+ boardCardDocumentLimitReached = 'board_card_document_limit_reached',
25
+ boardCardMoveInvalidDestination = 'board_card_move_invalid_destination',
26
+ boardCardLinkLimitReached = 'board_card_link_limit_reached',
27
+ boardCardLinkAlreadyExists = 'board_card_link_already_exists',
28
+ boardCardLinkToSelf = 'board_card_link_to_self',
29
+ shortLinkProtected = 'short_link_protected',
30
+ drawImageLimitReached = 'draw_image_limit_reached',
31
+ drawImageOwnerRequired = 'draw_image_owner_required',
32
+ drawImageNotInDraw = 'draw_image_not_in_draw',
33
+ }
@@ -0,0 +1,7 @@
1
+ // Combine strategy enum — mirror apps/api plan.types.ts exactly.
2
+
3
+ export enum CombineStrategy {
4
+ MAX_CONFIDENCE = 'maxConfidence',
5
+ FIRST_WINS = 'firstWins',
6
+ VOTE = 'vote',
7
+ }
@@ -0,0 +1,11 @@
1
+ // Document types supported by AbyssExtract. bank_statement is the legacy bank-statement profile.
2
+ export enum DocumentType {
3
+ BANK_STATEMENT = 'bank_statement',
4
+ INVOICE = 'invoice',
5
+ RECEIPT = 'receipt',
6
+ ID_CARD = 'id_card',
7
+ RIB = 'rib',
8
+ FINANCIAL_STATEMENT = 'financial_statement',
9
+ PAYSLIP = 'payslip',
10
+ GENERIC = 'generic',
11
+ }