facturas 0.7.0 → 0.8.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 +16 -4
- package/dist/chunk-76WU5BVI.mjs +109 -0
- package/dist/chunk-76WU5BVI.mjs.map +1 -0
- package/dist/{chunk-MBWOFO67.mjs → chunk-HUT3PFKF.mjs} +14 -2
- package/dist/{chunk-MBWOFO67.mjs.map → chunk-HUT3PFKF.mjs.map} +1 -1
- package/dist/{chunk-EDY3PNKJ.mjs → chunk-NUV5RZPZ.mjs} +2 -2
- package/dist/{chunk-IOKZX6CA.mjs → chunk-PPYGVNFA.mjs} +2 -2
- package/dist/{chunk-C55KOV5N.mjs → chunk-TOVSOJ3G.mjs} +239 -46
- package/dist/chunk-TOVSOJ3G.mjs.map +1 -0
- package/dist/{chunk-PKE4Z4GE.mjs → chunk-ZX4OOCML.mjs} +6 -5
- package/dist/chunk-ZX4OOCML.mjs.map +1 -0
- package/dist/constants.d.ts +49 -1
- package/dist/constants.mjs +9 -1
- package/dist/{fiscal-evidence-BQuBbJ3h.d.ts → errors-B0uouRzR.d.ts} +82 -74
- package/dist/errors.d.ts +1 -1
- package/dist/errors.mjs +5 -3
- package/dist/index.d.ts +199 -5
- package/dist/index.mjs +712 -10
- package/dist/index.mjs.map +1 -1
- package/dist/padron.mjs +2 -2
- package/dist/wsfe-CG_erq7V.d.ts +314 -0
- package/dist/wsfe.d.ts +4 -309
- package/dist/wsfe.mjs +4 -4
- package/dist/wsmtxca.d.ts +1 -1
- package/dist/wsmtxca.mjs +3 -3
- package/package.json +1 -1
- package/dist/chunk-C55KOV5N.mjs.map +0 -1
- package/dist/chunk-PKE4Z4GE.mjs.map +0 -1
- package/dist/chunk-VVY2LZIZ.mjs +0 -61
- package/dist/chunk-VVY2LZIZ.mjs.map +0 -1
- /package/dist/{chunk-EDY3PNKJ.mjs.map → chunk-NUV5RZPZ.mjs.map} +0 -0
- /package/dist/{chunk-IOKZX6CA.mjs.map → chunk-PPYGVNFA.mjs.map} +0 -0
package/README.md
CHANGED
|
@@ -29,10 +29,22 @@ The package exports:
|
|
|
29
29
|
- `facturas/errors`
|
|
30
30
|
- `facturas/types`
|
|
31
31
|
|
|
32
|
-
The primary
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
The primary invoice path is `client.vouchers.issue()`, using an explicit
|
|
33
|
+
`issuer`, a fiscal `to` receiver, a required `salesPoint`, and integer-minor-unit
|
|
34
|
+
items. It derives A/B/C, VAT and totals, and returns `authorized`, `rejected`,
|
|
35
|
+
`indeterminate`, or `conflict`. Raw provider evidence is opt-in.
|
|
36
|
+
|
|
37
|
+
**Single-writer contract:** serialize per `(representedTaxId, salesPoint,
|
|
38
|
+
voucherType)`. The SDK does not coordinate writers; concurrent calls collide on
|
|
39
|
+
10016. Servers and queues must persist attempts and use
|
|
40
|
+
`client.wsfe.authorizeVoucherOutcome()` directly. The facade makes one write
|
|
41
|
+
attempt and at most one identity-matched recovery lookup, never a resubmission.
|
|
42
|
+
|
|
43
|
+
`buildFacturaB()` and `buildFacturaC()` retain their v0.7.1 behavior and are
|
|
44
|
+
exported from `facturas` and `facturas/wsfe`. The facade and builders accept ISO
|
|
45
|
+
`ARS`/`USD`; exact `WsfeVoucherInput` uses provider identifiers `PES`/`DOL`.
|
|
46
|
+
The only existing type widening in v0.8 is required `ArcaClient.vouchers`;
|
|
47
|
+
hand-built typed mocks must add that member.
|
|
36
48
|
|
|
37
49
|
`facturas` also exports `createMemoryWsaaSessionStore()` for tests/local single-process coordination and the small `ArcaWsaaSessionStore` interface for applications that need to share WSAA tickets across workers through their own durable store.
|
|
38
50
|
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// src/constants.ts
|
|
2
|
+
var ARCA_VOUCHER_TYPES = {
|
|
3
|
+
FACTURA_A: 1,
|
|
4
|
+
NOTA_DEBITO_A: 2,
|
|
5
|
+
NOTA_CREDITO_A: 3,
|
|
6
|
+
FACTURA_B: 6,
|
|
7
|
+
NOTA_DEBITO_B: 7,
|
|
8
|
+
NOTA_CREDITO_B: 8,
|
|
9
|
+
FACTURA_C: 11,
|
|
10
|
+
NOTA_DEBITO_C: 12,
|
|
11
|
+
NOTA_CREDITO_C: 13
|
|
12
|
+
};
|
|
13
|
+
var ARCA_DOCUMENT_TYPES = {
|
|
14
|
+
CUIT: 80,
|
|
15
|
+
DNI: 96,
|
|
16
|
+
CONSUMIDOR_FINAL: 99
|
|
17
|
+
};
|
|
18
|
+
var ARCA_RECEIVER_VAT_CONDITIONS = {
|
|
19
|
+
RESPONSABLE_INSCRIPTO: 1,
|
|
20
|
+
EXENTO: 4,
|
|
21
|
+
CONSUMIDOR_FINAL: 5,
|
|
22
|
+
MONOTRIBUTISTA: 6,
|
|
23
|
+
IVA_NO_ALCANZADO: 15
|
|
24
|
+
};
|
|
25
|
+
var ARCA_CONCEPT_TYPES = {
|
|
26
|
+
PRODUCTOS: 1,
|
|
27
|
+
SERVICIOS: 2,
|
|
28
|
+
PRODUCTOS_Y_SERVICIOS: 3
|
|
29
|
+
};
|
|
30
|
+
var ARCA_VAT_RATES = {
|
|
31
|
+
IVA_0: 3,
|
|
32
|
+
IVA_10_5: 4,
|
|
33
|
+
IVA_21: 5,
|
|
34
|
+
IVA_27: 6,
|
|
35
|
+
IVA_5: 8,
|
|
36
|
+
IVA_2_5: 9
|
|
37
|
+
};
|
|
38
|
+
var ISO_CURRENCIES = {
|
|
39
|
+
ARS: "ARS",
|
|
40
|
+
USD: "USD"
|
|
41
|
+
};
|
|
42
|
+
var ARCA_CURRENCY_IDS = {
|
|
43
|
+
ARS: "PES",
|
|
44
|
+
USD: "DOL"
|
|
45
|
+
};
|
|
46
|
+
var ARCA_CURRENCIES = {
|
|
47
|
+
PES: "PES",
|
|
48
|
+
DOL: "DOL"
|
|
49
|
+
};
|
|
50
|
+
var ARCA_RECEIVER_CONDITION_IDS = {
|
|
51
|
+
responsable_inscripto: ARCA_RECEIVER_VAT_CONDITIONS.RESPONSABLE_INSCRIPTO,
|
|
52
|
+
monotributo: ARCA_RECEIVER_VAT_CONDITIONS.MONOTRIBUTISTA,
|
|
53
|
+
exento: ARCA_RECEIVER_VAT_CONDITIONS.EXENTO,
|
|
54
|
+
consumidor_final: ARCA_RECEIVER_VAT_CONDITIONS.CONSUMIDOR_FINAL,
|
|
55
|
+
no_alcanzado: ARCA_RECEIVER_VAT_CONDITIONS.IVA_NO_ALCANZADO
|
|
56
|
+
};
|
|
57
|
+
var ARCA_ISSUER_CONDITION_IDS = {
|
|
58
|
+
responsable_inscripto: 1,
|
|
59
|
+
monotributo: 6,
|
|
60
|
+
exento: 4,
|
|
61
|
+
no_alcanzado: 15
|
|
62
|
+
};
|
|
63
|
+
var ARCA_FINAL_CONSUMER_IDENTIFICATION_THRESHOLD_MINOR_UNITS = 1000000000n;
|
|
64
|
+
var ARCA_INVOICE_CLASS_BY_ISSUER = {
|
|
65
|
+
responsable_inscripto: {
|
|
66
|
+
responsable_inscripto: "A",
|
|
67
|
+
monotributo: "A",
|
|
68
|
+
exento: "B",
|
|
69
|
+
consumidor_final: "B",
|
|
70
|
+
no_alcanzado: "B"
|
|
71
|
+
},
|
|
72
|
+
monotributo: {
|
|
73
|
+
responsable_inscripto: "C",
|
|
74
|
+
monotributo: "C",
|
|
75
|
+
exento: "C",
|
|
76
|
+
consumidor_final: "C",
|
|
77
|
+
no_alcanzado: "C"
|
|
78
|
+
},
|
|
79
|
+
exento: {
|
|
80
|
+
responsable_inscripto: "C",
|
|
81
|
+
monotributo: "C",
|
|
82
|
+
exento: "C",
|
|
83
|
+
consumidor_final: "C",
|
|
84
|
+
no_alcanzado: "C"
|
|
85
|
+
},
|
|
86
|
+
no_alcanzado: {
|
|
87
|
+
responsable_inscripto: "C",
|
|
88
|
+
monotributo: "C",
|
|
89
|
+
exento: "C",
|
|
90
|
+
consumidor_final: "C",
|
|
91
|
+
no_alcanzado: "C"
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export {
|
|
96
|
+
ARCA_VOUCHER_TYPES,
|
|
97
|
+
ARCA_DOCUMENT_TYPES,
|
|
98
|
+
ARCA_RECEIVER_VAT_CONDITIONS,
|
|
99
|
+
ARCA_CONCEPT_TYPES,
|
|
100
|
+
ARCA_VAT_RATES,
|
|
101
|
+
ISO_CURRENCIES,
|
|
102
|
+
ARCA_CURRENCY_IDS,
|
|
103
|
+
ARCA_CURRENCIES,
|
|
104
|
+
ARCA_RECEIVER_CONDITION_IDS,
|
|
105
|
+
ARCA_ISSUER_CONDITION_IDS,
|
|
106
|
+
ARCA_FINAL_CONSUMER_IDENTIFICATION_THRESHOLD_MINOR_UNITS,
|
|
107
|
+
ARCA_INVOICE_CLASS_BY_ISSUER
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=chunk-76WU5BVI.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/** Common ARCA reference data for readable userland code and examples. */\nexport const ARCA_VOUCHER_TYPES = {\n FACTURA_A: 1,\n NOTA_DEBITO_A: 2,\n NOTA_CREDITO_A: 3,\n FACTURA_B: 6,\n NOTA_DEBITO_B: 7,\n NOTA_CREDITO_B: 8,\n FACTURA_C: 11,\n NOTA_DEBITO_C: 12,\n NOTA_CREDITO_C: 13,\n} as const;\n\n/** Common document types accepted by ARCA services. */\nexport const ARCA_DOCUMENT_TYPES = {\n CUIT: 80,\n DNI: 96,\n CONSUMIDOR_FINAL: 99,\n} as const;\n\n/**\n * Common receiver IVA condition identifiers used by WSFE.\n * Allowed values depend on the voucher class and ARCA's live catalog.\n */\nexport const ARCA_RECEIVER_VAT_CONDITIONS = {\n RESPONSABLE_INSCRIPTO: 1,\n EXENTO: 4,\n CONSUMIDOR_FINAL: 5,\n MONOTRIBUTISTA: 6,\n IVA_NO_ALCANZADO: 15,\n} as const;\n\n/** Supported invoice concept types for WSFE requests. */\nexport const ARCA_CONCEPT_TYPES = {\n PRODUCTOS: 1,\n SERVICIOS: 2,\n PRODUCTOS_Y_SERVICIOS: 3,\n} as const;\n\n/** Common IVA rate identifiers used by WSFE. */\nexport const ARCA_VAT_RATES = {\n IVA_0: 3,\n IVA_10_5: 4,\n IVA_21: 5,\n IVA_27: 6,\n IVA_5: 8,\n IVA_2_5: 9,\n} as const;\n\n/** ISO currency codes accepted by the high-level WSFE builders. */\nexport const ISO_CURRENCIES = {\n ARS: \"ARS\",\n USD: \"USD\",\n} as const;\n\n/** ARCA currency identifiers keyed by their corresponding ISO currency. */\nexport const ARCA_CURRENCY_IDS = {\n ARS: \"PES\",\n USD: \"DOL\",\n} as const;\n\n/**\n * Common ARCA currency identifiers.\n * @deprecated Use ISO_CURRENCIES for builders or ARCA_CURRENCY_IDS at the exact provider boundary.\n */\nexport const ARCA_CURRENCIES = {\n PES: \"PES\",\n DOL: \"DOL\",\n} as const;\n\n/** Legal assertions supported by the invoice facade; never inferred from Padrón. */\nexport type IssuerCondition =\n | \"responsable_inscripto\"\n | \"monotributo\"\n | \"exento\"\n | \"no_alcanzado\";\nexport type ReceiverCondition = IssuerCondition | \"consumidor_final\";\nexport type VoucherClass = \"A\" | \"B\" | \"C\";\n\nexport const ARCA_RECEIVER_CONDITION_IDS = {\n responsable_inscripto: ARCA_RECEIVER_VAT_CONDITIONS.RESPONSABLE_INSCRIPTO,\n monotributo: ARCA_RECEIVER_VAT_CONDITIONS.MONOTRIBUTISTA,\n exento: ARCA_RECEIVER_VAT_CONDITIONS.EXENTO,\n consumidor_final: ARCA_RECEIVER_VAT_CONDITIONS.CONSUMIDOR_FINAL,\n no_alcanzado: ARCA_RECEIVER_VAT_CONDITIONS.IVA_NO_ALCANZADO,\n} as const satisfies Record<ReceiverCondition, number>;\n\nexport const ARCA_ISSUER_CONDITION_IDS = {\n responsable_inscripto: 1,\n monotributo: 6,\n exento: 4,\n no_alcanzado: 15,\n} as const satisfies Record<IssuerCondition, number>;\n\n// RG 5866/2026, art. 1(f), effective 2026-07-01 (art. 4).\n// https://www.argentina.gob.ar/normativa/nacional/norma-427092/texto\nexport const ARCA_FINAL_CONSUMER_IDENTIFICATION_THRESHOLD_MINOR_UNITS =\n 1_000_000_000n;\n\n// WSFE v4.7, physical PDF p. 203, validations 10243/10246; issuer asserted first.\n// ARCA checks actual issuer eligibility independently at authorization.\nexport const ARCA_INVOICE_CLASS_BY_ISSUER = {\n responsable_inscripto: {\n responsable_inscripto: \"A\",\n monotributo: \"A\",\n exento: \"B\",\n consumidor_final: \"B\",\n no_alcanzado: \"B\",\n },\n monotributo: {\n responsable_inscripto: \"C\",\n monotributo: \"C\",\n exento: \"C\",\n consumidor_final: \"C\",\n no_alcanzado: \"C\",\n },\n exento: {\n responsable_inscripto: \"C\",\n monotributo: \"C\",\n exento: \"C\",\n consumidor_final: \"C\",\n no_alcanzado: \"C\",\n },\n no_alcanzado: {\n responsable_inscripto: \"C\",\n monotributo: \"C\",\n exento: \"C\",\n consumidor_final: \"C\",\n no_alcanzado: \"C\",\n },\n} as const satisfies Record<\n IssuerCondition,\n Record<ReceiverCondition, VoucherClass>\n>;\n"],"mappings":";AACO,IAAM,qBAAqB;AAAA,EAChC,WAAW;AAAA,EACX,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,eAAe;AAAA,EACf,gBAAgB;AAClB;AAGO,IAAM,sBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,KAAK;AAAA,EACL,kBAAkB;AACpB;AAMO,IAAM,+BAA+B;AAAA,EAC1C,uBAAuB;AAAA,EACvB,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,kBAAkB;AACpB;AAGO,IAAM,qBAAqB;AAAA,EAChC,WAAW;AAAA,EACX,WAAW;AAAA,EACX,uBAAuB;AACzB;AAGO,IAAM,iBAAiB;AAAA,EAC5B,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;AAGO,IAAM,iBAAiB;AAAA,EAC5B,KAAK;AAAA,EACL,KAAK;AACP;AAGO,IAAM,oBAAoB;AAAA,EAC/B,KAAK;AAAA,EACL,KAAK;AACP;AAMO,IAAM,kBAAkB;AAAA,EAC7B,KAAK;AAAA,EACL,KAAK;AACP;AAWO,IAAM,8BAA8B;AAAA,EACzC,uBAAuB,6BAA6B;AAAA,EACpD,aAAa,6BAA6B;AAAA,EAC1C,QAAQ,6BAA6B;AAAA,EACrC,kBAAkB,6BAA6B;AAAA,EAC/C,cAAc,6BAA6B;AAC7C;AAEO,IAAM,4BAA4B;AAAA,EACvC,uBAAuB;AAAA,EACvB,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,cAAc;AAChB;AAIO,IAAM,2DACX;AAIK,IAAM,+BAA+B;AAAA,EAC1C,uBAAuB;AAAA,IACrB,uBAAuB;AAAA,IACvB,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,kBAAkB;AAAA,IAClB,cAAc;AAAA,EAChB;AAAA,EACA,aAAa;AAAA,IACX,uBAAuB;AAAA,IACvB,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,kBAAkB;AAAA,IAClB,cAAc;AAAA,EAChB;AAAA,EACA,QAAQ;AAAA,IACN,uBAAuB;AAAA,IACvB,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,kBAAkB;AAAA,IAClB,cAAc;AAAA,EAChB;AAAA,EACA,cAAc;AAAA,IACZ,uBAAuB;AAAA,IACvB,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,kBAAkB;AAAA,IAClB,cAAc;AAAA,EAChB;AACF;","names":[]}
|
|
@@ -198,6 +198,17 @@ function normalizeProviderCode(providerCode) {
|
|
|
198
198
|
}
|
|
199
199
|
return void 0;
|
|
200
200
|
}
|
|
201
|
+
function toArcaSafeErrorMetadata(error) {
|
|
202
|
+
if (!(error instanceof Error)) {
|
|
203
|
+
return { name: "UnknownError", message: String(error) };
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
name: error.name,
|
|
207
|
+
message: error.message,
|
|
208
|
+
...error instanceof ArcaError ? { code: error.code } : {},
|
|
209
|
+
...error instanceof ArcaTransportError && error.statusCode !== void 0 ? { statusCode: error.statusCode } : {}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
201
212
|
|
|
202
213
|
export {
|
|
203
214
|
createResponseBodyDiagnostic,
|
|
@@ -210,6 +221,7 @@ export {
|
|
|
210
221
|
ArcaTransportError,
|
|
211
222
|
ArcaSoapFaultError,
|
|
212
223
|
ArcaInvalidSoapResponseError,
|
|
213
|
-
ArcaServiceError
|
|
224
|
+
ArcaServiceError,
|
|
225
|
+
toArcaSafeErrorMetadata
|
|
214
226
|
};
|
|
215
|
-
//# sourceMappingURL=chunk-
|
|
227
|
+
//# sourceMappingURL=chunk-HUT3PFKF.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/redaction.ts","../src/errors.ts"],"sourcesContent":["export const MAX_DIAGNOSTIC_PREVIEW_LENGTH = 4096;\n\nconst MAX_DIAGNOSTIC_SCALAR_LENGTH = 512;\nconst SENSITIVE_XML_ELEMENT_NAME = \"((?:[A-Za-z_][\\\\w.-]*:)?(?:Token|Sign))\";\nconst PAIRED_SENSITIVE_XML_ELEMENT = new RegExp(\n `<${SENSITIVE_XML_ELEMENT_NAME}\\\\b[^>]*>[\\\\s\\\\S]*?<\\\\/\\\\1\\\\s*>`,\n \"gi\"\n);\nconst SELF_CLOSING_SENSITIVE_XML_ELEMENT = new RegExp(\n `<${SENSITIVE_XML_ELEMENT_NAME}\\\\b[^>]*\\\\/\\\\s*>`,\n \"gi\"\n);\nconst UNTERMINATED_SENSITIVE_XML_ELEMENT = new RegExp(\n `<${SENSITIVE_XML_ELEMENT_NAME}\\\\b[^>]*>[^<]*`,\n \"gi\"\n);\n\nexport type ResponseBodyDiagnostic = {\n responseBodyLength: number;\n responseBodyPreview: string;\n};\n\nexport type SafeErrorDiagnostic = {\n errorName?: string;\n errorCode?: string;\n statusCode?: number;\n contentType?: string;\n responseBodyLength?: number;\n responseBodyPreview?: string;\n faultCode?: string;\n};\n\n/** Redacts credential-bearing XML elements and applies the global preview bound. */\nexport function redactDiagnosticPreview(\n value: string,\n requestedMaxLength = MAX_DIAGNOSTIC_PREVIEW_LENGTH\n): string {\n const maxLength = normalizePreviewLength(requestedMaxLength);\n\n return value\n .replace(\n PAIRED_SENSITIVE_XML_ELEMENT,\n (_match, tagName: string) => `<${tagName}>[REDACTED]</${tagName}>`\n )\n .replace(\n SELF_CLOSING_SENSITIVE_XML_ELEMENT,\n (_match, tagName: string) => `<${tagName}>[REDACTED]</${tagName}>`\n )\n .replace(\n UNTERMINATED_SENSITIVE_XML_ELEMENT,\n (_match, tagName: string) => `<${tagName}>[REDACTED]`\n )\n .slice(0, maxLength);\n}\n\n/** Produces the only response-body shape allowed in errors and logs. */\nexport function createResponseBodyDiagnostic(\n responseBody: string,\n requestedMaxLength = MAX_DIAGNOSTIC_PREVIEW_LENGTH\n): ResponseBodyDiagnostic {\n return {\n responseBodyLength: responseBody.length,\n responseBodyPreview: redactDiagnosticPreview(\n responseBody,\n requestedMaxLength\n ),\n };\n}\n\n/** Extracts a scalar allowlist from an error without exposing the error or cause. */\nexport function createSafeErrorDiagnostic(error: unknown): SafeErrorDiagnostic {\n if (!(error && typeof error === \"object\")) {\n return {};\n }\n\n const candidate = error as Record<string, unknown>;\n const diagnostic: SafeErrorDiagnostic = {};\n\n assignSafeString(diagnostic, \"errorName\", candidate.name);\n assignSafeString(diagnostic, \"errorCode\", candidate.code);\n assignSafeNumber(diagnostic, \"statusCode\", candidate.statusCode);\n assignSafeString(diagnostic, \"contentType\", candidate.contentType);\n assignSafeNumber(\n diagnostic,\n \"responseBodyLength\",\n candidate.responseBodyLength\n );\n if (typeof candidate.responseBodyPreview === \"string\") {\n diagnostic.responseBodyPreview = redactDiagnosticPreview(\n candidate.responseBodyPreview\n );\n }\n assignSafeString(diagnostic, \"faultCode\", candidate.faultCode);\n\n return diagnostic;\n}\n\nfunction normalizePreviewLength(requestedMaxLength: number): number {\n if (!Number.isFinite(requestedMaxLength)) {\n return MAX_DIAGNOSTIC_PREVIEW_LENGTH;\n }\n\n return Math.max(\n 0,\n Math.min(Math.trunc(requestedMaxLength), MAX_DIAGNOSTIC_PREVIEW_LENGTH)\n );\n}\n\nfunction assignSafeString<\n TKey extends \"errorName\" | \"errorCode\" | \"contentType\" | \"faultCode\",\n>(target: SafeErrorDiagnostic, key: TKey, value: unknown): void {\n if (typeof value === \"string\") {\n target[key] = redactDiagnosticPreview(value, MAX_DIAGNOSTIC_SCALAR_LENGTH);\n }\n}\n\nfunction assignSafeNumber<TKey extends \"statusCode\" | \"responseBodyLength\">(\n target: SafeErrorDiagnostic,\n key: TKey,\n value: unknown\n): void {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n target[key] = value;\n }\n}\n","import { redactDiagnosticPreview } from \"./internal/redaction\";\nimport type { ArcaServiceName } from \"./internal/types\";\nimport type {\n ArcaFiscalIssue,\n ArcaFiscalResultLevel,\n ArcaFiscalResults,\n} from \"./services/fiscal-evidence\";\n\n/** Base error class for all ARCA-related errors. */\nexport class ArcaError extends Error {\n readonly code: string;\n override readonly name: string = \"ArcaError\";\n\n constructor(message: string, code = \"ARCA_ERROR\", options?: ErrorOptions) {\n super(message, options);\n this.code = code;\n }\n}\n\n/** Thrown when the ARCA client configuration is missing or invalid. */\nexport class ArcaConfigurationError extends ArcaError {\n override readonly name: string = \"ArcaConfigurationError\";\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"ARCA_CONFIGURATION_ERROR\", options);\n }\n}\n\n/** Stable routing codes for caller-provided input failures. */\nexport type ArcaInputErrorCode =\n | \"ARCA_INPUT_INVALID_DATE\"\n | \"ARCA_INPUT_INVALID_AMOUNT\"\n | \"ARCA_INPUT_AMOUNT_PRECISION\"\n | \"ARCA_INPUT_AMOUNT_MISMATCH\"\n | \"ARCA_INPUT_INVALID_EXCHANGE_RATE\"\n | \"ARCA_INPUT_INVALID_VALUE\"\n | \"ARCA_INPUT_MISSING_FIELD\"\n | \"ARCA_INPUT_RESERVED_FIELD\";\n\nexport type ArcaInputErrorOptions = ErrorOptions & {\n code: ArcaInputErrorCode;\n field?: string;\n expected?: string;\n};\n\n/** Thrown when caller-provided input data is missing or invalid. */\nexport class ArcaInputError extends ArcaError {\n declare readonly code: ArcaInputErrorCode;\n override readonly name: string = \"ArcaInputError\";\n readonly field?: string;\n readonly expected?: string;\n\n constructor(message: string, options: ArcaInputErrorOptions) {\n super(message, options.code, options);\n this.field = options.field;\n this.expected = options.expected;\n }\n}\n\n/** Stable reasons exposed for explicit ARCA authentication rejections. */\nexport type ArcaAuthenticationReason =\n | \"invalid_token\"\n | \"unauthorized_computer\"\n | \"missing_relationship\"\n | \"authentication_rejected\";\n\nexport type ArcaAuthenticationErrorOptions = ErrorOptions & {\n reason: ArcaAuthenticationReason;\n service: ArcaServiceName;\n operation: string;\n providerCode?: string | number;\n};\n\n/** Thrown when ARCA explicitly rejects credentials before an operation runs. */\nexport class ArcaAuthenticationError extends ArcaError {\n declare readonly code: \"ARCA_AUTHENTICATION_ERROR\";\n override readonly name: string = \"ArcaAuthenticationError\";\n readonly reason: ArcaAuthenticationReason;\n readonly service: ArcaServiceName;\n readonly operation: string;\n readonly providerCode?: string | number;\n\n constructor(message: string, options: ArcaAuthenticationErrorOptions) {\n super(\n redactDiagnosticPreview(message),\n \"ARCA_AUTHENTICATION_ERROR\",\n options\n );\n this.reason = options.reason;\n this.service = options.service;\n this.operation = options.operation;\n this.providerCode = normalizeProviderCode(options.providerCode);\n }\n}\n\n/** Narrows unknown failures to the explicit authentication error contract. */\nexport function isArcaAuthenticationError(\n error: unknown\n): error is ArcaAuthenticationError {\n return error instanceof ArcaAuthenticationError;\n}\n\n/** Thrown when an HTTP request to an ARCA endpoint fails at the transport level. */\nexport class ArcaTransportError extends ArcaError {\n override readonly name: string = \"ArcaTransportError\";\n readonly statusCode?: number;\n readonly contentType?: string;\n readonly responseBodyLength?: number;\n readonly responseBodyPreview?: string;\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n statusCode?: number;\n contentType?: string;\n responseBodyLength?: number;\n responseBodyPreview?: string;\n }\n ) {\n super(message, \"ARCA_TRANSPORT_ERROR\", options);\n this.statusCode = options?.statusCode;\n this.contentType = options?.contentType;\n this.responseBodyLength = options?.responseBodyLength;\n this.responseBodyPreview =\n options?.responseBodyPreview === undefined\n ? undefined\n : redactDiagnosticPreview(options.responseBodyPreview);\n }\n}\n\n/** Thrown when the SOAP response contains a Fault element. */\nexport class ArcaSoapFaultError extends ArcaError {\n override readonly name: string = \"ArcaSoapFaultError\";\n readonly faultCode?: string;\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n faultCode?: string;\n }\n ) {\n super(redactDiagnosticPreview(message), \"ARCA_SOAP_FAULT\", options);\n this.faultCode =\n options?.faultCode === undefined\n ? undefined\n : redactDiagnosticPreview(options.faultCode);\n }\n}\n\n/** Thrown when a response cannot be parsed as a valid SOAP envelope. */\nexport class ArcaInvalidSoapResponseError extends ArcaError {\n override readonly name: string = \"ArcaInvalidSoapResponseError\";\n readonly service?: ArcaServiceName;\n readonly operation?: string;\n readonly endpointUrl?: string;\n readonly statusCode?: number;\n readonly contentType?: string;\n readonly responseBodyLength?: number;\n readonly responseBodyPreview?: string;\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n service?: ArcaServiceName;\n operation?: string;\n endpointUrl?: string;\n statusCode?: number;\n contentType?: string;\n responseBodyLength?: number;\n responseBodyPreview?: string;\n }\n ) {\n super(message, \"ARCA_INVALID_SOAP_RESPONSE\", options);\n this.service = options?.service;\n this.operation = options?.operation;\n this.endpointUrl = options?.endpointUrl;\n this.statusCode = options?.statusCode;\n this.contentType = options?.contentType;\n this.responseBodyLength = options?.responseBodyLength;\n this.responseBodyPreview =\n options?.responseBodyPreview === undefined\n ? undefined\n : redactDiagnosticPreview(options.responseBodyPreview);\n }\n}\n\n/** Thrown when an ARCA service (WSFE, WSMTXCA, Padron) returns a domain-level error. */\nexport class ArcaServiceError extends ArcaError {\n override readonly name: string = \"ArcaServiceError\";\n readonly serviceCode?: string | number;\n readonly service?: ArcaServiceName;\n readonly operation?: string;\n readonly result?: string;\n readonly resultLevel?: ArcaFiscalResultLevel;\n readonly results?: ArcaFiscalResults;\n readonly cae?: string;\n readonly issues?: readonly ArcaFiscalIssue[];\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n serviceCode?: string | number;\n service?: ArcaServiceName;\n operation?: string;\n result?: string;\n resultLevel?: ArcaFiscalResultLevel;\n results?: ArcaFiscalResults;\n cae?: string;\n issues?: readonly ArcaFiscalIssue[];\n }\n ) {\n super(message, \"ARCA_SERVICE_ERROR\", options);\n this.serviceCode = options?.serviceCode;\n this.service = options?.service;\n this.operation = options?.operation;\n this.result = options?.result;\n this.resultLevel = options?.resultLevel;\n this.results = options?.results;\n this.cae = options?.cae;\n this.issues = options?.issues;\n }\n}\n\nfunction normalizeProviderCode(\n providerCode: string | number | undefined\n): string | number | undefined {\n if (typeof providerCode === \"number\") {\n return Number.isFinite(providerCode) ? providerCode : undefined;\n }\n if (typeof providerCode === \"string\") {\n return redactDiagnosticPreview(providerCode, 512);\n }\n return undefined;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/redaction.ts","../src/errors.ts"],"sourcesContent":["export const MAX_DIAGNOSTIC_PREVIEW_LENGTH = 4096;\n\nconst MAX_DIAGNOSTIC_SCALAR_LENGTH = 512;\nconst SENSITIVE_XML_ELEMENT_NAME = \"((?:[A-Za-z_][\\\\w.-]*:)?(?:Token|Sign))\";\nconst PAIRED_SENSITIVE_XML_ELEMENT = new RegExp(\n `<${SENSITIVE_XML_ELEMENT_NAME}\\\\b[^>]*>[\\\\s\\\\S]*?<\\\\/\\\\1\\\\s*>`,\n \"gi\"\n);\nconst SELF_CLOSING_SENSITIVE_XML_ELEMENT = new RegExp(\n `<${SENSITIVE_XML_ELEMENT_NAME}\\\\b[^>]*\\\\/\\\\s*>`,\n \"gi\"\n);\nconst UNTERMINATED_SENSITIVE_XML_ELEMENT = new RegExp(\n `<${SENSITIVE_XML_ELEMENT_NAME}\\\\b[^>]*>[^<]*`,\n \"gi\"\n);\n\nexport type ResponseBodyDiagnostic = {\n responseBodyLength: number;\n responseBodyPreview: string;\n};\n\nexport type SafeErrorDiagnostic = {\n errorName?: string;\n errorCode?: string;\n statusCode?: number;\n contentType?: string;\n responseBodyLength?: number;\n responseBodyPreview?: string;\n faultCode?: string;\n};\n\n/** Redacts credential-bearing XML elements and applies the global preview bound. */\nexport function redactDiagnosticPreview(\n value: string,\n requestedMaxLength = MAX_DIAGNOSTIC_PREVIEW_LENGTH\n): string {\n const maxLength = normalizePreviewLength(requestedMaxLength);\n\n return value\n .replace(\n PAIRED_SENSITIVE_XML_ELEMENT,\n (_match, tagName: string) => `<${tagName}>[REDACTED]</${tagName}>`\n )\n .replace(\n SELF_CLOSING_SENSITIVE_XML_ELEMENT,\n (_match, tagName: string) => `<${tagName}>[REDACTED]</${tagName}>`\n )\n .replace(\n UNTERMINATED_SENSITIVE_XML_ELEMENT,\n (_match, tagName: string) => `<${tagName}>[REDACTED]`\n )\n .slice(0, maxLength);\n}\n\n/** Produces the only response-body shape allowed in errors and logs. */\nexport function createResponseBodyDiagnostic(\n responseBody: string,\n requestedMaxLength = MAX_DIAGNOSTIC_PREVIEW_LENGTH\n): ResponseBodyDiagnostic {\n return {\n responseBodyLength: responseBody.length,\n responseBodyPreview: redactDiagnosticPreview(\n responseBody,\n requestedMaxLength\n ),\n };\n}\n\n/** Extracts a scalar allowlist from an error without exposing the error or cause. */\nexport function createSafeErrorDiagnostic(error: unknown): SafeErrorDiagnostic {\n if (!(error && typeof error === \"object\")) {\n return {};\n }\n\n const candidate = error as Record<string, unknown>;\n const diagnostic: SafeErrorDiagnostic = {};\n\n assignSafeString(diagnostic, \"errorName\", candidate.name);\n assignSafeString(diagnostic, \"errorCode\", candidate.code);\n assignSafeNumber(diagnostic, \"statusCode\", candidate.statusCode);\n assignSafeString(diagnostic, \"contentType\", candidate.contentType);\n assignSafeNumber(\n diagnostic,\n \"responseBodyLength\",\n candidate.responseBodyLength\n );\n if (typeof candidate.responseBodyPreview === \"string\") {\n diagnostic.responseBodyPreview = redactDiagnosticPreview(\n candidate.responseBodyPreview\n );\n }\n assignSafeString(diagnostic, \"faultCode\", candidate.faultCode);\n\n return diagnostic;\n}\n\nfunction normalizePreviewLength(requestedMaxLength: number): number {\n if (!Number.isFinite(requestedMaxLength)) {\n return MAX_DIAGNOSTIC_PREVIEW_LENGTH;\n }\n\n return Math.max(\n 0,\n Math.min(Math.trunc(requestedMaxLength), MAX_DIAGNOSTIC_PREVIEW_LENGTH)\n );\n}\n\nfunction assignSafeString<\n TKey extends \"errorName\" | \"errorCode\" | \"contentType\" | \"faultCode\",\n>(target: SafeErrorDiagnostic, key: TKey, value: unknown): void {\n if (typeof value === \"string\") {\n target[key] = redactDiagnosticPreview(value, MAX_DIAGNOSTIC_SCALAR_LENGTH);\n }\n}\n\nfunction assignSafeNumber<TKey extends \"statusCode\" | \"responseBodyLength\">(\n target: SafeErrorDiagnostic,\n key: TKey,\n value: unknown\n): void {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n target[key] = value;\n }\n}\n","import { redactDiagnosticPreview } from \"./internal/redaction\";\nimport type { ArcaServiceName } from \"./internal/types\";\nimport type {\n ArcaFiscalIssue,\n ArcaFiscalResultLevel,\n ArcaFiscalResults,\n} from \"./services/fiscal-evidence\";\n\n/** Base error class for all ARCA-related errors. */\nexport class ArcaError extends Error {\n readonly code: string;\n override readonly name: string = \"ArcaError\";\n\n constructor(message: string, code = \"ARCA_ERROR\", options?: ErrorOptions) {\n super(message, options);\n this.code = code;\n }\n}\n\n/** Thrown when the ARCA client configuration is missing or invalid. */\nexport class ArcaConfigurationError extends ArcaError {\n override readonly name: string = \"ArcaConfigurationError\";\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"ARCA_CONFIGURATION_ERROR\", options);\n }\n}\n\n/** Stable routing codes for caller-provided input failures. */\nexport type ArcaInputErrorCode =\n | \"ARCA_INPUT_INVALID_DATE\"\n | \"ARCA_INPUT_INVALID_AMOUNT\"\n | \"ARCA_INPUT_AMOUNT_PRECISION\"\n | \"ARCA_INPUT_AMOUNT_MISMATCH\"\n | \"ARCA_INPUT_INVALID_EXCHANGE_RATE\"\n | \"ARCA_INPUT_INVALID_VALUE\"\n | \"ARCA_INPUT_MISSING_FIELD\"\n | \"ARCA_INPUT_RESERVED_FIELD\";\n\nexport type ArcaInputErrorOptions = ErrorOptions & {\n code: ArcaInputErrorCode;\n field?: string;\n expected?: string;\n};\n\n/** Thrown when caller-provided input data is missing or invalid. */\nexport class ArcaInputError extends ArcaError {\n declare readonly code: ArcaInputErrorCode;\n override readonly name: string = \"ArcaInputError\";\n readonly field?: string;\n readonly expected?: string;\n\n constructor(message: string, options: ArcaInputErrorOptions) {\n super(message, options.code, options);\n this.field = options.field;\n this.expected = options.expected;\n }\n}\n\n/** Stable reasons exposed for explicit ARCA authentication rejections. */\nexport type ArcaAuthenticationReason =\n | \"invalid_token\"\n | \"unauthorized_computer\"\n | \"missing_relationship\"\n | \"authentication_rejected\";\n\nexport type ArcaAuthenticationErrorOptions = ErrorOptions & {\n reason: ArcaAuthenticationReason;\n service: ArcaServiceName;\n operation: string;\n providerCode?: string | number;\n};\n\n/** Thrown when ARCA explicitly rejects credentials before an operation runs. */\nexport class ArcaAuthenticationError extends ArcaError {\n declare readonly code: \"ARCA_AUTHENTICATION_ERROR\";\n override readonly name: string = \"ArcaAuthenticationError\";\n readonly reason: ArcaAuthenticationReason;\n readonly service: ArcaServiceName;\n readonly operation: string;\n readonly providerCode?: string | number;\n\n constructor(message: string, options: ArcaAuthenticationErrorOptions) {\n super(\n redactDiagnosticPreview(message),\n \"ARCA_AUTHENTICATION_ERROR\",\n options\n );\n this.reason = options.reason;\n this.service = options.service;\n this.operation = options.operation;\n this.providerCode = normalizeProviderCode(options.providerCode);\n }\n}\n\n/** Narrows unknown failures to the explicit authentication error contract. */\nexport function isArcaAuthenticationError(\n error: unknown\n): error is ArcaAuthenticationError {\n return error instanceof ArcaAuthenticationError;\n}\n\n/** Thrown when an HTTP request to an ARCA endpoint fails at the transport level. */\nexport class ArcaTransportError extends ArcaError {\n override readonly name: string = \"ArcaTransportError\";\n readonly statusCode?: number;\n readonly contentType?: string;\n readonly responseBodyLength?: number;\n readonly responseBodyPreview?: string;\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n statusCode?: number;\n contentType?: string;\n responseBodyLength?: number;\n responseBodyPreview?: string;\n }\n ) {\n super(message, \"ARCA_TRANSPORT_ERROR\", options);\n this.statusCode = options?.statusCode;\n this.contentType = options?.contentType;\n this.responseBodyLength = options?.responseBodyLength;\n this.responseBodyPreview =\n options?.responseBodyPreview === undefined\n ? undefined\n : redactDiagnosticPreview(options.responseBodyPreview);\n }\n}\n\n/** Thrown when the SOAP response contains a Fault element. */\nexport class ArcaSoapFaultError extends ArcaError {\n override readonly name: string = \"ArcaSoapFaultError\";\n readonly faultCode?: string;\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n faultCode?: string;\n }\n ) {\n super(redactDiagnosticPreview(message), \"ARCA_SOAP_FAULT\", options);\n this.faultCode =\n options?.faultCode === undefined\n ? undefined\n : redactDiagnosticPreview(options.faultCode);\n }\n}\n\n/** Thrown when a response cannot be parsed as a valid SOAP envelope. */\nexport class ArcaInvalidSoapResponseError extends ArcaError {\n override readonly name: string = \"ArcaInvalidSoapResponseError\";\n readonly service?: ArcaServiceName;\n readonly operation?: string;\n readonly endpointUrl?: string;\n readonly statusCode?: number;\n readonly contentType?: string;\n readonly responseBodyLength?: number;\n readonly responseBodyPreview?: string;\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n service?: ArcaServiceName;\n operation?: string;\n endpointUrl?: string;\n statusCode?: number;\n contentType?: string;\n responseBodyLength?: number;\n responseBodyPreview?: string;\n }\n ) {\n super(message, \"ARCA_INVALID_SOAP_RESPONSE\", options);\n this.service = options?.service;\n this.operation = options?.operation;\n this.endpointUrl = options?.endpointUrl;\n this.statusCode = options?.statusCode;\n this.contentType = options?.contentType;\n this.responseBodyLength = options?.responseBodyLength;\n this.responseBodyPreview =\n options?.responseBodyPreview === undefined\n ? undefined\n : redactDiagnosticPreview(options.responseBodyPreview);\n }\n}\n\n/** Thrown when an ARCA service (WSFE, WSMTXCA, Padron) returns a domain-level error. */\nexport class ArcaServiceError extends ArcaError {\n override readonly name: string = \"ArcaServiceError\";\n readonly serviceCode?: string | number;\n readonly service?: ArcaServiceName;\n readonly operation?: string;\n readonly result?: string;\n readonly resultLevel?: ArcaFiscalResultLevel;\n readonly results?: ArcaFiscalResults;\n readonly cae?: string;\n readonly issues?: readonly ArcaFiscalIssue[];\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n serviceCode?: string | number;\n service?: ArcaServiceName;\n operation?: string;\n result?: string;\n resultLevel?: ArcaFiscalResultLevel;\n results?: ArcaFiscalResults;\n cae?: string;\n issues?: readonly ArcaFiscalIssue[];\n }\n ) {\n super(message, \"ARCA_SERVICE_ERROR\", options);\n this.serviceCode = options?.serviceCode;\n this.service = options?.service;\n this.operation = options?.operation;\n this.result = options?.result;\n this.resultLevel = options?.resultLevel;\n this.results = options?.results;\n this.cae = options?.cae;\n this.issues = options?.issues;\n }\n}\n\nfunction normalizeProviderCode(\n providerCode: string | number | undefined\n): string | number | undefined {\n if (typeof providerCode === \"number\") {\n return Number.isFinite(providerCode) ? providerCode : undefined;\n }\n if (typeof providerCode === \"string\") {\n return redactDiagnosticPreview(providerCode, 512);\n }\n return undefined;\n}\n\n/** Narrow error evidence: never includes a cause, raw response or stack. */\nexport type ArcaSafeErrorMetadata = {\n name: string;\n message: string;\n code?: string;\n statusCode?: number;\n};\n\nexport function toArcaSafeErrorMetadata(error: unknown): ArcaSafeErrorMetadata {\n if (!(error instanceof Error)) {\n return { name: \"UnknownError\", message: String(error) };\n }\n return {\n name: error.name,\n message: error.message,\n ...(error instanceof ArcaError ? { code: error.code } : {}),\n ...(error instanceof ArcaTransportError && error.statusCode !== undefined\n ? { statusCode: error.statusCode }\n : {}),\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ArcaSoapFaultError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HUT3PFKF.mjs";
|
|
4
4
|
|
|
5
5
|
// src/services/padron.ts
|
|
6
6
|
function createPadronService(options) {
|
|
@@ -103,4 +103,4 @@ async function executePadronOperation(options, service, operation, body) {
|
|
|
103
103
|
export {
|
|
104
104
|
createPadronService
|
|
105
105
|
};
|
|
106
|
-
//# sourceMappingURL=chunk-
|
|
106
|
+
//# sourceMappingURL=chunk-NUV5RZPZ.mjs.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ArcaServiceError,
|
|
4
4
|
ArcaSoapFaultError,
|
|
5
5
|
isArcaAuthenticationError
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-HUT3PFKF.mjs";
|
|
7
7
|
|
|
8
8
|
// src/internal/authentication.ts
|
|
9
9
|
var WSFE_AUTHENTICATION_CODES = {
|
|
@@ -192,4 +192,4 @@ export {
|
|
|
192
192
|
createArcaAuthenticationErrorFromEvidence,
|
|
193
193
|
executeWithAuthenticationRecovery
|
|
194
194
|
};
|
|
195
|
-
//# sourceMappingURL=chunk-
|
|
195
|
+
//# sourceMappingURL=chunk-PPYGVNFA.mjs.map
|
|
@@ -2,21 +2,21 @@ import {
|
|
|
2
2
|
ARCA_CURRENCY_IDS,
|
|
3
3
|
ARCA_VAT_RATES,
|
|
4
4
|
ARCA_VOUCHER_TYPES
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-76WU5BVI.mjs";
|
|
6
6
|
import {
|
|
7
7
|
classifyArcaAuthenticationError,
|
|
8
8
|
classifyArcaAuthenticationIssues,
|
|
9
9
|
createArcaAuthenticationErrorFromEvidence,
|
|
10
10
|
createArcaAuthenticationEvidence,
|
|
11
11
|
executeWithAuthenticationRecovery
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-PPYGVNFA.mjs";
|
|
13
13
|
import {
|
|
14
14
|
ArcaInputError,
|
|
15
15
|
ArcaInvalidSoapResponseError,
|
|
16
16
|
ArcaServiceError,
|
|
17
17
|
ArcaSoapFaultError,
|
|
18
18
|
ArcaTransportError
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-HUT3PFKF.mjs";
|
|
20
20
|
|
|
21
21
|
// src/internal/decimal.ts
|
|
22
22
|
var AMOUNT_SCALE = 100;
|
|
@@ -103,7 +103,23 @@ function calculateVatMinorUnits(taxableMinorUnits, vatRate, field) {
|
|
|
103
103
|
expected: "one of 0, 2.5, 5, 10.5, 21, or 27"
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
|
-
return (taxableMinorUnits * basisPoints
|
|
106
|
+
return roundHalfEvenRatio(taxableMinorUnits * basisPoints, 10000n);
|
|
107
|
+
}
|
|
108
|
+
function roundHalfEvenRatio(numerator, denominator) {
|
|
109
|
+
if (numerator < 0n || denominator <= 0n) {
|
|
110
|
+
throw new RangeError(
|
|
111
|
+
"roundHalfEvenRatio requires a non-negative numerator and a positive denominator."
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
const quotient = numerator / denominator;
|
|
115
|
+
const doubledRemainder = numerator % denominator * 2n;
|
|
116
|
+
if (doubledRemainder > denominator) {
|
|
117
|
+
return quotient + 1n;
|
|
118
|
+
}
|
|
119
|
+
if (doubledRemainder < denominator) {
|
|
120
|
+
return quotient;
|
|
121
|
+
}
|
|
122
|
+
return quotient % 2n === 0n ? quotient : quotient + 1n;
|
|
107
123
|
}
|
|
108
124
|
function isWithinArcaTolerance(actualMinorUnits, expectedMinorUnits, absoluteCentAllowance = 1) {
|
|
109
125
|
const difference = absoluteBigInt(actualMinorUnits - expectedMinorUnits);
|
|
@@ -1094,8 +1110,72 @@ function mapWsfeVoucherInfo(raw) {
|
|
|
1094
1110
|
"caeExpiry",
|
|
1095
1111
|
normalizeWsfeString(raw.FchVto ?? raw.CAEFchVto)
|
|
1096
1112
|
);
|
|
1113
|
+
assignWsfeValue(
|
|
1114
|
+
voucher,
|
|
1115
|
+
"serviceStartDate",
|
|
1116
|
+
normalizeWsfeString(raw.FchServDesde)
|
|
1117
|
+
);
|
|
1118
|
+
assignWsfeValue(
|
|
1119
|
+
voucher,
|
|
1120
|
+
"serviceEndDate",
|
|
1121
|
+
normalizeWsfeString(raw.FchServHasta)
|
|
1122
|
+
);
|
|
1123
|
+
assignWsfeValue(
|
|
1124
|
+
voucher,
|
|
1125
|
+
"paymentDueDate",
|
|
1126
|
+
normalizeWsfeString(raw.FchVtoPago)
|
|
1127
|
+
);
|
|
1128
|
+
assignWsfeValue(
|
|
1129
|
+
voucher,
|
|
1130
|
+
"vatRates",
|
|
1131
|
+
mapWsfeLookupDetails(raw.Iva, "AlicIva", mapWsfeLookupVat)
|
|
1132
|
+
);
|
|
1133
|
+
assignWsfeValue(
|
|
1134
|
+
voucher,
|
|
1135
|
+
"taxes",
|
|
1136
|
+
mapWsfeLookupDetails(raw.Tributos, "Tributo", mapWsfeLookupTax)
|
|
1137
|
+
);
|
|
1097
1138
|
return voucher;
|
|
1098
1139
|
}
|
|
1140
|
+
function mapWsfeLookupDetails(container, key, map) {
|
|
1141
|
+
const record = toWsfeRecord(container);
|
|
1142
|
+
if (!record || record[key] === void 0) {
|
|
1143
|
+
return void 0;
|
|
1144
|
+
}
|
|
1145
|
+
const rows = Array.isArray(record[key]) ? record[key] : [record[key]];
|
|
1146
|
+
const result = [];
|
|
1147
|
+
for (const value of rows) {
|
|
1148
|
+
const row = toWsfeRecord(value);
|
|
1149
|
+
const mapped = row ? map(row) : void 0;
|
|
1150
|
+
if (mapped === void 0) {
|
|
1151
|
+
return void 0;
|
|
1152
|
+
}
|
|
1153
|
+
result.push(mapped);
|
|
1154
|
+
}
|
|
1155
|
+
return result;
|
|
1156
|
+
}
|
|
1157
|
+
function mapWsfeLookupVat(row) {
|
|
1158
|
+
const id = normalizeWsfeNumber(row.Id);
|
|
1159
|
+
const baseAmount = normalizeWsfeNumber(row.BaseImp);
|
|
1160
|
+
const amount = normalizeWsfeNumber(row.Importe);
|
|
1161
|
+
if (id === void 0 || baseAmount === void 0 || amount === void 0) {
|
|
1162
|
+
return void 0;
|
|
1163
|
+
}
|
|
1164
|
+
return { id, baseAmount, amount };
|
|
1165
|
+
}
|
|
1166
|
+
function mapWsfeLookupTax(row) {
|
|
1167
|
+
const vat = mapWsfeLookupVat(row);
|
|
1168
|
+
const rate = normalizeWsfeNumber(row.Alic);
|
|
1169
|
+
if (!vat || rate === void 0) {
|
|
1170
|
+
return void 0;
|
|
1171
|
+
}
|
|
1172
|
+
const description = normalizeWsfeString(row.Desc);
|
|
1173
|
+
return {
|
|
1174
|
+
...vat,
|
|
1175
|
+
rate,
|
|
1176
|
+
...description === void 0 ? {} : { description }
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1099
1179
|
function createWsfeAuth(representedTaxId, token, sign) {
|
|
1100
1180
|
return {
|
|
1101
1181
|
Token: token,
|
|
@@ -1402,15 +1482,141 @@ function getWsfeResultEntries(result, key) {
|
|
|
1402
1482
|
);
|
|
1403
1483
|
}
|
|
1404
1484
|
|
|
1405
|
-
// src/services/wsfe-
|
|
1406
|
-
var
|
|
1407
|
-
0: ARCA_VAT_RATES.IVA_0,
|
|
1408
|
-
2.5: ARCA_VAT_RATES.IVA_2_5,
|
|
1409
|
-
5: ARCA_VAT_RATES.IVA_5,
|
|
1410
|
-
10.5: ARCA_VAT_RATES.IVA_10_5,
|
|
1411
|
-
21: ARCA_VAT_RATES.IVA_21,
|
|
1412
|
-
27: ARCA_VAT_RATES.IVA_27
|
|
1485
|
+
// src/services/wsfe-amounts.ts
|
|
1486
|
+
var RATES = {
|
|
1487
|
+
0: { id: ARCA_VAT_RATES.IVA_0, basisPoints: 0n },
|
|
1488
|
+
2.5: { id: ARCA_VAT_RATES.IVA_2_5, basisPoints: 250n },
|
|
1489
|
+
5: { id: ARCA_VAT_RATES.IVA_5, basisPoints: 500n },
|
|
1490
|
+
10.5: { id: ARCA_VAT_RATES.IVA_10_5, basisPoints: 1050n },
|
|
1491
|
+
21: { id: ARCA_VAT_RATES.IVA_21, basisPoints: 2100n },
|
|
1492
|
+
27: { id: ARCA_VAT_RATES.IVA_27, basisPoints: 2700n }
|
|
1413
1493
|
};
|
|
1494
|
+
function calculateWsfeAmounts(input) {
|
|
1495
|
+
if (!Array.isArray(input.items) || input.items.length === 0) {
|
|
1496
|
+
invalidItem("items", "a non-empty array of items");
|
|
1497
|
+
}
|
|
1498
|
+
const isVat = input.issuer === "responsable_inscripto";
|
|
1499
|
+
if (!(isVat || ["monotributo", "exento", "no_alcanzado"].includes(input.issuer))) {
|
|
1500
|
+
invalidItem("issuer", "a supported issuer condition");
|
|
1501
|
+
}
|
|
1502
|
+
const totals = collectItems(input.items, isVat);
|
|
1503
|
+
let net = totals.net;
|
|
1504
|
+
let vat = 0n;
|
|
1505
|
+
const { exempt, untaxed, groups } = totals;
|
|
1506
|
+
const vatRates = [];
|
|
1507
|
+
for (const [rate, group] of groups) {
|
|
1508
|
+
const { id, basisPoints } = RATES[rate];
|
|
1509
|
+
const netFromGross = roundHalfEvenRatio(
|
|
1510
|
+
group.gross * 10000n,
|
|
1511
|
+
10000n + basisPoints
|
|
1512
|
+
);
|
|
1513
|
+
const base = group.net + netFromGross;
|
|
1514
|
+
const tax = roundHalfEvenRatio(group.net * basisPoints, 10000n) + group.gross - netFromGross;
|
|
1515
|
+
if (base === 0n) {
|
|
1516
|
+
continue;
|
|
1517
|
+
}
|
|
1518
|
+
net += base;
|
|
1519
|
+
vat += tax;
|
|
1520
|
+
vatRates.push({
|
|
1521
|
+
id,
|
|
1522
|
+
baseAmount: arcaMinorUnitsToNumber(base, "netAmount"),
|
|
1523
|
+
amount: arcaMinorUnitsToNumber(tax, "vatAmount")
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
const computed = net + vat + exempt + untaxed;
|
|
1527
|
+
arcaMinorUnitsToNumber(computed, "totalAmount");
|
|
1528
|
+
const sent = input.total === void 0 ? computed : assertArcaMinorUnits(input.total, "total");
|
|
1529
|
+
const adjustment = sent - computed;
|
|
1530
|
+
const allowance = BigInt(vatRates.length);
|
|
1531
|
+
if (adjustment < -allowance || adjustment > allowance || vat + adjustment < 0n) {
|
|
1532
|
+
throw new ArcaInputError(
|
|
1533
|
+
"total does not match the computed amount within the VAT allowance.",
|
|
1534
|
+
{
|
|
1535
|
+
code: "ARCA_INPUT_AMOUNT_MISMATCH",
|
|
1536
|
+
field: "total",
|
|
1537
|
+
expected: `${computed} minor units (at most ${allowance} minor units of VAT adjustment, with non-negative VAT)`
|
|
1538
|
+
}
|
|
1539
|
+
);
|
|
1540
|
+
}
|
|
1541
|
+
return {
|
|
1542
|
+
data: {
|
|
1543
|
+
totalAmount: arcaMinorUnitsToNumber(sent, "totalAmount"),
|
|
1544
|
+
netAmount: arcaMinorUnitsToNumber(net, "netAmount"),
|
|
1545
|
+
vatAmount: arcaMinorUnitsToNumber(vat + adjustment, "vatAmount"),
|
|
1546
|
+
nonTaxableAmount: arcaMinorUnitsToNumber(untaxed, "nonTaxableAmount"),
|
|
1547
|
+
exemptAmount: arcaMinorUnitsToNumber(exempt, "exemptAmount"),
|
|
1548
|
+
taxAmount: 0,
|
|
1549
|
+
...isVat ? { vatRates } : {}
|
|
1550
|
+
},
|
|
1551
|
+
amounts: {
|
|
1552
|
+
computedTotal: Number(computed),
|
|
1553
|
+
sentTotal: Number(sent),
|
|
1554
|
+
vatAdjustment: Number(adjustment)
|
|
1555
|
+
}
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1558
|
+
function collectItems(items, isVat) {
|
|
1559
|
+
let net = 0n;
|
|
1560
|
+
let exempt = 0n;
|
|
1561
|
+
let untaxed = 0n;
|
|
1562
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1563
|
+
for (const [index, item] of items.entries()) {
|
|
1564
|
+
const path = `items[${index}]`;
|
|
1565
|
+
if (item === null || typeof item !== "object" || Array.isArray(item)) {
|
|
1566
|
+
invalidItem(path, "an item object");
|
|
1567
|
+
}
|
|
1568
|
+
if (!isVat) {
|
|
1569
|
+
net += classCAmount(item, path);
|
|
1570
|
+
continue;
|
|
1571
|
+
}
|
|
1572
|
+
const { amount, field, rate } = vatItemAmount(item, path);
|
|
1573
|
+
if (rate === "exempt") {
|
|
1574
|
+
exempt += amount;
|
|
1575
|
+
continue;
|
|
1576
|
+
}
|
|
1577
|
+
if (rate === "untaxed") {
|
|
1578
|
+
untaxed += amount;
|
|
1579
|
+
continue;
|
|
1580
|
+
}
|
|
1581
|
+
const group = groups.get(rate) ?? { net: 0n, gross: 0n };
|
|
1582
|
+
group[field] += amount;
|
|
1583
|
+
groups.set(rate, group);
|
|
1584
|
+
}
|
|
1585
|
+
return { net, exempt, untaxed, groups };
|
|
1586
|
+
}
|
|
1587
|
+
function classCAmount(item, path) {
|
|
1588
|
+
if ("vat" in item || "net" in item || "gross" in item) {
|
|
1589
|
+
invalidItem("items", "amount items for a non-RI issuer");
|
|
1590
|
+
}
|
|
1591
|
+
return assertArcaMinorUnits(item.amount, `${path}.amount`);
|
|
1592
|
+
}
|
|
1593
|
+
function vatItemAmount(item, path) {
|
|
1594
|
+
if ("amount" in item || "net" in item === "gross" in item) {
|
|
1595
|
+
invalidItem(
|
|
1596
|
+
"items",
|
|
1597
|
+
"exactly one of net or gross, and vat, for an RI issuer"
|
|
1598
|
+
);
|
|
1599
|
+
}
|
|
1600
|
+
const field = "net" in item ? "net" : "gross";
|
|
1601
|
+
const amount = assertArcaMinorUnits(
|
|
1602
|
+
item[field],
|
|
1603
|
+
`${path}.${field}`
|
|
1604
|
+
);
|
|
1605
|
+
const rate = item.vat;
|
|
1606
|
+
if (rate !== "exempt" && rate !== "untaxed" && (typeof rate !== "number" || !Object.hasOwn(RATES, rate))) {
|
|
1607
|
+
invalidItem(`${path}.vat`, "0, 2.5, 5, 10.5, 21, 27, exempt, or untaxed");
|
|
1608
|
+
}
|
|
1609
|
+
return { amount, field, rate };
|
|
1610
|
+
}
|
|
1611
|
+
function invalidItem(field, expected) {
|
|
1612
|
+
throw new ArcaInputError(`${field} must be ${expected}.`, {
|
|
1613
|
+
code: "ARCA_INPUT_INVALID_VALUE",
|
|
1614
|
+
field,
|
|
1615
|
+
expected
|
|
1616
|
+
});
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
// src/services/wsfe-builders.ts
|
|
1414
1620
|
function buildFacturaB(input) {
|
|
1415
1621
|
const taxableMinorUnits = assertArcaMinorUnits(
|
|
1416
1622
|
input.taxableAmount,
|
|
@@ -1431,15 +1637,6 @@ function buildFacturaB(input) {
|
|
|
1431
1637
|
input.vatRate,
|
|
1432
1638
|
"vatRate"
|
|
1433
1639
|
);
|
|
1434
|
-
const totalMinorUnits = taxableMinorUnits + vatMinorUnits;
|
|
1435
|
-
const vatRateId = VAT_RATE_IDS[input.vatRate];
|
|
1436
|
-
if (vatRateId === void 0) {
|
|
1437
|
-
throw new ArcaInputError("vatRate is not a supported VAT rate.", {
|
|
1438
|
-
code: "ARCA_INPUT_INVALID_VALUE",
|
|
1439
|
-
field: "vatRate",
|
|
1440
|
-
expected: "one of 0, 2.5, 5, 10.5, 21, or 27"
|
|
1441
|
-
});
|
|
1442
|
-
}
|
|
1443
1640
|
if (input.vatRate !== 0 && vatMinorUnits === 0n) {
|
|
1444
1641
|
throw new ArcaInputError(
|
|
1445
1642
|
"taxableAmount is too small to produce VAT at the selected positive vatRate.",
|
|
@@ -1450,39 +1647,30 @@ function buildFacturaB(input) {
|
|
|
1450
1647
|
}
|
|
1451
1648
|
);
|
|
1452
1649
|
}
|
|
1453
|
-
const
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
Object.freeze(vatRates);
|
|
1650
|
+
const { data } = calculateWsfeAmounts({
|
|
1651
|
+
issuer: "responsable_inscripto",
|
|
1652
|
+
items: [{ net: input.taxableAmount, vat: input.vatRate }]
|
|
1653
|
+
});
|
|
1654
|
+
for (const rate of data.vatRates ?? []) {
|
|
1655
|
+
Object.freeze(rate);
|
|
1656
|
+
}
|
|
1657
|
+
Object.freeze(data.vatRates);
|
|
1461
1658
|
return Object.freeze({
|
|
1462
1659
|
...buildCommonExactInput(input),
|
|
1463
1660
|
voucherType: ARCA_VOUCHER_TYPES.FACTURA_B,
|
|
1464
|
-
|
|
1465
|
-
nonTaxableAmount: 0,
|
|
1466
|
-
netAmount: arcaMinorUnitsToNumber(taxableMinorUnits, "taxableAmount"),
|
|
1467
|
-
exemptAmount: 0,
|
|
1468
|
-
taxAmount: 0,
|
|
1469
|
-
vatAmount: arcaMinorUnitsToNumber(vatMinorUnits, "vatAmount"),
|
|
1470
|
-
vatRates
|
|
1661
|
+
...data
|
|
1471
1662
|
});
|
|
1472
1663
|
}
|
|
1473
1664
|
function buildFacturaC(input) {
|
|
1474
|
-
|
|
1475
|
-
const
|
|
1665
|
+
assertArcaMinorUnits(input.amount, "amount");
|
|
1666
|
+
const { data } = calculateWsfeAmounts({
|
|
1667
|
+
issuer: "monotributo",
|
|
1668
|
+
items: [{ amount: input.amount }]
|
|
1669
|
+
});
|
|
1476
1670
|
return Object.freeze({
|
|
1477
1671
|
...buildCommonExactInput(input),
|
|
1478
1672
|
voucherType: ARCA_VOUCHER_TYPES.FACTURA_C,
|
|
1479
|
-
|
|
1480
|
-
nonTaxableAmount: 0,
|
|
1481
|
-
// ARCA defines ImpNeto as the subtotal for class C vouchers.
|
|
1482
|
-
netAmount: amount,
|
|
1483
|
-
exemptAmount: 0,
|
|
1484
|
-
taxAmount: 0,
|
|
1485
|
-
vatAmount: 0
|
|
1673
|
+
...data
|
|
1486
1674
|
});
|
|
1487
1675
|
}
|
|
1488
1676
|
function buildCommonExactInput(input) {
|
|
@@ -1579,8 +1767,13 @@ function normalizeBuilderCurrency(input) {
|
|
|
1579
1767
|
}
|
|
1580
1768
|
|
|
1581
1769
|
export {
|
|
1770
|
+
normalizeArcaAmountToMinorUnits,
|
|
1771
|
+
serializeArcaExchangeRate,
|
|
1582
1772
|
createWsfeService,
|
|
1773
|
+
normalizeWsfeVoucherInput,
|
|
1774
|
+
normalizeWsfeDateInput,
|
|
1775
|
+
calculateWsfeAmounts,
|
|
1583
1776
|
buildFacturaB,
|
|
1584
1777
|
buildFacturaC
|
|
1585
1778
|
};
|
|
1586
|
-
//# sourceMappingURL=chunk-
|
|
1779
|
+
//# sourceMappingURL=chunk-TOVSOJ3G.mjs.map
|