@lapyme/arca 0.1.0 → 0.2.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.
@@ -8,12 +8,11 @@ type ArcaServiceTarget = Exclude<ArcaServiceName, "wsaa">;
8
8
  type ArcaPadronServiceName = Extract<ArcaServiceTarget, "padron-a5" | "padron-a13">;
9
9
  /** WSAA service identifiers used for authentication scoping. */
10
10
  type ArcaWsaaServiceId = "wsfe" | "wsmtxca" | "ws_sr_constancia_inscripcion" | "ws_sr_padron_a13";
11
- /** WSAA credential cache strategy. Disk mode requires a `directory`. */
12
- type ArcaWsaaCacheConfig = {
13
- mode?: "memory";
14
- } | {
15
- mode: "disk";
16
- directory: string;
11
+ type ArcaLogLevel = "debug" | "info" | "warn" | "error";
12
+ type ArcaLoggerConfig = {
13
+ disabled?: boolean;
14
+ level?: ArcaLogLevel;
15
+ log?: (level: ArcaLogLevel, message: string, ...args: unknown[]) => void;
17
16
  };
18
17
  /** Configuration required to create an ARCA client. */
19
18
  type ArcaClientConfig = {
@@ -21,9 +20,10 @@ type ArcaClientConfig = {
21
20
  certificatePem: string;
22
21
  privateKeyPem: string;
23
22
  environment: ArcaEnvironment;
24
- wsaa?: {
25
- cache?: ArcaWsaaCacheConfig;
26
- };
23
+ timeout?: number;
24
+ retries?: number;
25
+ retryDelay?: number;
26
+ logger?: ArcaLoggerConfig;
27
27
  };
28
28
  /** Credentials returned by a WSAA login. */
29
29
  type ArcaAuthCredentials = {
@@ -50,4 +50,4 @@ type ArcaSoapExecutionOptions<TBody> = {
50
50
  body: TBody;
51
51
  };
52
52
 
53
- export type { ArcaClientConfig as A, ArcaEnvironment as a, ArcaAuthCredentials as b, ArcaAuthOptions as c, ArcaPadronServiceName as d, ArcaRepresentedTaxId as e, ArcaServiceName as f, ArcaServiceTarget as g, ArcaWsaaCacheConfig as h, ArcaWsaaServiceId as i, ArcaSoapExecutionOptions as j, ArcaSoapResponse as k };
53
+ export type { ArcaClientConfig as A, ArcaEnvironment as a, ArcaAuthCredentials as b, ArcaAuthOptions as c, ArcaLogLevel as d, ArcaLoggerConfig as e, ArcaPadronServiceName as f, ArcaRepresentedTaxId as g, ArcaServiceName as h, ArcaServiceTarget as i, ArcaWsaaServiceId as j, ArcaSoapExecutionOptions as k, ArcaSoapResponse as l };
package/dist/types.d.ts CHANGED
@@ -1 +1 @@
1
- export { b as ArcaAuthCredentials, c as ArcaAuthOptions, A as ArcaClientConfig, a as ArcaEnvironment, d as ArcaPadronServiceName, e as ArcaRepresentedTaxId, f as ArcaServiceName, g as ArcaServiceTarget, h as ArcaWsaaCacheConfig, i as ArcaWsaaServiceId } from './types-DWsYue4B.js';
1
+ export { b as ArcaAuthCredentials, c as ArcaAuthOptions, A as ArcaClientConfig, a as ArcaEnvironment, d as ArcaLogLevel, e as ArcaLoggerConfig, f as ArcaPadronServiceName, g as ArcaRepresentedTaxId, h as ArcaServiceName, i as ArcaServiceTarget, j as ArcaWsaaServiceId } from './types-SloiIQkT.js';
package/dist/wsfe.d.ts CHANGED
@@ -1,13 +1,15 @@
1
- import { W as WsaaAuthModule, S as SoapTransport } from './index-vWZOjFDO.js';
2
- import { A as ArcaClientConfig } from './types-DWsYue4B.js';
1
+ import { A as ArcaClientConfig } from './types-SloiIQkT.js';
2
+ import { W as WsaaAuthModule, S as SoapTransport } from './index-BLq3d6xg.js';
3
3
 
4
+ /** Accepted public date inputs for WSFE request fields. */
5
+ type WsfeDateInput = `${number}${number}${number}${number}-${number}${number}-${number}${number}` | `${number}${number}${number}${number}${number}${number}${number}${number}`;
4
6
  /** An associated voucher referenced by a WSFE invoice request. */
5
7
  type WsfeAssociatedVoucher = {
6
8
  type: number;
7
9
  salesPoint: number;
8
10
  number: number;
9
11
  taxId?: string;
10
- voucherDate?: string;
12
+ voucherDate?: WsfeDateInput;
11
13
  };
12
14
  /** A tax (tributo) item in a WSFE invoice request. */
13
15
  type WsfeTax = {
@@ -42,7 +44,7 @@ type WsfeVoucherInput = {
42
44
  documentType: number;
43
45
  documentNumber: number;
44
46
  receiverVatConditionId?: number;
45
- voucherDate: string;
47
+ voucherDate: WsfeDateInput;
46
48
  totalAmount: number;
47
49
  nonTaxableAmount: number;
48
50
  netAmount: number;
@@ -51,9 +53,9 @@ type WsfeVoucherInput = {
51
53
  vatAmount: number;
52
54
  currencyId: string;
53
55
  exchangeRate: number;
54
- serviceStartDate?: string;
55
- serviceEndDate?: string;
56
- paymentDueDate?: string;
56
+ serviceStartDate?: WsfeDateInput;
57
+ serviceEndDate?: WsfeDateInput;
58
+ paymentDueDate?: WsfeDateInput;
57
59
  associatedVouchers?: WsfeAssociatedVoucher[];
58
60
  taxes?: WsfeTax[];
59
61
  vatRates?: WsfeVatRate[];
@@ -86,6 +88,26 @@ type WsfeVoucherInfo = {
86
88
  caeExpiry?: string;
87
89
  raw: Record<string, unknown>;
88
90
  };
91
+ type WsfeCatalogEntry = {
92
+ id: number;
93
+ description: string;
94
+ };
95
+ type WsfeCurrencyType = {
96
+ id: string;
97
+ description: string;
98
+ validFrom: string;
99
+ validTo: string;
100
+ };
101
+ type WsfeServerStatus = {
102
+ appServer: string;
103
+ dbServer: string;
104
+ authServer: string;
105
+ };
106
+ type WsfeQuotation = {
107
+ currencyId: string;
108
+ rate: number;
109
+ date: string;
110
+ };
89
111
  /** WSFE electronic invoicing service. */
90
112
  type WsfeService = {
91
113
  /** Authorizes a new voucher by fetching the next number and requesting a CAE. */
@@ -94,6 +116,16 @@ type WsfeService = {
94
116
  data: WsfeVoucherInput;
95
117
  }): Promise<WsfeAuthorizationResult>;
96
118
  /** Returns the next available voucher number for the given sales point and type. */
119
+ getNextVoucherNumber(input: {
120
+ representedTaxId?: number | string;
121
+ salesPoint: number;
122
+ voucherType: number;
123
+ forceAuthRefresh?: boolean;
124
+ }): Promise<number>;
125
+ /**
126
+ * @deprecated Use `getNextVoucherNumber()` instead.
127
+ * Returns the next available voucher number, not the last authorized one.
128
+ */
97
129
  getLastVoucher(input: {
98
130
  representedTaxId?: number | string;
99
131
  salesPoint: number;
@@ -105,6 +137,49 @@ type WsfeService = {
105
137
  representedTaxId?: number | string;
106
138
  forceAuthRefresh?: boolean;
107
139
  }): Promise<WsfeSalesPoint[]>;
140
+ /** Lists voucher types accepted by WSFE. */
141
+ getVoucherTypes(input: {
142
+ representedTaxId?: number | string;
143
+ forceAuthRefresh?: boolean;
144
+ }): Promise<WsfeCatalogEntry[]>;
145
+ /** Lists document types accepted by WSFE. */
146
+ getDocumentTypes(input: {
147
+ representedTaxId?: number | string;
148
+ forceAuthRefresh?: boolean;
149
+ }): Promise<WsfeCatalogEntry[]>;
150
+ /** Lists concept types accepted by WSFE. */
151
+ getConceptTypes(input: {
152
+ representedTaxId?: number | string;
153
+ forceAuthRefresh?: boolean;
154
+ }): Promise<WsfeCatalogEntry[]>;
155
+ /** Lists supported currency types. */
156
+ getCurrencyTypes(input: {
157
+ representedTaxId?: number | string;
158
+ forceAuthRefresh?: boolean;
159
+ }): Promise<WsfeCurrencyType[]>;
160
+ /** Lists VAT rates accepted by WSFE. */
161
+ getVatRates(input: {
162
+ representedTaxId?: number | string;
163
+ forceAuthRefresh?: boolean;
164
+ }): Promise<WsfeCatalogEntry[]>;
165
+ /** Lists tax types accepted by WSFE. */
166
+ getTaxTypes(input: {
167
+ representedTaxId?: number | string;
168
+ forceAuthRefresh?: boolean;
169
+ }): Promise<WsfeCatalogEntry[]>;
170
+ /** Lists optional field types accepted by WSFE. */
171
+ getOptionalTypes(input: {
172
+ representedTaxId?: number | string;
173
+ forceAuthRefresh?: boolean;
174
+ }): Promise<WsfeCatalogEntry[]>;
175
+ /** Reports WSFE backend status without requiring taxpayer authorization. */
176
+ getServerStatus(): Promise<WsfeServerStatus>;
177
+ /** Returns the exchange rate for a given currency. */
178
+ getQuotation(input: {
179
+ currencyId: string;
180
+ representedTaxId?: number | string;
181
+ forceAuthRefresh?: boolean;
182
+ }): Promise<WsfeQuotation>;
108
183
  /** Retrieves details for a specific voucher. Returns `null` if not found. */
109
184
  getVoucherInfo(input: {
110
185
  representedTaxId?: number | string;
@@ -121,4 +196,4 @@ type CreateWsfeServiceOptions = {
121
196
  /** Creates a WSFE service instance wired with authentication and SOAP transport. */
122
197
  declare function createWsfeService(options: CreateWsfeServiceOptions): WsfeService;
123
198
 
124
- export { type CreateWsfeServiceOptions, type WsfeAssociatedVoucher, type WsfeAuthorizationResult, type WsfeBuyer, type WsfeOptionalField, type WsfeSalesPoint, type WsfeService, type WsfeTax, type WsfeVatRate, type WsfeVoucherInfo, type WsfeVoucherInput, createWsfeService };
199
+ export { type CreateWsfeServiceOptions, type WsfeAssociatedVoucher, type WsfeAuthorizationResult, type WsfeBuyer, type WsfeCatalogEntry, type WsfeCurrencyType, type WsfeDateInput, type WsfeOptionalField, type WsfeQuotation, type WsfeSalesPoint, type WsfeServerStatus, type WsfeService, type WsfeTax, type WsfeVatRate, type WsfeVoucherInfo, type WsfeVoucherInput, createWsfeService };
package/dist/wsfe.js CHANGED
@@ -7,6 +7,14 @@ var ArcaError = class extends Error {
7
7
  this.code = code;
8
8
  }
9
9
  };
10
+ var ArcaInputError = class extends ArcaError {
11
+ name = "ArcaInputError";
12
+ detail;
13
+ constructor(message, options) {
14
+ super(message, "ARCA_INPUT_ERROR", options);
15
+ this.detail = options?.detail;
16
+ }
17
+ };
10
18
  var ArcaServiceError = class extends ArcaError {
11
19
  name = "ArcaServiceError";
12
20
  serviceCode;
@@ -20,43 +28,68 @@ var ArcaServiceError = class extends ArcaError {
20
28
 
21
29
  // src/services/wsfe.ts
22
30
  function createWsfeService(options) {
23
- async function getLastVoucher({
24
- representedTaxId,
25
- salesPoint,
26
- voucherType,
27
- forceAuthRefresh
28
- }) {
31
+ async function executeWsfeAuthenticatedOperation(operation, input, body = {}) {
29
32
  const auth = await options.auth.login("wsfe", {
30
- representedTaxId,
31
- forceRefresh: forceAuthRefresh
33
+ representedTaxId: input.representedTaxId,
34
+ forceRefresh: input.forceAuthRefresh
32
35
  });
33
36
  const response = await options.soap.execute({
34
37
  service: "wsfe",
35
- operation: "FECompUltimoAutorizado",
38
+ operation,
36
39
  body: {
37
40
  Auth: createWsfeAuth(
38
- representedTaxId ?? options.config.taxId,
41
+ input.representedTaxId ?? options.config.taxId,
39
42
  auth.token,
40
43
  auth.sign
41
44
  ),
42
- PtoVta: salesPoint,
43
- CbteTipo: voucherType
45
+ ...body
44
46
  }
45
47
  });
46
- const result = unwrapWsfeOperationResult(
48
+ return unwrapWsfeOperationResult(operation, response.result);
49
+ }
50
+ async function executeWsfeOperation(operation, body = {}) {
51
+ const response = await options.soap.execute({
52
+ service: "wsfe",
53
+ operation,
54
+ body
55
+ });
56
+ return unwrapWsfeOperationResult(operation, response.result);
57
+ }
58
+ async function getNextVoucherNumber({
59
+ representedTaxId,
60
+ salesPoint,
61
+ voucherType,
62
+ forceAuthRefresh
63
+ }) {
64
+ const result = await executeWsfeAuthenticatedOperation(
47
65
  "FECompUltimoAutorizado",
48
- response.result
66
+ {
67
+ representedTaxId,
68
+ forceAuthRefresh
69
+ },
70
+ {
71
+ PtoVta: salesPoint,
72
+ CbteTipo: voucherType
73
+ }
49
74
  );
50
75
  return Number(result.CbteNro ?? 0) + 1;
51
76
  }
77
+ async function getWsfeCatalog(operation, resultKey, input) {
78
+ const result = await executeWsfeAuthenticatedOperation(operation, {
79
+ representedTaxId: input.representedTaxId,
80
+ forceAuthRefresh: input.forceAuthRefresh
81
+ });
82
+ return getWsfeResultEntries(result, resultKey).map(mapWsfeCatalogEntry);
83
+ }
52
84
  return {
53
85
  async createNextVoucher({ representedTaxId, data }) {
54
- const voucherNumber = await getLastVoucher({
86
+ const normalizedInput = normalizeWsfeVoucherInput(data);
87
+ const voucherNumber = await getNextVoucherNumber({
55
88
  representedTaxId,
56
- salesPoint: data.salesPoint,
57
- voucherType: data.voucherType
89
+ salesPoint: normalizedInput.salesPoint,
90
+ voucherType: normalizedInput.voucherType
58
91
  });
59
- const requestData = mapWsfeVoucherInput(data, voucherNumber);
92
+ const requestData = mapWsfeVoucherInput(normalizedInput, voucherNumber);
60
93
  const auth = await options.auth.login("wsfe", { representedTaxId });
61
94
  const response = await options.soap.execute({
62
95
  service: "wsfe",
@@ -70,8 +103,8 @@ function createWsfeService(options) {
70
103
  FeCAEReq: {
71
104
  FeCabReq: {
72
105
  CantReg: 1,
73
- PtoVta: data.salesPoint,
74
- CbteTipo: data.voucherType
106
+ PtoVta: normalizedInput.salesPoint,
107
+ CbteTipo: normalizedInput.voucherType
75
108
  },
76
109
  FeDetReq: {
77
110
  FECAEDetRequest: requestData
@@ -99,61 +132,89 @@ function createWsfeService(options) {
99
132
  raw: result
100
133
  };
101
134
  },
102
- getLastVoucher,
135
+ getNextVoucherNumber,
136
+ getLastVoucher(input) {
137
+ return getNextVoucherNumber(input);
138
+ },
103
139
  async getSalesPoints({ representedTaxId, forceAuthRefresh }) {
104
- const auth = await options.auth.login("wsfe", {
105
- representedTaxId,
106
- forceRefresh: forceAuthRefresh
107
- });
108
- const response = await options.soap.execute({
109
- service: "wsfe",
110
- operation: "FEParamGetPtosVenta",
111
- body: {
112
- Auth: createWsfeAuth(
113
- representedTaxId ?? options.config.taxId,
114
- auth.token,
115
- auth.sign
116
- )
117
- }
118
- });
119
- const result = unwrapWsfeOperationResult(
140
+ const result = await executeWsfeAuthenticatedOperation(
120
141
  "FEParamGetPtosVenta",
121
- response.result
142
+ {
143
+ representedTaxId,
144
+ forceAuthRefresh
145
+ }
122
146
  );
123
- const resultGet = result.ResultGet;
124
- const rawPoints = resultGet?.PtoVenta;
147
+ const rawPoints = result.ResultGet?.PtoVenta;
125
148
  if (!rawPoints) {
126
149
  return [];
127
150
  }
128
151
  const entries = Array.isArray(rawPoints) ? rawPoints : [rawPoints];
129
152
  return entries.map(mapWsfeSalesPoint);
130
153
  },
154
+ getVoucherTypes(input) {
155
+ return getWsfeCatalog("FEParamGetTiposCbte", "CbteTipo", input);
156
+ },
157
+ getDocumentTypes(input) {
158
+ return getWsfeCatalog("FEParamGetTiposDoc", "DocTipo", input);
159
+ },
160
+ getConceptTypes(input) {
161
+ return getWsfeCatalog("FEParamGetTiposConcepto", "ConceptoTipo", input);
162
+ },
163
+ async getCurrencyTypes({ representedTaxId, forceAuthRefresh }) {
164
+ const result = await executeWsfeAuthenticatedOperation(
165
+ "FEParamGetTiposMonedas",
166
+ {
167
+ representedTaxId,
168
+ forceAuthRefresh
169
+ }
170
+ );
171
+ return getWsfeResultEntries(result, "Moneda").map(mapWsfeCurrencyType);
172
+ },
173
+ getVatRates(input) {
174
+ return getWsfeCatalog("FEParamGetTiposIva", "IvaTipo", input);
175
+ },
176
+ getTaxTypes(input) {
177
+ return getWsfeCatalog("FEParamGetTiposTributos", "TributoTipo", input);
178
+ },
179
+ getOptionalTypes(input) {
180
+ return getWsfeCatalog("FEParamGetTiposOpcional", "OpcionalTipo", input);
181
+ },
182
+ async getServerStatus() {
183
+ const result = await executeWsfeOperation("FEDummy");
184
+ return mapWsfeServerStatus(result);
185
+ },
186
+ async getQuotation({ currencyId, representedTaxId, forceAuthRefresh }) {
187
+ const result = await executeWsfeAuthenticatedOperation(
188
+ "FEParamGetCotizacion",
189
+ {
190
+ representedTaxId,
191
+ forceAuthRefresh
192
+ },
193
+ {
194
+ MonId: currencyId
195
+ }
196
+ );
197
+ const raw = result.ResultGet ?? {};
198
+ return mapWsfeQuotation(raw);
199
+ },
131
200
  async getVoucherInfo({
132
201
  representedTaxId,
133
202
  number,
134
203
  salesPoint,
135
204
  voucherType
136
205
  }) {
137
- const auth = await options.auth.login("wsfe", { representedTaxId });
138
- const response = await options.soap.execute({
139
- service: "wsfe",
140
- operation: "FECompConsultar",
141
- body: {
142
- Auth: createWsfeAuth(
143
- representedTaxId ?? options.config.taxId,
144
- auth.token,
145
- auth.sign
146
- ),
206
+ const result = await executeWsfeAuthenticatedOperation(
207
+ "FECompConsultar",
208
+ {
209
+ representedTaxId
210
+ },
211
+ {
147
212
  FeCompConsReq: {
148
213
  CbteNro: number,
149
214
  PtoVta: salesPoint,
150
215
  CbteTipo: voucherType
151
216
  }
152
217
  }
153
- });
154
- const result = unwrapWsfeOperationResult(
155
- "FECompConsultar",
156
- response.result
157
218
  );
158
219
  const raw = result.ResultGet ?? null;
159
220
  if (!raw) {
@@ -200,8 +261,8 @@ function mapWsfeVoucherInput(input, voucherNumber) {
200
261
  Tipo: v.type,
201
262
  PtoVta: v.salesPoint,
202
263
  Nro: v.number,
203
- ...v.taxId !== void 0 ? { Cuit: v.taxId } : {},
204
- ...v.voucherDate !== void 0 ? { CbteFch: v.voucherDate } : {}
264
+ ...v.taxId === void 0 ? {} : { Cuit: v.taxId },
265
+ ...v.voucherDate === void 0 ? {} : { CbteFch: v.voucherDate }
205
266
  }))
206
267
  };
207
268
  }
@@ -209,7 +270,7 @@ function mapWsfeVoucherInput(input, voucherNumber) {
209
270
  data.Tributos = {
210
271
  Tributo: input.taxes.map((t) => ({
211
272
  Id: t.id,
212
- ...t.description !== void 0 ? { Desc: t.description } : {},
273
+ ...t.description === void 0 ? {} : { Desc: t.description },
213
274
  BaseImp: t.baseAmount,
214
275
  Alic: t.rate,
215
276
  Importe: t.amount
@@ -244,25 +305,144 @@ function mapWsfeVoucherInput(input, voucherNumber) {
244
305
  }
245
306
  return data;
246
307
  }
308
+ function normalizeWsfeVoucherInput(input) {
309
+ const {
310
+ voucherDate,
311
+ serviceStartDate,
312
+ serviceEndDate,
313
+ paymentDueDate,
314
+ associatedVouchers,
315
+ ...rest
316
+ } = input;
317
+ return {
318
+ ...rest,
319
+ voucherDate: normalizeWsfeDateInput(voucherDate, "voucherDate"),
320
+ ...serviceStartDate === void 0 ? {} : {
321
+ serviceStartDate: normalizeWsfeDateInput(
322
+ serviceStartDate,
323
+ "serviceStartDate"
324
+ )
325
+ },
326
+ ...serviceEndDate === void 0 ? {} : {
327
+ serviceEndDate: normalizeWsfeDateInput(
328
+ serviceEndDate,
329
+ "serviceEndDate"
330
+ )
331
+ },
332
+ ...paymentDueDate === void 0 ? {} : {
333
+ paymentDueDate: normalizeWsfeDateInput(
334
+ paymentDueDate,
335
+ "paymentDueDate"
336
+ )
337
+ },
338
+ ...associatedVouchers === void 0 ? {} : {
339
+ associatedVouchers: associatedVouchers.map((voucher, index) => {
340
+ const { voucherDate: associatedVoucherDate, ...associatedRest } = voucher;
341
+ return {
342
+ ...associatedRest,
343
+ ...associatedVoucherDate === void 0 ? {} : {
344
+ voucherDate: normalizeWsfeDateInput(
345
+ associatedVoucherDate,
346
+ `associatedVouchers[${index}].voucherDate`
347
+ )
348
+ }
349
+ };
350
+ })
351
+ }
352
+ };
353
+ }
354
+ function normalizeWsfeDateInput(value, fieldName) {
355
+ if (typeof value !== "string") {
356
+ throw new ArcaInputError(
357
+ `Invalid WSFE ${fieldName}: expected a YYYY-MM-DD or YYYYMMDD string`,
358
+ {
359
+ detail: { field: fieldName, value }
360
+ }
361
+ );
362
+ }
363
+ const normalizedValue = value.trim();
364
+ const afipMatch = normalizedValue.match(/^(\d{4})(\d{2})(\d{2})$/);
365
+ if (afipMatch) {
366
+ const [, year, month, day] = afipMatch;
367
+ assertValidCalendarDate(year, month, day, fieldName, normalizedValue);
368
+ return normalizedValue;
369
+ }
370
+ const isoMatch = normalizedValue.match(/^(\d{4})-(\d{2})-(\d{2})$/);
371
+ if (isoMatch) {
372
+ const [, year, month, day] = isoMatch;
373
+ assertValidCalendarDate(year, month, day, fieldName, normalizedValue);
374
+ return `${year}${month}${day}`;
375
+ }
376
+ throw new ArcaInputError(
377
+ `Invalid WSFE ${fieldName}: expected a YYYY-MM-DD or YYYYMMDD string`,
378
+ {
379
+ detail: { field: fieldName, value: normalizedValue }
380
+ }
381
+ );
382
+ }
383
+ function assertValidCalendarDate(yearInput, monthInput, dayInput, fieldName, value) {
384
+ const year = Number(yearInput);
385
+ const month = Number(monthInput);
386
+ const day = Number(dayInput);
387
+ const candidate = new Date(Date.UTC(year, month - 1, day));
388
+ if (candidate.getUTCFullYear() !== year || candidate.getUTCMonth() !== month - 1 || candidate.getUTCDate() !== day) {
389
+ throw new ArcaInputError(
390
+ `Invalid WSFE ${fieldName}: received a non-existent calendar date`,
391
+ {
392
+ detail: { field: fieldName, value }
393
+ }
394
+ );
395
+ }
396
+ }
247
397
  function mapWsfeSalesPoint(raw) {
248
398
  const record = raw;
249
399
  return {
250
400
  number: Number(record.Nro ?? 0),
251
- ...record.EmisionTipo !== void 0 ? { emissionType: String(record.EmisionTipo) } : {},
252
- ...record.Bloqueado !== void 0 ? { blocked: String(record.Bloqueado) } : {},
253
- ...record.FchBaja !== void 0 ? { deletedSince: String(record.FchBaja) } : {}
401
+ ...record.EmisionTipo === void 0 ? {} : { emissionType: String(record.EmisionTipo) },
402
+ ...record.Bloqueado === void 0 ? {} : { blocked: String(record.Bloqueado) },
403
+ ...record.FchBaja === void 0 ? {} : { deletedSince: String(record.FchBaja) }
404
+ };
405
+ }
406
+ function mapWsfeCatalogEntry(raw) {
407
+ const record = raw;
408
+ return {
409
+ id: Number(record.Id ?? 0),
410
+ description: String(record.Desc ?? "")
411
+ };
412
+ }
413
+ function mapWsfeCurrencyType(raw) {
414
+ const record = raw;
415
+ return {
416
+ id: String(record.Id ?? ""),
417
+ description: String(record.Desc ?? ""),
418
+ validFrom: String(record.FchDesde ?? ""),
419
+ validTo: String(record.FchHasta ?? "")
420
+ };
421
+ }
422
+ function mapWsfeServerStatus(raw) {
423
+ return {
424
+ appServer: String(raw.AppServer ?? ""),
425
+ dbServer: String(raw.DbServer ?? ""),
426
+ authServer: String(raw.AuthServer ?? "")
427
+ };
428
+ }
429
+ function mapWsfeQuotation(raw) {
430
+ return {
431
+ currencyId: String(raw.MonId ?? ""),
432
+ rate: Number(raw.MonCotiz ?? 0),
433
+ date: String(raw.FchCotiz ?? "")
254
434
  };
255
435
  }
256
436
  function mapWsfeVoucherInfo(raw) {
257
437
  return {
258
438
  voucherNumber: Number(raw.CbteDesde ?? raw.CbteHasta ?? 0),
259
- ...raw.CbteFch !== void 0 ? { voucherDate: String(raw.CbteFch) } : {},
260
- ...raw.PtoVta !== void 0 ? { salesPoint: Number(raw.PtoVta) } : {},
261
- ...raw.CbteTipo !== void 0 ? { voucherType: Number(raw.CbteTipo) } : {},
262
- ...raw.ImpTotal !== void 0 ? { totalAmount: Number(raw.ImpTotal) } : {},
263
- ...raw.Resultado !== void 0 ? { result: String(raw.Resultado) } : {},
264
- ...raw.CAE !== void 0 ? { cae: String(raw.CAE) } : {},
265
- ...raw.CAEFchVto !== void 0 ? { caeExpiry: String(raw.CAEFchVto) } : {},
439
+ ...raw.CbteFch === void 0 ? {} : { voucherDate: String(raw.CbteFch) },
440
+ ...raw.PtoVta === void 0 ? {} : { salesPoint: Number(raw.PtoVta) },
441
+ ...raw.CbteTipo === void 0 ? {} : { voucherType: Number(raw.CbteTipo) },
442
+ ...raw.ImpTotal === void 0 ? {} : { totalAmount: Number(raw.ImpTotal) },
443
+ ...raw.Resultado === void 0 ? {} : { result: String(raw.Resultado) },
444
+ ...raw.CAE === void 0 ? {} : { cae: String(raw.CAE) },
445
+ ...raw.CAEFchVto === void 0 ? {} : { caeExpiry: String(raw.CAEFchVto) },
266
446
  raw
267
447
  };
268
448
  }
@@ -334,6 +514,15 @@ function normalizeWsfeErrors(rawErrors) {
334
514
  };
335
515
  });
336
516
  }
517
+ function getWsfeResultEntries(result, key) {
518
+ const rawEntries = result.ResultGet?.[key];
519
+ if (!rawEntries) {
520
+ return [];
521
+ }
522
+ return (Array.isArray(rawEntries) ? rawEntries : [rawEntries]).map(
523
+ (entry) => entry
524
+ );
525
+ }
337
526
  export {
338
527
  createWsfeService
339
528
  };