@happyvertical/accounting 0.99.0 → 0.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -0
- package/dist/chunks/{OAuthClient-DgRaQp_Y.js → OAuthClient-CF65pAW_.js} +2 -2
- package/dist/chunks/{OAuthClient-DgRaQp_Y.js.map → OAuthClient-CF65pAW_.js.map} +1 -1
- package/dist/chunks/{errors-Dvn2QzOB.js → errors-Dt7tUtsB.js} +24 -2
- package/dist/chunks/errors-Dt7tUtsB.js.map +1 -0
- package/dist/chunks/invoice-request-D6XcgNzI.js +51 -0
- package/dist/chunks/invoice-request-D6XcgNzI.js.map +1 -0
- package/dist/chunks/{quickbooks-DujZt_Gx.js → quickbooks-DLkypnT9.js} +55 -47
- package/dist/chunks/quickbooks-DLkypnT9.js.map +1 -0
- package/dist/chunks/{stripe-CZlx1zrs.js → stripe-Dpp7VB-7.js} +2 -2
- package/dist/chunks/{stripe-CZlx1zrs.js.map → stripe-Dpp7VB-7.js.map} +1 -1
- package/dist/errors.d.ts +21 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/providers/quickbooks/index.d.ts +2 -2
- package/dist/providers/quickbooks/index.d.ts.map +1 -1
- package/dist/providers/quickbooks/invoice-request.d.ts +29 -0
- package/dist/providers/quickbooks/invoice-request.d.ts.map +1 -0
- package/dist/types.d.ts +11 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/chunks/errors-Dvn2QzOB.js.map +0 -1
- package/dist/chunks/quickbooks-DujZt_Gx.js.map +0 -1
|
@@ -43,7 +43,29 @@ var StripeApiError = class extends Error {
|
|
|
43
43
|
function str(value) {
|
|
44
44
|
return typeof value === "string" && value ? value : void 0;
|
|
45
45
|
}
|
|
46
|
+
/** A write was rejected, or may have committed and requires caller reconciliation. */
|
|
47
|
+
var QuickBooksWriteError = class extends Error {
|
|
48
|
+
code = "QBO_WRITE_ERROR";
|
|
49
|
+
outcome;
|
|
50
|
+
realmId;
|
|
51
|
+
environment;
|
|
52
|
+
endpoint;
|
|
53
|
+
requestId;
|
|
54
|
+
payloadHash;
|
|
55
|
+
status;
|
|
56
|
+
constructor(details) {
|
|
57
|
+
super(`QuickBooks write outcome ${details.outcome}; reconcile before creating a new request identity`, { cause: details.cause });
|
|
58
|
+
this.name = "QuickBooksWriteError";
|
|
59
|
+
this.outcome = details.outcome;
|
|
60
|
+
this.realmId = details.realmId;
|
|
61
|
+
this.environment = details.environment;
|
|
62
|
+
this.endpoint = details.endpoint;
|
|
63
|
+
this.requestId = details.requestId;
|
|
64
|
+
this.payloadHash = details.payloadHash;
|
|
65
|
+
this.status = details.status;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
46
68
|
//#endregion
|
|
47
|
-
export { StripeApiError as t };
|
|
69
|
+
export { StripeApiError as n, QuickBooksWriteError as t };
|
|
48
70
|
|
|
49
|
-
//# sourceMappingURL=errors-
|
|
71
|
+
//# sourceMappingURL=errors-Dt7tUtsB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-Dt7tUtsB.js","names":[],"sources":["../../src/errors.ts"],"sourcesContent":["/**\n * Provider error types, kept free of provider modules so the package entry\n * point can export them without loading optional integrations.\n */\n\n/**\n * Error thrown for a non-2xx Stripe API response. The message is unchanged\n * from earlier releases (`Stripe API error (<status>): <body>`); the parsed\n * Stripe error fields are exposed for callers that branch on them.\n */\nexport class StripeApiError extends Error {\n readonly status: number;\n /** Stripe error type, for example `card_error` or `invalid_request_error`. */\n readonly type?: string;\n /** Stripe error code, for example `card_declined` or `resource_missing`. */\n readonly code?: string;\n /** Issuer decline code for card errors. */\n readonly declineCode?: string;\n /** Stripe's human-readable error message (never contains card data). */\n readonly stripeMessage?: string;\n /** The PaymentIntent a failed confirmation left behind, if any. */\n readonly paymentIntent?: unknown;\n\n constructor(status: number, body: string) {\n super(`Stripe API error (${status}): ${body}`);\n this.name = 'StripeApiError';\n this.status = status;\n let parsed: { error?: Record<string, unknown> } | undefined;\n try {\n parsed = JSON.parse(body) as { error?: Record<string, unknown> };\n } catch {\n // Non-JSON bodies (proxies, outages) keep only the status and message.\n parsed = undefined;\n }\n const error = parsed?.error;\n if (error && typeof error === 'object') {\n this.type = str(error.type);\n this.code = str(error.code);\n this.declineCode = str(error.decline_code);\n this.stripeMessage = str(error.message);\n this.paymentIntent = error.payment_intent;\n }\n }\n}\n\nfunction str(value: unknown): string | undefined {\n return typeof value === 'string' && value ? value : undefined;\n}\n\n/** A write was rejected, or may have committed and requires caller reconciliation. */\nexport class QuickBooksWriteError extends Error {\n readonly code = 'QBO_WRITE_ERROR';\n readonly outcome: 'unknown' | 'rejected';\n readonly realmId: string;\n readonly environment: 'sandbox' | 'production';\n readonly endpoint: string;\n readonly requestId?: string;\n readonly payloadHash?: string;\n readonly status?: number;\n\n constructor(details: {\n outcome: 'unknown' | 'rejected';\n realmId: string;\n environment: 'sandbox' | 'production';\n endpoint: string;\n requestId?: string;\n payloadHash?: string;\n status?: number;\n cause: unknown;\n }) {\n super(\n `QuickBooks write outcome ${details.outcome}; reconcile before creating a new request identity`,\n { cause: details.cause },\n );\n this.name = 'QuickBooksWriteError';\n this.outcome = details.outcome;\n this.realmId = details.realmId;\n this.environment = details.environment;\n this.endpoint = details.endpoint;\n this.requestId = details.requestId;\n this.payloadHash = details.payloadHash;\n this.status = details.status;\n }\n}\n"],"mappings":";;;;;;;;;;AAUA,IAAa,iBAAb,cAAoC,MAAM;CACxC;;CAEA;;CAEA;;CAEA;;CAEA;;CAEA;CAEA,YAAY,QAAgB,MAAc;EACxC,MAAM,qBAAqB,OAAO,KAAK,MAAM;EAC7C,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,IAAI;EAC1B,QAAQ;GAEN,SAAS,KAAA;EACX;EACA,MAAM,QAAQ,QAAQ;EACtB,IAAI,SAAS,OAAO,UAAU,UAAU;GACtC,KAAK,OAAO,IAAI,MAAM,IAAI;GAC1B,KAAK,OAAO,IAAI,MAAM,IAAI;GAC1B,KAAK,cAAc,IAAI,MAAM,YAAY;GACzC,KAAK,gBAAgB,IAAI,MAAM,OAAO;GACtC,KAAK,gBAAgB,MAAM;EAC7B;CACF;AACF;AAEA,SAAS,IAAI,OAAoC;CAC/C,OAAO,OAAO,UAAU,YAAY,QAAQ,QAAQ,KAAA;AACtD;;AAGA,IAAa,uBAAb,cAA0C,MAAM;CAC9C,OAAgB;CAChB;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,SAST;EACD,MACE,4BAA4B,QAAQ,QAAQ,qDAC5C,EAAE,OAAO,QAAQ,MAAM,CACzB;EACA,KAAK,OAAO;EACZ,KAAK,UAAU,QAAQ;EACvB,KAAK,UAAU,QAAQ;EACvB,KAAK,cAAc,QAAQ;EAC3B,KAAK,WAAW,QAAQ;EACxB,KAAK,YAAY,QAAQ;EACzB,KAAK,cAAc,QAAQ;EAC3B,KAAK,SAAS,QAAQ;CACxB;AACF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
//#region src/providers/quickbooks/invoice-request.ts
|
|
3
|
+
/** Prepare once, persist before sending, and reuse unchanged. Performs no I/O. */
|
|
4
|
+
function prepareQuickBooksInvoiceRequest(invoice, identity) {
|
|
5
|
+
if (invoice.externalId) throw new Error("QuickBooks request identity is only for invoice creation");
|
|
6
|
+
const payload = JSON.stringify(mapInvoiceToQBO(invoice));
|
|
7
|
+
const request = {
|
|
8
|
+
...identity,
|
|
9
|
+
payloadHash: hash(payload)
|
|
10
|
+
};
|
|
11
|
+
validateQuickBooksInvoiceRequest(request, identity.realmId, identity.environment, payload);
|
|
12
|
+
return Object.freeze(request);
|
|
13
|
+
}
|
|
14
|
+
function hash(payload) {
|
|
15
|
+
return createHash("sha256").update(payload).digest("hex");
|
|
16
|
+
}
|
|
17
|
+
function validateQuickBooksInvoiceRequest(request, realmId, environment, payload) {
|
|
18
|
+
if (!request || typeof request.requestId !== "string" || !/^[A-Za-z0-9._-]{1,50}$/.test(request.requestId)) throw new Error("QuickBooks requestId must contain 1–50 URL-safe letters, digits, dots, underscores or hyphens");
|
|
19
|
+
if (!request.realmId || request.realmId !== realmId || !["sandbox", "production"].includes(request.environment) || request.environment !== environment) throw new Error("QuickBooks invoice request realm/environment mismatch");
|
|
20
|
+
if (!payload || request.payloadHash !== hash(payload)) throw new Error("QuickBooks invoice request payload mismatch; reconcile the original request");
|
|
21
|
+
const parsed = JSON.parse(payload);
|
|
22
|
+
if (parsed.Id !== void 0 || parsed.SyncToken !== void 0) throw new Error("QuickBooks request identity is only for invoice creation");
|
|
23
|
+
}
|
|
24
|
+
function formatLocalDate(date) {
|
|
25
|
+
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
|
|
26
|
+
}
|
|
27
|
+
function mapInvoiceToQBO(invoice) {
|
|
28
|
+
if (invoice.collectionMethod === "charge_automatically") throw new Error("QuickBooks does not support charge_automatically invoice collection");
|
|
29
|
+
return {
|
|
30
|
+
CustomerRef: { value: invoice.customerExternalId || invoice.customerId },
|
|
31
|
+
DocNumber: invoice.invoiceNumber,
|
|
32
|
+
TxnDate: formatLocalDate(invoice.issueDate),
|
|
33
|
+
DueDate: formatLocalDate(invoice.dueDate),
|
|
34
|
+
Line: invoice.lineItems.map((item, idx) => ({
|
|
35
|
+
LineNum: idx + 1,
|
|
36
|
+
Description: item.description,
|
|
37
|
+
Amount: item.amount ?? item.quantity * item.unitPrice,
|
|
38
|
+
DetailType: "SalesItemLineDetail",
|
|
39
|
+
SalesItemLineDetail: {
|
|
40
|
+
Qty: item.quantity,
|
|
41
|
+
UnitPrice: item.unitPrice
|
|
42
|
+
}
|
|
43
|
+
})),
|
|
44
|
+
CurrencyRef: invoice.currency ? { value: invoice.currency } : void 0,
|
|
45
|
+
CustomerMemo: invoice.memo ? { value: invoice.memo } : void 0
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { prepareQuickBooksInvoiceRequest as n, validateQuickBooksInvoiceRequest as r, mapInvoiceToQBO as t };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=invoice-request-D6XcgNzI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoice-request-D6XcgNzI.js","names":[],"sources":["../../src/providers/quickbooks/invoice-request.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport type { InvoiceInput, QuickBooksInvoiceRequest } from '../../types.js';\n\n/** Prepare once, persist before sending, and reuse unchanged. Performs no I/O. */\nexport function prepareQuickBooksInvoiceRequest(\n invoice: InvoiceInput,\n identity: Omit<QuickBooksInvoiceRequest, 'payloadHash'>,\n): QuickBooksInvoiceRequest {\n if (invoice.externalId)\n throw new Error('QuickBooks request identity is only for invoice creation');\n const payload = JSON.stringify(mapInvoiceToQBO(invoice));\n const request = { ...identity, payloadHash: hash(payload) };\n validateQuickBooksInvoiceRequest(\n request,\n identity.realmId,\n identity.environment,\n payload,\n );\n return Object.freeze(request);\n}\n\nfunction hash(payload: string): string {\n return createHash('sha256').update(payload).digest('hex');\n}\n\nexport function validateQuickBooksInvoiceRequest(\n request: QuickBooksInvoiceRequest,\n realmId: string,\n environment: 'sandbox' | 'production',\n payload: string | undefined,\n): void {\n // A deliberately conservative URL-safe subset of Intuit's 50-character limit.\n if (\n !request ||\n typeof request.requestId !== 'string' ||\n !/^[A-Za-z0-9._-]{1,50}$/.test(request.requestId)\n ) {\n throw new Error(\n 'QuickBooks requestId must contain 1–50 URL-safe letters, digits, dots, underscores or hyphens',\n );\n }\n if (\n !request.realmId ||\n request.realmId !== realmId ||\n !['sandbox', 'production'].includes(request.environment) ||\n request.environment !== environment\n ) {\n throw new Error('QuickBooks invoice request realm/environment mismatch');\n }\n if (!payload || request.payloadHash !== hash(payload)) {\n throw new Error(\n 'QuickBooks invoice request payload mismatch; reconcile the original request',\n );\n }\n const parsed = JSON.parse(payload);\n if (parsed.Id !== undefined || parsed.SyncToken !== undefined) {\n throw new Error('QuickBooks request identity is only for invoice creation');\n }\n}\n\nfunction formatLocalDate(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n}\n\nexport function mapInvoiceToQBO(invoice: InvoiceInput) {\n if (invoice.collectionMethod === 'charge_automatically') {\n // QuickBooks cannot charge a stored payment method for an invoice.\n throw new Error(\n 'QuickBooks does not support charge_automatically invoice collection',\n );\n }\n return {\n CustomerRef: { value: invoice.customerExternalId || invoice.customerId },\n DocNumber: invoice.invoiceNumber,\n TxnDate: formatLocalDate(invoice.issueDate),\n DueDate: formatLocalDate(invoice.dueDate),\n Line: invoice.lineItems.map((item, idx) => ({\n LineNum: idx + 1,\n Description: item.description,\n Amount: item.amount ?? item.quantity * item.unitPrice,\n DetailType: 'SalesItemLineDetail' as const,\n SalesItemLineDetail: {\n Qty: item.quantity,\n UnitPrice: item.unitPrice,\n },\n })),\n CurrencyRef: invoice.currency ? { value: invoice.currency } : undefined,\n CustomerMemo: invoice.memo ? { value: invoice.memo } : undefined,\n };\n}\n"],"mappings":";;;AAIA,SAAgB,gCACd,SACA,UAC0B;CAC1B,IAAI,QAAQ,YACV,MAAM,IAAI,MAAM,0DAA0D;CAC5E,MAAM,UAAU,KAAK,UAAU,gBAAgB,OAAO,CAAC;CACvD,MAAM,UAAU;EAAE,GAAG;EAAU,aAAa,KAAK,OAAO;CAAE;CAC1D,iCACE,SACA,SAAS,SACT,SAAS,aACT,OACF;CACA,OAAO,OAAO,OAAO,OAAO;AAC9B;AAEA,SAAS,KAAK,SAAyB;CACrC,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,OAAO,KAAK;AAC1D;AAEA,SAAgB,iCACd,SACA,SACA,aACA,SACM;CAEN,IACE,CAAC,WACD,OAAO,QAAQ,cAAc,YAC7B,CAAC,yBAAyB,KAAK,QAAQ,SAAS,GAEhD,MAAM,IAAI,MACR,+FACF;CAEF,IACE,CAAC,QAAQ,WACT,QAAQ,YAAY,WACpB,CAAC,CAAC,WAAW,YAAY,CAAC,CAAC,SAAS,QAAQ,WAAW,KACvD,QAAQ,gBAAgB,aAExB,MAAM,IAAI,MAAM,uDAAuD;CAEzE,IAAI,CAAC,WAAW,QAAQ,gBAAgB,KAAK,OAAO,GAClD,MAAM,IAAI,MACR,6EACF;CAEF,MAAM,SAAS,KAAK,MAAM,OAAO;CACjC,IAAI,OAAO,OAAO,KAAA,KAAa,OAAO,cAAc,KAAA,GAClD,MAAM,IAAI,MAAM,0DAA0D;AAE9E;AAEA,SAAS,gBAAgB,MAAoB;CAI3C,OAAO,GAHM,KAAK,YAGR,EAAK,GAFD,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,GAEpC,EAAM,GADZ,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,GAAG,GACpB;AAC7B;AAEA,SAAgB,gBAAgB,SAAuB;CACrD,IAAI,QAAQ,qBAAqB,wBAE/B,MAAM,IAAI,MACR,qEACF;CAEF,OAAO;EACL,aAAa,EAAE,OAAO,QAAQ,sBAAsB,QAAQ,WAAW;EACvE,WAAW,QAAQ;EACnB,SAAS,gBAAgB,QAAQ,SAAS;EAC1C,SAAS,gBAAgB,QAAQ,OAAO;EACxC,MAAM,QAAQ,UAAU,KAAK,MAAM,SAAS;GAC1C,SAAS,MAAM;GACf,aAAa,KAAK;GAClB,QAAQ,KAAK,UAAU,KAAK,WAAW,KAAK;GAC5C,YAAY;GACZ,qBAAqB;IACnB,KAAK,KAAK;IACV,WAAW,KAAK;GAClB;EACF,EAAE;EACF,aAAa,QAAQ,WAAW,EAAE,OAAO,QAAQ,SAAS,IAAI,KAAA;EAC9D,cAAc,QAAQ,OAAO,EAAE,OAAO,QAAQ,KAAK,IAAI,KAAA;CACzD;AACF"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { t as QuickBooksWriteError } from "./errors-Dt7tUtsB.js";
|
|
2
|
+
import { r as validateQuickBooksInvoiceRequest, t as mapInvoiceToQBO } from "./invoice-request-D6XcgNzI.js";
|
|
1
3
|
import { createHmac } from "node:crypto";
|
|
2
4
|
//#region \0rolldown/runtime.js
|
|
3
5
|
var __create = Object.create;
|
|
@@ -132,7 +134,7 @@ var QuickBooksProvider = class {
|
|
|
132
134
|
* Refresh the OAuth access token
|
|
133
135
|
*/
|
|
134
136
|
async refreshAccessToken() {
|
|
135
|
-
const OAuthClient = (await import("./OAuthClient-
|
|
137
|
+
const OAuthClient = (await import("./OAuthClient-CF65pAW_.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1))).default;
|
|
136
138
|
const redirectUri = this.options.redirectUri || "https://developer.intuit.com/v2/OAuth2Playground/RedirectUrl";
|
|
137
139
|
const oauthClient = new OAuthClient({
|
|
138
140
|
clientId: this.options.clientId,
|
|
@@ -155,46 +157,71 @@ var QuickBooksProvider = class {
|
|
|
155
157
|
/**
|
|
156
158
|
* Make an authenticated request to the QBO API with timeout and retry support
|
|
157
159
|
*/
|
|
158
|
-
async request(method, endpoint, body) {
|
|
160
|
+
async request(method, endpoint, body, invoiceRequest) {
|
|
161
|
+
const serializedBody = body === void 0 ? void 0 : JSON.stringify(body);
|
|
162
|
+
const realmId = this.realmId;
|
|
163
|
+
const environment = this.options.environment === "production" ? "production" : "sandbox";
|
|
164
|
+
if (invoiceRequest) {
|
|
165
|
+
if (method !== "POST" || endpoint !== "invoice") throw new Error("QuickBooks request identity is only supported for invoice creation");
|
|
166
|
+
validateQuickBooksInvoiceRequest(invoiceRequest, realmId, environment, serializedBody);
|
|
167
|
+
}
|
|
168
|
+
const requestId = invoiceRequest?.requestId;
|
|
169
|
+
const payloadHash = invoiceRequest?.payloadHash;
|
|
170
|
+
const url = new URL(`${this.baseUrl}/v3/company/${realmId}/${endpoint}`);
|
|
171
|
+
if (requestId) url.searchParams.set("requestid", requestId);
|
|
172
|
+
const timeout = this.options.timeout ?? 3e4;
|
|
173
|
+
const maxRetries = method === "GET" || requestId ? this.options.maxRetries ?? 3 : 0;
|
|
174
|
+
const responseEntity = [
|
|
175
|
+
"Customer",
|
|
176
|
+
"Vendor",
|
|
177
|
+
"Bill",
|
|
178
|
+
"Invoice",
|
|
179
|
+
"Payment"
|
|
180
|
+
].find((entity) => entity.toLowerCase() === endpoint.split(/[/?]/, 1)[0]);
|
|
159
181
|
const accessToken = await this.ensureAccessToken();
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const maxRetries = this.options.maxRetries || 3;
|
|
163
|
-
let lastError = null;
|
|
164
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) try {
|
|
182
|
+
let uncertain = requestId !== void 0;
|
|
183
|
+
for (let attempt = 0;; attempt++) {
|
|
165
184
|
const controller = new AbortController();
|
|
166
185
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
186
|
+
let status;
|
|
187
|
+
let failure;
|
|
167
188
|
try {
|
|
168
|
-
const response = await fetch(url, {
|
|
189
|
+
const response = await fetch(url.toString(), {
|
|
169
190
|
method,
|
|
170
191
|
headers: {
|
|
171
192
|
Authorization: `Bearer ${accessToken}`,
|
|
172
193
|
Accept: "application/json",
|
|
173
194
|
"Content-Type": "application/json"
|
|
174
195
|
},
|
|
175
|
-
body:
|
|
196
|
+
body: serializedBody,
|
|
176
197
|
signal: controller.signal
|
|
177
198
|
});
|
|
178
|
-
|
|
179
|
-
if (!response.ok) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
199
|
+
status = response.status;
|
|
200
|
+
if (!response.ok) throw new Error(`QBO API error (${status}): ${await response.text()}`);
|
|
201
|
+
const result = await response.json();
|
|
202
|
+
if (method !== "GET" && responseEntity && (typeof result?.[responseEntity]?.Id !== "string" || !result[responseEntity].Id.trim())) throw new Error(`QBO response is missing ${responseEntity}.Id`);
|
|
203
|
+
return result;
|
|
204
|
+
} catch (error) {
|
|
205
|
+
failure = error;
|
|
206
|
+
uncertain ||= status === void 0 || status >= 500 || status >= 200 && status < 300;
|
|
185
207
|
} finally {
|
|
186
208
|
clearTimeout(timeoutId);
|
|
187
209
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
210
|
+
if (!(status === void 0 || status === 429 || status >= 500 || status >= 200 && status < 300) || attempt >= maxRetries) {
|
|
211
|
+
if (method !== "GET") throw new QuickBooksWriteError({
|
|
212
|
+
realmId,
|
|
213
|
+
environment,
|
|
214
|
+
endpoint,
|
|
215
|
+
requestId,
|
|
216
|
+
status,
|
|
217
|
+
payloadHash,
|
|
218
|
+
outcome: uncertain ? "unknown" : "rejected",
|
|
219
|
+
cause: failure
|
|
220
|
+
});
|
|
221
|
+
throw failure;
|
|
194
222
|
}
|
|
195
|
-
|
|
223
|
+
await sleep(2 ** attempt * 1e3);
|
|
196
224
|
}
|
|
197
|
-
throw lastError || /* @__PURE__ */ new Error("Request failed after retries");
|
|
198
225
|
}
|
|
199
226
|
/**
|
|
200
227
|
* Execute a QBO query with pagination support
|
|
@@ -259,10 +286,11 @@ var QuickBooksInvoiceOperations = class {
|
|
|
259
286
|
this.provider = provider;
|
|
260
287
|
}
|
|
261
288
|
async push(invoice) {
|
|
289
|
+
if (invoice.externalId && invoice.quickbooksRequest) throw new Error("QuickBooks invoice request identity cannot be used for updates");
|
|
262
290
|
const qboInvoice = mapInvoiceToQBO(invoice);
|
|
263
291
|
return {
|
|
264
292
|
action: "created",
|
|
265
|
-
externalId: (await this.provider.request("POST", "invoice", qboInvoice)).Invoice.Id,
|
|
293
|
+
externalId: (await this.provider.request("POST", "invoice", qboInvoice, invoice.quickbooksRequest)).Invoice.Id,
|
|
266
294
|
syncedAt: /* @__PURE__ */ new Date()
|
|
267
295
|
};
|
|
268
296
|
}
|
|
@@ -280,6 +308,7 @@ var QuickBooksInvoiceOperations = class {
|
|
|
280
308
|
}
|
|
281
309
|
async sync(invoice) {
|
|
282
310
|
if (invoice.externalId) {
|
|
311
|
+
if (invoice.quickbooksRequest) throw new Error("QuickBooks invoice request identity cannot be used for updates");
|
|
283
312
|
const existing = await this.provider.request("GET", `invoice/${invoice.externalId}`);
|
|
284
313
|
const qboInvoice = {
|
|
285
314
|
...mapInvoiceToQBO(invoice),
|
|
@@ -617,27 +646,6 @@ function mapQBOToCustomer(qbo) {
|
|
|
617
646
|
raw: qbo
|
|
618
647
|
};
|
|
619
648
|
}
|
|
620
|
-
function mapInvoiceToQBO(invoice) {
|
|
621
|
-
if (invoice.collectionMethod === "charge_automatically") throw new Error("QuickBooks does not support charge_automatically invoice collection");
|
|
622
|
-
return {
|
|
623
|
-
CustomerRef: { value: invoice.customerExternalId || invoice.customerId },
|
|
624
|
-
DocNumber: invoice.invoiceNumber,
|
|
625
|
-
TxnDate: formatLocalDate(invoice.issueDate),
|
|
626
|
-
DueDate: formatLocalDate(invoice.dueDate),
|
|
627
|
-
Line: invoice.lineItems.map((item, idx) => ({
|
|
628
|
-
LineNum: idx + 1,
|
|
629
|
-
Description: item.description,
|
|
630
|
-
Amount: item.amount ?? item.quantity * item.unitPrice,
|
|
631
|
-
DetailType: "SalesItemLineDetail",
|
|
632
|
-
SalesItemLineDetail: {
|
|
633
|
-
Qty: item.quantity,
|
|
634
|
-
UnitPrice: item.unitPrice
|
|
635
|
-
}
|
|
636
|
-
})),
|
|
637
|
-
CurrencyRef: invoice.currency ? { value: invoice.currency } : void 0,
|
|
638
|
-
CustomerMemo: invoice.memo ? { value: invoice.memo } : void 0
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
649
|
function mapQBOToInvoice(qbo) {
|
|
642
650
|
const balance = qbo.Balance ?? 0;
|
|
643
651
|
const totalAmount = qbo.TotalAmt ?? 0;
|
|
@@ -771,4 +779,4 @@ function mapQBOToAddress(qbo) {
|
|
|
771
779
|
//#endregion
|
|
772
780
|
export { QuickBooksProvider, __toCommonJS as a, __require as i, __esmMin as n, __exportAll as r, __commonJSMin as t };
|
|
773
781
|
|
|
774
|
-
//# sourceMappingURL=quickbooks-
|
|
782
|
+
//# sourceMappingURL=quickbooks-DLkypnT9.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickbooks-DLkypnT9.js","names":[],"sources":["../../src/providers/quickbooks/index.ts"],"sourcesContent":["/**\n * QuickBooks Online Provider\n *\n * Implements the AccountingProvider interface for QuickBooks Online.\n * Uses the Intuit OAuth2 library for authentication and the QBO API for operations.\n */\n\n/// <reference path=\"../../intuit-oauth.d.ts\" />\n\nimport { createHmac } from 'node:crypto';\nimport { QuickBooksWriteError } from '../../errors.js';\nimport type {\n AccountingProvider,\n Address,\n AuditDiscrepancy,\n AuditMatch,\n AuditOperations,\n AuditReport,\n BillInput,\n BillOperations,\n CustomerInput,\n CustomerOperations,\n DateRange,\n ExternalBill,\n ExternalCustomer,\n ExternalInvoice,\n ExternalPayment,\n ExternalRecord,\n ExternalVendor,\n FieldDiff,\n InvoiceInput,\n InvoiceOperations,\n ListOptions,\n PaymentInput,\n PaymentOperations,\n QuickBooksInvoiceRequest,\n QuickBooksOptions,\n SyncResult,\n TokenSet,\n VendorInput,\n VendorOperations,\n WebhookEvent,\n WebhookOperations,\n} from '../../types.js';\nimport {\n mapInvoiceToQBO,\n validateQuickBooksInvoiceRequest,\n} from './invoice-request.js';\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Format a Date to YYYY-MM-DD in local timezone (not UTC)\n * This prevents timezone conversion issues where dates shift by a day\n */\nfunction formatLocalDate(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n}\n\n/**\n * Sleep for a given number of milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Compare two values for equality (handles dates, objects, etc.)\n */\nfunction valuesEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n if (typeof a === 'number' && typeof b === 'number') {\n // Allow for floating point precision issues\n return Math.abs(a - b) < 0.01;\n }\n return false;\n}\n\n// =============================================================================\n// QuickBooks Provider\n// =============================================================================\n\n/**\n * QuickBooks Online accounting provider\n */\nexport class QuickBooksProvider implements AccountingProvider {\n readonly type = 'quickbooks' as const;\n\n private options: QuickBooksOptions;\n private accessToken: string | null = null;\n private tokenExpiresAt: Date | null = null;\n\n readonly customers: CustomerOperations;\n readonly invoices: InvoiceOperations;\n readonly vendors: VendorOperations;\n readonly bills: BillOperations;\n readonly payments: PaymentOperations;\n readonly audit: AuditOperations;\n readonly webhooks: WebhookOperations;\n\n constructor(options: QuickBooksOptions) {\n this.options = {\n timeout: 30000,\n maxRetries: 3,\n ...options,\n };\n\n // Initialize operation handlers\n this.customers = new QuickBooksCustomerOperations(this);\n this.invoices = new QuickBooksInvoiceOperations(this);\n this.vendors = new QuickBooksVendorOperations(this);\n this.bills = new QuickBooksBillOperations(this);\n this.payments = new QuickBooksPaymentOperations(this);\n this.audit = new QuickBooksAuditOperations(this);\n this.webhooks = new QuickBooksWebhookOperations(this.options);\n }\n\n /**\n * Get the QBO API base URL\n */\n get baseUrl(): string {\n return this.options.environment === 'production'\n ? 'https://quickbooks.api.intuit.com'\n : 'https://sandbox-quickbooks.api.intuit.com';\n }\n\n /**\n * Get the company/realm ID\n */\n get realmId(): string {\n return this.options.realmId;\n }\n\n /**\n * Ensure we have a valid access token, refreshing if needed\n */\n async ensureAccessToken(): Promise<string> {\n // Check if current token is still valid (with 5 min buffer)\n if (this.accessToken && this.tokenExpiresAt) {\n const bufferMs = 5 * 60 * 1000;\n if (new Date().getTime() < this.tokenExpiresAt.getTime() - bufferMs) {\n return this.accessToken;\n }\n }\n\n // Refresh the token\n const tokens = await this.refreshAccessToken();\n this.accessToken = tokens.accessToken;\n this.tokenExpiresAt = tokens.expiresAt;\n\n // Update stored refresh token so subsequent refreshes use the new token\n this.options.refreshToken = tokens.refreshToken;\n\n // Notify callback if provided\n if (this.options.onTokenRefresh) {\n await this.options.onTokenRefresh(tokens);\n }\n\n return this.accessToken;\n }\n\n /**\n * Refresh the OAuth access token\n */\n private async refreshAccessToken(): Promise<TokenSet> {\n // Import intuit-oauth dynamically\n const OAuthClient = (await import('intuit-oauth')).default;\n\n const redirectUri =\n this.options.redirectUri ||\n 'https://developer.intuit.com/v2/OAuth2Playground/RedirectUrl';\n\n const oauthClient = new OAuthClient({\n clientId: this.options.clientId,\n clientSecret: this.options.clientSecret,\n environment:\n this.options.environment === 'production' ? 'production' : 'sandbox',\n redirectUri,\n });\n\n oauthClient.setToken({\n refresh_token: this.options.refreshToken,\n access_token: this.accessToken || '',\n });\n\n const response = await oauthClient.refresh();\n const token = response.getJson();\n\n return {\n accessToken: token.access_token,\n refreshToken: token.refresh_token,\n expiresAt: new Date(Date.now() + token.expires_in * 1000),\n tokenType: token.token_type,\n };\n }\n\n /**\n * Make an authenticated request to the QBO API with timeout and retry support\n */\n async request<T>(\n method: 'GET' | 'POST' | 'DELETE',\n endpoint: string,\n body?: unknown,\n invoiceRequest?: QuickBooksInvoiceRequest,\n ): Promise<T> {\n // Freeze identity and bytes before any asynchronous work.\n const serializedBody =\n body === undefined ? undefined : JSON.stringify(body);\n const realmId = this.realmId;\n const environment =\n this.options.environment === 'production' ? 'production' : 'sandbox';\n if (invoiceRequest) {\n if (method !== 'POST' || endpoint !== 'invoice') {\n throw new Error(\n 'QuickBooks request identity is only supported for invoice creation',\n );\n }\n validateQuickBooksInvoiceRequest(\n invoiceRequest,\n realmId,\n environment,\n serializedBody,\n );\n }\n const requestId = invoiceRequest?.requestId;\n const payloadHash = invoiceRequest?.payloadHash;\n const url = new URL(`${this.baseUrl}/v3/company/${realmId}/${endpoint}`);\n if (requestId) url.searchParams.set('requestid', requestId);\n const timeout = this.options.timeout ?? 30000;\n const maxRetries =\n method === 'GET' || requestId ? (this.options.maxRetries ?? 3) : 0;\n const responseEntity = [\n 'Customer',\n 'Vendor',\n 'Bill',\n 'Invoice',\n 'Payment',\n ].find((entity) => entity.toLowerCase() === endpoint.split(/[/?]/, 1)[0]);\n const accessToken = await this.ensureAccessToken();\n // A persisted identity may have been sent by an earlier worker. Without a\n // durable attempt history, even its first observed 4xx cannot prove that\n // the logical write was never accepted. Fail closed across process retries.\n let uncertain = requestId !== undefined;\n\n for (let attempt = 0; ; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n let status: number | undefined;\n let failure: unknown;\n try {\n const response = await fetch(url.toString(), {\n method,\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: serializedBody,\n signal: controller.signal,\n });\n status = response.status;\n if (!response.ok) {\n throw new Error(\n `QBO API error (${status}): ${await response.text()}`,\n );\n }\n const result = await response.json();\n // Every supported write must return a usable remote identity. Validate\n // inside this boundary so malformed successes cannot escape reconciliation.\n if (\n method !== 'GET' &&\n responseEntity &&\n (typeof result?.[responseEntity]?.Id !== 'string' ||\n !result[responseEntity].Id.trim())\n ) {\n throw new Error(`QBO response is missing ${responseEntity}.Id`);\n }\n return result as T;\n } catch (error) {\n failure = error;\n uncertain ||=\n status === undefined ||\n status >= 500 ||\n (status >= 200 && status < 300);\n } finally {\n clearTimeout(timeoutId);\n }\n const retryable =\n status === undefined ||\n status === 429 ||\n status >= 500 ||\n (status >= 200 && status < 300);\n if (!retryable || attempt >= maxRetries) {\n if (method !== 'GET') {\n throw new QuickBooksWriteError({\n realmId,\n environment,\n endpoint,\n requestId,\n status,\n payloadHash,\n outcome: uncertain ? 'unknown' : 'rejected',\n cause: failure,\n });\n }\n throw failure;\n }\n await sleep(2 ** attempt * 1000);\n }\n }\n\n /**\n * Execute a QBO query with pagination support\n */\n async queryAll<T>(\n entity: string,\n whereClause?: string,\n maxResults = 1000,\n ): Promise<T[]> {\n const results: T[] = [];\n let startPosition = 1;\n const pageSize = 100; // QBO max is 1000, but smaller pages are safer\n\n while (results.length < maxResults) {\n let query = `SELECT * FROM ${entity}`;\n if (whereClause) {\n query += ` WHERE ${whereClause}`;\n }\n query += ` MAXRESULTS ${pageSize} STARTPOSITION ${startPosition}`;\n\n const response = await this.request<{\n QueryResponse: Record<string, T[] | undefined>;\n }>('GET', `query?query=${encodeURIComponent(query)}`);\n\n const items = response.QueryResponse[entity] || [];\n results.push(...items);\n\n // If we got fewer than pageSize, we've reached the end\n if (items.length < pageSize) {\n break;\n }\n\n startPosition += pageSize;\n }\n\n return results;\n }\n}\n\n// =============================================================================\n// Customer Operations\n// =============================================================================\n\nclass QuickBooksCustomerOperations implements CustomerOperations {\n constructor(private provider: QuickBooksProvider) {}\n\n async push(customer: CustomerInput): Promise<SyncResult> {\n const qboCustomer = mapCustomerToQBO(customer);\n\n const response = await this.provider.request<{ Customer: QBOCustomer }>(\n 'POST',\n 'customer',\n qboCustomer,\n );\n\n return {\n action: 'created',\n externalId: response.Customer.Id,\n syncedAt: new Date(),\n };\n }\n\n async pull(externalId: string): Promise<ExternalCustomer> {\n const response = await this.provider.request<{ Customer: QBOCustomer }>(\n 'GET',\n `customer/${externalId}`,\n );\n\n return mapQBOToCustomer(response.Customer);\n }\n\n async list(options?: ListOptions): Promise<ExternalCustomer[]> {\n const limit = options?.limit || 1000;\n const customers = await this.provider.queryAll<QBOCustomer>(\n 'Customer',\n undefined,\n limit,\n );\n return customers.map(mapQBOToCustomer);\n }\n\n async sync(customer: CustomerInput): Promise<SyncResult> {\n if (customer.externalId) {\n // Update existing\n const existing = await this.provider.request<{ Customer: QBOCustomer }>(\n 'GET',\n `customer/${customer.externalId}`,\n );\n\n const qboCustomer: QBOCustomerUpdate = {\n ...mapCustomerToQBO(customer),\n Id: customer.externalId,\n SyncToken: existing.Customer.SyncToken,\n };\n\n await this.provider.request('POST', 'customer', qboCustomer);\n\n return {\n action: 'updated',\n externalId: customer.externalId,\n syncedAt: new Date(),\n };\n }\n\n return this.push(customer);\n }\n}\n\n// =============================================================================\n// Invoice Operations\n// =============================================================================\n\nclass QuickBooksInvoiceOperations implements InvoiceOperations {\n constructor(private provider: QuickBooksProvider) {}\n\n async push(invoice: InvoiceInput): Promise<SyncResult> {\n if (invoice.externalId && invoice.quickbooksRequest)\n throw new Error(\n 'QuickBooks invoice request identity cannot be used for updates',\n );\n const qboInvoice = mapInvoiceToQBO(invoice);\n\n const response = await this.provider.request<{ Invoice: QBOInvoice }>(\n 'POST',\n 'invoice',\n qboInvoice,\n invoice.quickbooksRequest,\n );\n\n return {\n action: 'created',\n externalId: response.Invoice.Id,\n syncedAt: new Date(),\n };\n }\n\n async pull(externalId: string): Promise<ExternalInvoice> {\n const response = await this.provider.request<{ Invoice: QBOInvoice }>(\n 'GET',\n `invoice/${externalId}`,\n );\n\n return mapQBOToInvoice(response.Invoice);\n }\n\n async list(options?: ListOptions): Promise<ExternalInvoice[]> {\n const limit = options?.limit || 1000;\n let whereClause: string | undefined;\n\n if (options?.startDate) {\n whereClause = `TxnDate >= '${formatLocalDate(options.startDate)}'`;\n if (options?.endDate) {\n whereClause += ` AND TxnDate <= '${formatLocalDate(options.endDate)}'`;\n }\n }\n\n const invoices = await this.provider.queryAll<QBOInvoice>(\n 'Invoice',\n whereClause,\n limit,\n );\n return invoices.map(mapQBOToInvoice);\n }\n\n async sync(invoice: InvoiceInput): Promise<SyncResult> {\n if (invoice.externalId) {\n if (invoice.quickbooksRequest)\n throw new Error(\n 'QuickBooks invoice request identity cannot be used for updates',\n );\n const existing = await this.provider.request<{ Invoice: QBOInvoice }>(\n 'GET',\n `invoice/${invoice.externalId}`,\n );\n\n const qboInvoice: QBOInvoiceUpdate = {\n ...mapInvoiceToQBO(invoice),\n Id: invoice.externalId,\n SyncToken: existing.Invoice.SyncToken,\n };\n\n await this.provider.request('POST', 'invoice', qboInvoice);\n\n return {\n action: 'updated',\n externalId: invoice.externalId,\n syncedAt: new Date(),\n };\n }\n\n return this.push(invoice);\n }\n\n async send(externalId: string): Promise<void> {\n await this.provider.request('POST', `invoice/${externalId}/send`);\n }\n\n async void(externalId: string): Promise<void> {\n const existing = await this.provider.request<{ Invoice: QBOInvoice }>(\n 'GET',\n `invoice/${externalId}`,\n );\n\n await this.provider.request('POST', 'invoice', {\n Id: externalId,\n SyncToken: existing.Invoice.SyncToken,\n sparse: true,\n // QBO doesn't have a Void field - you delete the invoice instead\n // or create a credit memo. For now, we'll use sparse update to mark private note\n PrivateNote: 'VOIDED',\n });\n }\n}\n\n// =============================================================================\n// Vendor Operations\n// =============================================================================\n\nclass QuickBooksVendorOperations implements VendorOperations {\n constructor(private provider: QuickBooksProvider) {}\n\n async push(vendor: VendorInput): Promise<SyncResult> {\n const qboVendor = mapVendorToQBO(vendor);\n\n const response = await this.provider.request<{ Vendor: QBOVendor }>(\n 'POST',\n 'vendor',\n qboVendor,\n );\n\n return {\n action: 'created',\n externalId: response.Vendor.Id,\n syncedAt: new Date(),\n };\n }\n\n async pull(externalId: string): Promise<ExternalVendor> {\n const response = await this.provider.request<{ Vendor: QBOVendor }>(\n 'GET',\n `vendor/${externalId}`,\n );\n\n return mapQBOToVendor(response.Vendor);\n }\n\n async list(options?: ListOptions): Promise<ExternalVendor[]> {\n const limit = options?.limit || 1000;\n const vendors = await this.provider.queryAll<QBOVendor>(\n 'Vendor',\n undefined,\n limit,\n );\n return vendors.map(mapQBOToVendor);\n }\n\n async sync(vendor: VendorInput): Promise<SyncResult> {\n if (vendor.externalId) {\n const existing = await this.provider.request<{ Vendor: QBOVendor }>(\n 'GET',\n `vendor/${vendor.externalId}`,\n );\n\n const qboVendor: QBOVendorUpdate = {\n ...mapVendorToQBO(vendor),\n Id: vendor.externalId,\n SyncToken: existing.Vendor.SyncToken,\n };\n\n await this.provider.request('POST', 'vendor', qboVendor);\n\n return {\n action: 'updated',\n externalId: vendor.externalId,\n syncedAt: new Date(),\n };\n }\n\n return this.push(vendor);\n }\n}\n\n// =============================================================================\n// Bill Operations\n// =============================================================================\n\nclass QuickBooksBillOperations implements BillOperations {\n constructor(private provider: QuickBooksProvider) {}\n\n async push(bill: BillInput): Promise<SyncResult> {\n const qboBill = mapBillToQBO(bill);\n\n const response = await this.provider.request<{ Bill: QBOBill }>(\n 'POST',\n 'bill',\n qboBill,\n );\n\n return {\n action: 'created',\n externalId: response.Bill.Id,\n syncedAt: new Date(),\n };\n }\n\n async pull(externalId: string): Promise<ExternalBill> {\n const response = await this.provider.request<{ Bill: QBOBill }>(\n 'GET',\n `bill/${externalId}`,\n );\n\n return mapQBOToBill(response.Bill);\n }\n\n async list(options?: ListOptions): Promise<ExternalBill[]> {\n const limit = options?.limit || 1000;\n let whereClause: string | undefined;\n\n if (options?.startDate) {\n whereClause = `TxnDate >= '${formatLocalDate(options.startDate)}'`;\n if (options?.endDate) {\n whereClause += ` AND TxnDate <= '${formatLocalDate(options.endDate)}'`;\n }\n }\n\n const bills = await this.provider.queryAll<QBOBill>(\n 'Bill',\n whereClause,\n limit,\n );\n return bills.map(mapQBOToBill);\n }\n\n async sync(bill: BillInput): Promise<SyncResult> {\n if (bill.externalId) {\n const existing = await this.provider.request<{ Bill: QBOBill }>(\n 'GET',\n `bill/${bill.externalId}`,\n );\n\n const qboBill: QBOBillUpdate = {\n ...mapBillToQBO(bill),\n Id: bill.externalId,\n SyncToken: existing.Bill.SyncToken,\n };\n\n await this.provider.request('POST', 'bill', qboBill);\n\n return {\n action: 'updated',\n externalId: bill.externalId,\n syncedAt: new Date(),\n };\n }\n\n return this.push(bill);\n }\n}\n\n// =============================================================================\n// Payment Operations\n// =============================================================================\n\nclass QuickBooksPaymentOperations implements PaymentOperations {\n constructor(private provider: QuickBooksProvider) {}\n\n async pull(externalId: string): Promise<ExternalPayment> {\n const response = await this.provider.request<{ Payment: QBOPayment }>(\n 'GET',\n `payment/${externalId}`,\n );\n\n return mapQBOToPayment(response.Payment);\n }\n\n async list(options?: ListOptions): Promise<ExternalPayment[]> {\n const limit = options?.limit || 1000;\n let whereClause: string | undefined;\n\n if (options?.startDate) {\n whereClause = `TxnDate >= '${formatLocalDate(options.startDate)}'`;\n if (options?.endDate) {\n whereClause += ` AND TxnDate <= '${formatLocalDate(options.endDate)}'`;\n }\n }\n\n const payments = await this.provider.queryAll<QBOPayment>(\n 'Payment',\n whereClause,\n limit,\n );\n return payments.map(mapQBOToPayment);\n }\n}\n\n// =============================================================================\n// Audit Operations\n// =============================================================================\n\nclass QuickBooksAuditOperations implements AuditOperations {\n constructor(private provider: QuickBooksProvider) {}\n\n async reconcileCustomers(\n locals: CustomerInput[],\n ): Promise<AuditReport<CustomerInput>> {\n const externals = await this.provider.customers.list({ limit: 10000 });\n return reconcileRecords(\n locals,\n externals,\n (l) => l.externalId,\n (e) => e.externalId,\n compareCustomer,\n );\n }\n\n async reconcileInvoices(\n locals: InvoiceInput[],\n dateRange?: DateRange,\n ): Promise<AuditReport<InvoiceInput>> {\n const externals = await this.provider.invoices.list({\n limit: 10000,\n startDate: dateRange?.start,\n endDate: dateRange?.end,\n });\n return reconcileRecords(\n locals,\n externals,\n (l) => l.externalId,\n (e) => e.externalId,\n compareInvoice,\n );\n }\n\n async reconcileVendors(\n locals: VendorInput[],\n ): Promise<AuditReport<VendorInput>> {\n const externals = await this.provider.vendors.list({ limit: 10000 });\n return reconcileRecords(\n locals,\n externals,\n (l) => l.externalId,\n (e) => e.externalId,\n compareVendor,\n );\n }\n\n async reconcileBills(\n locals: BillInput[],\n dateRange?: DateRange,\n ): Promise<AuditReport<BillInput>> {\n const externals = await this.provider.bills.list({\n limit: 10000,\n startDate: dateRange?.start,\n endDate: dateRange?.end,\n });\n return reconcileRecords(\n locals,\n externals,\n (l) => l.externalId,\n (e) => e.externalId,\n compareBill,\n );\n }\n\n async reconcilePayments(\n locals: PaymentInput[],\n dateRange?: DateRange,\n ): Promise<AuditReport<PaymentInput>> {\n const externals = await this.provider.payments.list({\n limit: 10000,\n startDate: dateRange?.start,\n endDate: dateRange?.end,\n });\n return reconcileRecords(\n locals,\n externals,\n (l) => l.externalId,\n (e) => e.externalId,\n comparePayment,\n );\n }\n}\n\n/**\n * Generic reconciliation function with field comparison\n */\nfunction reconcileRecords<TLocal, TExternal extends ExternalRecord>(\n locals: TLocal[],\n externals: TExternal[],\n getLocalExternalId: (local: TLocal) => string | undefined,\n getExternalId: (external: TExternal) => string,\n compareFields: (local: TLocal, external: TExternal) => FieldDiff[],\n): AuditReport<TLocal> {\n const externalMap = new Map(externals.map((e) => [getExternalId(e), e]));\n const matchedExternalIds = new Set<string>();\n\n const matched: AuditMatch<TLocal>[] = [];\n const localOnly: TLocal[] = [];\n const discrepancies: AuditDiscrepancy<TLocal>[] = [];\n\n for (const local of locals) {\n const externalId = getLocalExternalId(local);\n if (externalId && externalMap.has(externalId)) {\n const external = externalMap.get(externalId)!;\n matchedExternalIds.add(externalId);\n\n // Compare fields\n const differences = compareFields(local, external);\n\n if (differences.length === 0) {\n matched.push({\n local,\n external,\n status: 'identical',\n });\n } else {\n discrepancies.push({\n local,\n external,\n differences,\n });\n }\n } else {\n localOnly.push(local);\n }\n }\n\n const externalOnly = externals.filter(\n (e) => !matchedExternalIds.has(getExternalId(e)),\n );\n\n return {\n provider: 'quickbooks',\n auditedAt: new Date(),\n matched,\n localOnly,\n externalOnly,\n discrepancies,\n summary: {\n total: locals.length + externalOnly.length,\n matched: matched.length,\n localOnly: localOnly.length,\n externalOnly: externalOnly.length,\n discrepancies: discrepancies.length,\n },\n };\n}\n\n// Field comparison functions\nfunction compareCustomer(\n local: CustomerInput,\n external: ExternalCustomer,\n): FieldDiff[] {\n const diffs: FieldDiff[] = [];\n\n if (local.name !== external.name) {\n diffs.push({\n field: 'name',\n localValue: local.name,\n externalValue: external.name,\n });\n }\n if (local.email !== external.email) {\n diffs.push({\n field: 'email',\n localValue: local.email,\n externalValue: external.email,\n });\n }\n\n return diffs;\n}\n\nfunction compareInvoice(\n local: InvoiceInput,\n external: ExternalInvoice,\n): FieldDiff[] {\n const diffs: FieldDiff[] = [];\n\n if (!valuesEqual(local.totalAmount, external.totalAmount)) {\n diffs.push({\n field: 'totalAmount',\n localValue: local.totalAmount,\n externalValue: external.totalAmount,\n });\n }\n if (local.invoiceNumber !== external.invoiceNumber) {\n diffs.push({\n field: 'invoiceNumber',\n localValue: local.invoiceNumber,\n externalValue: external.invoiceNumber,\n });\n }\n\n return diffs;\n}\n\nfunction compareVendor(\n local: VendorInput,\n external: ExternalVendor,\n): FieldDiff[] {\n const diffs: FieldDiff[] = [];\n\n if (local.name !== external.name) {\n diffs.push({\n field: 'name',\n localValue: local.name,\n externalValue: external.name,\n });\n }\n if (local.email !== external.email) {\n diffs.push({\n field: 'email',\n localValue: local.email,\n externalValue: external.email,\n });\n }\n\n return diffs;\n}\n\nfunction compareBill(local: BillInput, external: ExternalBill): FieldDiff[] {\n const diffs: FieldDiff[] = [];\n\n if (!valuesEqual(local.totalAmount, external.totalAmount)) {\n diffs.push({\n field: 'totalAmount',\n localValue: local.totalAmount,\n externalValue: external.totalAmount,\n });\n }\n\n return diffs;\n}\n\nfunction comparePayment(\n local: PaymentInput,\n external: ExternalPayment,\n): FieldDiff[] {\n const diffs: FieldDiff[] = [];\n\n if (!valuesEqual(local.amount, external.amount)) {\n diffs.push({\n field: 'amount',\n localValue: local.amount,\n externalValue: external.amount,\n });\n }\n\n return diffs;\n}\n\n// =============================================================================\n// Webhook Operations\n// =============================================================================\n\nclass QuickBooksWebhookOperations implements WebhookOperations {\n constructor(private options: QuickBooksOptions) {}\n\n /**\n * Verify webhook signature using HMAC-SHA256\n * @see https://developer.intuit.com/app/developer/qbo/docs/develop/webhooks/verify-webhooks\n */\n verify(payload: string, signature: string, secret: string): boolean {\n // Use provided secret or fall back to configured webhook verifier token\n const verifierToken = secret || this.options.webhookVerifierToken;\n\n if (!verifierToken) {\n throw new Error(\n 'Webhook verifier token not provided. Pass it as the secret parameter or configure webhookVerifierToken in options.',\n );\n }\n\n // QBO uses HMAC-SHA256 and base64 encodes the signature\n const hmac = createHmac('sha256', verifierToken);\n hmac.update(payload);\n const expectedSignature = hmac.digest('base64');\n\n // Constant-time comparison to prevent timing attacks\n if (signature.length !== expectedSignature.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < signature.length; i++) {\n result |= signature.charCodeAt(i) ^ expectedSignature.charCodeAt(i);\n }\n return result === 0;\n }\n\n parse(payload: string): WebhookEvent {\n let data: QBOWebhookPayload;\n try {\n data = JSON.parse(payload) as QBOWebhookPayload;\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown JSON parse error';\n throw new Error(`Invalid QuickBooks webhook payload: ${message}`);\n }\n\n // QBO webhook payload structure\n const eventNotifications = data.eventNotifications || [];\n const firstEvent = eventNotifications[0]?.dataChangeEvent?.entities?.[0];\n\n return {\n type: firstEvent?.operation || 'unknown',\n provider: 'quickbooks',\n timestamp: new Date(),\n payload: data,\n resourceType: mapQBOResourceType(firstEvent?.name),\n resourceId: firstEvent?.id,\n };\n }\n}\n\nfunction mapQBOResourceType(\n name?: string,\n): WebhookEvent['resourceType'] | undefined {\n switch (name?.toLowerCase()) {\n case 'customer':\n return 'customer';\n case 'invoice':\n return 'invoice';\n case 'payment':\n return 'payment';\n case 'vendor':\n return 'vendor';\n case 'bill':\n return 'bill';\n default:\n return undefined;\n }\n}\n\n// =============================================================================\n// Mapping Functions\n// =============================================================================\n\nfunction mapCustomerToQBO(customer: CustomerInput): QBOCustomerCreate {\n return {\n DisplayName: customer.name,\n PrimaryEmailAddr: customer.email ? { Address: customer.email } : undefined,\n PrimaryPhone: customer.phone\n ? { FreeFormNumber: customer.phone }\n : undefined,\n BillAddr: mapAddressToQBO(customer.billingAddress),\n ShipAddr: mapAddressToQBO(customer.shippingAddress),\n CurrencyRef: customer.currency ? { value: customer.currency } : undefined,\n };\n}\n\nfunction mapQBOToCustomer(qbo: QBOCustomer): ExternalCustomer {\n return {\n externalId: qbo.Id,\n provider: 'quickbooks',\n syncedAt: new Date(),\n name: qbo.DisplayName,\n email: qbo.PrimaryEmailAddr?.Address,\n phone: qbo.PrimaryPhone?.FreeFormNumber,\n billingAddress: mapQBOToAddress(qbo.BillAddr),\n balance: qbo.Balance,\n currency: qbo.CurrencyRef?.value,\n raw: qbo,\n };\n}\n\nfunction mapQBOToInvoice(qbo: QBOInvoice): ExternalInvoice {\n const balance = qbo.Balance ?? 0;\n const totalAmount = qbo.TotalAmt ?? 0;\n\n return {\n externalId: qbo.Id,\n provider: 'quickbooks',\n syncedAt: new Date(),\n invoiceNumber: qbo.DocNumber || '',\n customerExternalId: qbo.CustomerRef?.value || '',\n issueDate: new Date(qbo.TxnDate),\n dueDate: new Date(qbo.DueDate),\n subtotal: totalAmount - (qbo.TxnTaxDetail?.TotalTax ?? 0),\n taxAmount: qbo.TxnTaxDetail?.TotalTax ?? 0,\n totalAmount,\n amountPaid: totalAmount - balance,\n balance,\n status: mapInvoiceStatus(balance, totalAmount, qbo.DueDate),\n currency: qbo.CurrencyRef?.value || 'USD',\n raw: qbo,\n };\n}\n\nfunction mapInvoiceStatus(\n balance: number,\n total: number,\n dueDate: string,\n): ExternalInvoice['status'] {\n if (balance === 0) return 'paid';\n if (balance < total) return 'viewed'; // Partial payment\n if (new Date(dueDate) < new Date()) return 'overdue';\n return 'sent';\n}\n\nfunction mapVendorToQBO(vendor: VendorInput): QBOVendorCreate {\n return {\n DisplayName: vendor.name,\n PrimaryEmailAddr: vendor.email ? { Address: vendor.email } : undefined,\n PrimaryPhone: vendor.phone ? { FreeFormNumber: vendor.phone } : undefined,\n BillAddr: mapAddressToQBO(vendor.address),\n TaxIdentifier: vendor.taxId,\n CurrencyRef: vendor.currency ? { value: vendor.currency } : undefined,\n };\n}\n\nfunction mapQBOToVendor(qbo: QBOVendor): ExternalVendor {\n return {\n externalId: qbo.Id,\n provider: 'quickbooks',\n syncedAt: new Date(),\n name: qbo.DisplayName,\n email: qbo.PrimaryEmailAddr?.Address,\n phone: qbo.PrimaryPhone?.FreeFormNumber,\n address: mapQBOToAddress(qbo.BillAddr),\n balance: qbo.Balance,\n currency: qbo.CurrencyRef?.value,\n raw: qbo,\n };\n}\n\nfunction mapBillToQBO(bill: BillInput): QBOBillCreate {\n return {\n VendorRef: { value: bill.vendorExternalId || bill.vendorId },\n DocNumber: bill.billNumber,\n TxnDate: formatLocalDate(bill.billDate),\n DueDate: formatLocalDate(bill.dueDate),\n Line: bill.lineItems.map((item, idx) => ({\n LineNum: idx + 1,\n Description: item.description,\n Amount: item.amount ?? item.quantity * item.unitPrice,\n DetailType: 'AccountBasedExpenseLineDetail' as const,\n AccountBasedExpenseLineDetail: {\n AccountRef: item.accountCode ? { value: item.accountCode } : undefined,\n },\n })),\n CurrencyRef: bill.currency ? { value: bill.currency } : undefined,\n };\n}\n\nfunction mapQBOToBill(qbo: QBOBill): ExternalBill {\n const balance = qbo.Balance ?? 0;\n const totalAmount = qbo.TotalAmt ?? 0;\n\n return {\n externalId: qbo.Id,\n provider: 'quickbooks',\n syncedAt: new Date(),\n billNumber: qbo.DocNumber,\n vendorExternalId: qbo.VendorRef?.value || '',\n billDate: new Date(qbo.TxnDate),\n dueDate: new Date(qbo.DueDate),\n subtotal: totalAmount - (qbo.TxnTaxDetail?.TotalTax ?? 0),\n taxAmount: qbo.TxnTaxDetail?.TotalTax ?? 0,\n totalAmount,\n amountPaid: totalAmount - balance,\n balance,\n status: mapBillStatus(balance, totalAmount, qbo.DueDate),\n currency: qbo.CurrencyRef?.value || 'USD',\n raw: qbo,\n };\n}\n\nfunction mapBillStatus(\n balance: number,\n total: number,\n dueDate: string,\n): ExternalBill['status'] {\n if (balance === 0) return 'paid';\n if (new Date(dueDate) < new Date()) return 'overdue';\n return 'pending';\n}\n\nfunction mapQBOToPayment(qbo: QBOPayment): ExternalPayment {\n return {\n externalId: qbo.Id,\n provider: 'quickbooks',\n syncedAt: new Date(),\n amount: qbo.TotalAmt ?? 0,\n currency: qbo.CurrencyRef?.value || 'USD',\n paidAt: new Date(qbo.TxnDate),\n method: qbo.PaymentMethodRef?.name,\n transactionId: qbo.PaymentRefNum,\n invoiceExternalIds: qbo.Line?.filter((l) => l.LinkedTxn).flatMap(\n (l) => l.LinkedTxn?.map((t) => t.TxnId) || [],\n ),\n status: 'completed',\n raw: qbo,\n };\n}\n\nfunction mapAddressToQBO(address?: Address): QBOAddress | undefined {\n if (!address) return undefined;\n return {\n Line1: address.street1,\n Line2: address.street2,\n City: address.city,\n CountrySubDivisionCode: address.state,\n PostalCode: address.postalCode,\n Country: address.country,\n };\n}\n\nfunction mapQBOToAddress(qbo?: QBOAddress): Address | undefined {\n if (!qbo) return undefined;\n return {\n street1: qbo.Line1,\n street2: qbo.Line2,\n city: qbo.City,\n state: qbo.CountrySubDivisionCode,\n postalCode: qbo.PostalCode,\n country: qbo.Country,\n };\n}\n\n// =============================================================================\n// QBO API Types (internal, strongly typed)\n// =============================================================================\n\ninterface QBORef {\n value: string;\n name?: string;\n}\n\ninterface QBOAddress {\n Line1?: string;\n Line2?: string;\n City?: string;\n CountrySubDivisionCode?: string;\n PostalCode?: string;\n Country?: string;\n}\n\ninterface QBOEmail {\n Address: string;\n}\n\ninterface QBOPhone {\n FreeFormNumber: string;\n}\n\n// Customer types\ninterface QBOCustomerBase {\n DisplayName: string;\n PrimaryEmailAddr?: QBOEmail;\n PrimaryPhone?: QBOPhone;\n BillAddr?: QBOAddress;\n ShipAddr?: QBOAddress;\n Balance?: number;\n CurrencyRef?: QBORef;\n}\n\ninterface QBOCustomerCreate extends QBOCustomerBase {}\n\ninterface QBOCustomerUpdate extends QBOCustomerBase {\n Id: string;\n SyncToken: string;\n}\n\ninterface QBOCustomer extends QBOCustomerBase {\n Id: string;\n SyncToken: string;\n}\n\n// Invoice types\ninterface QBOInvoiceLine {\n LineNum: number;\n Description?: string;\n Amount: number;\n DetailType: 'SalesItemLineDetail';\n SalesItemLineDetail?: {\n Qty?: number;\n UnitPrice?: number;\n ItemRef?: QBORef;\n };\n}\n\ninterface QBOInvoiceBase {\n CustomerRef: QBORef;\n DocNumber?: string;\n TxnDate: string;\n DueDate: string;\n Line: QBOInvoiceLine[];\n TotalAmt?: number;\n Balance?: number;\n TxnTaxDetail?: {\n TotalTax?: number;\n };\n CurrencyRef?: QBORef;\n CustomerMemo?: { value: string };\n}\n\ninterface QBOInvoiceUpdate extends QBOInvoiceBase {\n Id: string;\n SyncToken: string;\n}\n\ninterface QBOInvoice extends QBOInvoiceBase {\n Id: string;\n SyncToken: string;\n}\n\n// Vendor types\ninterface QBOVendorBase {\n DisplayName: string;\n PrimaryEmailAddr?: QBOEmail;\n PrimaryPhone?: QBOPhone;\n BillAddr?: QBOAddress;\n Balance?: number;\n TaxIdentifier?: string;\n CurrencyRef?: QBORef;\n}\n\ninterface QBOVendorCreate extends QBOVendorBase {}\n\ninterface QBOVendorUpdate extends QBOVendorBase {\n Id: string;\n SyncToken: string;\n}\n\ninterface QBOVendor extends QBOVendorBase {\n Id: string;\n SyncToken: string;\n}\n\n// Bill types\ninterface QBOBillLine {\n LineNum: number;\n Description?: string;\n Amount: number;\n DetailType: 'AccountBasedExpenseLineDetail';\n AccountBasedExpenseLineDetail?: {\n AccountRef?: QBORef;\n };\n}\n\ninterface QBOBillBase {\n VendorRef: QBORef;\n DocNumber?: string;\n TxnDate: string;\n DueDate: string;\n Line: QBOBillLine[];\n TotalAmt?: number;\n Balance?: number;\n TxnTaxDetail?: {\n TotalTax?: number;\n };\n CurrencyRef?: QBORef;\n}\n\ninterface QBOBillCreate extends QBOBillBase {}\n\ninterface QBOBillUpdate extends QBOBillBase {\n Id: string;\n SyncToken: string;\n}\n\ninterface QBOBill extends QBOBillBase {\n Id: string;\n SyncToken: string;\n}\n\n// Payment types\ninterface QBOPaymentLine {\n Amount: number;\n LinkedTxn?: {\n TxnId: string;\n TxnType: string;\n }[];\n}\n\ninterface QBOPayment {\n Id: string;\n SyncToken: string;\n TxnDate: string;\n TotalAmt?: number;\n CustomerRef?: QBORef;\n PaymentMethodRef?: QBORef;\n PaymentRefNum?: string;\n Line?: QBOPaymentLine[];\n CurrencyRef?: QBORef;\n}\n\n// Webhook types\ninterface QBOWebhookPayload {\n eventNotifications?: {\n realmId: string;\n dataChangeEvent?: {\n entities?: {\n name: string;\n id: string;\n operation: string;\n lastUpdated: string;\n }[];\n };\n }[];\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as StripeApiError } from "./errors-Dt7tUtsB.js";
|
|
2
2
|
import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
3
3
|
//#region src/providers/stripe/index.ts
|
|
4
4
|
/**
|
|
@@ -1298,4 +1298,4 @@ function sleep(ms) {
|
|
|
1298
1298
|
//#endregion
|
|
1299
1299
|
export { StripeProvider };
|
|
1300
1300
|
|
|
1301
|
-
//# sourceMappingURL=stripe-
|
|
1301
|
+
//# sourceMappingURL=stripe-Dpp7VB-7.js.map
|