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.
Files changed (38) hide show
  1. package/README.md +95 -786
  2. package/bin/facturas.mjs +4 -0
  3. package/dist/{chunk-RCM4NAAG.mjs → chunk-5KCTRQJX.mjs} +83 -284
  4. package/dist/chunk-5KCTRQJX.mjs.map +1 -0
  5. package/dist/{chunk-XNBD5NVL.mjs → chunk-ALH5IPSY.mjs} +2 -57
  6. package/dist/chunk-ALH5IPSY.mjs.map +1 -0
  7. package/dist/{chunk-76WU5BVI.mjs → chunk-GX5ERXT6.mjs} +1 -1
  8. package/dist/chunk-GX5ERXT6.mjs.map +1 -0
  9. package/dist/chunk-LOWV7IF6.mjs +3758 -0
  10. package/dist/chunk-LOWV7IF6.mjs.map +1 -0
  11. package/dist/chunk-LR4M2AMG.mjs +169 -0
  12. package/dist/chunk-LR4M2AMG.mjs.map +1 -0
  13. package/dist/{chunk-4QVFXT35.mjs → chunk-UDX6HLAU.mjs} +1 -17
  14. package/dist/{chunk-4QVFXT35.mjs.map → chunk-UDX6HLAU.mjs.map} +1 -1
  15. package/dist/cli.d.ts +49 -0
  16. package/dist/cli.mjs +2316 -0
  17. package/dist/cli.mjs.map +1 -0
  18. package/dist/client-BZxeScuK.d.ts +521 -0
  19. package/dist/constants.d.ts +1 -1
  20. package/dist/constants.mjs +1 -1
  21. package/dist/{wsfe-DF0jAE2k.d.ts → decimal-B0HtrMFY.d.ts} +9 -66
  22. package/dist/errors.d.ts +2 -2
  23. package/dist/{fiscal-evidence-DBzakqBE.d.ts → fiscal-evidence-B1Qe6XMg.d.ts} +2 -2
  24. package/dist/{index-CVGQyyYM.d.ts → index-D8LGFvxV.d.ts} +1 -1
  25. package/dist/index.d.ts +11 -235
  26. package/dist/index.mjs +21 -2315
  27. package/dist/index.mjs.map +1 -1
  28. package/dist/padron.d.ts +2 -2
  29. package/dist/{types-BiznC1-X.d.ts → types-r2nf55gh.d.ts} +1 -1
  30. package/dist/types.d.ts +1 -1
  31. package/dist/wsfe.d.ts +45 -4
  32. package/dist/wsfe.mjs +6 -4
  33. package/dist/wsmtxca.d.ts +4 -20
  34. package/dist/wsmtxca.mjs +2 -2
  35. package/package.json +5 -1
  36. package/dist/chunk-76WU5BVI.mjs.map +0 -1
  37. package/dist/chunk-RCM4NAAG.mjs.map +0 -1
  38. 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-4QVFXT35.mjs.map
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 };