facturas 0.20.4 → 0.21.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/dist/{chunk-B2M64SIK.mjs → chunk-4PSLYA2B.mjs} +2 -2
- package/dist/{chunk-6U4NRHFP.mjs → chunk-FQD2PZXE.mjs} +88 -23
- package/dist/chunk-FQD2PZXE.mjs.map +1 -0
- package/dist/chunk-HLSFMWRT.mjs +38 -0
- package/dist/chunk-HLSFMWRT.mjs.map +1 -0
- package/dist/{chunk-WG6TAMBB.mjs → chunk-HSGTCGUX.mjs} +83 -30
- package/dist/chunk-HSGTCGUX.mjs.map +1 -0
- package/dist/{chunk-NT2A6YMO.mjs → chunk-Q7IURW54.mjs} +12 -1
- package/dist/chunk-Q7IURW54.mjs.map +1 -0
- package/dist/{chunk-UOIZQMA6.mjs → chunk-QHNI4ZIA.mjs} +3 -3
- package/dist/{chunk-CYXS3F34.mjs → chunk-WEEV76IC.mjs} +284 -161
- package/dist/chunk-WEEV76IC.mjs.map +1 -0
- package/dist/cli.d.ts +4 -4
- package/dist/cli.mjs +7 -7
- package/dist/{client-BgWH_jKT.d.ts → client-CP1PQD_j.d.ts} +2 -2
- package/dist/errors.d.ts +2 -2
- package/dist/errors.mjs +3 -1
- package/dist/{fiscal-evidence-Bg4o9nxt.d.ts → fiscal-evidence-Cp-ntg5p.d.ts} +20 -4
- package/dist/{index-DAC3edtw.d.ts → index-abxokwjJ.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.mjs +32 -13
- package/dist/index.mjs.map +1 -1
- package/dist/padron.d.ts +2 -2
- package/dist/padron.mjs +3 -3
- package/dist/{types-Su7QwloQ.d.ts → types-DhrPnj3r.d.ts} +12 -3
- package/dist/types.d.ts +1 -1
- package/dist/wsfe.d.ts +3 -3
- package/dist/wsfe.mjs +4 -4
- package/dist/wsmtxca.d.ts +3 -3
- package/dist/wsmtxca.mjs +4 -4
- package/package.json +1 -1
- package/dist/chunk-6U4NRHFP.mjs.map +0 -1
- package/dist/chunk-CYXS3F34.mjs.map +0 -1
- package/dist/chunk-KDLY2XJO.mjs +0 -19
- package/dist/chunk-KDLY2XJO.mjs.map +0 -1
- package/dist/chunk-NT2A6YMO.mjs.map +0 -1
- package/dist/chunk-WG6TAMBB.mjs.map +0 -1
- /package/dist/{chunk-B2M64SIK.mjs.map → chunk-4PSLYA2B.mjs.map} +0 -0
- /package/dist/{chunk-UOIZQMA6.mjs.map → chunk-QHNI4ZIA.mjs.map} +0 -0
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "./chunk-C2KX652X.mjs";
|
|
11
11
|
import {
|
|
12
12
|
createPadronService
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QHNI4ZIA.mjs";
|
|
14
14
|
import {
|
|
15
15
|
arcaMinorUnitsToNumber,
|
|
16
16
|
assertArcaMinorUnits,
|
|
@@ -22,22 +22,23 @@ import {
|
|
|
22
22
|
roundHalfEvenRatio,
|
|
23
23
|
serializeArcaExchangeRate,
|
|
24
24
|
toIsoDate
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-FQD2PZXE.mjs";
|
|
26
26
|
import {
|
|
27
27
|
createWsmtxcaService
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-HSGTCGUX.mjs";
|
|
29
29
|
import {
|
|
30
30
|
ArcaConfigurationError,
|
|
31
31
|
ArcaError,
|
|
32
32
|
ArcaInputError,
|
|
33
33
|
ArcaInvalidSoapResponseError,
|
|
34
|
+
ArcaLockTimeoutError,
|
|
34
35
|
ArcaServiceError,
|
|
35
36
|
ArcaSoapFaultError,
|
|
36
37
|
ArcaTransportError,
|
|
37
38
|
createResponseBodyDiagnostic,
|
|
38
39
|
createSafeErrorDiagnostic,
|
|
39
40
|
toArcaSafeErrorMetadata
|
|
40
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-Q7IURW54.mjs";
|
|
41
42
|
|
|
42
43
|
// src/config.ts
|
|
43
44
|
var ARCA_ENVIRONMENTS = ["production", "test"];
|
|
@@ -2701,7 +2702,7 @@ async function withWsaaSessionStoreLock(config, key, service, fn) {
|
|
|
2701
2702
|
if (entered) {
|
|
2702
2703
|
throw error;
|
|
2703
2704
|
}
|
|
2704
|
-
if (error instanceof ArcaConfigurationError) {
|
|
2705
|
+
if (error instanceof ArcaConfigurationError || error instanceof ArcaLockTimeoutError) {
|
|
2705
2706
|
throw error;
|
|
2706
2707
|
}
|
|
2707
2708
|
throw new ArcaConfigurationError(
|
|
@@ -3876,48 +3877,39 @@ async function runOperation(wsfe, operation, input, prepare, options, context, r
|
|
|
3876
3877
|
return await replay(existing);
|
|
3877
3878
|
}
|
|
3878
3879
|
const prepared = withinDateWindow(await prepare(), options);
|
|
3879
|
-
const sequence = {
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
// The sequence belongs to the taxpayer whose numbering ARCA advances.
|
|
3885
|
-
taxId: String(options.representedTaxId ?? context.taxId)
|
|
3886
|
-
};
|
|
3887
|
-
const sequenceRecord = sequenceKey(
|
|
3888
|
-
environment,
|
|
3889
|
-
sequence.taxId,
|
|
3890
|
-
sequence.coordinates.salesPoint,
|
|
3891
|
-
sequence.coordinates.voucherType
|
|
3892
|
-
);
|
|
3880
|
+
const sequence = sequenceOf(environment, taxId, {
|
|
3881
|
+
representedTaxId,
|
|
3882
|
+
salesPoint: prepared.data.salesPoint,
|
|
3883
|
+
voucherType: prepared.data.voucherType
|
|
3884
|
+
});
|
|
3893
3885
|
if (!store.withLock) {
|
|
3894
3886
|
return await claim();
|
|
3895
3887
|
}
|
|
3896
3888
|
return await store.withLock(
|
|
3897
|
-
|
|
3898
|
-
environment,
|
|
3899
|
-
sequence.taxId,
|
|
3900
|
-
sequence.coordinates.salesPoint,
|
|
3901
|
-
sequence.coordinates.voucherType
|
|
3902
|
-
),
|
|
3889
|
+
sequence.lock,
|
|
3903
3890
|
async () => {
|
|
3891
|
+
const prior = await storeCall(() => store.get(key));
|
|
3892
|
+
if (prior !== null) {
|
|
3893
|
+
return await replay(prior, true);
|
|
3894
|
+
}
|
|
3904
3895
|
const barrier = await runSequenceBarrier({
|
|
3905
3896
|
store,
|
|
3906
3897
|
environment,
|
|
3907
3898
|
taxId,
|
|
3908
|
-
sequence:
|
|
3899
|
+
sequence: sequence.marker,
|
|
3909
3900
|
sequenceTaxId: sequence.taxId,
|
|
3910
|
-
coordinates: sequence.coordinates,
|
|
3911
3901
|
select: select ?? (() => wsfe),
|
|
3912
3902
|
options,
|
|
3913
3903
|
supersededBy: idempotencyKey,
|
|
3914
|
-
readNext: () => nextNumber(wsfe, prepared.data, options)
|
|
3904
|
+
readNext: () => nextNumber(wsfe, prepared.data, { ...options, number: void 0 })
|
|
3915
3905
|
});
|
|
3916
3906
|
return "blocked" in barrier ? {
|
|
3917
3907
|
...barrier.blocked,
|
|
3918
3908
|
...requestEvidence(prepared.data, void 0, options)
|
|
3919
3909
|
} : await claim(barrier.reserved);
|
|
3920
|
-
}
|
|
3910
|
+
},
|
|
3911
|
+
// The deadline also bounds the wait: giving up there reserved nothing.
|
|
3912
|
+
{ signal: options.abortSignal }
|
|
3921
3913
|
);
|
|
3922
3914
|
function reservation(number) {
|
|
3923
3915
|
const service = options.service ?? "wsfe";
|
|
@@ -3937,10 +3929,6 @@ async function runOperation(wsfe, operation, input, prepare, options, context, r
|
|
|
3937
3929
|
}
|
|
3938
3930
|
async function claim(reserved) {
|
|
3939
3931
|
const coordinated = store.withLock !== void 0;
|
|
3940
|
-
const prior = coordinated ? await storeCall(() => store.get(key)) : null;
|
|
3941
|
-
if (prior !== null) {
|
|
3942
|
-
return await replay(prior, true);
|
|
3943
|
-
}
|
|
3944
3932
|
const number = options.number ?? reserved ?? await nextNumber(wsfe, prepared.data, options);
|
|
3945
3933
|
const record = reservation(number);
|
|
3946
3934
|
const claimed = {
|
|
@@ -3951,21 +3939,20 @@ async function runOperation(wsfe, operation, input, prepare, options, context, r
|
|
|
3951
3939
|
claimedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3952
3940
|
};
|
|
3953
3941
|
if (coordinated) {
|
|
3954
|
-
await storeCall(
|
|
3942
|
+
await storeCall(
|
|
3943
|
+
() => store.set(sequence.marker, JSON.stringify(claimed))
|
|
3944
|
+
);
|
|
3955
3945
|
}
|
|
3956
3946
|
if (await storeCall(() => store.add(key, JSON.stringify(record)))) {
|
|
3957
|
-
|
|
3958
|
-
|
|
3947
|
+
return await settle2(
|
|
3948
|
+
record,
|
|
3949
|
+
runAuthorization(wsfe, prepared, options, issuer, number, {
|
|
3950
|
+
strangerAtNumber: true
|
|
3951
|
+
}),
|
|
3952
|
+
// Without the lock, a retry of this key may write the number while
|
|
3953
|
+
// this claim is still in flight: its 10016 is not marked.
|
|
3954
|
+
{ written: claimed, everyRejected: true, racing: !coordinated }
|
|
3959
3955
|
);
|
|
3960
|
-
if (coordinated && outcome.kind !== "indeterminate") {
|
|
3961
|
-
await storeCall(
|
|
3962
|
-
() => store.set(
|
|
3963
|
-
sequenceRecord,
|
|
3964
|
-
JSON.stringify({ ...claimed, resolvedAt: (/* @__PURE__ */ new Date()).toISOString() })
|
|
3965
|
-
)
|
|
3966
|
-
);
|
|
3967
|
-
}
|
|
3968
|
-
return outcome;
|
|
3969
3956
|
}
|
|
3970
3957
|
const winner = await storeCall(() => store.get(key));
|
|
3971
3958
|
if (winner === null) {
|
|
@@ -3986,51 +3973,157 @@ async function runOperation(wsfe, operation, input, prepare, options, context, r
|
|
|
3986
3973
|
}
|
|
3987
3974
|
);
|
|
3988
3975
|
}
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
3976
|
+
return await consultKey(
|
|
3977
|
+
{ store, environment, taxId, idempotencyKey },
|
|
3978
|
+
stored,
|
|
3979
|
+
locked,
|
|
3980
|
+
select ?? (() => wsfe),
|
|
3981
|
+
options,
|
|
3982
|
+
resend
|
|
3983
|
+
);
|
|
3984
|
+
}
|
|
3985
|
+
async function resend(current) {
|
|
3986
|
+
const rejected = current.rejectedAt !== void 0;
|
|
3987
|
+
if (rejected) {
|
|
3988
|
+
const held = await clearRejection(current);
|
|
3989
|
+
if (held !== void 0) {
|
|
3990
|
+
return held;
|
|
4000
3991
|
}
|
|
4001
|
-
return await settle2(
|
|
4002
|
-
runAuthorization(
|
|
4003
|
-
wsfe,
|
|
4004
|
-
{
|
|
4005
|
-
...preparedFromRecord(stored),
|
|
4006
|
-
...replayAmounts ? { amounts: replayAmounts } : {}
|
|
4007
|
-
},
|
|
4008
|
-
options,
|
|
4009
|
-
issuer,
|
|
4010
|
-
stored.number,
|
|
4011
|
-
true
|
|
4012
|
-
)
|
|
4013
|
-
);
|
|
4014
|
-
};
|
|
4015
|
-
if (locked || !store.withLock) {
|
|
4016
|
-
return await consult();
|
|
4017
3992
|
}
|
|
4018
|
-
return await
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
3993
|
+
return await settle2(
|
|
3994
|
+
current,
|
|
3995
|
+
runAuthorization(
|
|
3996
|
+
wsfe,
|
|
3997
|
+
{
|
|
3998
|
+
...preparedFromRecord(current),
|
|
3999
|
+
...replayAmounts ? { amounts: replayAmounts } : {}
|
|
4000
|
+
},
|
|
4001
|
+
options,
|
|
4002
|
+
issuer,
|
|
4003
|
+
current.number,
|
|
4004
|
+
{ lookupFirst: !rejected, strangerAtNumber: rejected }
|
|
4024
4005
|
),
|
|
4025
|
-
|
|
4006
|
+
{ everyRejected: rejected, presumed: rejected, racing: rejected }
|
|
4007
|
+
);
|
|
4008
|
+
}
|
|
4009
|
+
async function settle2(record, running, {
|
|
4010
|
+
written,
|
|
4011
|
+
everyRejected = false,
|
|
4012
|
+
presumed = false,
|
|
4013
|
+
racing = false
|
|
4014
|
+
} = {}) {
|
|
4015
|
+
const uncoordinated = !store.withLock;
|
|
4016
|
+
const outcome = await recordConflict(
|
|
4017
|
+
store,
|
|
4018
|
+
settled,
|
|
4019
|
+
await running,
|
|
4020
|
+
!(presumed && uncoordinated)
|
|
4021
|
+
);
|
|
4022
|
+
const marks = outcome.kind === "rejected" && everyRejected && !(uncoordinated && racing && mayHoldNumber(outcome.issues, record.service));
|
|
4023
|
+
if (marks) {
|
|
4024
|
+
const rejected = { ...record, rejectedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4025
|
+
await storeCall(() => store.set(key, JSON.stringify(rejected)));
|
|
4026
|
+
}
|
|
4027
|
+
if (!store.withLock || outcome.kind === "indeterminate" || outcome.kind === "rejected" && !marks) {
|
|
4028
|
+
return outcome;
|
|
4029
|
+
}
|
|
4030
|
+
const { marker } = sequenceOf(environment, taxId, record);
|
|
4031
|
+
const json = written ? null : await storeCall(() => store.get(marker));
|
|
4032
|
+
const claimed = written ?? (json === null ? null : readSequenceRecord(json));
|
|
4033
|
+
if (claimed !== null && isOwnClaim(claimed) && claimed.number === record.number && claimed.resolvedAt === void 0) {
|
|
4034
|
+
const resolved = { ...claimed, resolvedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
4035
|
+
await storeCall(() => store.set(marker, JSON.stringify(resolved)));
|
|
4036
|
+
}
|
|
4037
|
+
return outcome;
|
|
4038
|
+
}
|
|
4039
|
+
async function clearRejection(record) {
|
|
4040
|
+
const checked = await settle2(
|
|
4041
|
+
record,
|
|
4042
|
+
consultReservation(select ?? (() => wsfe), record, options, taxId, true),
|
|
4043
|
+
{ presumed: true }
|
|
4026
4044
|
);
|
|
4045
|
+
if (checked.kind !== "indeterminate" || checked.lookup.kind !== "not_found") {
|
|
4046
|
+
return checked;
|
|
4047
|
+
}
|
|
4048
|
+
const holder = await reclaim(record);
|
|
4049
|
+
if (holder !== void 0) {
|
|
4050
|
+
return withheld(
|
|
4051
|
+
record,
|
|
4052
|
+
{ kind: "blocked", by: holder.key, byTaxId: holder.issuerTaxId },
|
|
4053
|
+
options
|
|
4054
|
+
);
|
|
4055
|
+
}
|
|
4056
|
+
const { rejectedAt: _, ...pending } = record;
|
|
4057
|
+
await storeCall(() => store.set(key, JSON.stringify(pending)));
|
|
4027
4058
|
}
|
|
4028
|
-
async function
|
|
4029
|
-
|
|
4059
|
+
async function reclaim(record) {
|
|
4060
|
+
if (!store.withLock) {
|
|
4061
|
+
return;
|
|
4062
|
+
}
|
|
4063
|
+
const { marker } = sequenceOf(environment, taxId, record);
|
|
4064
|
+
const json = await storeCall(() => store.get(marker));
|
|
4065
|
+
const claimed = json === null ? null : readSequenceRecord(json);
|
|
4066
|
+
if (claimed !== null && !isOwnClaim(claimed) && claimed.resolvedAt === void 0) {
|
|
4067
|
+
return { key: claimed.key, issuerTaxId: claimed.issuerTaxId ?? taxId };
|
|
4068
|
+
}
|
|
4069
|
+
const reopened = {
|
|
4070
|
+
v: 1,
|
|
4071
|
+
key: idempotencyKey,
|
|
4072
|
+
issuerTaxId: taxId,
|
|
4073
|
+
number: record.number,
|
|
4074
|
+
claimedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4075
|
+
};
|
|
4076
|
+
await storeCall(() => store.set(marker, JSON.stringify(reopened)));
|
|
4030
4077
|
}
|
|
4078
|
+
function isOwnClaim(claimed) {
|
|
4079
|
+
return claimed.key === idempotencyKey && (claimed.issuerTaxId ?? taxId) === taxId;
|
|
4080
|
+
}
|
|
4081
|
+
}
|
|
4082
|
+
function sequenceOf(environment, taxId, {
|
|
4083
|
+
representedTaxId,
|
|
4084
|
+
salesPoint,
|
|
4085
|
+
voucherType
|
|
4086
|
+
}) {
|
|
4087
|
+
const owner = representedTaxId ?? taxId;
|
|
4088
|
+
return {
|
|
4089
|
+
taxId: owner,
|
|
4090
|
+
marker: sequenceKey(environment, owner, salesPoint, voucherType),
|
|
4091
|
+
lock: sequenceLockKey(environment, owner, salesPoint, voucherType)
|
|
4092
|
+
};
|
|
4031
4093
|
}
|
|
4032
|
-
async function
|
|
4033
|
-
|
|
4094
|
+
async function consultKey({ store, environment, taxId, idempotencyKey }, stored, locked, select, options, unrecorded) {
|
|
4095
|
+
const consult = async (current) => {
|
|
4096
|
+
const recorded = await storeCall(
|
|
4097
|
+
() => store.get(settledKey(environment, taxId, idempotencyKey))
|
|
4098
|
+
);
|
|
4099
|
+
if (recorded === null) {
|
|
4100
|
+
return await unrecorded(current);
|
|
4101
|
+
}
|
|
4102
|
+
return await settledOutcome(
|
|
4103
|
+
select,
|
|
4104
|
+
current,
|
|
4105
|
+
readSettledRecord(recorded),
|
|
4106
|
+
options,
|
|
4107
|
+
taxId,
|
|
4108
|
+
(owner, other) => storeCall(() => store.get(settledKey(environment, owner, other)))
|
|
4109
|
+
);
|
|
4110
|
+
};
|
|
4111
|
+
if (locked || !store.withLock) {
|
|
4112
|
+
return await consult(stored);
|
|
4113
|
+
}
|
|
4114
|
+
return await store.withLock(
|
|
4115
|
+
sequenceOf(environment, taxId, stored).lock,
|
|
4116
|
+
async () => {
|
|
4117
|
+
const json = await storeCall(
|
|
4118
|
+
() => store.get(attemptKey(environment, taxId, idempotencyKey))
|
|
4119
|
+
);
|
|
4120
|
+
return await consult(json === null ? stored : readRecord(json));
|
|
4121
|
+
},
|
|
4122
|
+
{ signal: options.abortSignal }
|
|
4123
|
+
);
|
|
4124
|
+
}
|
|
4125
|
+
async function recordConflict(store, key, outcome, durable = true) {
|
|
4126
|
+
if (outcome.kind !== "conflict" || !durable) {
|
|
4034
4127
|
return outcome;
|
|
4035
4128
|
}
|
|
4036
4129
|
const record = {
|
|
@@ -4077,26 +4170,33 @@ async function settledOutcome(select, reservation, settled, options, taxId, sett
|
|
|
4077
4170
|
if (!empty && (outcome.kind !== "conflict" || await successionDisputed(settled, taxId, settledFor))) {
|
|
4078
4171
|
return outcome;
|
|
4079
4172
|
}
|
|
4173
|
+
return withheld(
|
|
4174
|
+
reservation,
|
|
4175
|
+
{ kind: "superseded", by: settled.by, byTaxId: settled.byTaxId ?? taxId },
|
|
4176
|
+
options,
|
|
4177
|
+
settled.number
|
|
4178
|
+
);
|
|
4179
|
+
}
|
|
4180
|
+
function withheld(reservation, lookup, options, number = reservation.number) {
|
|
4080
4181
|
return {
|
|
4081
4182
|
kind: "indeterminate",
|
|
4082
4183
|
attempted: {
|
|
4083
4184
|
salesPoint: reservation.salesPoint,
|
|
4084
4185
|
voucherType: reservation.voucherType,
|
|
4085
|
-
number
|
|
4186
|
+
number
|
|
4086
4187
|
},
|
|
4087
4188
|
attempt: replayEvidence(reservation.service),
|
|
4088
|
-
lookup
|
|
4089
|
-
|
|
4090
|
-
by: settled.by,
|
|
4091
|
-
byTaxId: settled.byTaxId ?? taxId
|
|
4092
|
-
},
|
|
4093
|
-
...requestEvidence(
|
|
4094
|
-
preparedFromRecord(reservation).data,
|
|
4095
|
-
reservation.number,
|
|
4096
|
-
{ ...options, service: reservation.service ?? "wsfe" }
|
|
4097
|
-
)
|
|
4189
|
+
lookup,
|
|
4190
|
+
...reservationEvidence(reservation, options)
|
|
4098
4191
|
};
|
|
4099
4192
|
}
|
|
4193
|
+
function reservationEvidence(reservation, options) {
|
|
4194
|
+
return requestEvidence(
|
|
4195
|
+
preparedFromRecord(reservation).data,
|
|
4196
|
+
reservation.number,
|
|
4197
|
+
{ ...options, service: reservation.service ?? "wsfe" }
|
|
4198
|
+
);
|
|
4199
|
+
}
|
|
4100
4200
|
async function successionDisputed(superseded, taxId, settledFor) {
|
|
4101
4201
|
let owner = superseded.byTaxId ?? taxId;
|
|
4102
4202
|
let next = superseded.by;
|
|
@@ -4125,11 +4225,7 @@ function settledConflict(settled, reservation, options) {
|
|
|
4125
4225
|
attempt: replayEvidence(reservation.service),
|
|
4126
4226
|
found: settled.found,
|
|
4127
4227
|
reason: "This key already recorded another voucher at the reserved number. Reconcile before issuing under a new key.",
|
|
4128
|
-
...
|
|
4129
|
-
preparedFromRecord(reservation).data,
|
|
4130
|
-
reservation.number,
|
|
4131
|
-
{ ...options, service: reservation.service ?? "wsfe" }
|
|
4132
|
-
)
|
|
4228
|
+
...reservationEvidence(reservation, options)
|
|
4133
4229
|
};
|
|
4134
4230
|
}
|
|
4135
4231
|
function validateKeyStore(options, context) {
|
|
@@ -4151,7 +4247,7 @@ function validateKeyStore(options, context) {
|
|
|
4151
4247
|
function readRecord(json) {
|
|
4152
4248
|
try {
|
|
4153
4249
|
const record = JSON.parse(json);
|
|
4154
|
-
if (!record || record.v !== 1 && record.v !== 2 || record.v === 2 && record.service === void 0 || !["issue", "creditNote", "debitNote"].includes(record.operation) || typeof record.inputHash !== "string" || !record.sent || !Number.isSafeInteger(record.number) || record.number < 1 || record.number > 99999999 || record.sent.salesPoint !== record.salesPoint || record.sent.voucherType !== record.voucherType) {
|
|
4250
|
+
if (!record || record.v !== 1 && record.v !== 2 || record.v === 2 && record.service === void 0 || !["issue", "creditNote", "debitNote"].includes(record.operation) || typeof record.inputHash !== "string" || !record.sent || record.rejectedAt !== void 0 && typeof record.rejectedAt !== "string" || !Number.isSafeInteger(record.number) || record.number < 1 || record.number > 99999999 || record.sent.salesPoint !== record.salesPoint || record.sent.voucherType !== record.voucherType) {
|
|
4155
4251
|
throw new Error("Invalid reservation structure");
|
|
4156
4252
|
}
|
|
4157
4253
|
normalizeWsfeVoucherInput(record.sent);
|
|
@@ -4201,7 +4297,7 @@ async function nextNumber(wsfe, data, options) {
|
|
|
4201
4297
|
}
|
|
4202
4298
|
return number;
|
|
4203
4299
|
}
|
|
4204
|
-
async function runAuthorization(wsfe, { data, voucherClass, amounts }, options, taxId, reservedNumber,
|
|
4300
|
+
async function runAuthorization(wsfe, { data, voucherClass, amounts }, options, taxId, reservedNumber, { lookupFirst = false, strangerAtNumber = false } = {}) {
|
|
4205
4301
|
const auth = {
|
|
4206
4302
|
representedTaxId: options.representedTaxId,
|
|
4207
4303
|
forceRefresh: options.forceRefresh,
|
|
@@ -4231,7 +4327,7 @@ async function runAuthorization(wsfe, { data, voucherClass, amounts }, options,
|
|
|
4231
4327
|
voucher,
|
|
4232
4328
|
service: options.service
|
|
4233
4329
|
};
|
|
4234
|
-
if (
|
|
4330
|
+
if (lookupFirst) {
|
|
4235
4331
|
const attempt2 = replayEvidence(options.service);
|
|
4236
4332
|
let lookup;
|
|
4237
4333
|
try {
|
|
@@ -4277,7 +4373,7 @@ async function runAuthorization(wsfe, { data, voucherClass, amounts }, options,
|
|
|
4277
4373
|
recovery,
|
|
4278
4374
|
options,
|
|
4279
4375
|
includeRawResponse,
|
|
4280
|
-
|
|
4376
|
+
strangerAtNumber
|
|
4281
4377
|
);
|
|
4282
4378
|
}
|
|
4283
4379
|
const uncertain = authorization.kind === "indeterminate" ? authorization : {
|
|
@@ -4298,9 +4394,9 @@ async function runAuthorization(wsfe, { data, voucherClass, amounts }, options,
|
|
|
4298
4394
|
voucher
|
|
4299
4395
|
});
|
|
4300
4396
|
}
|
|
4301
|
-
async function resolveRejection(authorization, recovery, options, includeRawResponse,
|
|
4397
|
+
async function resolveRejection(authorization, recovery, options, includeRawResponse, strangerAtNumber) {
|
|
4302
4398
|
const issues = [...authorization.errors, ...authorization.observations];
|
|
4303
|
-
const consult = options.idempotencyKey !== void 0 && (options.service
|
|
4399
|
+
const consult = options.idempotencyKey !== void 0 && mayHoldNumber(issues, options.service);
|
|
4304
4400
|
if (consult) {
|
|
4305
4401
|
const recovered = await recoverInvoice({
|
|
4306
4402
|
...recovery,
|
|
@@ -4312,7 +4408,7 @@ async function resolveRejection(authorization, recovery, options, includeRawResp
|
|
|
4312
4408
|
},
|
|
4313
4409
|
includeRawResponse
|
|
4314
4410
|
),
|
|
4315
|
-
strangerAtNumber
|
|
4411
|
+
strangerAtNumber
|
|
4316
4412
|
});
|
|
4317
4413
|
if (recovered.kind === "authorized" || recovered.kind === "conflict") {
|
|
4318
4414
|
return recovered;
|
|
@@ -4326,6 +4422,9 @@ async function resolveRejection(authorization, recovery, options, includeRawResp
|
|
|
4326
4422
|
...recovery.includedRequest
|
|
4327
4423
|
};
|
|
4328
4424
|
}
|
|
4425
|
+
function mayHoldNumber(issues, service = "wsfe") {
|
|
4426
|
+
return service === "wsmtxca" || issues.some((issue) => issue.code === "10016");
|
|
4427
|
+
}
|
|
4329
4428
|
async function recoverInvoice({
|
|
4330
4429
|
wsfe,
|
|
4331
4430
|
auth,
|
|
@@ -4376,7 +4475,7 @@ async function recoverInvoice({
|
|
|
4376
4475
|
attempted,
|
|
4377
4476
|
attempt,
|
|
4378
4477
|
found: { ...toVoucherSummary(lookup.voucher), ...rawResponse },
|
|
4379
|
-
reason: "
|
|
4478
|
+
reason: "This key never wrote the number it reserved, and another voucher occupies it",
|
|
4380
4479
|
...includedRequest
|
|
4381
4480
|
};
|
|
4382
4481
|
}
|
|
@@ -4816,14 +4915,10 @@ async function recoverOperation(select, key, inputOptions, context) {
|
|
|
4816
4915
|
);
|
|
4817
4916
|
validateOptions(options);
|
|
4818
4917
|
validateKeyStore({ ...options, idempotencyKey: key }, context);
|
|
4918
|
+
const scope = keyScope(context, key);
|
|
4919
|
+
const { store, environment, taxId } = scope;
|
|
4819
4920
|
const json = await storeCall(
|
|
4820
|
-
() =>
|
|
4821
|
-
attemptKey(
|
|
4822
|
-
context.environment,
|
|
4823
|
-
context.taxId,
|
|
4824
|
-
key
|
|
4825
|
-
)
|
|
4826
|
-
)
|
|
4921
|
+
() => store.get(attemptKey(environment, taxId, key))
|
|
4827
4922
|
);
|
|
4828
4923
|
if (json === null) {
|
|
4829
4924
|
throw new ArcaInputError("No reservation exists for this idempotency key", {
|
|
@@ -4832,44 +4927,40 @@ async function recoverOperation(select, key, inputOptions, context) {
|
|
|
4832
4927
|
});
|
|
4833
4928
|
}
|
|
4834
4929
|
const record = readRecord(json);
|
|
4835
|
-
|
|
4836
|
-
const settled = settledKey(
|
|
4837
|
-
context.environment,
|
|
4838
|
-
context.taxId,
|
|
4839
|
-
key
|
|
4840
|
-
);
|
|
4841
|
-
if (options.representedTaxId !== void 0 && String(options.representedTaxId) !== (record.representedTaxId ?? context?.taxId)) {
|
|
4930
|
+
if (options.representedTaxId !== void 0 && String(options.representedTaxId) !== (record.representedTaxId ?? taxId)) {
|
|
4842
4931
|
throw new ArcaInputError(
|
|
4843
4932
|
"Reservation belongs to another represented taxpayer",
|
|
4844
4933
|
{ code: "ARCA_INPUT_IDEMPOTENCY_MISMATCH" }
|
|
4845
4934
|
);
|
|
4846
4935
|
}
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
)
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
return await recordConflict(
|
|
4863
|
-
store,
|
|
4864
|
-
settled,
|
|
4865
|
-
await consultReservation(
|
|
4866
|
-
select,
|
|
4867
|
-
record,
|
|
4868
|
-
options,
|
|
4869
|
-
context.taxId
|
|
4870
|
-
)
|
|
4936
|
+
return await consultKey(
|
|
4937
|
+
scope,
|
|
4938
|
+
record,
|
|
4939
|
+
false,
|
|
4940
|
+
select,
|
|
4941
|
+
options,
|
|
4942
|
+
async (current) => {
|
|
4943
|
+
const rejected = current.rejectedAt !== void 0;
|
|
4944
|
+
return await recordConflict(
|
|
4945
|
+
store,
|
|
4946
|
+
settledKey(environment, taxId, key),
|
|
4947
|
+
await consultReservation(select, current, options, taxId, rejected),
|
|
4948
|
+
!rejected || store.withLock !== void 0
|
|
4949
|
+
);
|
|
4950
|
+
}
|
|
4871
4951
|
);
|
|
4872
4952
|
}
|
|
4953
|
+
function keyScope(context, idempotencyKey) {
|
|
4954
|
+
if (!context?.store) {
|
|
4955
|
+
throw new ArcaConfigurationError("idempotencyKey requires a store.");
|
|
4956
|
+
}
|
|
4957
|
+
return {
|
|
4958
|
+
store: context.store,
|
|
4959
|
+
environment: context.environment,
|
|
4960
|
+
taxId: context.taxId,
|
|
4961
|
+
idempotencyKey
|
|
4962
|
+
};
|
|
4963
|
+
}
|
|
4873
4964
|
function consultReservation(select, record, options, taxId, strangerAtNumber = false) {
|
|
4874
4965
|
const storedOptions = {
|
|
4875
4966
|
...options,
|
|
@@ -4995,7 +5086,6 @@ async function runSequenceBarrier({
|
|
|
4995
5086
|
taxId,
|
|
4996
5087
|
sequence,
|
|
4997
5088
|
sequenceTaxId,
|
|
4998
|
-
coordinates,
|
|
4999
5089
|
select,
|
|
5000
5090
|
options,
|
|
5001
5091
|
supersededBy,
|
|
@@ -5021,13 +5111,15 @@ async function runSequenceBarrier({
|
|
|
5021
5111
|
return {};
|
|
5022
5112
|
}
|
|
5023
5113
|
const record = readRecord(reservation);
|
|
5114
|
+
if (record.rejectedAt !== void 0) {
|
|
5115
|
+
return {};
|
|
5116
|
+
}
|
|
5024
5117
|
const blocked = {
|
|
5025
|
-
blocked:
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
}
|
|
5118
|
+
blocked: withheld(
|
|
5119
|
+
record,
|
|
5120
|
+
{ kind: "blocked", by: claimed.key, byTaxId: owner },
|
|
5121
|
+
options
|
|
5122
|
+
)
|
|
5031
5123
|
};
|
|
5032
5124
|
const outcome = await recordConflict(
|
|
5033
5125
|
store,
|
|
@@ -5054,6 +5146,9 @@ async function runSequenceBarrier({
|
|
|
5054
5146
|
if (outcome.kind !== "indeterminate" || outcome.lookup.kind !== "not_found") {
|
|
5055
5147
|
return blocked;
|
|
5056
5148
|
}
|
|
5149
|
+
if (options.number !== void 0 && options.number !== record.number) {
|
|
5150
|
+
return blocked;
|
|
5151
|
+
}
|
|
5057
5152
|
const next = await readNext();
|
|
5058
5153
|
if (next !== record.number) {
|
|
5059
5154
|
return blocked;
|
|
@@ -5344,19 +5439,26 @@ var ARCA_LEASE_MS = 6e4;
|
|
|
5344
5439
|
var RENEW_MS = 2e4;
|
|
5345
5440
|
var POLL_MS = 50;
|
|
5346
5441
|
var MAX_WAIT_MS = 2 * ARCA_LEASE_MS;
|
|
5347
|
-
async function withLease(key, driver, fn) {
|
|
5442
|
+
async function withLease(key, driver, fn, { signal } = {}) {
|
|
5348
5443
|
const owner = randomUUID();
|
|
5349
5444
|
const deadline = Date.now() + MAX_WAIT_MS;
|
|
5445
|
+
throwIfAborted(key, signal);
|
|
5350
5446
|
let held = await driver.acquire(owner);
|
|
5351
5447
|
while (!held) {
|
|
5352
5448
|
if (Date.now() >= deadline) {
|
|
5353
|
-
throw new
|
|
5354
|
-
`ARCA store lock ${key} stayed held; no work was attempted
|
|
5449
|
+
throw new ArcaLockTimeoutError(
|
|
5450
|
+
`ARCA store lock ${key} stayed held; no work was attempted.`,
|
|
5451
|
+
{ reason: "held" }
|
|
5355
5452
|
);
|
|
5356
5453
|
}
|
|
5357
|
-
await delay2(POLL_MS + Math.floor(Math.random() * POLL_MS));
|
|
5454
|
+
await delay2(POLL_MS + Math.floor(Math.random() * POLL_MS), signal);
|
|
5455
|
+
throwIfAborted(key, signal);
|
|
5358
5456
|
held = await driver.acquire(owner);
|
|
5359
5457
|
}
|
|
5458
|
+
if (signal?.aborted) {
|
|
5459
|
+
await driver.release(owner).catch(() => void 0);
|
|
5460
|
+
throwIfAborted(key, signal);
|
|
5461
|
+
}
|
|
5360
5462
|
const renewal = setInterval(() => {
|
|
5361
5463
|
driver.renew(owner).catch(() => void 0);
|
|
5362
5464
|
}, RENEW_MS);
|
|
@@ -5368,10 +5470,29 @@ async function withLease(key, driver, fn) {
|
|
|
5368
5470
|
await driver.release(owner).catch(() => void 0);
|
|
5369
5471
|
}
|
|
5370
5472
|
}
|
|
5371
|
-
function
|
|
5473
|
+
function throwIfAborted(key, signal) {
|
|
5474
|
+
if (signal?.aborted) {
|
|
5475
|
+
throw new ArcaLockTimeoutError(
|
|
5476
|
+
`Stopped waiting for ARCA store lock ${key}: the caller's signal aborted; no work was attempted.`,
|
|
5477
|
+
{ reason: "aborted", cause: signal.reason }
|
|
5478
|
+
);
|
|
5479
|
+
}
|
|
5480
|
+
}
|
|
5481
|
+
function delay2(ms, signal) {
|
|
5482
|
+
if (signal?.aborted) {
|
|
5483
|
+
return Promise.resolve();
|
|
5484
|
+
}
|
|
5372
5485
|
return new Promise((resolve) => {
|
|
5373
|
-
const
|
|
5486
|
+
const wake = () => {
|
|
5487
|
+
clearTimeout(timer);
|
|
5488
|
+
resolve();
|
|
5489
|
+
};
|
|
5490
|
+
const timer = setTimeout(() => {
|
|
5491
|
+
signal?.removeEventListener("abort", wake);
|
|
5492
|
+
resolve();
|
|
5493
|
+
}, ms);
|
|
5374
5494
|
timer.unref?.();
|
|
5495
|
+
signal?.addEventListener("abort", wake, { once: true });
|
|
5375
5496
|
});
|
|
5376
5497
|
}
|
|
5377
5498
|
|
|
@@ -5421,10 +5542,10 @@ function createFileStore(directory) {
|
|
|
5421
5542
|
}
|
|
5422
5543
|
}
|
|
5423
5544
|
}),
|
|
5424
|
-
withLock: (key, fn) => (
|
|
5545
|
+
withLock: (key, fn, options) => (
|
|
5425
5546
|
// A lock directory: mkdir is the atomic claim on every POSIX filesystem
|
|
5426
5547
|
// and on Windows, and the holder file inside carries the lease.
|
|
5427
|
-
withLease(key, fileLease(`${path(key)}.lock`, ensure), fn)
|
|
5548
|
+
withLease(key, fileLease(`${path(key)}.lock`, ensure), fn, options)
|
|
5428
5549
|
)
|
|
5429
5550
|
};
|
|
5430
5551
|
}
|
|
@@ -5600,12 +5721,14 @@ export {
|
|
|
5600
5721
|
arcaQrPayload,
|
|
5601
5722
|
voucherDateWindow,
|
|
5602
5723
|
matchWsfeVoucherIdentity,
|
|
5724
|
+
abortable,
|
|
5603
5725
|
createMemoryWsaaSessionStore,
|
|
5604
5726
|
createWsaaAuthModule,
|
|
5605
5727
|
createWsaaStoreAdapter,
|
|
5606
5728
|
createArcaClient,
|
|
5607
5729
|
ARCA_LEASE_MS,
|
|
5608
5730
|
withLease,
|
|
5731
|
+
throwIfAborted,
|
|
5609
5732
|
createFileStore
|
|
5610
5733
|
};
|
|
5611
|
-
//# sourceMappingURL=chunk-
|
|
5734
|
+
//# sourceMappingURL=chunk-WEEV76IC.mjs.map
|