facturas 0.9.0 → 0.11.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 +95 -786
- package/bin/facturas.mjs +4 -0
- package/dist/{chunk-RCM4NAAG.mjs → chunk-5KCTRQJX.mjs} +83 -284
- package/dist/chunk-5KCTRQJX.mjs.map +1 -0
- package/dist/{chunk-XNBD5NVL.mjs → chunk-ALH5IPSY.mjs} +2 -57
- package/dist/chunk-ALH5IPSY.mjs.map +1 -0
- package/dist/{chunk-76WU5BVI.mjs → chunk-GX5ERXT6.mjs} +1 -1
- package/dist/chunk-GX5ERXT6.mjs.map +1 -0
- package/dist/chunk-LOWV7IF6.mjs +3758 -0
- package/dist/chunk-LOWV7IF6.mjs.map +1 -0
- package/dist/chunk-LR4M2AMG.mjs +169 -0
- package/dist/chunk-LR4M2AMG.mjs.map +1 -0
- package/dist/{chunk-4QVFXT35.mjs → chunk-UDX6HLAU.mjs} +1 -17
- package/dist/{chunk-4QVFXT35.mjs.map → chunk-UDX6HLAU.mjs.map} +1 -1
- package/dist/cli.d.ts +49 -0
- package/dist/cli.mjs +2316 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/client-BZxeScuK.d.ts +521 -0
- package/dist/constants.d.ts +1 -1
- package/dist/constants.mjs +1 -1
- package/dist/{wsfe-DF0jAE2k.d.ts → decimal-B0HtrMFY.d.ts} +9 -66
- package/dist/errors.d.ts +2 -2
- package/dist/{fiscal-evidence-DBzakqBE.d.ts → fiscal-evidence-B1Qe6XMg.d.ts} +2 -2
- package/dist/{index-CVGQyyYM.d.ts → index-D8LGFvxV.d.ts} +1 -1
- package/dist/index.d.ts +11 -235
- package/dist/index.mjs +21 -2315
- package/dist/index.mjs.map +1 -1
- package/dist/padron.d.ts +2 -2
- package/dist/{types-BiznC1-X.d.ts → types-r2nf55gh.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/wsfe.d.ts +45 -4
- package/dist/wsfe.mjs +6 -4
- package/dist/wsmtxca.d.ts +4 -20
- package/dist/wsmtxca.mjs +2 -2
- package/package.json +5 -1
- package/dist/chunk-76WU5BVI.mjs.map +0 -1
- package/dist/chunk-RCM4NAAG.mjs.map +0 -1
- package/dist/chunk-XNBD5NVL.mjs.map +0 -1
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertArcaMinorUnits,
|
|
3
|
+
calculateVatMinorUnits,
|
|
4
|
+
calculateWsfeAmounts,
|
|
5
|
+
serializeArcaExchangeRate
|
|
6
|
+
} from "./chunk-5KCTRQJX.mjs";
|
|
7
|
+
import {
|
|
8
|
+
ARCA_CURRENCY_IDS,
|
|
9
|
+
ARCA_VOUCHER_TYPES
|
|
10
|
+
} from "./chunk-GX5ERXT6.mjs";
|
|
11
|
+
import {
|
|
12
|
+
ArcaInputError
|
|
13
|
+
} from "./chunk-ZOSNASXB.mjs";
|
|
14
|
+
|
|
15
|
+
// src/services/wsfe-builders.ts
|
|
16
|
+
function buildFacturaB(input) {
|
|
17
|
+
const taxableMinorUnits = assertArcaMinorUnits(
|
|
18
|
+
input.taxableAmount,
|
|
19
|
+
"taxableAmount"
|
|
20
|
+
);
|
|
21
|
+
if (taxableMinorUnits === 0n) {
|
|
22
|
+
throw new ArcaInputError(
|
|
23
|
+
"taxableAmount must be greater than zero for Factura B.",
|
|
24
|
+
{
|
|
25
|
+
code: "ARCA_INPUT_INVALID_AMOUNT",
|
|
26
|
+
field: "taxableAmount",
|
|
27
|
+
expected: "a positive safe integer in currency minor units"
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
const vatMinorUnits = calculateVatMinorUnits(
|
|
32
|
+
taxableMinorUnits,
|
|
33
|
+
input.vatRate,
|
|
34
|
+
"vatRate"
|
|
35
|
+
);
|
|
36
|
+
if (input.vatRate !== 0 && vatMinorUnits === 0n) {
|
|
37
|
+
throw new ArcaInputError(
|
|
38
|
+
"taxableAmount is too small to produce VAT at the selected positive vatRate.",
|
|
39
|
+
{
|
|
40
|
+
code: "ARCA_INPUT_INVALID_AMOUNT",
|
|
41
|
+
field: "taxableAmount",
|
|
42
|
+
expected: "an amount that rounds to at least one currency minor unit of VAT for a positive vatRate"
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
const { data } = calculateWsfeAmounts({
|
|
47
|
+
voucherClass: "B",
|
|
48
|
+
items: [{ net: input.taxableAmount, vat: input.vatRate }]
|
|
49
|
+
});
|
|
50
|
+
for (const rate of data.vatRates ?? []) {
|
|
51
|
+
Object.freeze(rate);
|
|
52
|
+
}
|
|
53
|
+
Object.freeze(data.vatRates);
|
|
54
|
+
return Object.freeze({
|
|
55
|
+
...buildCommonExactInput(input),
|
|
56
|
+
voucherType: ARCA_VOUCHER_TYPES.FACTURA_B,
|
|
57
|
+
...data
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function buildFacturaC(input) {
|
|
61
|
+
assertArcaMinorUnits(input.amount, "amount");
|
|
62
|
+
const { data } = calculateWsfeAmounts({
|
|
63
|
+
voucherClass: "C",
|
|
64
|
+
items: [{ amount: input.amount }]
|
|
65
|
+
});
|
|
66
|
+
return Object.freeze({
|
|
67
|
+
...buildCommonExactInput(input),
|
|
68
|
+
voucherType: ARCA_VOUCHER_TYPES.FACTURA_C,
|
|
69
|
+
...data
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function buildCommonExactInput(input) {
|
|
73
|
+
return {
|
|
74
|
+
salesPoint: input.salesPoint,
|
|
75
|
+
concept: input.concept,
|
|
76
|
+
documentType: input.documentType,
|
|
77
|
+
documentNumber: input.documentNumber,
|
|
78
|
+
receiverVatConditionId: input.receiverVatConditionId,
|
|
79
|
+
voucherDate: input.voucherDate,
|
|
80
|
+
...normalizeBuilderCurrency(input),
|
|
81
|
+
...input.serviceStartDate === void 0 ? {} : { serviceStartDate: input.serviceStartDate },
|
|
82
|
+
...input.serviceEndDate === void 0 ? {} : { serviceEndDate: input.serviceEndDate },
|
|
83
|
+
...input.paymentDueDate === void 0 ? {} : { paymentDueDate: input.paymentDueDate }
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function normalizeBuilderCurrency(input) {
|
|
87
|
+
const unsafeInput = input;
|
|
88
|
+
const currency = unsafeInput.currency ?? "ARS";
|
|
89
|
+
if (unsafeInput.sameCurrencyForeignCancellation !== void 0 && typeof unsafeInput.sameCurrencyForeignCancellation !== "boolean") {
|
|
90
|
+
throw new ArcaInputError(
|
|
91
|
+
"sameCurrencyForeignCancellation must be a boolean when provided.",
|
|
92
|
+
{
|
|
93
|
+
code: "ARCA_INPUT_INVALID_VALUE",
|
|
94
|
+
field: "sameCurrencyForeignCancellation",
|
|
95
|
+
expected: "true, false, or omitted"
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
if (currency === "ARS") {
|
|
100
|
+
if (unsafeInput.exchangeRate !== void 0) {
|
|
101
|
+
throw new ArcaInputError(
|
|
102
|
+
"exchangeRate must be omitted when currency is ARS.",
|
|
103
|
+
{
|
|
104
|
+
code: "ARCA_INPUT_INVALID_EXCHANGE_RATE",
|
|
105
|
+
field: "exchangeRate",
|
|
106
|
+
expected: "omitted when currency is ARS"
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
if (unsafeInput.sameCurrencyForeignCancellation !== void 0) {
|
|
111
|
+
throw new ArcaInputError(
|
|
112
|
+
"sameCurrencyForeignCancellation applies only when currency is USD.",
|
|
113
|
+
{
|
|
114
|
+
code: "ARCA_INPUT_INVALID_VALUE",
|
|
115
|
+
field: "sameCurrencyForeignCancellation",
|
|
116
|
+
expected: "omitted when currency is ARS"
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
currencyId: ARCA_CURRENCY_IDS.ARS,
|
|
122
|
+
exchangeRate: "1"
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (currency !== "USD") {
|
|
126
|
+
throw new ArcaInputError("currency is not supported by this builder.", {
|
|
127
|
+
code: "ARCA_INPUT_INVALID_VALUE",
|
|
128
|
+
field: "currency",
|
|
129
|
+
expected: "ARS or USD"
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
if (unsafeInput.sameCurrencyForeignCancellation === true) {
|
|
133
|
+
if (unsafeInput.exchangeRate !== void 0) {
|
|
134
|
+
throw new ArcaInputError(
|
|
135
|
+
"exchangeRate must be omitted for same-currency foreign cancellation.",
|
|
136
|
+
{
|
|
137
|
+
code: "ARCA_INPUT_INVALID_EXCHANGE_RATE",
|
|
138
|
+
field: "exchangeRate",
|
|
139
|
+
expected: "omitted when sameCurrencyForeignCancellation is true"
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
currencyId: ARCA_CURRENCY_IDS.USD,
|
|
145
|
+
sameCurrencyForeignCancellation: "S"
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
if (typeof unsafeInput.exchangeRate !== "string") {
|
|
149
|
+
throw new ArcaInputError("exchangeRate is required for USD invoices.", {
|
|
150
|
+
code: "ARCA_INPUT_MISSING_FIELD",
|
|
151
|
+
field: "exchangeRate",
|
|
152
|
+
expected: "a decimal string unless sameCurrencyForeignCancellation is true"
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
currencyId: ARCA_CURRENCY_IDS.USD,
|
|
157
|
+
exchangeRate: serializeArcaExchangeRate(
|
|
158
|
+
unsafeInput.exchangeRate,
|
|
159
|
+
"exchangeRate"
|
|
160
|
+
),
|
|
161
|
+
...unsafeInput.sameCurrencyForeignCancellation === false ? { sameCurrencyForeignCancellation: "N" } : {}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export {
|
|
166
|
+
buildFacturaB,
|
|
167
|
+
buildFacturaC
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=chunk-LR4M2AMG.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/wsfe-builders.ts"],"sourcesContent":["import { ARCA_CURRENCY_IDS, ARCA_VOUCHER_TYPES } from \"../constants\";\nimport { ArcaInputError } from \"../errors\";\nimport {\n assertArcaMinorUnits,\n calculateVatMinorUnits,\n type SupportedVatRate,\n serializeArcaExchangeRate,\n} from \"../internal/decimal\";\nimport type { WsfeDateInput, WsfeVoucherInput } from \"./wsfe\";\nimport { calculateWsfeAmounts } from \"./wsfe-amounts\";\n\nexport type WsfeBuilderCurrencyInput =\n | {\n currency?: \"ARS\";\n exchangeRate?: never;\n sameCurrencyForeignCancellation?: never;\n }\n | {\n currency: \"USD\";\n exchangeRate: string;\n sameCurrencyForeignCancellation?: false;\n }\n | {\n currency: \"USD\";\n exchangeRate?: never;\n sameCurrencyForeignCancellation: true;\n };\n\nexport type WsfeBuilderVatRate = SupportedVatRate;\n\ntype WsfeInvoiceBuilderBaseInput = {\n salesPoint: number;\n concept: number;\n documentType: number;\n documentNumber: number;\n receiverVatConditionId: number;\n voucherDate: WsfeDateInput;\n serviceStartDate?: WsfeDateInput;\n serviceEndDate?: WsfeDateInput;\n paymentDueDate?: WsfeDateInput;\n};\n\nexport type BuildFacturaBInput = WsfeInvoiceBuilderBaseInput &\n WsfeBuilderCurrencyInput & {\n /** Positive integer currency minor units forming the taxable base. */\n taxableAmount: number;\n vatRate: WsfeBuilderVatRate;\n };\n\nexport type BuildFacturaCInput = WsfeInvoiceBuilderBaseInput &\n WsfeBuilderCurrencyInput & {\n amount: number;\n };\n\n/** Builds a narrow Factura B exact WSFE input from integer currency minor units. */\nexport function buildFacturaB(input: BuildFacturaBInput): WsfeVoucherInput {\n const taxableMinorUnits = assertArcaMinorUnits(\n input.taxableAmount,\n \"taxableAmount\"\n );\n if (taxableMinorUnits === 0n) {\n throw new ArcaInputError(\n \"taxableAmount must be greater than zero for Factura B.\",\n {\n code: \"ARCA_INPUT_INVALID_AMOUNT\",\n field: \"taxableAmount\",\n expected: \"a positive safe integer in currency minor units\",\n }\n );\n }\n\n const vatMinorUnits = calculateVatMinorUnits(\n taxableMinorUnits,\n input.vatRate,\n \"vatRate\"\n );\n if (input.vatRate !== 0 && vatMinorUnits === 0n) {\n throw new ArcaInputError(\n \"taxableAmount is too small to produce VAT at the selected positive vatRate.\",\n {\n code: \"ARCA_INPUT_INVALID_AMOUNT\",\n field: \"taxableAmount\",\n expected:\n \"an amount that rounds to at least one currency minor unit of VAT for a positive vatRate\",\n }\n );\n }\n\n const { data } = calculateWsfeAmounts({\n voucherClass: \"B\",\n items: [{ net: input.taxableAmount, vat: input.vatRate }],\n });\n for (const rate of data.vatRates ?? []) {\n Object.freeze(rate);\n }\n Object.freeze(data.vatRates);\n return Object.freeze({\n ...buildCommonExactInput(input),\n voucherType: ARCA_VOUCHER_TYPES.FACTURA_B,\n ...data,\n });\n}\n\n/** Builds a narrow Factura C exact WSFE input from integer currency minor units. */\nexport function buildFacturaC(input: BuildFacturaCInput): WsfeVoucherInput {\n assertArcaMinorUnits(input.amount, \"amount\");\n const { data } = calculateWsfeAmounts({\n voucherClass: \"C\",\n items: [{ amount: input.amount }],\n });\n return Object.freeze({\n ...buildCommonExactInput(input),\n voucherType: ARCA_VOUCHER_TYPES.FACTURA_C,\n ...data,\n });\n}\n\nfunction buildCommonExactInput(\n input: WsfeInvoiceBuilderBaseInput & WsfeBuilderCurrencyInput\n): Pick<\n WsfeVoucherInput,\n | \"salesPoint\"\n | \"concept\"\n | \"documentType\"\n | \"documentNumber\"\n | \"receiverVatConditionId\"\n | \"voucherDate\"\n | \"currencyId\"\n | \"exchangeRate\"\n | \"sameCurrencyForeignCancellation\"\n | \"serviceStartDate\"\n | \"serviceEndDate\"\n | \"paymentDueDate\"\n> {\n return {\n salesPoint: input.salesPoint,\n concept: input.concept,\n documentType: input.documentType,\n documentNumber: input.documentNumber,\n receiverVatConditionId: input.receiverVatConditionId,\n voucherDate: input.voucherDate,\n ...normalizeBuilderCurrency(input),\n ...(input.serviceStartDate === undefined\n ? {}\n : { serviceStartDate: input.serviceStartDate }),\n ...(input.serviceEndDate === undefined\n ? {}\n : { serviceEndDate: input.serviceEndDate }),\n ...(input.paymentDueDate === undefined\n ? {}\n : { paymentDueDate: input.paymentDueDate }),\n };\n}\n\nfunction normalizeBuilderCurrency(\n input: WsfeBuilderCurrencyInput\n): Pick<\n WsfeVoucherInput,\n \"currencyId\" | \"exchangeRate\" | \"sameCurrencyForeignCancellation\"\n> {\n const unsafeInput = input as {\n currency?: string;\n exchangeRate?: unknown;\n sameCurrencyForeignCancellation?: unknown;\n };\n const currency = unsafeInput.currency ?? \"ARS\";\n\n if (\n unsafeInput.sameCurrencyForeignCancellation !== undefined &&\n typeof unsafeInput.sameCurrencyForeignCancellation !== \"boolean\"\n ) {\n throw new ArcaInputError(\n \"sameCurrencyForeignCancellation must be a boolean when provided.\",\n {\n code: \"ARCA_INPUT_INVALID_VALUE\",\n field: \"sameCurrencyForeignCancellation\",\n expected: \"true, false, or omitted\",\n }\n );\n }\n\n if (currency === \"ARS\") {\n if (unsafeInput.exchangeRate !== undefined) {\n throw new ArcaInputError(\n \"exchangeRate must be omitted when currency is ARS.\",\n {\n code: \"ARCA_INPUT_INVALID_EXCHANGE_RATE\",\n field: \"exchangeRate\",\n expected: \"omitted when currency is ARS\",\n }\n );\n }\n if (unsafeInput.sameCurrencyForeignCancellation !== undefined) {\n throw new ArcaInputError(\n \"sameCurrencyForeignCancellation applies only when currency is USD.\",\n {\n code: \"ARCA_INPUT_INVALID_VALUE\",\n field: \"sameCurrencyForeignCancellation\",\n expected: \"omitted when currency is ARS\",\n }\n );\n }\n\n return {\n currencyId: ARCA_CURRENCY_IDS.ARS,\n exchangeRate: \"1\",\n };\n }\n\n if (currency !== \"USD\") {\n throw new ArcaInputError(\"currency is not supported by this builder.\", {\n code: \"ARCA_INPUT_INVALID_VALUE\",\n field: \"currency\",\n expected: \"ARS or USD\",\n });\n }\n\n if (unsafeInput.sameCurrencyForeignCancellation === true) {\n if (unsafeInput.exchangeRate !== undefined) {\n throw new ArcaInputError(\n \"exchangeRate must be omitted for same-currency foreign cancellation.\",\n {\n code: \"ARCA_INPUT_INVALID_EXCHANGE_RATE\",\n field: \"exchangeRate\",\n expected: \"omitted when sameCurrencyForeignCancellation is true\",\n }\n );\n }\n\n return {\n currencyId: ARCA_CURRENCY_IDS.USD,\n sameCurrencyForeignCancellation: \"S\",\n };\n }\n\n if (typeof unsafeInput.exchangeRate !== \"string\") {\n throw new ArcaInputError(\"exchangeRate is required for USD invoices.\", {\n code: \"ARCA_INPUT_MISSING_FIELD\",\n field: \"exchangeRate\",\n expected:\n \"a decimal string unless sameCurrencyForeignCancellation is true\",\n });\n }\n\n return {\n currencyId: ARCA_CURRENCY_IDS.USD,\n exchangeRate: serializeArcaExchangeRate(\n unsafeInput.exchangeRate,\n \"exchangeRate\"\n ),\n ...(unsafeInput.sameCurrencyForeignCancellation === false\n ? { sameCurrencyForeignCancellation: \"N\" as const }\n : {}),\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -82,21 +82,6 @@ function createArcaAuthenticationEvidence(error) {
|
|
|
82
82
|
...error.providerCode === void 0 ? {} : { providerCode: error.providerCode }
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
function createArcaAuthenticationErrorFromEvidence(evidence, context) {
|
|
86
|
-
return new ArcaAuthenticationError(
|
|
87
|
-
formatAuthenticationMessage(
|
|
88
|
-
context.service,
|
|
89
|
-
context.operation,
|
|
90
|
-
evidence.reason
|
|
91
|
-
),
|
|
92
|
-
{
|
|
93
|
-
reason: evidence.reason,
|
|
94
|
-
service: context.service,
|
|
95
|
-
operation: context.operation,
|
|
96
|
-
...evidence.providerCode === void 0 ? {} : { providerCode: evidence.providerCode }
|
|
97
|
-
}
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
85
|
async function executeWithAuthenticationRecovery(options) {
|
|
101
86
|
const executeAttempt = async (forceRefresh) => {
|
|
102
87
|
try {
|
|
@@ -189,7 +174,6 @@ export {
|
|
|
189
174
|
classifyArcaAuthenticationError,
|
|
190
175
|
classifyArcaAuthenticationIssues,
|
|
191
176
|
createArcaAuthenticationEvidence,
|
|
192
|
-
createArcaAuthenticationErrorFromEvidence,
|
|
193
177
|
executeWithAuthenticationRecovery
|
|
194
178
|
};
|
|
195
|
-
//# sourceMappingURL=chunk-
|
|
179
|
+
//# sourceMappingURL=chunk-UDX6HLAU.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/authentication.ts"],"sourcesContent":["import {\n ArcaAuthenticationError,\n type ArcaAuthenticationReason,\n ArcaServiceError,\n ArcaSoapFaultError,\n isArcaAuthenticationError,\n} from \"../errors\";\nimport type {\n ArcaAuthenticationEvidence,\n ArcaFiscalIssue,\n} from \"../services/fiscal-evidence\";\nimport type { ArcaServiceName } from \"./types\";\n\ntype AuthenticationContext = {\n service: ArcaServiceName;\n operation: string;\n};\n\ntype AuthenticationCandidate = AuthenticationContext & {\n providerCode?: string | number;\n message?: string;\n cause?: unknown;\n};\n\ntype AuthenticationRecoveryOptions<T> = AuthenticationContext & {\n forceRefresh?: boolean;\n allowRetry?: boolean;\n execute(forceRefresh?: boolean): Promise<T>;\n};\n\nconst WSFE_AUTHENTICATION_CODES: Readonly<\n Record<string, ArcaAuthenticationReason>\n> = {\n \"600\": \"invalid_token\",\n \"601\": \"missing_relationship\",\n};\n\n/** Classifies one safe provider code/message pair without inspecting object graphs. */\nexport function classifyArcaAuthenticationCandidate(\n candidate: AuthenticationCandidate\n): ArcaAuthenticationError | undefined {\n const providerCode = normalizeProviderCode(candidate.providerCode);\n const reason =\n getStructuredAuthenticationReason(candidate.service, providerCode) ??\n getTextAuthenticationReason(candidate.message);\n\n if (!reason) {\n return undefined;\n }\n\n return new ArcaAuthenticationError(\n formatAuthenticationMessage(candidate.service, candidate.operation, reason),\n {\n reason,\n service: candidate.service,\n operation: candidate.operation,\n ...(providerCode === undefined ? {} : { providerCode }),\n ...(candidate.cause === undefined ? {} : { cause: candidate.cause }),\n }\n );\n}\n\n/** Classifies supported public ARCA errors while ignoring arbitrary errors and causes. */\nexport function classifyArcaAuthenticationError(\n error: unknown,\n context: AuthenticationContext\n): ArcaAuthenticationError | undefined {\n if (isArcaAuthenticationError(error)) {\n return error;\n }\n\n if (error instanceof ArcaSoapFaultError) {\n return classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: error.faultCode,\n message: error.message,\n cause: error,\n });\n }\n\n if (error instanceof ArcaServiceError) {\n const issueError = classifyArcaAuthenticationIssues(\n error.issues ?? [],\n context\n );\n if (issueError) {\n return new ArcaAuthenticationError(issueError.message, {\n reason: issueError.reason,\n service: issueError.service,\n operation: issueError.operation,\n ...(issueError.providerCode === undefined\n ? {}\n : { providerCode: issueError.providerCode }),\n cause: error,\n });\n }\n\n return classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: error.serviceCode,\n message: error.message,\n cause: error,\n });\n }\n\n return undefined;\n}\n\n/** Classifies structured service issues in provider order. */\nexport function classifyArcaAuthenticationIssues(\n issues: readonly ArcaFiscalIssue[],\n context: AuthenticationContext\n): ArcaAuthenticationError | undefined {\n for (const issue of issues) {\n const authenticationError = classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: issue.code,\n message: issue.message,\n });\n if (authenticationError) {\n return authenticationError;\n }\n }\n return undefined;\n}\n\n/** Converts the public error to safe serializable exact-attempt evidence. */\nexport function createArcaAuthenticationEvidence(\n error: ArcaAuthenticationError\n): ArcaAuthenticationEvidence {\n return {\n code: \"ARCA_AUTHENTICATION_ERROR\",\n reason: error.reason,\n ...(error.providerCode === undefined\n ? {}\n : { providerCode: error.providerCode }),\n };\n}\n\n/** Recreates the throwable contract from safe exact-attempt evidence. */\nexport function createArcaAuthenticationErrorFromEvidence(\n evidence: ArcaAuthenticationEvidence,\n context: AuthenticationContext\n): ArcaAuthenticationError {\n return new ArcaAuthenticationError(\n formatAuthenticationMessage(\n context.service,\n context.operation,\n evidence.reason\n ),\n {\n reason: evidence.reason,\n service: context.service,\n operation: context.operation,\n ...(evidence.providerCode === undefined\n ? {}\n : { providerCode: evidence.providerCode }),\n }\n );\n}\n\n/** Runs one convenience operation and permits one proven-safe forced refresh. */\nexport async function executeWithAuthenticationRecovery<T>(\n options: AuthenticationRecoveryOptions<T>\n): Promise<T> {\n const executeAttempt = async (forceRefresh?: boolean): Promise<T> => {\n try {\n return await options.execute(forceRefresh);\n } catch (error) {\n throw classifyArcaAuthenticationError(error, options) ?? error;\n }\n };\n\n try {\n return await executeAttempt(options.forceRefresh);\n } catch (error) {\n const allowRetry =\n options.allowRetry !== false && options.forceRefresh !== true;\n if (!(allowRetry && isArcaAuthenticationError(error))) {\n throw error;\n }\n return executeAttempt(true);\n }\n}\n\nfunction getStructuredAuthenticationReason(\n service: ArcaServiceName,\n providerCode: string | number | undefined\n): ArcaAuthenticationReason | undefined {\n if (service !== \"wsfe\" || providerCode === undefined) {\n return undefined;\n }\n return WSFE_AUTHENTICATION_CODES[String(providerCode).trim()];\n}\n\nfunction getTextAuthenticationReason(\n message: string | undefined\n): ArcaAuthenticationReason | undefined {\n if (!message) {\n return undefined;\n }\n const normalized = normalizeAuthenticationText(message);\n\n if (\n includesWholePhrase(\n normalized,\n \"no aparecio cuit en lista de relaciones\"\n ) ||\n includesWholePhrase(normalized, \"cuit representada no incluida en token\")\n ) {\n return \"missing_relationship\";\n }\n if (includesWholePhrase(normalized, \"computador no autorizado\")) {\n return \"unauthorized_computer\";\n }\n if (\n includesWholePhrase(normalized, \"validaciondetoken\") ||\n includesWholePhrase(normalized, \"token vencido\") ||\n includesWholePhrase(normalized, \"no se corresponden token y firma\")\n ) {\n return \"invalid_token\";\n }\n if (\n includesWholePhrase(normalized, \"no autorizado a acceder al servicio\") ||\n includesWholePhrase(normalized, \"no autorizado a acceder a los servicios\")\n ) {\n return \"authentication_rejected\";\n }\n return undefined;\n}\n\nfunction normalizeAuthenticationText(value: string): string {\n return value\n .normalize(\"NFD\")\n .replace(/\\p{Diacritic}/gu, \"\")\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction includesWholePhrase(value: string, phrase: string): boolean {\n let searchFrom = 0;\n while (searchFrom <= value.length - phrase.length) {\n const index = value.indexOf(phrase, searchFrom);\n if (index < 0) {\n return false;\n }\n const before = value[index - 1];\n const after = value[index + phrase.length];\n if (!(isWordCharacter(before) || isWordCharacter(after))) {\n return true;\n }\n searchFrom = index + phrase.length;\n }\n return false;\n}\n\nfunction isWordCharacter(value: string | undefined): boolean {\n return value !== undefined && /[a-z0-9]/.test(value);\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 const normalized = providerCode.trim();\n return normalized || undefined;\n }\n return undefined;\n}\n\nfunction formatAuthenticationMessage(\n service: ArcaServiceName,\n operation: string,\n reason: ArcaAuthenticationReason\n): string {\n const descriptions: Record<ArcaAuthenticationReason, string> = {\n invalid_token: \"the token or signature was rejected\",\n unauthorized_computer: \"the certificate or computer is not authorized\",\n missing_relationship: \"the represented taxpayer relationship is missing\",\n authentication_rejected: \"the service denied authenticated access\",\n };\n return `ARCA rejected authentication for ${service}.${operation}: ${descriptions[reason]}.`;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/authentication.ts"],"sourcesContent":["import {\n ArcaAuthenticationError,\n type ArcaAuthenticationReason,\n ArcaServiceError,\n ArcaSoapFaultError,\n isArcaAuthenticationError,\n} from \"../errors\";\nimport type {\n ArcaAuthenticationEvidence,\n ArcaFiscalIssue,\n} from \"../services/fiscal-evidence\";\nimport type { ArcaServiceName } from \"./types\";\n\ntype AuthenticationContext = {\n service: ArcaServiceName;\n operation: string;\n};\n\ntype AuthenticationCandidate = AuthenticationContext & {\n providerCode?: string | number;\n message?: string;\n cause?: unknown;\n};\n\ntype AuthenticationRecoveryOptions<T> = AuthenticationContext & {\n forceRefresh?: boolean;\n allowRetry?: boolean;\n execute(forceRefresh?: boolean): Promise<T>;\n};\n\nconst WSFE_AUTHENTICATION_CODES: Readonly<\n Record<string, ArcaAuthenticationReason>\n> = {\n \"600\": \"invalid_token\",\n \"601\": \"missing_relationship\",\n};\n\n/** Classifies one safe provider code/message pair without inspecting object graphs. */\nexport function classifyArcaAuthenticationCandidate(\n candidate: AuthenticationCandidate\n): ArcaAuthenticationError | undefined {\n const providerCode = normalizeProviderCode(candidate.providerCode);\n const reason =\n getStructuredAuthenticationReason(candidate.service, providerCode) ??\n getTextAuthenticationReason(candidate.message);\n\n if (!reason) {\n return undefined;\n }\n\n return new ArcaAuthenticationError(\n formatAuthenticationMessage(candidate.service, candidate.operation, reason),\n {\n reason,\n service: candidate.service,\n operation: candidate.operation,\n ...(providerCode === undefined ? {} : { providerCode }),\n ...(candidate.cause === undefined ? {} : { cause: candidate.cause }),\n }\n );\n}\n\n/** Classifies supported public ARCA errors while ignoring arbitrary errors and causes. */\nexport function classifyArcaAuthenticationError(\n error: unknown,\n context: AuthenticationContext\n): ArcaAuthenticationError | undefined {\n if (isArcaAuthenticationError(error)) {\n return error;\n }\n\n if (error instanceof ArcaSoapFaultError) {\n return classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: error.faultCode,\n message: error.message,\n cause: error,\n });\n }\n\n if (error instanceof ArcaServiceError) {\n const issueError = classifyArcaAuthenticationIssues(\n error.issues ?? [],\n context\n );\n if (issueError) {\n return new ArcaAuthenticationError(issueError.message, {\n reason: issueError.reason,\n service: issueError.service,\n operation: issueError.operation,\n ...(issueError.providerCode === undefined\n ? {}\n : { providerCode: issueError.providerCode }),\n cause: error,\n });\n }\n\n return classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: error.serviceCode,\n message: error.message,\n cause: error,\n });\n }\n\n return undefined;\n}\n\n/** Classifies structured service issues in provider order. */\nexport function classifyArcaAuthenticationIssues(\n issues: readonly ArcaFiscalIssue[],\n context: AuthenticationContext\n): ArcaAuthenticationError | undefined {\n for (const issue of issues) {\n const authenticationError = classifyArcaAuthenticationCandidate({\n ...context,\n providerCode: issue.code,\n message: issue.message,\n });\n if (authenticationError) {\n return authenticationError;\n }\n }\n return undefined;\n}\n\n/** Converts the public error to safe serializable exact-attempt evidence. */\nexport function createArcaAuthenticationEvidence(\n error: ArcaAuthenticationError\n): ArcaAuthenticationEvidence {\n return {\n code: \"ARCA_AUTHENTICATION_ERROR\",\n reason: error.reason,\n ...(error.providerCode === undefined\n ? {}\n : { providerCode: error.providerCode }),\n };\n}\n\n/** Recreates the throwable contract from safe exact-attempt evidence. */\nexport function createArcaAuthenticationErrorFromEvidence(\n evidence: ArcaAuthenticationEvidence,\n context: AuthenticationContext\n): ArcaAuthenticationError {\n return new ArcaAuthenticationError(\n formatAuthenticationMessage(\n context.service,\n context.operation,\n evidence.reason\n ),\n {\n reason: evidence.reason,\n service: context.service,\n operation: context.operation,\n ...(evidence.providerCode === undefined\n ? {}\n : { providerCode: evidence.providerCode }),\n }\n );\n}\n\n/** Runs one convenience operation and permits one proven-safe forced refresh. */\nexport async function executeWithAuthenticationRecovery<T>(\n options: AuthenticationRecoveryOptions<T>\n): Promise<T> {\n const executeAttempt = async (forceRefresh?: boolean): Promise<T> => {\n try {\n return await options.execute(forceRefresh);\n } catch (error) {\n throw classifyArcaAuthenticationError(error, options) ?? error;\n }\n };\n\n try {\n return await executeAttempt(options.forceRefresh);\n } catch (error) {\n const allowRetry =\n options.allowRetry !== false && options.forceRefresh !== true;\n if (!(allowRetry && isArcaAuthenticationError(error))) {\n throw error;\n }\n return executeAttempt(true);\n }\n}\n\nfunction getStructuredAuthenticationReason(\n service: ArcaServiceName,\n providerCode: string | number | undefined\n): ArcaAuthenticationReason | undefined {\n if (service !== \"wsfe\" || providerCode === undefined) {\n return undefined;\n }\n return WSFE_AUTHENTICATION_CODES[String(providerCode).trim()];\n}\n\nfunction getTextAuthenticationReason(\n message: string | undefined\n): ArcaAuthenticationReason | undefined {\n if (!message) {\n return undefined;\n }\n const normalized = normalizeAuthenticationText(message);\n\n if (\n includesWholePhrase(\n normalized,\n \"no aparecio cuit en lista de relaciones\"\n ) ||\n includesWholePhrase(normalized, \"cuit representada no incluida en token\")\n ) {\n return \"missing_relationship\";\n }\n if (includesWholePhrase(normalized, \"computador no autorizado\")) {\n return \"unauthorized_computer\";\n }\n if (\n includesWholePhrase(normalized, \"validaciondetoken\") ||\n includesWholePhrase(normalized, \"token vencido\") ||\n includesWholePhrase(normalized, \"no se corresponden token y firma\")\n ) {\n return \"invalid_token\";\n }\n if (\n includesWholePhrase(normalized, \"no autorizado a acceder al servicio\") ||\n includesWholePhrase(normalized, \"no autorizado a acceder a los servicios\")\n ) {\n return \"authentication_rejected\";\n }\n return undefined;\n}\n\nfunction normalizeAuthenticationText(value: string): string {\n return value\n .normalize(\"NFD\")\n .replace(/\\p{Diacritic}/gu, \"\")\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction includesWholePhrase(value: string, phrase: string): boolean {\n let searchFrom = 0;\n while (searchFrom <= value.length - phrase.length) {\n const index = value.indexOf(phrase, searchFrom);\n if (index < 0) {\n return false;\n }\n const before = value[index - 1];\n const after = value[index + phrase.length];\n if (!(isWordCharacter(before) || isWordCharacter(after))) {\n return true;\n }\n searchFrom = index + phrase.length;\n }\n return false;\n}\n\nfunction isWordCharacter(value: string | undefined): boolean {\n return value !== undefined && /[a-z0-9]/.test(value);\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 const normalized = providerCode.trim();\n return normalized || undefined;\n }\n return undefined;\n}\n\nfunction formatAuthenticationMessage(\n service: ArcaServiceName,\n operation: string,\n reason: ArcaAuthenticationReason\n): string {\n const descriptions: Record<ArcaAuthenticationReason, string> = {\n invalid_token: \"the token or signature was rejected\",\n unauthorized_computer: \"the certificate or computer is not authorized\",\n missing_relationship: \"the represented taxpayer relationship is missing\",\n authentication_rejected: \"the service denied authenticated access\",\n };\n return `ARCA rejected authentication for ${service}.${operation}: ${descriptions[reason]}.`;\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { A as ArcaClient } from './client-BZxeScuK.js';
|
|
2
|
+
import { A as ArcaClientOptions, a as ArcaClientConfig } from './types-r2nf55gh.js';
|
|
3
|
+
import { W as WsaaAuthModule } from './index-D8LGFvxV.js';
|
|
4
|
+
import './padron.js';
|
|
5
|
+
import './decimal-B0HtrMFY.js';
|
|
6
|
+
import './fiscal-evidence-B1Qe6XMg.js';
|
|
7
|
+
import './constants.js';
|
|
8
|
+
import './wsmtxca.js';
|
|
9
|
+
|
|
10
|
+
/** Minimal writable surface the CLI needs. Tests pass a string collector. */
|
|
11
|
+
type CliOutputStream = {
|
|
12
|
+
write(chunk: string): void;
|
|
13
|
+
isTTY?: boolean;
|
|
14
|
+
};
|
|
15
|
+
/** Minimal readable surface the CLI needs for interactive prompts. */
|
|
16
|
+
type CliInputStream = NodeJS.ReadableStream & {
|
|
17
|
+
isTTY?: boolean;
|
|
18
|
+
};
|
|
19
|
+
/** Everything the CLI touches outside itself. Injected so tests stay offline. */
|
|
20
|
+
type CliIo = {
|
|
21
|
+
stdout: CliOutputStream;
|
|
22
|
+
stderr: CliOutputStream;
|
|
23
|
+
stdin: CliInputStream;
|
|
24
|
+
env: Record<string, string | undefined>;
|
|
25
|
+
cwd: string;
|
|
26
|
+
/** Where the WSAA ticket is cached between runs. Never holds anything else. */
|
|
27
|
+
cacheDir: string;
|
|
28
|
+
now(): Date;
|
|
29
|
+
/**
|
|
30
|
+
* Puts text in the system clipboard, answering whether it got there. Nothing
|
|
31
|
+
* else in the CLI touches the clipboard, and a `false` is never an error.
|
|
32
|
+
*/
|
|
33
|
+
copyToClipboard(text: string): Promise<boolean>;
|
|
34
|
+
createClient(options: ArcaClientOptions): ArcaClient;
|
|
35
|
+
createAuth(config: ArcaClientConfig): WsaaAuthModule;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** Runs one CLI invocation and returns its exit code. Never calls `exit`. */
|
|
39
|
+
declare function run(argv: readonly string[], io: CliIo): Promise<number>;
|
|
40
|
+
/**
|
|
41
|
+
* Entry point used by `bin/facturas.mjs`. Sets the process exit code. Nothing
|
|
42
|
+
* reaches node's unhandled rejection handler from here: whatever a command
|
|
43
|
+
* failed to catch comes out as the SDK's safe message, never a stack or a PEM.
|
|
44
|
+
*/
|
|
45
|
+
declare function main(argv?: readonly string[], io?: CliIo): Promise<void>;
|
|
46
|
+
/** The real world: real streams, real env, the real SDK. */
|
|
47
|
+
declare function createDefaultIo(): CliIo;
|
|
48
|
+
|
|
49
|
+
export { createDefaultIo, main, run };
|