@voyantjs/finance 0.74.0 → 0.74.2
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 +4 -0
- package/dist/invoice-fx.d.ts +26 -2
- package/dist/invoice-fx.d.ts.map +1 -1
- package/dist/invoice-fx.js +56 -5
- package/dist/route-runtime.d.ts.map +1 -1
- package/dist/route-runtime.js +2 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -154,6 +154,10 @@ The default data resolver calls the Voyant Data FX pair route
|
|
|
154
154
|
`/data/fx/v1/fx/pair/{invoiceCurrency}/{baseCurrency}`. If the invoice currency
|
|
155
155
|
matches the operator base currency, no FX fields are emitted.
|
|
156
156
|
|
|
157
|
+
The same resolver also backs `GET /v1/finance/invoice-fx-rate`, which lets
|
|
158
|
+
operator UI surfaces auto-fill cross-currency payment rates without exposing
|
|
159
|
+
the Voyant Cloud API key to the browser.
|
|
160
|
+
|
|
157
161
|
## Exports
|
|
158
162
|
|
|
159
163
|
| Entry | Description |
|
package/dist/invoice-fx.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ModuleContainer } from "@voyantjs/core";
|
|
1
2
|
import type { HonoExtension } from "@voyantjs/hono/module";
|
|
2
3
|
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
3
4
|
import type { Hono } from "hono";
|
|
@@ -23,6 +24,7 @@ export interface InvoiceFxOptions {
|
|
|
23
24
|
resolveInvoiceFxSettings?: ResolveInvoiceFxSettings;
|
|
24
25
|
updateInvoiceFxSettings?: UpdateInvoiceFxSettings;
|
|
25
26
|
resolveInvoiceExchangeRate?: ResolveInvoiceExchangeRate;
|
|
27
|
+
resolveInvoiceExchangeRateResolver?: (bindings: Record<string, unknown>) => ResolveInvoiceExchangeRate | undefined;
|
|
26
28
|
onInvoiceFxResolutionError?: HandleInvoiceFxResolutionError;
|
|
27
29
|
}
|
|
28
30
|
export interface InvoiceFxRouteOptions extends InvoiceFxOptions {
|
|
@@ -51,10 +53,15 @@ export type VoyantDataFxResolverOptions = {
|
|
|
51
53
|
authScheme?: string | null;
|
|
52
54
|
fetch?: typeof fetch;
|
|
53
55
|
};
|
|
56
|
+
type InvoiceFxRouteEnv = Env & {
|
|
57
|
+
Variables: Env["Variables"] & {
|
|
58
|
+
container?: ModuleContainer;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
54
61
|
export declare function resolveInvoiceFxSettingsOrDefault(db: PostgresJsDatabase, options?: InvoiceFxOptions): Promise<ResolvedInvoiceFxSettings>;
|
|
55
62
|
export declare function resolveInvoiceFxContext(db: PostgresJsDatabase, invoice: InvoiceFxInvoice, options?: InvoiceFxOptions): Promise<InvoiceFxContext | null>;
|
|
56
63
|
export declare function createVoyantDataFxExchangeRateResolver(options: VoyantDataFxResolverOptions): ResolveInvoiceExchangeRate;
|
|
57
|
-
export declare function createInvoiceFxRoutes(options?: InvoiceFxRouteOptions): import("hono/hono-base").HonoBase<
|
|
64
|
+
export declare function createInvoiceFxRoutes(options?: InvoiceFxRouteOptions): import("hono/hono-base").HonoBase<InvoiceFxRouteEnv, {
|
|
58
65
|
"/invoice-fx-settings": {
|
|
59
66
|
$get: {
|
|
60
67
|
input: {};
|
|
@@ -84,7 +91,24 @@ export declare function createInvoiceFxRoutes(options?: InvoiceFxRouteOptions):
|
|
|
84
91
|
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
85
92
|
};
|
|
86
93
|
};
|
|
87
|
-
}
|
|
94
|
+
} & {
|
|
95
|
+
"/invoice-fx-rate": {
|
|
96
|
+
$get: {
|
|
97
|
+
input: {};
|
|
98
|
+
output: {
|
|
99
|
+
data: {
|
|
100
|
+
rate: number;
|
|
101
|
+
baseCurrency: string;
|
|
102
|
+
quoteCurrency: string;
|
|
103
|
+
date: string | undefined;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
outputFormat: "json";
|
|
107
|
+
status: import("hono/utils/http-status").ContentfulStatusCode;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
}, "/", "/invoice-fx-rate">;
|
|
88
111
|
export declare function mountInvoiceFxRoutes(hono: Hono, options?: InvoiceFxRouteOptions): Hono;
|
|
89
112
|
export declare function createInvoiceFxHonoExtension(options?: InvoiceFxRouteOptions): HonoExtension;
|
|
113
|
+
export {};
|
|
90
114
|
//# sourceMappingURL=invoice-fx.d.ts.map
|
package/dist/invoice-fx.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoice-fx.d.ts","sourceRoot":"","sources":["../src/invoice-fx.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"invoice-fx.d.ts","sourceRoot":"","sources":["../src/invoice-fx.ts"],"names":[],"mappings":"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"}
|
package/dist/invoice-fx.js
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
import { ApiHttpError, parseJsonBody } from "@voyantjs/hono";
|
|
1
|
+
import { ApiHttpError, parseJsonBody, parseQuery } from "@voyantjs/hono";
|
|
2
2
|
import { Hono as HonoApp } from "hono";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import { buildFinanceRouteRuntime, FINANCE_ROUTE_RUNTIME_CONTAINER_KEY, } from "./route-runtime.js";
|
|
4
5
|
const DEFAULT_DATA_BASE_URL = "https://api.voyantjs.com";
|
|
5
6
|
const invoiceFxSettingsPatchSchema = z.object({
|
|
6
7
|
baseCurrency: z.string().min(3).max(8).nullable().optional(),
|
|
7
8
|
fxCommissionBps: z.number().int().min(0).max(100_000).nullable().optional(),
|
|
8
9
|
fxCommissionInvoiceMention: z.string().nullable().optional(),
|
|
9
10
|
});
|
|
11
|
+
const invoiceExchangeRateQuerySchema = z.object({
|
|
12
|
+
baseCurrency: z.string().min(3).max(8),
|
|
13
|
+
quoteCurrency: z.string().min(3).max(8),
|
|
14
|
+
date: z.string().optional(),
|
|
15
|
+
});
|
|
16
|
+
function getInvoiceFxRuntime(options, bindings, container) {
|
|
17
|
+
return ((container?.has(FINANCE_ROUTE_RUNTIME_CONTAINER_KEY)
|
|
18
|
+
? container.resolve(FINANCE_ROUTE_RUNTIME_CONTAINER_KEY)
|
|
19
|
+
: undefined) ?? buildFinanceRouteRuntime(bindings, options));
|
|
20
|
+
}
|
|
10
21
|
export async function resolveInvoiceFxSettingsOrDefault(db, options = {}) {
|
|
11
22
|
const settings = await resolveConfiguredInvoiceFxSettings(db, options);
|
|
12
23
|
return {
|
|
@@ -72,26 +83,66 @@ export function createVoyantDataFxExchangeRateResolver(options) {
|
|
|
72
83
|
export function createInvoiceFxRoutes(options = {}) {
|
|
73
84
|
return new HonoApp()
|
|
74
85
|
.get("/invoice-fx-settings", async (c) => {
|
|
86
|
+
const runtime = getInvoiceFxRuntime(options, c.env, c.var.container);
|
|
75
87
|
return c.json({
|
|
76
|
-
data: await resolveInvoiceFxSettingsOrDefault(c.get("db"),
|
|
88
|
+
data: await resolveInvoiceFxSettingsOrDefault(c.get("db"), runtime),
|
|
77
89
|
});
|
|
78
90
|
})
|
|
79
91
|
.patch("/invoice-fx-settings", async (c) => {
|
|
80
|
-
|
|
92
|
+
const runtime = getInvoiceFxRuntime(options, c.env, c.var.container);
|
|
93
|
+
if (!runtime.updateInvoiceFxSettings) {
|
|
81
94
|
throw new ApiHttpError("Invoice FX settings updates are not configured", {
|
|
82
95
|
status: 501,
|
|
83
96
|
code: "invoice_fx_settings_update_not_configured",
|
|
84
97
|
});
|
|
85
98
|
}
|
|
86
|
-
const current = await resolveInvoiceFxSettingsOrDefault(c.get("db"),
|
|
99
|
+
const current = await resolveInvoiceFxSettingsOrDefault(c.get("db"), runtime);
|
|
87
100
|
const patch = await parseJsonBody(c, invoiceFxSettingsPatchSchema);
|
|
88
|
-
const next = await
|
|
101
|
+
const next = await runtime.updateInvoiceFxSettings(c.get("db"), {
|
|
89
102
|
...current,
|
|
90
103
|
...patch,
|
|
91
104
|
});
|
|
92
105
|
return c.json({
|
|
93
106
|
data: await resolveInvoiceFxSettingsOrDefault(c.get("db"), { invoiceFxSettings: next }),
|
|
94
107
|
});
|
|
108
|
+
})
|
|
109
|
+
.get("/invoice-fx-rate", async (c) => {
|
|
110
|
+
const runtime = getInvoiceFxRuntime(options, c.env, c.var.container);
|
|
111
|
+
if (!runtime.resolveInvoiceExchangeRate) {
|
|
112
|
+
throw new ApiHttpError("Invoice FX rate resolution is not configured", {
|
|
113
|
+
status: 501,
|
|
114
|
+
code: "invoice_fx_rate_resolution_not_configured",
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const query = parseQuery(c, invoiceExchangeRateQuerySchema);
|
|
118
|
+
const input = {
|
|
119
|
+
baseCurrency: normalizeCurrency(query.baseCurrency) ?? query.baseCurrency,
|
|
120
|
+
quoteCurrency: normalizeCurrency(query.quoteCurrency) ?? query.quoteCurrency,
|
|
121
|
+
date: query.date,
|
|
122
|
+
};
|
|
123
|
+
let rate;
|
|
124
|
+
try {
|
|
125
|
+
rate = await runtime.resolveInvoiceExchangeRate(input);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
await notifyInvoiceFxResolutionError(runtime, error, input);
|
|
129
|
+
throw new ApiHttpError("Invoice FX rate resolution failed", {
|
|
130
|
+
status: 502,
|
|
131
|
+
code: "invoice_fx_rate_resolution_failed",
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (typeof rate !== "number" || !Number.isFinite(rate) || rate <= 0) {
|
|
135
|
+
throw new ApiHttpError("Invoice FX rate was not found", {
|
|
136
|
+
status: 404,
|
|
137
|
+
code: "invoice_fx_rate_not_found",
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return c.json({
|
|
141
|
+
data: {
|
|
142
|
+
...input,
|
|
143
|
+
rate: roundRate(rate),
|
|
144
|
+
},
|
|
145
|
+
});
|
|
95
146
|
});
|
|
96
147
|
}
|
|
97
148
|
export function mountInvoiceFxRoutes(hono, options = {}) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-runtime.d.ts","sourceRoot":"","sources":["../src/route-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,KAAK,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAClG,OAAO,KAAK,EAAE,6BAA6B,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAEpG,MAAM,MAAM,mBAAmB,GAAG;IAChC,wBAAwB,CAAC,EAAE,wBAAwB,CAAA;IACnD,0BAA0B,CAAC,EAAE,2BAA2B,CAAC,4BAA4B,CAAC,CAAA;IACtF,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAA;IACjE,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB,GAAG,gBAAgB,CAAA;AAEpB,eAAO,MAAM,mCAAmC,8BAA8B,CAAA;AAE9E,MAAM,WAAW,qBACf,SAAQ,2BAA2B,EACjC,6BAA6B,EAC7B,gBAAgB;CAAG;AAEvB,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,OAAO,GAAE,qBAA0B,GAClC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"route-runtime.d.ts","sourceRoot":"","sources":["../src/route-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,KAAK,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAClG,OAAO,KAAK,EAAE,6BAA6B,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAEpG,MAAM,MAAM,mBAAmB,GAAG;IAChC,wBAAwB,CAAC,EAAE,wBAAwB,CAAA;IACnD,0BAA0B,CAAC,EAAE,2BAA2B,CAAC,4BAA4B,CAAC,CAAA;IACtF,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAA;IACjE,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB,GAAG,gBAAgB,CAAA;AAEpB,eAAO,MAAM,mCAAmC,8BAA8B,CAAA;AAE9E,MAAM,WAAW,qBACf,SAAQ,2BAA2B,EACjC,6BAA6B,EAC7B,gBAAgB;CAAG;AAEvB,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,OAAO,GAAE,qBAA0B,GAClC,mBAAmB,CAerB"}
|
package/dist/route-runtime.js
CHANGED
|
@@ -8,6 +8,7 @@ export function buildFinanceRouteRuntime(bindings, options = {}) {
|
|
|
8
8
|
invoiceFxSettings: options.invoiceFxSettings,
|
|
9
9
|
resolveInvoiceFxSettings: options.resolveInvoiceFxSettings,
|
|
10
10
|
updateInvoiceFxSettings: options.updateInvoiceFxSettings,
|
|
11
|
-
resolveInvoiceExchangeRate: options.resolveInvoiceExchangeRate,
|
|
11
|
+
resolveInvoiceExchangeRate: options.resolveInvoiceExchangeRateResolver?.(bindings) ?? options.resolveInvoiceExchangeRate,
|
|
12
|
+
resolveInvoiceExchangeRateResolver: options.resolveInvoiceExchangeRateResolver,
|
|
12
13
|
};
|
|
13
14
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/finance",
|
|
3
|
-
"version": "0.74.
|
|
3
|
+
"version": "0.74.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -59,14 +59,14 @@
|
|
|
59
59
|
"drizzle-orm": "^0.45.2",
|
|
60
60
|
"hono": "^4.12.10",
|
|
61
61
|
"zod": "^4.3.6",
|
|
62
|
-
"@voyantjs/action-ledger": "0.74.
|
|
63
|
-
"@voyantjs/bookings": "0.74.
|
|
64
|
-
"@voyantjs/core": "0.74.
|
|
65
|
-
"@voyantjs/db": "0.74.
|
|
66
|
-
"@voyantjs/hono": "0.74.
|
|
67
|
-
"@voyantjs/products": "0.74.
|
|
68
|
-
"@voyantjs/utils": "0.74.
|
|
69
|
-
"@voyantjs/storage": "0.74.
|
|
62
|
+
"@voyantjs/action-ledger": "0.74.2",
|
|
63
|
+
"@voyantjs/bookings": "0.74.2",
|
|
64
|
+
"@voyantjs/core": "0.74.2",
|
|
65
|
+
"@voyantjs/db": "0.74.2",
|
|
66
|
+
"@voyantjs/hono": "0.74.2",
|
|
67
|
+
"@voyantjs/products": "0.74.2",
|
|
68
|
+
"@voyantjs/utils": "0.74.2",
|
|
69
|
+
"@voyantjs/storage": "0.74.2"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"typescript": "^6.0.2",
|