@voyantjs/plugin-smartbill 0.77.6 → 0.77.11
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/artifacts.d.ts +20 -0
- package/dist/artifacts.d.ts.map +1 -1
- package/dist/artifacts.js +143 -37
- package/dist/client.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/plugin.d.ts +8 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +79 -5
- package/dist/runtime.d.ts +1 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +1 -0
- package/dist/validation.d.ts +2 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +2 -0
- package/package.json +8 -8
package/dist/artifacts.d.ts
CHANGED
|
@@ -31,6 +31,14 @@ export interface PersistSmartbillInvoiceArtifactInput {
|
|
|
31
31
|
body: SmartbillInvoiceBody;
|
|
32
32
|
result: SmartbillInvoiceResponse;
|
|
33
33
|
}
|
|
34
|
+
export interface RecordSmartbillInvoiceArtifactFailureInput {
|
|
35
|
+
runtime: SmartbillArtifactPersistenceRuntime;
|
|
36
|
+
event: VoyantInvoiceEvent;
|
|
37
|
+
documentType: SmartbillDocumentType;
|
|
38
|
+
body: SmartbillInvoiceBody;
|
|
39
|
+
result: SmartbillInvoiceResponse;
|
|
40
|
+
error: unknown;
|
|
41
|
+
}
|
|
34
42
|
export type SmartbillExternalRef = Pick<InvoiceExternalRef, "id" | "invoiceId" | "externalId" | "externalNumber" | "externalUrl" | "metadata">;
|
|
35
43
|
export interface RetrySmartbillInvoiceArtifactInput {
|
|
36
44
|
runtime: SmartbillArtifactPersistenceRuntime;
|
|
@@ -40,6 +48,17 @@ export interface RetrySmartbillInvoiceArtifactInput {
|
|
|
40
48
|
}
|
|
41
49
|
type InvoiceAttachmentRecord = Awaited<ReturnType<typeof financeService.createInvoiceAttachment>>;
|
|
42
50
|
type InvoiceRenditionRecord = Awaited<ReturnType<typeof financeService.createInvoiceRendition>>;
|
|
51
|
+
export type SmartbillPdfPersistStage = "attachment_lookup" | "viewInvoicePdf" | "viewEstimatePdf" | "storage_upload" | "rendition_insert" | "attachment_insert" | "unknown";
|
|
52
|
+
export declare class SmartbillPdfPersistError extends Error {
|
|
53
|
+
readonly stage: SmartbillPdfPersistStage;
|
|
54
|
+
readonly originalError: unknown;
|
|
55
|
+
constructor(stage: SmartbillPdfPersistStage, error: unknown);
|
|
56
|
+
}
|
|
57
|
+
export declare class SmartbillPdfPersistMetadataUpdateError extends Error {
|
|
58
|
+
readonly originalError: unknown;
|
|
59
|
+
constructor(error: unknown);
|
|
60
|
+
}
|
|
61
|
+
export declare function isSmartbillPdfPersistMetadataUpdateError(error: unknown): error is SmartbillPdfPersistMetadataUpdateError;
|
|
43
62
|
export type SmartbillArtifactPersistenceResult = {
|
|
44
63
|
status: "skipped";
|
|
45
64
|
reason: "missing_db" | "missing_invoice" | "missing_document_storage" | "missing_smartbill_reference";
|
|
@@ -55,6 +74,7 @@ export type SmartbillArtifactPersistenceResult = {
|
|
|
55
74
|
attachment: InvoiceAttachmentRecord;
|
|
56
75
|
};
|
|
57
76
|
export declare function persistSmartbillInvoiceArtifact({ runtime, client, event, documentType, body, result, }: PersistSmartbillInvoiceArtifactInput): Promise<SmartbillArtifactPersistenceResult>;
|
|
77
|
+
export declare function recordSmartbillInvoiceArtifactFailure({ runtime, event, documentType, body, result, error, }: RecordSmartbillInvoiceArtifactFailureInput): Promise<SmartbillArtifactPersistenceResult>;
|
|
58
78
|
export declare function retrySmartbillInvoiceArtifact({ runtime, client, externalRef, documentType, }: RetrySmartbillInvoiceArtifactInput): Promise<SmartbillArtifactPersistenceResult>;
|
|
59
79
|
export {};
|
|
60
80
|
//# sourceMappingURL=artifacts.d.ts.map
|
package/dist/artifacts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../src/artifacts.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../src/artifacts.ts"],"names":[],"mappings":"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"}
|
package/dist/artifacts.js
CHANGED
|
@@ -1,4 +1,25 @@
|
|
|
1
1
|
import { financeService } from "@voyantjs/finance";
|
|
2
|
+
export class SmartbillPdfPersistError extends Error {
|
|
3
|
+
stage;
|
|
4
|
+
originalError;
|
|
5
|
+
constructor(stage, error) {
|
|
6
|
+
super(`SmartBill PDF persist failed at ${stage}: ${errorMessage(error)}`);
|
|
7
|
+
this.name = "SmartbillPdfPersistError";
|
|
8
|
+
this.stage = stage;
|
|
9
|
+
this.originalError = error;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class SmartbillPdfPersistMetadataUpdateError extends Error {
|
|
13
|
+
originalError;
|
|
14
|
+
constructor(error) {
|
|
15
|
+
super(`SmartBill PDF persist metadata update failed: ${errorMessage(error)}`);
|
|
16
|
+
this.name = "SmartbillPdfPersistMetadataUpdateError";
|
|
17
|
+
this.originalError = error;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function isSmartbillPdfPersistMetadataUpdateError(error) {
|
|
21
|
+
return error instanceof SmartbillPdfPersistMetadataUpdateError;
|
|
22
|
+
}
|
|
2
23
|
const SMARTBILL_ATTACHMENT_KIND = "smartbill_pdf";
|
|
3
24
|
function isResolver(value) {
|
|
4
25
|
return typeof value === "function";
|
|
@@ -32,16 +53,37 @@ function metadataString(metadata, key) {
|
|
|
32
53
|
const value = metadata?.[key];
|
|
33
54
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
34
55
|
}
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
56
|
+
function errorMessage(error) {
|
|
57
|
+
if (error instanceof SmartbillPdfPersistError)
|
|
58
|
+
return errorMessage(error.originalError);
|
|
59
|
+
if (error instanceof Error)
|
|
60
|
+
return error.message;
|
|
61
|
+
return String(error);
|
|
62
|
+
}
|
|
63
|
+
function errorStage(error) {
|
|
64
|
+
return error instanceof SmartbillPdfPersistError ? error.stage : "unknown";
|
|
65
|
+
}
|
|
66
|
+
async function withPdfPersistStage(stage, operation) {
|
|
67
|
+
try {
|
|
68
|
+
return await operation();
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
throw new SmartbillPdfPersistError(stage, error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function buildSmartbillExternalRefMetadata({ body, result, documentType, extra, }) {
|
|
75
|
+
return {
|
|
76
|
+
companyVatCode: body.companyVatCode,
|
|
77
|
+
seriesName: body.seriesName,
|
|
78
|
+
series: result.series ?? body.seriesName,
|
|
79
|
+
number: result.number ?? null,
|
|
80
|
+
documentType,
|
|
81
|
+
...extra,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async function registerSmartbillExternalRef(db, invoiceId, body, result, documentType, metadataExtra) {
|
|
43
85
|
const number = result.number;
|
|
44
|
-
|
|
86
|
+
return financeService.registerInvoiceExternalRef(db, invoiceId, {
|
|
45
87
|
provider: "smartbill",
|
|
46
88
|
externalId: number ?? null,
|
|
47
89
|
externalNumber: number ?? null,
|
|
@@ -49,14 +91,39 @@ export async function persistSmartbillInvoiceArtifact({ runtime, client, event,
|
|
|
49
91
|
status: result.errorText ? "error" : "issued",
|
|
50
92
|
syncedAt: new Date().toISOString(),
|
|
51
93
|
syncError: result.errorText ?? null,
|
|
52
|
-
metadata: {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
series: seriesName,
|
|
56
|
-
number: number ?? null,
|
|
94
|
+
metadata: buildSmartbillExternalRefMetadata({
|
|
95
|
+
body,
|
|
96
|
+
result,
|
|
57
97
|
documentType,
|
|
58
|
-
|
|
98
|
+
extra: metadataExtra,
|
|
99
|
+
}),
|
|
59
100
|
});
|
|
101
|
+
}
|
|
102
|
+
async function recordSmartbillInvoiceArtifactReady(db, invoiceId, body, result, documentType, storageKey, existingMetadata) {
|
|
103
|
+
try {
|
|
104
|
+
await registerSmartbillExternalRef(db, invoiceId, body, result, documentType, {
|
|
105
|
+
...(existingMetadata ?? {}),
|
|
106
|
+
pdfPersistStatus: "ready",
|
|
107
|
+
pdfPersistedAt: new Date().toISOString(),
|
|
108
|
+
pdfStorageKey: storageKey,
|
|
109
|
+
pdfPersistError: null,
|
|
110
|
+
pdfPersistStage: null,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
throw new SmartbillPdfPersistMetadataUpdateError(error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export async function persistSmartbillInvoiceArtifact({ runtime, client, event, documentType, body, result, }) {
|
|
118
|
+
if (!runtime.db)
|
|
119
|
+
return { status: "skipped", reason: "missing_db" };
|
|
120
|
+
const context = { event, documentType, body, result };
|
|
121
|
+
const db = await resolveMaybe(runtime.db, context);
|
|
122
|
+
if (!db)
|
|
123
|
+
return { status: "skipped", reason: "missing_db" };
|
|
124
|
+
const seriesName = result.series ?? body.seriesName;
|
|
125
|
+
const number = result.number;
|
|
126
|
+
const externalRef = await registerSmartbillExternalRef(db, event.id, body, result, documentType);
|
|
60
127
|
if (!externalRef)
|
|
61
128
|
return { status: "skipped", reason: "missing_invoice" };
|
|
62
129
|
const storage = await resolveMaybe(runtime.documentStorage, context);
|
|
@@ -65,7 +132,7 @@ export async function persistSmartbillInvoiceArtifact({ runtime, client, event,
|
|
|
65
132
|
if (!number)
|
|
66
133
|
return { status: "registered_ref", reason: "missing_number" };
|
|
67
134
|
const keyPrefix = await resolveMaybe(runtime.documentStorageKeyPrefix, context);
|
|
68
|
-
|
|
135
|
+
const persisted = await persistSmartbillPdfArtifact({
|
|
69
136
|
db,
|
|
70
137
|
storage,
|
|
71
138
|
client,
|
|
@@ -77,6 +144,27 @@ export async function persistSmartbillInvoiceArtifact({ runtime, client, event,
|
|
|
77
144
|
language: body.language ?? null,
|
|
78
145
|
keyPrefix,
|
|
79
146
|
});
|
|
147
|
+
if (persisted.status === "persisted" || persisted.status === "already_exists") {
|
|
148
|
+
await recordSmartbillInvoiceArtifactReady(db, event.id, body, result, documentType, persisted.attachment?.storageKey ?? null);
|
|
149
|
+
}
|
|
150
|
+
return persisted;
|
|
151
|
+
}
|
|
152
|
+
export async function recordSmartbillInvoiceArtifactFailure({ runtime, event, documentType, body, result, error, }) {
|
|
153
|
+
if (!runtime.db)
|
|
154
|
+
return { status: "skipped", reason: "missing_db" };
|
|
155
|
+
const context = { event, documentType, body, result };
|
|
156
|
+
const db = await resolveMaybe(runtime.db, context);
|
|
157
|
+
if (!db)
|
|
158
|
+
return { status: "skipped", reason: "missing_db" };
|
|
159
|
+
const externalRef = await registerSmartbillExternalRef(db, event.id, body, result, documentType, {
|
|
160
|
+
pdfPersistStatus: "failed",
|
|
161
|
+
pdfPersistError: errorMessage(error),
|
|
162
|
+
pdfPersistStage: errorStage(error),
|
|
163
|
+
pdfPersistedAt: null,
|
|
164
|
+
});
|
|
165
|
+
if (!externalRef)
|
|
166
|
+
return { status: "skipped", reason: "missing_invoice" };
|
|
167
|
+
return { status: "registered_ref" };
|
|
80
168
|
}
|
|
81
169
|
export async function retrySmartbillInvoiceArtifact({ runtime, client, externalRef, documentType, }) {
|
|
82
170
|
if (!runtime.db)
|
|
@@ -115,34 +203,52 @@ export async function retrySmartbillInvoiceArtifact({ runtime, client, externalR
|
|
|
115
203
|
if (!storage)
|
|
116
204
|
return { status: "skipped", reason: "missing_document_storage" };
|
|
117
205
|
const keyPrefix = await resolveMaybe(runtime.documentStorageKeyPrefix, context);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
206
|
+
const result = context.result;
|
|
207
|
+
let persisted;
|
|
208
|
+
try {
|
|
209
|
+
persisted = await persistSmartbillPdfArtifact({
|
|
210
|
+
db,
|
|
211
|
+
storage,
|
|
212
|
+
client,
|
|
213
|
+
invoiceId: externalRef.invoiceId,
|
|
214
|
+
documentType,
|
|
215
|
+
companyVatCode,
|
|
216
|
+
seriesName,
|
|
217
|
+
number,
|
|
218
|
+
language: metadataString(metadata, "language"),
|
|
219
|
+
keyPrefix,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
await registerSmartbillExternalRef(db, externalRef.invoiceId, context.body, result, documentType, {
|
|
224
|
+
...(metadata ?? {}),
|
|
225
|
+
pdfPersistStatus: "failed",
|
|
226
|
+
pdfPersistError: errorMessage(error),
|
|
227
|
+
pdfPersistStage: errorStage(error),
|
|
228
|
+
pdfPersistedAt: null,
|
|
229
|
+
});
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
if (persisted.status === "persisted" || persisted.status === "already_exists") {
|
|
233
|
+
await recordSmartbillInvoiceArtifactReady(db, externalRef.invoiceId, context.body, result, documentType, persisted.attachment?.storageKey ?? null, metadata);
|
|
234
|
+
}
|
|
235
|
+
return persisted;
|
|
130
236
|
}
|
|
131
237
|
async function persistSmartbillPdfArtifact({ db, storage, client, invoiceId, documentType, companyVatCode, seriesName, number, language, keyPrefix, }) {
|
|
132
|
-
const existingAttachments = await financeService.listInvoiceAttachments(db, invoiceId);
|
|
238
|
+
const existingAttachments = await withPdfPersistStage("attachment_lookup", () => financeService.listInvoiceAttachments(db, invoiceId));
|
|
133
239
|
const existingSmartbillAttachment = existingAttachments.find((attachment) => attachment.kind === SMARTBILL_ATTACHMENT_KIND);
|
|
134
240
|
if (existingSmartbillAttachment) {
|
|
135
241
|
return { status: "already_exists", attachment: existingSmartbillAttachment };
|
|
136
242
|
}
|
|
137
243
|
const pdf = documentType === "proforma"
|
|
138
|
-
? await client.viewEstimatePdf(companyVatCode, seriesName, number)
|
|
139
|
-
: await client.viewInvoicePdf(companyVatCode, seriesName, number);
|
|
244
|
+
? await withPdfPersistStage("viewEstimatePdf", () => client.viewEstimatePdf(companyVatCode, seriesName, number))
|
|
245
|
+
: await withPdfPersistStage("viewInvoicePdf", () => client.viewInvoicePdf(companyVatCode, seriesName, number));
|
|
140
246
|
const defaultPrefix = `invoices/${invoiceId}/smartbill`;
|
|
141
247
|
const resolvedKeyPrefix = keyPrefix ?? defaultPrefix;
|
|
142
248
|
const key = `${resolvedKeyPrefix.replace(/\/$/, "")}/${documentType}-${sanitizeKeyPart(seriesName)}-${sanitizeKeyPart(number)}.pdf`;
|
|
143
249
|
const contentType = pdf.contentType || "application/pdf";
|
|
144
250
|
const checksum = await sha256(pdf.bytes);
|
|
145
|
-
const uploaded = await storage.upload(pdf.bytes, {
|
|
251
|
+
const uploaded = await withPdfPersistStage("storage_upload", () => storage.upload(pdf.bytes, {
|
|
146
252
|
key,
|
|
147
253
|
contentType,
|
|
148
254
|
metadata: {
|
|
@@ -152,7 +258,7 @@ async function persistSmartbillPdfArtifact({ db, storage, client, invoiceId, doc
|
|
|
152
258
|
seriesName,
|
|
153
259
|
number,
|
|
154
260
|
},
|
|
155
|
-
});
|
|
261
|
+
}));
|
|
156
262
|
const commonMetadata = {
|
|
157
263
|
provider: "smartbill",
|
|
158
264
|
documentType,
|
|
@@ -162,7 +268,7 @@ async function persistSmartbillPdfArtifact({ db, storage, client, invoiceId, doc
|
|
|
162
268
|
storageProvider: storage.name,
|
|
163
269
|
...(uploaded.url ? { url: uploaded.url } : {}),
|
|
164
270
|
};
|
|
165
|
-
const rendition = await financeService.createInvoiceRendition(db, invoiceId, {
|
|
271
|
+
const rendition = await withPdfPersistStage("rendition_insert", () => financeService.createInvoiceRendition(db, invoiceId, {
|
|
166
272
|
format: "pdf",
|
|
167
273
|
status: "ready",
|
|
168
274
|
storageKey: uploaded.key,
|
|
@@ -171,8 +277,8 @@ async function persistSmartbillPdfArtifact({ db, storage, client, invoiceId, doc
|
|
|
171
277
|
language: language ?? null,
|
|
172
278
|
generatedAt: new Date().toISOString(),
|
|
173
279
|
metadata: commonMetadata,
|
|
174
|
-
});
|
|
175
|
-
const attachment = await financeService.createInvoiceAttachment(db, invoiceId, {
|
|
280
|
+
}));
|
|
281
|
+
const attachment = await withPdfPersistStage("attachment_insert", () => financeService.createInvoiceAttachment(db, invoiceId, {
|
|
176
282
|
kind: SMARTBILL_ATTACHMENT_KIND,
|
|
177
283
|
name: smartbillAttachmentName(documentType, seriesName, number),
|
|
178
284
|
mimeType: contentType,
|
|
@@ -183,6 +289,6 @@ async function persistSmartbillPdfArtifact({ db, storage, client, invoiceId, doc
|
|
|
183
289
|
...commonMetadata,
|
|
184
290
|
renditionId: rendition?.id ?? null,
|
|
185
291
|
},
|
|
186
|
-
});
|
|
292
|
+
}));
|
|
187
293
|
return { status: "persisted", rendition, attachment };
|
|
188
294
|
}
|
package/dist/client.js
CHANGED
|
@@ -46,7 +46,7 @@ export function createSmartbillClient(options) {
|
|
|
46
46
|
}
|
|
47
47
|
const response = await fetchImpl(`${apiUrl}${path}`, {
|
|
48
48
|
method: "GET",
|
|
49
|
-
headers: { ...headers(), Accept: "application/
|
|
49
|
+
headers: { ...headers(), Accept: "application/octet-stream" },
|
|
50
50
|
});
|
|
51
51
|
if (!response.ok) {
|
|
52
52
|
const text = await response.text().catch(() => "");
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export type { SmartbillEventValue, SmartbillMappingOptions, SmartbillMaybePromis
|
|
|
6
6
|
export { mapClient, mapLineItems, mapVoyantInvoiceToSmartbill, mapVoyantInvoiceToSmartbillAsync, } from "./mapping.js";
|
|
7
7
|
export type { SmartbillMockDocument, SmartbillMockDocumentKind, SmartbillMockDocumentStatus, SmartbillMockListenOptions, SmartbillMockRequest, SmartbillMockResponse, SmartbillMockSeries, SmartbillMockServer, SmartbillMockServerHandle, SmartbillMockServerOptions, SmartbillMockTax, } from "./mock.js";
|
|
8
8
|
export { createSmartbillMockServer } from "./mock.js";
|
|
9
|
-
export type { SmartbillErrorHandler, SmartbillIdempotencyOptions, SmartbillLogger, SmartbillMapFn, SmartbillPluginOptions, SmartbillSyncEventNames, } from "./plugin.js";
|
|
9
|
+
export type { SmartbillErrorHandler, SmartbillIdempotencyOptions, SmartbillInvoiceNumberWriteBackFormatter, SmartbillLogger, SmartbillMapFn, SmartbillPluginOptions, SmartbillSyncEventNames, } from "./plugin.js";
|
|
10
10
|
export { smartbillPlugin } from "./plugin.js";
|
|
11
11
|
export type { ResolvedSmartbillSyncEventNames, SmartbillSyncRuntime } from "./runtime.js";
|
|
12
12
|
export { createSmartbillSyncRuntime } from "./runtime.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,kCAAkC,EAClC,mCAAmC,EACnC,kCAAkC,EAClC,mCAAmC,EACnC,+BAA+B,EAC/B,mBAAmB,EACnB,gCAAgC,EAChC,qBAAqB,EACrB,oBAAoB,EACpB,iCAAiC,GAClC,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAA;AAC9D,YAAY,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACnD,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,2BAA2B,EAC3B,gCAAgC,GACjC,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,0BAA0B,EAC1B,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAA;AACrD,YAAY,EACV,qBAAqB,EACrB,2BAA2B,EAC3B,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,YAAY,EAAE,+BAA+B,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA;AACzD,YAAY,EACV,gCAAgC,EAChC,uCAAuC,EACvC,8BAA8B,EAC9B,0BAA0B,EAC1B,gCAAgC,EAChC,+BAA+B,EAC/B,gCAAgC,GACjC,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,sCAAsC,EAAE,MAAM,iBAAiB,CAAA;AACxE,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,iCAAiC,EACjC,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACxB,+BAA+B,EAC/B,8BAA8B,EAC9B,2BAA2B,EAC3B,iCAAiC,EACjC,wCAAwC,EACxC,uCAAuC,EACvC,uBAAuB,EACvB,uBAAuB,EACvB,6BAA6B,EAC7B,6BAA6B,EAC7B,sBAAsB,EACtB,4BAA4B,EAC5B,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,8BAA8B,EAC9B,uCAAuC,GACxC,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,kCAAkC,EAClC,mCAAmC,EACnC,kCAAkC,EAClC,mCAAmC,EACnC,+BAA+B,EAC/B,mBAAmB,EACnB,gCAAgC,EAChC,qBAAqB,EACrB,oBAAoB,EACpB,iCAAiC,GAClC,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAA;AAC9D,YAAY,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACnD,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,2BAA2B,EAC3B,gCAAgC,GACjC,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,0BAA0B,EAC1B,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAA;AACrD,YAAY,EACV,qBAAqB,EACrB,2BAA2B,EAC3B,wCAAwC,EACxC,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,YAAY,EAAE,+BAA+B,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA;AACzD,YAAY,EACV,gCAAgC,EAChC,uCAAuC,EACvC,8BAA8B,EAC9B,0BAA0B,EAC1B,gCAAgC,EAChC,+BAA+B,EAC/B,gCAAgC,GACjC,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,sCAAsC,EAAE,MAAM,iBAAiB,CAAA;AACxE,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,iCAAiC,EACjC,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACxB,+BAA+B,EAC/B,8BAA8B,EAC9B,2BAA2B,EAC3B,iCAAiC,EACjC,wCAAwC,EACxC,uCAAuC,EACvC,uBAAuB,EACvB,uBAAuB,EACvB,6BAA6B,EAC7B,6BAA6B,EAC7B,sBAAsB,EACtB,4BAA4B,EAC5B,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,8BAA8B,EAC9B,uCAAuC,GACxC,MAAM,gBAAgB,CAAA"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Plugin } from "@voyantjs/core";
|
|
|
2
2
|
import { type SmartbillArtifactPersistenceOptions } from "./artifacts.js";
|
|
3
3
|
import type { SmartbillClientOptions } from "./client.js";
|
|
4
4
|
import type { SmartbillMappingOptions } from "./mapping.js";
|
|
5
|
-
import type { SmartbillInvoiceBody, VoyantInvoiceEvent } from "./types.js";
|
|
5
|
+
import type { SmartbillInvoiceBody, SmartbillInvoiceResponse, VoyantInvoiceEvent } from "./types.js";
|
|
6
6
|
export interface SmartbillSyncEventNames {
|
|
7
7
|
issued?: string;
|
|
8
8
|
proformaIssued?: string;
|
|
@@ -23,12 +23,19 @@ export interface SmartbillIdempotencyOptions {
|
|
|
23
23
|
skipExistingExternalRef?: boolean;
|
|
24
24
|
}
|
|
25
25
|
export type SmartbillErrorHandler = (event: VoyantInvoiceEvent, error: unknown) => void | Promise<void>;
|
|
26
|
+
export type SmartbillInvoiceNumberWriteBackFormatter = (event: VoyantInvoiceEvent, result: SmartbillInvoiceResponse) => string | Promise<string>;
|
|
26
27
|
export interface SmartbillPluginOptions extends SmartbillClientOptions, SmartbillMappingOptions {
|
|
27
28
|
events?: SmartbillSyncEventNames;
|
|
28
29
|
mapEvent?: SmartbillMapFn;
|
|
29
30
|
logger?: SmartbillLogger;
|
|
30
31
|
idempotency?: SmartbillIdempotencyOptions;
|
|
31
32
|
onError?: SmartbillErrorHandler;
|
|
33
|
+
/**
|
|
34
|
+
* When enabled, mirrors SmartBill's issued series-number back onto
|
|
35
|
+
* `invoices.invoice_number` after a successful create. `true` uses
|
|
36
|
+
* `${series}-${number}`; a formatter can return a custom value.
|
|
37
|
+
*/
|
|
38
|
+
writeBackInvoiceNumber?: boolean | SmartbillInvoiceNumberWriteBackFormatter;
|
|
32
39
|
/**
|
|
33
40
|
* Optional finance artifact persistence. When `db` is supplied, the plugin
|
|
34
41
|
* registers the SmartBill external ref after creation. When
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,gBAAgB,CAAA;AAIxD,OAAO,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,gBAAgB,CAAA;AAIxD,OAAO,EAKL,KAAK,mCAAmC,EAIzC,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAE3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAGpG,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IAChD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CACjD;AAED,MAAM,MAAM,cAAc,GAAG,CAC3B,KAAK,EAAE,kBAAkB,KACtB,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;AAEzD,MAAM,WAAW,2BAA2B;IAC1C;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC;AAED,MAAM,MAAM,qBAAqB,GAAG,CAClC,KAAK,EAAE,kBAAkB,EACzB,KAAK,EAAE,OAAO,KACX,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAEzB,MAAM,MAAM,wCAAwC,GAAG,CACrD,KAAK,EAAE,kBAAkB,EACzB,MAAM,EAAE,wBAAwB,KAC7B,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAE7B,MAAM,WAAW,sBAAuB,SAAQ,sBAAsB,EAAE,uBAAuB;IAC7F,MAAM,CAAC,EAAE,uBAAuB,CAAA;IAChC,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,WAAW,CAAC,EAAE,2BAA2B,CAAA;IACzC,OAAO,CAAC,EAAE,qBAAqB,CAAA;IAC/B;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,GAAG,wCAAwC,CAAA;IAC3E;;;;;OAKG;IACH,SAAS,CAAC,EAAE,mCAAmC,CAAA;IAC/C,sCAAsC;IACtC,EAAE,CAAC,EAAE,mCAAmC,CAAC,IAAI,CAAC,CAAA;IAC9C,mDAAmD;IACnD,eAAe,CAAC,EAAE,mCAAmC,CAAC,iBAAiB,CAAC,CAAA;IACxE,4DAA4D;IAC5D,wBAAwB,CAAC,EAAE,mCAAmC,CAAC,0BAA0B,CAAC,CAAA;CAC3F;AAYD,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAiavE"}
|
package/dist/plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { financeService } from "@voyantjs/finance";
|
|
2
2
|
import { ZodError } from "zod";
|
|
3
|
-
import { persistSmartbillInvoiceArtifact, retrySmartbillInvoiceArtifact, } from "./artifacts.js";
|
|
3
|
+
import { isSmartbillPdfPersistMetadataUpdateError, persistSmartbillInvoiceArtifact, recordSmartbillInvoiceArtifactFailure, retrySmartbillInvoiceArtifact, } from "./artifacts.js";
|
|
4
4
|
import { createSmartbillSyncRuntime } from "./runtime.js";
|
|
5
5
|
import { smartbillPluginOptionsSchema } from "./validation.js";
|
|
6
6
|
function coerceEvent(data) {
|
|
@@ -16,7 +16,7 @@ function coerceEvent(data) {
|
|
|
16
16
|
}
|
|
17
17
|
export function smartbillPlugin(options) {
|
|
18
18
|
const validatedOptions = parseSmartbillPluginOptions(options);
|
|
19
|
-
const { client, logger, mapEvent, eventNames, artifacts, idempotency, onError } = createSmartbillSyncRuntime(validatedOptions);
|
|
19
|
+
const { client, logger, mapEvent, eventNames, artifacts, idempotency, onError, writeBackInvoiceNumber, } = createSmartbillSyncRuntime(validatedOptions);
|
|
20
20
|
async function resolveMaybe(value, context) {
|
|
21
21
|
return typeof value === "function"
|
|
22
22
|
? await value(context)
|
|
@@ -46,11 +46,12 @@ export function smartbillPlugin(options) {
|
|
|
46
46
|
if (!db)
|
|
47
47
|
return null;
|
|
48
48
|
const refs = await financeService.listInvoiceExternalRefs(db, event.id);
|
|
49
|
-
return refs.find((ref) =>
|
|
49
|
+
return refs.find((ref) => isMatchingSmartbillRef(ref, documentType)) ?? null;
|
|
50
50
|
}
|
|
51
51
|
async function handleExistingSmartbillRef(event, documentType, body, externalRef) {
|
|
52
52
|
logger.info?.(`[smartbill] ${documentType} already has SmartBill ref for ${event.id}; skipping create`, externalRef);
|
|
53
53
|
await applyExternalAllocationFromRefIfRequired(event, documentType, body, externalRef);
|
|
54
|
+
await writeBackInvoiceNumberFromRefIfRequired(event, documentType, body, externalRef);
|
|
54
55
|
try {
|
|
55
56
|
const persisted = await retrySmartbillInvoiceArtifact({
|
|
56
57
|
runtime: artifacts,
|
|
@@ -63,7 +64,10 @@ export function smartbillPlugin(options) {
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
catch (err) {
|
|
66
|
-
|
|
67
|
+
const message = isSmartbillPdfPersistMetadataUpdateError(err)
|
|
68
|
+
? `[smartbill] artifact re-attach metadata update failed for ${event.id}`
|
|
69
|
+
: `[smartbill] artifact re-attach failed for ${event.id}`;
|
|
70
|
+
logger.error(message, err);
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
73
|
async function persistArtifact(event, documentType, body, result) {
|
|
@@ -81,7 +85,24 @@ export function smartbillPlugin(options) {
|
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
catch (err) {
|
|
88
|
+
if (isSmartbillPdfPersistMetadataUpdateError(err)) {
|
|
89
|
+
logger.error(`[smartbill] artifact persistence metadata update failed for ${event.id}`, err);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
84
92
|
logger.error(`[smartbill] artifact persistence failed for ${event.id}`, err);
|
|
93
|
+
try {
|
|
94
|
+
await recordSmartbillInvoiceArtifactFailure({
|
|
95
|
+
runtime: artifacts,
|
|
96
|
+
event,
|
|
97
|
+
documentType,
|
|
98
|
+
body,
|
|
99
|
+
result,
|
|
100
|
+
error: err,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch (recordError) {
|
|
104
|
+
logger.error(`[smartbill] artifact failure external-ref update failed for ${event.id}`, recordError);
|
|
105
|
+
}
|
|
85
106
|
}
|
|
86
107
|
}
|
|
87
108
|
async function applyExternalAllocationIfRequired(event, documentType, body, result) {
|
|
@@ -117,6 +138,52 @@ export function smartbillPlugin(options) {
|
|
|
117
138
|
url: externalRef.externalUrl ?? undefined,
|
|
118
139
|
});
|
|
119
140
|
}
|
|
141
|
+
async function resolveWriteBackInvoiceNumber(event, body, result) {
|
|
142
|
+
if (!writeBackInvoiceNumber)
|
|
143
|
+
return null;
|
|
144
|
+
if (typeof writeBackInvoiceNumber === "function") {
|
|
145
|
+
const invoiceNumber = await writeBackInvoiceNumber(event, result);
|
|
146
|
+
if (typeof invoiceNumber !== "string" || invoiceNumber.trim().length === 0) {
|
|
147
|
+
throw new Error("SmartBill invoice number write-back formatter returned an empty value");
|
|
148
|
+
}
|
|
149
|
+
return invoiceNumber;
|
|
150
|
+
}
|
|
151
|
+
if (!result.number)
|
|
152
|
+
return null;
|
|
153
|
+
return formatExternalInvoiceNumber(result.series ?? body.seriesName, result.number);
|
|
154
|
+
}
|
|
155
|
+
async function writeBackInvoiceNumberIfRequired(event, documentType, body, result) {
|
|
156
|
+
const invoiceNumber = await resolveWriteBackInvoiceNumber(event, body, result);
|
|
157
|
+
if (!invoiceNumber)
|
|
158
|
+
return;
|
|
159
|
+
const db = await resolveArtifactDb(event, documentType, body, result);
|
|
160
|
+
if (!db) {
|
|
161
|
+
throw new Error("SmartBill invoice number write-back requires artifact database access");
|
|
162
|
+
}
|
|
163
|
+
const invoice = await financeService.updateInvoice(db, event.id, { invoiceNumber });
|
|
164
|
+
if (!invoice) {
|
|
165
|
+
throw new Error(`SmartBill invoice number write-back failed for missing invoice ${event.id}`);
|
|
166
|
+
}
|
|
167
|
+
logger.info?.(`[smartbill] invoice number write-back applied for ${event.id}`, invoice);
|
|
168
|
+
}
|
|
169
|
+
async function writeBackInvoiceNumberFromRefIfRequired(event, documentType, body, externalRef) {
|
|
170
|
+
if (!writeBackInvoiceNumber)
|
|
171
|
+
return;
|
|
172
|
+
const metadata = coerceMetadata(externalRef.metadata);
|
|
173
|
+
const number = metadataString(metadata, "number") ??
|
|
174
|
+
externalRef.externalNumber ??
|
|
175
|
+
externalRef.externalId ??
|
|
176
|
+
null;
|
|
177
|
+
if (!number)
|
|
178
|
+
return;
|
|
179
|
+
await writeBackInvoiceNumberIfRequired(event, documentType, body, {
|
|
180
|
+
number,
|
|
181
|
+
series: metadataString(metadata, "series") ??
|
|
182
|
+
metadataString(metadata, "seriesName") ??
|
|
183
|
+
body.seriesName,
|
|
184
|
+
url: externalRef.externalUrl ?? undefined,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
120
187
|
async function recordSyncError(event, documentType, err) {
|
|
121
188
|
try {
|
|
122
189
|
await onError?.(event, err);
|
|
@@ -129,7 +196,7 @@ export function smartbillPlugin(options) {
|
|
|
129
196
|
if (!db)
|
|
130
197
|
return;
|
|
131
198
|
const refs = await financeService.listInvoiceExternalRefs(db, event.id);
|
|
132
|
-
if (refs.some((ref) =>
|
|
199
|
+
if (refs.some((ref) => isMatchingSmartbillRef(ref, documentType)))
|
|
133
200
|
return;
|
|
134
201
|
await financeService.registerInvoiceExternalRef(db, event.id, {
|
|
135
202
|
provider: "smartbill",
|
|
@@ -172,6 +239,7 @@ export function smartbillPlugin(options) {
|
|
|
172
239
|
const result = await client.createInvoice(body);
|
|
173
240
|
logger.info?.(`[smartbill] invoice created: ${result.series}-${result.number} for ${event.id}`, result);
|
|
174
241
|
await persistArtifact(event, "invoice", body, result);
|
|
242
|
+
await writeBackInvoiceNumberIfRequired(event, "invoice", body, result);
|
|
175
243
|
await applyExternalAllocationIfRequired(event, "invoice", body, result);
|
|
176
244
|
}
|
|
177
245
|
catch (err) {
|
|
@@ -198,6 +266,7 @@ export function smartbillPlugin(options) {
|
|
|
198
266
|
const result = await client.createProforma(body);
|
|
199
267
|
logger.info?.(`[smartbill] proforma created: ${result.series}-${result.number} for ${event.id}`, result);
|
|
200
268
|
await persistArtifact(event, "proforma", body, result);
|
|
269
|
+
await writeBackInvoiceNumberIfRequired(event, "proforma", body, result);
|
|
201
270
|
await applyExternalAllocationIfRequired(event, "proforma", body, result);
|
|
202
271
|
}
|
|
203
272
|
catch (err) {
|
|
@@ -293,6 +362,11 @@ function isUsableSmartbillRef(ref) {
|
|
|
293
362
|
!ref.syncError &&
|
|
294
363
|
Boolean(ref.externalNumber || ref.externalId));
|
|
295
364
|
}
|
|
365
|
+
function isMatchingSmartbillRef(ref, documentType) {
|
|
366
|
+
if (!isUsableSmartbillRef(ref))
|
|
367
|
+
return false;
|
|
368
|
+
return metadataString(coerceMetadata(ref.metadata), "documentType") === documentType;
|
|
369
|
+
}
|
|
296
370
|
function parseSmartbillPluginOptions(options) {
|
|
297
371
|
try {
|
|
298
372
|
return smartbillPluginOptionsSchema.parse(options);
|
package/dist/runtime.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface SmartbillSyncRuntime {
|
|
|
15
15
|
artifacts: SmartbillArtifactPersistenceOptions;
|
|
16
16
|
idempotency: NonNullable<SmartbillPluginOptions["idempotency"]>;
|
|
17
17
|
onError: SmartbillPluginOptions["onError"];
|
|
18
|
+
writeBackInvoiceNumber: SmartbillPluginOptions["writeBackInvoiceNumber"];
|
|
18
19
|
}
|
|
19
20
|
export declare function createSmartbillSyncRuntime(options: SmartbillPluginOptions): SmartbillSyncRuntime;
|
|
20
21
|
//# sourceMappingURL=runtime.d.ts.map
|
package/dist/runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,gBAAgB,CAAA;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAG1F,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA;IAChD,MAAM,EAAE,eAAe,CAAA;IACvB,QAAQ,EAAE,cAAc,CAAA;IACxB,UAAU,EAAE,+BAA+B,CAAA;IAC3C,SAAS,EAAE,mCAAmC,CAAA;IAC9C,WAAW,EAAE,WAAW,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,CAAA;IAC/D,OAAO,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,gBAAgB,CAAA;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAG1F,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA;IAChD,MAAM,EAAE,eAAe,CAAA;IACvB,QAAQ,EAAE,cAAc,CAAA;IACxB,UAAU,EAAE,+BAA+B,CAAA;IAC3C,SAAS,EAAE,mCAAmC,CAAA;IAC9C,WAAW,EAAE,WAAW,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,CAAA;IAC/D,OAAO,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAA;IAC1C,sBAAsB,EAAE,sBAAsB,CAAC,wBAAwB,CAAC,CAAA;CACzE;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,sBAAsB,GAAG,oBAAoB,CAyChG"}
|
package/dist/runtime.js
CHANGED
package/dist/validation.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { SmartbillArtifactPersistenceOptions, SmartbillDbResolver, SmartbillDocumentStorageResolver, SmartbillStorageKeyPrefixResolver } from "./artifacts.js";
|
|
3
|
-
import type { SmartbillErrorHandler, SmartbillIdempotencyOptions, SmartbillLogger, SmartbillMapFn, SmartbillSyncEventNames } from "./plugin.js";
|
|
3
|
+
import type { SmartbillErrorHandler, SmartbillIdempotencyOptions, SmartbillInvoiceNumberWriteBackFormatter, SmartbillLogger, SmartbillMapFn, SmartbillSyncEventNames } from "./plugin.js";
|
|
4
4
|
import type { SmartbillFetch } from "./types.js";
|
|
5
5
|
export declare const smartbillPluginOptionsSchema: z.ZodObject<{
|
|
6
6
|
username: z.ZodString;
|
|
@@ -21,6 +21,7 @@ export declare const smartbillPluginOptionsSchema: z.ZodObject<{
|
|
|
21
21
|
logger: z.ZodOptional<z.ZodCustom<SmartbillLogger | undefined, SmartbillLogger | undefined>>;
|
|
22
22
|
idempotency: z.ZodOptional<z.ZodCustom<SmartbillIdempotencyOptions | undefined, SmartbillIdempotencyOptions | undefined>>;
|
|
23
23
|
onError: z.ZodOptional<z.ZodCustom<SmartbillErrorHandler | undefined, SmartbillErrorHandler | undefined>>;
|
|
24
|
+
writeBackInvoiceNumber: z.ZodOptional<z.ZodCustom<boolean | SmartbillInvoiceNumberWriteBackFormatter | undefined, boolean | SmartbillInvoiceNumberWriteBackFormatter | undefined>>;
|
|
24
25
|
artifacts: z.ZodOptional<z.ZodCustom<SmartbillArtifactPersistenceOptions | undefined, SmartbillArtifactPersistenceOptions | undefined>>;
|
|
25
26
|
db: z.ZodOptional<z.ZodCustom<SmartbillDbResolver | undefined, SmartbillDbResolver | undefined>>;
|
|
26
27
|
documentStorage: z.ZodOptional<z.ZodCustom<SmartbillDocumentStorageResolver | undefined, SmartbillDocumentStorageResolver | undefined>>;
|
package/dist/validation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EACV,mCAAmC,EACnC,mBAAmB,EACnB,gCAAgC,EAChC,iCAAiC,EAClC,MAAM,gBAAgB,CAAA;AAEvB,OAAO,KAAK,EACV,qBAAqB,EACrB,2BAA2B,EAC3B,eAAe,EACf,cAAc,EAEd,uBAAuB,EACxB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EACV,mCAAmC,EACnC,mBAAmB,EACnB,gCAAgC,EAChC,iCAAiC,EAClC,MAAM,gBAAgB,CAAA;AAEvB,OAAO,KAAK,EACV,qBAAqB,EACrB,2BAA2B,EAC3B,wCAAwC,EACxC,eAAe,EACf,cAAc,EAEd,uBAAuB,EACxB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAgHhD,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;iBAwBK,CAAA"}
|
package/dist/validation.js
CHANGED
|
@@ -14,6 +14,7 @@ const optionalLogger = z.custom((value) => value === undefined ||
|
|
|
14
14
|
typeof value.info === "function")), "Expected a logger with an error function");
|
|
15
15
|
const optionalMapEvent = z.custom((value) => value === undefined || typeof value === "function", "Expected a mapEvent function");
|
|
16
16
|
const optionalOnError = z.custom((value) => value === undefined || typeof value === "function", "Expected an onError function");
|
|
17
|
+
const optionalWriteBackInvoiceNumber = z.custom((value) => value === undefined || typeof value === "boolean" || typeof value === "function", "Expected a boolean or invoice number formatter function");
|
|
17
18
|
const optionalDb = z.custom((value) => value === undefined ||
|
|
18
19
|
typeof value === "function" ||
|
|
19
20
|
(typeof value === "object" && value !== null), "Expected a database handle or resolver function");
|
|
@@ -76,6 +77,7 @@ export const smartbillPluginOptionsSchema = z.object({
|
|
|
76
77
|
logger: optionalLogger.optional(),
|
|
77
78
|
idempotency: optionalIdempotency.optional(),
|
|
78
79
|
onError: optionalOnError.optional(),
|
|
80
|
+
writeBackInvoiceNumber: optionalWriteBackInvoiceNumber.optional(),
|
|
79
81
|
artifacts: optionalArtifacts.optional(),
|
|
80
82
|
db: optionalDb.optional(),
|
|
81
83
|
documentStorage: optionalDocumentStorage.optional(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/plugin-smartbill",
|
|
3
|
-
"version": "0.77.
|
|
3
|
+
"version": "0.77.11",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -48,17 +48,17 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"drizzle-orm": "^0.45.2",
|
|
50
50
|
"zod": "^4.3.6",
|
|
51
|
-
"@voyantjs/core": "0.77.
|
|
52
|
-
"@voyantjs/finance": "0.77.
|
|
53
|
-
"@voyantjs/storage": "0.77.
|
|
51
|
+
"@voyantjs/core": "0.77.11",
|
|
52
|
+
"@voyantjs/finance": "0.77.11",
|
|
53
|
+
"@voyantjs/storage": "0.77.11"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"@tanstack/react-query": "^5.0.0",
|
|
57
57
|
"lucide-react": "^0.475.0",
|
|
58
58
|
"react": "^19.0.0",
|
|
59
59
|
"react-dom": "^19.0.0",
|
|
60
|
-
"@voyantjs/finance-react": "0.77.
|
|
61
|
-
"@voyantjs/ui": "0.77.
|
|
60
|
+
"@voyantjs/finance-react": "0.77.11",
|
|
61
|
+
"@voyantjs/ui": "0.77.11"
|
|
62
62
|
},
|
|
63
63
|
"peerDependenciesMeta": {
|
|
64
64
|
"@tanstack/react-query": {
|
|
@@ -89,8 +89,8 @@
|
|
|
89
89
|
"react-dom": "^19.2.4",
|
|
90
90
|
"typescript": "^6.0.2",
|
|
91
91
|
"vitest": "^4.1.2",
|
|
92
|
-
"@voyantjs/finance-react": "0.77.
|
|
93
|
-
"@voyantjs/ui": "0.77.
|
|
92
|
+
"@voyantjs/finance-react": "0.77.11",
|
|
93
|
+
"@voyantjs/ui": "0.77.11",
|
|
94
94
|
"@voyantjs/voyant-typescript-config": "0.1.0"
|
|
95
95
|
},
|
|
96
96
|
"files": [
|