@usethrottle/invoices 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +37 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +27 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,17 +17,36 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.tsx
|
|
21
31
|
var index_exports = {};
|
|
22
32
|
__export(index_exports, {
|
|
33
|
+
CURRENCIES: () => import_money.CURRENCIES,
|
|
23
34
|
InvoiceProvider: () => InvoiceProvider,
|
|
24
35
|
InvoicesClient: () => InvoicesClient,
|
|
25
36
|
ThrottleError: () => import_errors2.ThrottleError,
|
|
26
37
|
ThrottleInvoicesError: () => ThrottleInvoicesError,
|
|
38
|
+
UnknownCurrencyError: () => import_money.UnknownCurrencyError,
|
|
27
39
|
createInvoicesClient: () => createInvoicesClient,
|
|
40
|
+
currencySymbol: () => import_money.currencySymbol,
|
|
41
|
+
formatMoney: () => import_money.formatMoney,
|
|
42
|
+
isKnownCurrency: () => import_money.isKnownCurrency,
|
|
28
43
|
isThrottleError: () => import_errors2.isThrottleError,
|
|
44
|
+
minorUnitsOf: () => import_money.minorUnitsOf,
|
|
45
|
+
money: () => money,
|
|
46
|
+
moneyValue: () => import_money.moneyValue,
|
|
47
|
+
parseMoney: () => import_money.parseMoney,
|
|
48
|
+
toDecimalString: () => import_money.toDecimalString,
|
|
49
|
+
toMinor: () => import_money.toMinor,
|
|
29
50
|
useDownloadInvoice: () => useDownloadInvoice,
|
|
30
51
|
useInvoice: () => useInvoice,
|
|
31
52
|
useInvoiceClient: () => useInvoiceClient,
|
|
@@ -68,7 +89,7 @@ var InvoicesClient = class {
|
|
|
68
89
|
const init = { method, headers: { "content-type": "application/json", ...this.apiKey ? { "x-api-key": this.apiKey } : {} }, signal: ctrl.signal };
|
|
69
90
|
const res = this.fetcher ? await this.fetcher(path, init) : await this.fetchImpl(`${this.baseUrl}${path}`, init);
|
|
70
91
|
const json = await res.json().catch(() => ({}));
|
|
71
|
-
if (!res.ok) throw new ThrottleInvoicesError({ code: json.error?.code ?? "unknown_error", message: json.error?.message ?? `HTTP ${res.status}`, statusCode: res.status, details: json.error?.details });
|
|
92
|
+
if (!res.ok) throw new ThrottleInvoicesError({ code: json.error?.code ?? "unknown_error", message: json.error?.message ?? `HTTP ${res.status}`, statusCode: res.status, details: json.error?.details, responseHeaders: res.headers });
|
|
72
93
|
return json;
|
|
73
94
|
} finally {
|
|
74
95
|
clearTimeout(timer);
|
|
@@ -223,14 +244,29 @@ function useStableValue(value) {
|
|
|
223
244
|
const key = JSON.stringify(value);
|
|
224
245
|
return (0, import_react2.useMemo)(() => value, [key]);
|
|
225
246
|
}
|
|
247
|
+
|
|
248
|
+
// src/index.tsx
|
|
249
|
+
var money = __toESM(require("@usethrottle/money"), 1);
|
|
250
|
+
var import_money = require("@usethrottle/money");
|
|
226
251
|
// Annotate the CommonJS export names for ESM import in node:
|
|
227
252
|
0 && (module.exports = {
|
|
253
|
+
CURRENCIES,
|
|
228
254
|
InvoiceProvider,
|
|
229
255
|
InvoicesClient,
|
|
230
256
|
ThrottleError,
|
|
231
257
|
ThrottleInvoicesError,
|
|
258
|
+
UnknownCurrencyError,
|
|
232
259
|
createInvoicesClient,
|
|
260
|
+
currencySymbol,
|
|
261
|
+
formatMoney,
|
|
262
|
+
isKnownCurrency,
|
|
233
263
|
isThrottleError,
|
|
264
|
+
minorUnitsOf,
|
|
265
|
+
money,
|
|
266
|
+
moneyValue,
|
|
267
|
+
parseMoney,
|
|
268
|
+
toDecimalString,
|
|
269
|
+
toMinor,
|
|
234
270
|
useDownloadInvoice,
|
|
235
271
|
useInvoice,
|
|
236
272
|
useInvoiceClient,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx","../src/errors.ts","../src/client.ts","../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["export { InvoicesClient, createInvoicesClient } from './client';\nexport { ThrottleInvoicesError, ThrottleError, isThrottleError } from './errors';\nexport { InvoiceProvider, useInvoiceClient, useInvoiceInvalidation } from './provider';\nexport { useInvoices, useInvoice, useDownloadInvoice } from './hooks';\nexport type * from './types';\n","import { ThrottleError } from '@usethrottle/errors';\nexport class ThrottleInvoicesError extends ThrottleError {\n constructor(args: { code: string; message: string; statusCode: number; details?: unknown }) {\n super(args); this.name = 'ThrottleInvoicesError';\n }\n}\nexport { ThrottleError, isThrottleError } from '@usethrottle/errors';\n","import { ThrottleInvoicesError } from './errors';\nimport type { Invoice, InvoicesClientContract, InvoicesClientOptions, ListInvoicesParams, PaginatedInvoices, ThrottleEnvelope } from './types';\n\nexport class InvoicesClient implements InvoicesClientContract {\n private readonly apiKey?: string; private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch; private readonly fetcher?: InvoicesClientOptions['fetcher']; private readonly timeoutMs: number;\n constructor(opts: InvoicesClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('InvoicesClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) throw new Error('InvoicesClient: apiKey or fetcher is required');\n this.apiKey = opts.apiKey; this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl; this.fetcher = opts.fetcher; this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n private async requestEnvelope<T>(method: string, path: string): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController(); const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n try {\n const init: RequestInit = { method, headers: { 'content-type': 'application/json', ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}) }, signal: ctrl.signal };\n const res = this.fetcher ? await this.fetcher(path, init) : await this.fetchImpl(`${this.baseUrl}${path}`, init);\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) throw new ThrottleInvoicesError({ code: json.error?.code ?? 'unknown_error', message: json.error?.message ?? `HTTP ${res.status}`, statusCode: res.status, details: json.error?.details });\n return json;\n } finally { clearTimeout(timer); }\n }\n async list(params: ListInvoicesParams = {}): Promise<PaginatedInvoices> {\n const q = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) if (v !== undefined && v !== null && v !== '') q.set(k, String(v));\n const suffix = q.toString() ? `?${q}` : '';\n const env = await this.requestEnvelope<Invoice[]>('GET', `/api/v1/invoices${suffix}`);\n return { data: env.data ?? [], pagination: env.meta?.pagination ? { cursor: env.meta.pagination.cursor ?? null, hasMore: Boolean(env.meta.pagination.hasMore) } : undefined };\n }\n async get(id: string): Promise<Invoice> {\n const env = await this.requestEnvelope<Invoice>('GET', `/api/v1/invoices/${encodeURIComponent(id)}`);\n return env.data as Invoice;\n }\n async getDownloadUrl(id: string): Promise<string> {\n const env = await this.requestEnvelope<{ url: string }>('GET', `/api/v1/invoices/${encodeURIComponent(id)}/download?format=json`);\n return (env.data as { url: string }).url;\n }\n}\nexport function createInvoicesClient(opts: InvoicesClientOptions): InvoicesClient { return new InvoicesClient(opts); }\n","import { createContext, useCallback, useContext, useMemo, useReducer, type ReactNode } from 'react';\nimport { InvoicesClient } from './client';\nimport type {\n InvoiceFetcher,\n InvoicesProviderProps,\n InvoicesClientContract,\n} from './types';\n\ninterface InvoiceContextValue {\n client: InvoicesClientContract;\n cacheVersion: number;\n invalidate: () => void;\n}\n\nconst InvoiceContext = createContext<InvoiceContextValue | null>(null);\n\nexport function InvoiceProvider({\n children,\n client,\n fetcher,\n baseUrl,\n timeoutMs,\n}: InvoicesProviderProps) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const resolvedClient = useMemo(() => {\n if (client) return client;\n return new InvoicesClient({\n fetcher: fetcher ?? createInvoiceFetcher('/api/throttle'),\n baseUrl,\n timeoutMs,\n });\n }, [baseUrl, client, fetcher, timeoutMs]);\n\n const value = useMemo(\n () => ({ client: resolvedClient, cacheVersion, invalidate }),\n [cacheVersion, resolvedClient],\n );\n\n return <InvoiceContext.Provider value={value}>{children}</InvoiceContext.Provider>;\n}\n\nexport function useInvoiceClient(): InvoicesClientContract {\n return useInvoiceContext().client;\n}\n\nexport function useInvoiceInvalidation(): () => void {\n return useInvoiceContext().invalidate;\n}\n\nexport function useInvoiceCacheVersion(): number {\n return useInvoiceContext().cacheVersion;\n}\n\nexport function createInvoiceFetcher(basePath: string): InvoiceFetcher {\n const cleanBase = basePath.replace(/\\/+$/, '');\n return (path, init) => {\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return fetch(`${cleanBase}${cleanPath}`, init);\n };\n}\n\nexport function useInvoiceContext(): InvoiceContextValue {\n const ctx = useContext(InvoiceContext);\n if (!ctx) {\n throw new Error(\n '@usethrottle/invoices hooks must be used inside <InvoiceProvider />',\n );\n }\n return ctx;\n}\n\nexport function InvoiceProviderWithClient({\n children,\n client,\n}: {\n children: ReactNode;\n client: InvoicesClientContract;\n}) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const value = useMemo(() => ({ client, cacheVersion, invalidate }), [cacheVersion, client]);\n return <InvoiceContext.Provider value={value}>{children}</InvoiceContext.Provider>;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useInvoiceCacheVersion,\n useInvoiceClient,\n} from './provider';\nimport type {\n Invoice,\n ListInvoicesParams,\n PaginatedInvoices,\n QueryOptions,\n QueryState,\n} from './types';\n\nexport function useInvoices(\n params: ListInvoicesParams = {},\n options: QueryOptions<PaginatedInvoices> = {},\n): QueryState<PaginatedInvoices> {\n const client = useInvoiceClient();\n const v = useInvoiceCacheVersion();\n const p = useStableValue(params);\n return useAsyncQuery(() => client.list(p), [client, p, v], options);\n}\n\nexport function useInvoice(\n id: string | null | undefined,\n options: QueryOptions<Invoice> = {},\n): QueryState<Invoice> {\n const client = useInvoiceClient();\n const v = useInvoiceCacheVersion();\n return useAsyncQuery(\n () => (id ? client.get(id) : Promise.resolve(null)),\n [client, id, v],\n { ...options, enabled: options.enabled ?? Boolean(id) },\n );\n}\n\nexport function useDownloadInvoice() {\n const client = useInvoiceClient();\n return async (id: string) => {\n const url = await client.getDownloadUrl(id);\n if (typeof window !== 'undefined') window.open(url, '_blank');\n return url;\n };\n}\n\nfunction useAsyncQuery<T>(\n load: () => Promise<T | null>,\n deps: readonly unknown[],\n options: QueryOptions<T>,\n): QueryState<T> {\n const enabled = options.enabled ?? true;\n const [data, setData] = useState<T | null>(options.initialData ?? null);\n const [error, setError] = useState<unknown>(null);\n const [isLoading, setIsLoading] = useState(enabled && options.initialData === undefined);\n const [isFetching, setIsFetching] = useState(false);\n const loadRef = useRef(load);\n loadRef.current = load;\n\n const refetch = useCallback(async () => {\n if (!enabled) return data;\n setIsFetching(true);\n setError(null);\n try {\n const next = await loadRef.current();\n setData(next);\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsFetching(false);\n setIsLoading(false);\n }\n }, [data, enabled]);\n\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n let cancelled = false;\n setIsFetching(true);\n setError(null);\n load()\n .then((next) => {\n if (!cancelled) setData(next);\n })\n .catch((err) => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoading(false);\n setIsFetching(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, ...deps]);\n\n return { data, error, isLoading, isFetching, refetch };\n}\n\nfunction useStableValue<T>(value: T): T {\n const key = JSON.stringify(value);\n return useMemo(() => value, [key]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA8B;AAM9B,IAAAA,iBAA+C;AALxC,IAAM,wBAAN,cAAoC,4BAAc;AAAA,EACvD,YAAY,MAAgF;AAC1F,UAAM,IAAI;AAAG,SAAK,OAAO;AAAA,EAC3B;AACF;;;ACFO,IAAM,iBAAN,MAAuD;AAAA,EAC3C;AAAA,EAAkC;AAAA,EAClC;AAAA,EAAqD;AAAA,EAA6D;AAAA,EACnI,YAAY,OAA8B,CAAC,GAAG;AAC5C,UAAM,YAAY,KAAK,SAAS,WAAW;AAC3C,QAAI,CAAC,UAAW,OAAM,IAAI,MAAM,mCAAmC;AACnE,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,QAAS,OAAM,IAAI,MAAM,+CAA+C;AAClG,SAAK,SAAS,KAAK;AAAQ,SAAK,WAAW,KAAK,WAAW,+BAA+B,QAAQ,QAAQ,EAAE;AAC5G,SAAK,YAAY;AAAW,SAAK,UAAU,KAAK;AAAS,SAAK,YAAY,KAAK,aAAa;AAAA,EAC9F;AAAA,EACA,MAAc,gBAAmB,QAAgB,MAA4C;AAC3F,UAAM,OAAO,IAAI,gBAAgB;AAAG,UAAM,QAAQ,WAAW,MAAM,KAAK,MAAM,GAAG,KAAK,SAAS;AAC/F,QAAI;AACF,YAAM,OAAoB,EAAE,QAAQ,SAAS,EAAE,gBAAgB,oBAAoB,GAAI,KAAK,SAAS,EAAE,aAAa,KAAK,OAAO,IAAI,CAAC,EAAG,GAAG,QAAQ,KAAK,OAAO;AAC/J,YAAM,MAAM,KAAK,UAAU,MAAM,KAAK,QAAQ,MAAM,IAAI,IAAI,MAAM,KAAK,UAAU,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI,IAAI;AAC/G,YAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC/C,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,sBAAsB,EAAE,MAAM,KAAK,OAAO,QAAQ,iBAAiB,SAAS,KAAK,OAAO,WAAW,QAAQ,IAAI,MAAM,IAAI,YAAY,IAAI,QAAQ,SAAS,KAAK,OAAO,QAAQ,CAAC;AACtM,aAAO;AAAA,IACT,UAAE;AAAU,mBAAa,KAAK;AAAA,IAAG;AAAA,EACnC;AAAA,EACA,MAAM,KAAK,SAA6B,CAAC,GAA+B;AACtE,UAAM,IAAI,IAAI,gBAAgB;AAC9B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,EAAG,KAAI,MAAM,UAAa,MAAM,QAAQ,MAAM,GAAI,GAAE,IAAI,GAAG,OAAO,CAAC,CAAC;AAC9G,UAAM,SAAS,EAAE,SAAS,IAAI,IAAI,CAAC,KAAK;AACxC,UAAM,MAAM,MAAM,KAAK,gBAA2B,OAAO,mBAAmB,MAAM,EAAE;AACpF,WAAO,EAAE,MAAM,IAAI,QAAQ,CAAC,GAAG,YAAY,IAAI,MAAM,aAAa,EAAE,QAAQ,IAAI,KAAK,WAAW,UAAU,MAAM,SAAS,QAAQ,IAAI,KAAK,WAAW,OAAO,EAAE,IAAI,OAAU;AAAA,EAC9K;AAAA,EACA,MAAM,IAAI,IAA8B;AACtC,UAAM,MAAM,MAAM,KAAK,gBAAyB,OAAO,oBAAoB,mBAAmB,EAAE,CAAC,EAAE;AACnG,WAAO,IAAI;AAAA,EACb;AAAA,EACA,MAAM,eAAe,IAA6B;AAChD,UAAM,MAAM,MAAM,KAAK,gBAAiC,OAAO,oBAAoB,mBAAmB,EAAE,CAAC,uBAAuB;AAChI,WAAQ,IAAI,KAAyB;AAAA,EACvC;AACF;AACO,SAAS,qBAAqB,MAA6C;AAAE,SAAO,IAAI,eAAe,IAAI;AAAG;;;ACvCrH,mBAA4F;AAsCnF;AAxBT,IAAM,qBAAiB,4BAA0C,IAAI;AAE9D,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,CAAC,cAAc,UAAU,QAAI,yBAAW,CAACC,WAAkBA,SAAQ,GAAG,CAAC;AAC7E,QAAM,qBAAiB,sBAAQ,MAAM;AACnC,QAAI,OAAQ,QAAO;AACnB,WAAO,IAAI,eAAe;AAAA,MACxB,SAAS,WAAW,qBAAqB,eAAe;AAAA,MACxD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,SAAS,QAAQ,SAAS,SAAS,CAAC;AAExC,QAAM,YAAQ;AAAA,IACZ,OAAO,EAAE,QAAQ,gBAAgB,cAAc,WAAW;AAAA,IAC1D,CAAC,cAAc,cAAc;AAAA,EAC/B;AAEA,SAAO,4CAAC,eAAe,UAAf,EAAwB,OAAe,UAAS;AAC1D;AAEO,SAAS,mBAA2C;AACzD,SAAO,kBAAkB,EAAE;AAC7B;AAEO,SAAS,yBAAqC;AACnD,SAAO,kBAAkB,EAAE;AAC7B;AAEO,SAAS,yBAAiC;AAC/C,SAAO,kBAAkB,EAAE;AAC7B;AAEO,SAAS,qBAAqB,UAAkC;AACrE,QAAM,YAAY,SAAS,QAAQ,QAAQ,EAAE;AAC7C,SAAO,CAAC,MAAM,SAAS;AACrB,UAAM,YAAY,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AACxD,WAAO,MAAM,GAAG,SAAS,GAAG,SAAS,IAAI,IAAI;AAAA,EAC/C;AACF;AAEO,SAAS,oBAAyC;AACvD,QAAM,UAAM,yBAAW,cAAc;AACrC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACrEA,IAAAC,gBAAkE;AAa3D,SAAS,YACd,SAA6B,CAAC,GAC9B,UAA2C,CAAC,GACb;AAC/B,QAAM,SAAS,iBAAiB;AAChC,QAAM,IAAI,uBAAuB;AACjC,QAAM,IAAI,eAAe,MAAM;AAC/B,SAAO,cAAc,MAAM,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,GAAG,OAAO;AACpE;AAEO,SAAS,WACd,IACA,UAAiC,CAAC,GACb;AACrB,QAAM,SAAS,iBAAiB;AAChC,QAAM,IAAI,uBAAuB;AACjC,SAAO;AAAA,IACL,MAAO,KAAK,OAAO,IAAI,EAAE,IAAI,QAAQ,QAAQ,IAAI;AAAA,IACjD,CAAC,QAAQ,IAAI,CAAC;AAAA,IACd,EAAE,GAAG,SAAS,SAAS,QAAQ,WAAW,QAAQ,EAAE,EAAE;AAAA,EACxD;AACF;AAEO,SAAS,qBAAqB;AACnC,QAAM,SAAS,iBAAiB;AAChC,SAAO,OAAO,OAAe;AAC3B,UAAM,MAAM,MAAM,OAAO,eAAe,EAAE;AAC1C,QAAI,OAAO,WAAW,YAAa,QAAO,KAAK,KAAK,QAAQ;AAC5D,WAAO;AAAA,EACT;AACF;AAEA,SAAS,cACP,MACA,MACA,SACe;AACf,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAmB,QAAQ,eAAe,IAAI;AACtE,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAkB,IAAI;AAChD,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,WAAW,QAAQ,gBAAgB,MAAS;AACvF,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAS,KAAK;AAClD,QAAM,cAAU,sBAAO,IAAI;AAC3B,UAAQ,UAAU;AAElB,QAAM,cAAU,2BAAY,YAAY;AACtC,QAAI,CAAC,QAAS,QAAO;AACrB,kBAAc,IAAI;AAClB,aAAS,IAAI;AACb,QAAI;AACF,YAAM,OAAO,MAAM,QAAQ,QAAQ;AACnC,cAAQ,IAAI;AACZ,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,eAAS,GAAG;AACZ,YAAM;AAAA,IACR,UAAE;AACA,oBAAc,KAAK;AACnB,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,MAAM,OAAO,CAAC;AAElB,+BAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ,mBAAa,KAAK;AAClB;AAAA,IACF;AACA,QAAI,YAAY;AAChB,kBAAc,IAAI;AAClB,aAAS,IAAI;AACb,SAAK,EACF,KAAK,CAAC,SAAS;AACd,UAAI,CAAC,UAAW,SAAQ,IAAI;AAAA,IAC9B,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,UAAI,CAAC,UAAW,UAAS,GAAG;AAAA,IAC9B,CAAC,EACA,QAAQ,MAAM;AACb,UAAI,CAAC,WAAW;AACd,qBAAa,KAAK;AAClB,sBAAc,KAAK;AAAA,MACrB;AAAA,IACF,CAAC;AAEH,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EAEF,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC;AAErB,SAAO,EAAE,MAAM,OAAO,WAAW,YAAY,QAAQ;AACvD;AAEA,SAAS,eAAkB,OAAa;AACtC,QAAM,MAAM,KAAK,UAAU,KAAK;AAChC,aAAO,uBAAQ,MAAM,OAAO,CAAC,GAAG,CAAC;AACnC;","names":["import_errors","value","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx","../src/errors.ts","../src/client.ts","../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["export { InvoicesClient, createInvoicesClient } from './client';\nexport { ThrottleInvoicesError, ThrottleError, isThrottleError } from './errors';\nexport { InvoiceProvider, useInvoiceClient, useInvoiceInvalidation } from './provider';\nexport { useInvoices, useInvoice, useDownloadInvoice } from './hooks';\nexport type * from './types';\n// Money helpers (MC2-R34): amounts are integer minor units of their `currency`.\nexport * as money from '@usethrottle/money';\nexport {\n formatMoney,\n currencySymbol,\n minorUnitsOf,\n toDecimalString,\n toMinor,\n parseMoney,\n moneyValue,\n CURRENCIES,\n isKnownCurrency,\n UnknownCurrencyError,\n} from '@usethrottle/money';\nexport type { CurrencyCode, MoneyValue } from '@usethrottle/money';\n","import { ThrottleError, type ThrottleErrorArgs } from '@usethrottle/errors';\nexport class ThrottleInvoicesError extends ThrottleError {\n constructor(args: { code: string; message: string; statusCode: number; details?: unknown; responseHeaders?: ThrottleErrorArgs['responseHeaders'] }) {\n super(args); this.name = 'ThrottleInvoicesError';\n }\n}\nexport { ThrottleError, isThrottleError } from '@usethrottle/errors';\n","import { ThrottleInvoicesError } from './errors';\nimport type { Invoice, InvoicesClientContract, InvoicesClientOptions, ListInvoicesParams, PaginatedInvoices, ThrottleEnvelope } from './types';\n\nexport class InvoicesClient implements InvoicesClientContract {\n private readonly apiKey?: string; private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch; private readonly fetcher?: InvoicesClientOptions['fetcher']; private readonly timeoutMs: number;\n constructor(opts: InvoicesClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('InvoicesClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) throw new Error('InvoicesClient: apiKey or fetcher is required');\n this.apiKey = opts.apiKey; this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl; this.fetcher = opts.fetcher; this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n private async requestEnvelope<T>(method: string, path: string): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController(); const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n try {\n const init: RequestInit = { method, headers: { 'content-type': 'application/json', ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}) }, signal: ctrl.signal };\n const res = this.fetcher ? await this.fetcher(path, init) : await this.fetchImpl(`${this.baseUrl}${path}`, init);\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) throw new ThrottleInvoicesError({ code: json.error?.code ?? 'unknown_error', message: json.error?.message ?? `HTTP ${res.status}`, statusCode: res.status, details: json.error?.details, responseHeaders: res.headers });\n return json;\n } finally { clearTimeout(timer); }\n }\n async list(params: ListInvoicesParams = {}): Promise<PaginatedInvoices> {\n const q = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) if (v !== undefined && v !== null && v !== '') q.set(k, String(v));\n const suffix = q.toString() ? `?${q}` : '';\n const env = await this.requestEnvelope<Invoice[]>('GET', `/api/v1/invoices${suffix}`);\n return { data: env.data ?? [], pagination: env.meta?.pagination ? { cursor: env.meta.pagination.cursor ?? null, hasMore: Boolean(env.meta.pagination.hasMore) } : undefined };\n }\n async get(id: string): Promise<Invoice> {\n const env = await this.requestEnvelope<Invoice>('GET', `/api/v1/invoices/${encodeURIComponent(id)}`);\n return env.data as Invoice;\n }\n async getDownloadUrl(id: string): Promise<string> {\n const env = await this.requestEnvelope<{ url: string }>('GET', `/api/v1/invoices/${encodeURIComponent(id)}/download?format=json`);\n return (env.data as { url: string }).url;\n }\n}\nexport function createInvoicesClient(opts: InvoicesClientOptions): InvoicesClient { return new InvoicesClient(opts); }\n","import { createContext, useCallback, useContext, useMemo, useReducer, type ReactNode } from 'react';\nimport { InvoicesClient } from './client';\nimport type {\n InvoiceFetcher,\n InvoicesProviderProps,\n InvoicesClientContract,\n} from './types';\n\ninterface InvoiceContextValue {\n client: InvoicesClientContract;\n cacheVersion: number;\n invalidate: () => void;\n}\n\nconst InvoiceContext = createContext<InvoiceContextValue | null>(null);\n\nexport function InvoiceProvider({\n children,\n client,\n fetcher,\n baseUrl,\n timeoutMs,\n}: InvoicesProviderProps) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const resolvedClient = useMemo(() => {\n if (client) return client;\n return new InvoicesClient({\n fetcher: fetcher ?? createInvoiceFetcher('/api/throttle'),\n baseUrl,\n timeoutMs,\n });\n }, [baseUrl, client, fetcher, timeoutMs]);\n\n const value = useMemo(\n () => ({ client: resolvedClient, cacheVersion, invalidate }),\n [cacheVersion, resolvedClient],\n );\n\n return <InvoiceContext.Provider value={value}>{children}</InvoiceContext.Provider>;\n}\n\nexport function useInvoiceClient(): InvoicesClientContract {\n return useInvoiceContext().client;\n}\n\nexport function useInvoiceInvalidation(): () => void {\n return useInvoiceContext().invalidate;\n}\n\nexport function useInvoiceCacheVersion(): number {\n return useInvoiceContext().cacheVersion;\n}\n\nexport function createInvoiceFetcher(basePath: string): InvoiceFetcher {\n const cleanBase = basePath.replace(/\\/+$/, '');\n return (path, init) => {\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return fetch(`${cleanBase}${cleanPath}`, init);\n };\n}\n\nexport function useInvoiceContext(): InvoiceContextValue {\n const ctx = useContext(InvoiceContext);\n if (!ctx) {\n throw new Error(\n '@usethrottle/invoices hooks must be used inside <InvoiceProvider />',\n );\n }\n return ctx;\n}\n\nexport function InvoiceProviderWithClient({\n children,\n client,\n}: {\n children: ReactNode;\n client: InvoicesClientContract;\n}) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const value = useMemo(() => ({ client, cacheVersion, invalidate }), [cacheVersion, client]);\n return <InvoiceContext.Provider value={value}>{children}</InvoiceContext.Provider>;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useInvoiceCacheVersion,\n useInvoiceClient,\n} from './provider';\nimport type {\n Invoice,\n ListInvoicesParams,\n PaginatedInvoices,\n QueryOptions,\n QueryState,\n} from './types';\n\nexport function useInvoices(\n params: ListInvoicesParams = {},\n options: QueryOptions<PaginatedInvoices> = {},\n): QueryState<PaginatedInvoices> {\n const client = useInvoiceClient();\n const v = useInvoiceCacheVersion();\n const p = useStableValue(params);\n return useAsyncQuery(() => client.list(p), [client, p, v], options);\n}\n\nexport function useInvoice(\n id: string | null | undefined,\n options: QueryOptions<Invoice> = {},\n): QueryState<Invoice> {\n const client = useInvoiceClient();\n const v = useInvoiceCacheVersion();\n return useAsyncQuery(\n () => (id ? client.get(id) : Promise.resolve(null)),\n [client, id, v],\n { ...options, enabled: options.enabled ?? Boolean(id) },\n );\n}\n\nexport function useDownloadInvoice() {\n const client = useInvoiceClient();\n return async (id: string) => {\n const url = await client.getDownloadUrl(id);\n if (typeof window !== 'undefined') window.open(url, '_blank');\n return url;\n };\n}\n\nfunction useAsyncQuery<T>(\n load: () => Promise<T | null>,\n deps: readonly unknown[],\n options: QueryOptions<T>,\n): QueryState<T> {\n const enabled = options.enabled ?? true;\n const [data, setData] = useState<T | null>(options.initialData ?? null);\n const [error, setError] = useState<unknown>(null);\n const [isLoading, setIsLoading] = useState(enabled && options.initialData === undefined);\n const [isFetching, setIsFetching] = useState(false);\n const loadRef = useRef(load);\n loadRef.current = load;\n\n const refetch = useCallback(async () => {\n if (!enabled) return data;\n setIsFetching(true);\n setError(null);\n try {\n const next = await loadRef.current();\n setData(next);\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsFetching(false);\n setIsLoading(false);\n }\n }, [data, enabled]);\n\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n let cancelled = false;\n setIsFetching(true);\n setError(null);\n load()\n .then((next) => {\n if (!cancelled) setData(next);\n })\n .catch((err) => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoading(false);\n setIsFetching(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, ...deps]);\n\n return { data, error, isLoading, isFetching, refetch };\n}\n\nfunction useStableValue<T>(value: T): T {\n const key = JSON.stringify(value);\n return useMemo(() => value, [key]);\n}\n"],"mappings":"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","names":["import_errors","value","import_react"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { CurrencyCode } from '@usethrottle/money';
|
|
3
|
+
import * as money from '@usethrottle/money';
|
|
4
|
+
export { money };
|
|
5
|
+
export { CURRENCIES, CurrencyCode, MoneyValue, UnknownCurrencyError, currencySymbol, formatMoney, isKnownCurrency, minorUnitsOf, moneyValue, parseMoney, toDecimalString, toMinor } from '@usethrottle/money';
|
|
6
|
+
import { ThrottleError, ThrottleErrorArgs } from '@usethrottle/errors';
|
|
3
7
|
export { ThrottleError, isThrottleError } from '@usethrottle/errors';
|
|
4
8
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
9
|
|
|
@@ -10,7 +14,7 @@ interface Invoice {
|
|
|
10
14
|
number: string;
|
|
11
15
|
status: InvoiceStatus;
|
|
12
16
|
sourceType?: InvoiceSourceType;
|
|
13
|
-
currency:
|
|
17
|
+
currency: CurrencyCode;
|
|
14
18
|
subtotal?: number;
|
|
15
19
|
taxTotal?: number;
|
|
16
20
|
shippingTotal?: number;
|
|
@@ -104,6 +108,7 @@ declare class ThrottleInvoicesError extends ThrottleError {
|
|
|
104
108
|
message: string;
|
|
105
109
|
statusCode: number;
|
|
106
110
|
details?: unknown;
|
|
111
|
+
responseHeaders?: ThrottleErrorArgs['responseHeaders'];
|
|
107
112
|
});
|
|
108
113
|
}
|
|
109
114
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { CurrencyCode } from '@usethrottle/money';
|
|
3
|
+
import * as money from '@usethrottle/money';
|
|
4
|
+
export { money };
|
|
5
|
+
export { CURRENCIES, CurrencyCode, MoneyValue, UnknownCurrencyError, currencySymbol, formatMoney, isKnownCurrency, minorUnitsOf, moneyValue, parseMoney, toDecimalString, toMinor } from '@usethrottle/money';
|
|
6
|
+
import { ThrottleError, ThrottleErrorArgs } from '@usethrottle/errors';
|
|
3
7
|
export { ThrottleError, isThrottleError } from '@usethrottle/errors';
|
|
4
8
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
9
|
|
|
@@ -10,7 +14,7 @@ interface Invoice {
|
|
|
10
14
|
number: string;
|
|
11
15
|
status: InvoiceStatus;
|
|
12
16
|
sourceType?: InvoiceSourceType;
|
|
13
|
-
currency:
|
|
17
|
+
currency: CurrencyCode;
|
|
14
18
|
subtotal?: number;
|
|
15
19
|
taxTotal?: number;
|
|
16
20
|
shippingTotal?: number;
|
|
@@ -104,6 +108,7 @@ declare class ThrottleInvoicesError extends ThrottleError {
|
|
|
104
108
|
message: string;
|
|
105
109
|
statusCode: number;
|
|
106
110
|
details?: unknown;
|
|
111
|
+
responseHeaders?: ThrottleErrorArgs['responseHeaders'];
|
|
107
112
|
});
|
|
108
113
|
}
|
|
109
114
|
|
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ var InvoicesClient = class {
|
|
|
32
32
|
const init = { method, headers: { "content-type": "application/json", ...this.apiKey ? { "x-api-key": this.apiKey } : {} }, signal: ctrl.signal };
|
|
33
33
|
const res = this.fetcher ? await this.fetcher(path, init) : await this.fetchImpl(`${this.baseUrl}${path}`, init);
|
|
34
34
|
const json = await res.json().catch(() => ({}));
|
|
35
|
-
if (!res.ok) throw new ThrottleInvoicesError({ code: json.error?.code ?? "unknown_error", message: json.error?.message ?? `HTTP ${res.status}`, statusCode: res.status, details: json.error?.details });
|
|
35
|
+
if (!res.ok) throw new ThrottleInvoicesError({ code: json.error?.code ?? "unknown_error", message: json.error?.message ?? `HTTP ${res.status}`, statusCode: res.status, details: json.error?.details, responseHeaders: res.headers });
|
|
36
36
|
return json;
|
|
37
37
|
} finally {
|
|
38
38
|
clearTimeout(timer);
|
|
@@ -187,13 +187,39 @@ function useStableValue(value) {
|
|
|
187
187
|
const key = JSON.stringify(value);
|
|
188
188
|
return useMemo2(() => value, [key]);
|
|
189
189
|
}
|
|
190
|
+
|
|
191
|
+
// src/index.tsx
|
|
192
|
+
import * as money from "@usethrottle/money";
|
|
193
|
+
import {
|
|
194
|
+
formatMoney,
|
|
195
|
+
currencySymbol,
|
|
196
|
+
minorUnitsOf,
|
|
197
|
+
toDecimalString,
|
|
198
|
+
toMinor,
|
|
199
|
+
parseMoney,
|
|
200
|
+
moneyValue,
|
|
201
|
+
CURRENCIES,
|
|
202
|
+
isKnownCurrency,
|
|
203
|
+
UnknownCurrencyError
|
|
204
|
+
} from "@usethrottle/money";
|
|
190
205
|
export {
|
|
206
|
+
CURRENCIES,
|
|
191
207
|
InvoiceProvider,
|
|
192
208
|
InvoicesClient,
|
|
193
209
|
ThrottleError2 as ThrottleError,
|
|
194
210
|
ThrottleInvoicesError,
|
|
211
|
+
UnknownCurrencyError,
|
|
195
212
|
createInvoicesClient,
|
|
213
|
+
currencySymbol,
|
|
214
|
+
formatMoney,
|
|
215
|
+
isKnownCurrency,
|
|
196
216
|
isThrottleError,
|
|
217
|
+
minorUnitsOf,
|
|
218
|
+
money,
|
|
219
|
+
moneyValue,
|
|
220
|
+
parseMoney,
|
|
221
|
+
toDecimalString,
|
|
222
|
+
toMinor,
|
|
197
223
|
useDownloadInvoice,
|
|
198
224
|
useInvoice,
|
|
199
225
|
useInvoiceClient,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["import { ThrottleError } from '@usethrottle/errors';\nexport class ThrottleInvoicesError extends ThrottleError {\n constructor(args: { code: string; message: string; statusCode: number; details?: unknown }) {\n super(args); this.name = 'ThrottleInvoicesError';\n }\n}\nexport { ThrottleError, isThrottleError } from '@usethrottle/errors';\n","import { ThrottleInvoicesError } from './errors';\nimport type { Invoice, InvoicesClientContract, InvoicesClientOptions, ListInvoicesParams, PaginatedInvoices, ThrottleEnvelope } from './types';\n\nexport class InvoicesClient implements InvoicesClientContract {\n private readonly apiKey?: string; private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch; private readonly fetcher?: InvoicesClientOptions['fetcher']; private readonly timeoutMs: number;\n constructor(opts: InvoicesClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('InvoicesClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) throw new Error('InvoicesClient: apiKey or fetcher is required');\n this.apiKey = opts.apiKey; this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl; this.fetcher = opts.fetcher; this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n private async requestEnvelope<T>(method: string, path: string): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController(); const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n try {\n const init: RequestInit = { method, headers: { 'content-type': 'application/json', ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}) }, signal: ctrl.signal };\n const res = this.fetcher ? await this.fetcher(path, init) : await this.fetchImpl(`${this.baseUrl}${path}`, init);\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) throw new ThrottleInvoicesError({ code: json.error?.code ?? 'unknown_error', message: json.error?.message ?? `HTTP ${res.status}`, statusCode: res.status, details: json.error?.details });\n return json;\n } finally { clearTimeout(timer); }\n }\n async list(params: ListInvoicesParams = {}): Promise<PaginatedInvoices> {\n const q = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) if (v !== undefined && v !== null && v !== '') q.set(k, String(v));\n const suffix = q.toString() ? `?${q}` : '';\n const env = await this.requestEnvelope<Invoice[]>('GET', `/api/v1/invoices${suffix}`);\n return { data: env.data ?? [], pagination: env.meta?.pagination ? { cursor: env.meta.pagination.cursor ?? null, hasMore: Boolean(env.meta.pagination.hasMore) } : undefined };\n }\n async get(id: string): Promise<Invoice> {\n const env = await this.requestEnvelope<Invoice>('GET', `/api/v1/invoices/${encodeURIComponent(id)}`);\n return env.data as Invoice;\n }\n async getDownloadUrl(id: string): Promise<string> {\n const env = await this.requestEnvelope<{ url: string }>('GET', `/api/v1/invoices/${encodeURIComponent(id)}/download?format=json`);\n return (env.data as { url: string }).url;\n }\n}\nexport function createInvoicesClient(opts: InvoicesClientOptions): InvoicesClient { return new InvoicesClient(opts); }\n","import { createContext, useCallback, useContext, useMemo, useReducer, type ReactNode } from 'react';\nimport { InvoicesClient } from './client';\nimport type {\n InvoiceFetcher,\n InvoicesProviderProps,\n InvoicesClientContract,\n} from './types';\n\ninterface InvoiceContextValue {\n client: InvoicesClientContract;\n cacheVersion: number;\n invalidate: () => void;\n}\n\nconst InvoiceContext = createContext<InvoiceContextValue | null>(null);\n\nexport function InvoiceProvider({\n children,\n client,\n fetcher,\n baseUrl,\n timeoutMs,\n}: InvoicesProviderProps) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const resolvedClient = useMemo(() => {\n if (client) return client;\n return new InvoicesClient({\n fetcher: fetcher ?? createInvoiceFetcher('/api/throttle'),\n baseUrl,\n timeoutMs,\n });\n }, [baseUrl, client, fetcher, timeoutMs]);\n\n const value = useMemo(\n () => ({ client: resolvedClient, cacheVersion, invalidate }),\n [cacheVersion, resolvedClient],\n );\n\n return <InvoiceContext.Provider value={value}>{children}</InvoiceContext.Provider>;\n}\n\nexport function useInvoiceClient(): InvoicesClientContract {\n return useInvoiceContext().client;\n}\n\nexport function useInvoiceInvalidation(): () => void {\n return useInvoiceContext().invalidate;\n}\n\nexport function useInvoiceCacheVersion(): number {\n return useInvoiceContext().cacheVersion;\n}\n\nexport function createInvoiceFetcher(basePath: string): InvoiceFetcher {\n const cleanBase = basePath.replace(/\\/+$/, '');\n return (path, init) => {\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return fetch(`${cleanBase}${cleanPath}`, init);\n };\n}\n\nexport function useInvoiceContext(): InvoiceContextValue {\n const ctx = useContext(InvoiceContext);\n if (!ctx) {\n throw new Error(\n '@usethrottle/invoices hooks must be used inside <InvoiceProvider />',\n );\n }\n return ctx;\n}\n\nexport function InvoiceProviderWithClient({\n children,\n client,\n}: {\n children: ReactNode;\n client: InvoicesClientContract;\n}) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const value = useMemo(() => ({ client, cacheVersion, invalidate }), [cacheVersion, client]);\n return <InvoiceContext.Provider value={value}>{children}</InvoiceContext.Provider>;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useInvoiceCacheVersion,\n useInvoiceClient,\n} from './provider';\nimport type {\n Invoice,\n ListInvoicesParams,\n PaginatedInvoices,\n QueryOptions,\n QueryState,\n} from './types';\n\nexport function useInvoices(\n params: ListInvoicesParams = {},\n options: QueryOptions<PaginatedInvoices> = {},\n): QueryState<PaginatedInvoices> {\n const client = useInvoiceClient();\n const v = useInvoiceCacheVersion();\n const p = useStableValue(params);\n return useAsyncQuery(() => client.list(p), [client, p, v], options);\n}\n\nexport function useInvoice(\n id: string | null | undefined,\n options: QueryOptions<Invoice> = {},\n): QueryState<Invoice> {\n const client = useInvoiceClient();\n const v = useInvoiceCacheVersion();\n return useAsyncQuery(\n () => (id ? client.get(id) : Promise.resolve(null)),\n [client, id, v],\n { ...options, enabled: options.enabled ?? Boolean(id) },\n );\n}\n\nexport function useDownloadInvoice() {\n const client = useInvoiceClient();\n return async (id: string) => {\n const url = await client.getDownloadUrl(id);\n if (typeof window !== 'undefined') window.open(url, '_blank');\n return url;\n };\n}\n\nfunction useAsyncQuery<T>(\n load: () => Promise<T | null>,\n deps: readonly unknown[],\n options: QueryOptions<T>,\n): QueryState<T> {\n const enabled = options.enabled ?? true;\n const [data, setData] = useState<T | null>(options.initialData ?? null);\n const [error, setError] = useState<unknown>(null);\n const [isLoading, setIsLoading] = useState(enabled && options.initialData === undefined);\n const [isFetching, setIsFetching] = useState(false);\n const loadRef = useRef(load);\n loadRef.current = load;\n\n const refetch = useCallback(async () => {\n if (!enabled) return data;\n setIsFetching(true);\n setError(null);\n try {\n const next = await loadRef.current();\n setData(next);\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsFetching(false);\n setIsLoading(false);\n }\n }, [data, enabled]);\n\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n let cancelled = false;\n setIsFetching(true);\n setError(null);\n load()\n .then((next) => {\n if (!cancelled) setData(next);\n })\n .catch((err) => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoading(false);\n setIsFetching(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, ...deps]);\n\n return { data, error, isLoading, isFetching, refetch };\n}\n\nfunction useStableValue<T>(value: T): T {\n const key = JSON.stringify(value);\n return useMemo(() => value, [key]);\n}\n"],"mappings":"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","names":["ThrottleError","value","useCallback","useMemo","useCallback","useMemo"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/provider.tsx","../src/hooks.ts","../src/index.tsx"],"sourcesContent":["import { ThrottleError, type ThrottleErrorArgs } from '@usethrottle/errors';\nexport class ThrottleInvoicesError extends ThrottleError {\n constructor(args: { code: string; message: string; statusCode: number; details?: unknown; responseHeaders?: ThrottleErrorArgs['responseHeaders'] }) {\n super(args); this.name = 'ThrottleInvoicesError';\n }\n}\nexport { ThrottleError, isThrottleError } from '@usethrottle/errors';\n","import { ThrottleInvoicesError } from './errors';\nimport type { Invoice, InvoicesClientContract, InvoicesClientOptions, ListInvoicesParams, PaginatedInvoices, ThrottleEnvelope } from './types';\n\nexport class InvoicesClient implements InvoicesClientContract {\n private readonly apiKey?: string; private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch; private readonly fetcher?: InvoicesClientOptions['fetcher']; private readonly timeoutMs: number;\n constructor(opts: InvoicesClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('InvoicesClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) throw new Error('InvoicesClient: apiKey or fetcher is required');\n this.apiKey = opts.apiKey; this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl; this.fetcher = opts.fetcher; this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n private async requestEnvelope<T>(method: string, path: string): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController(); const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n try {\n const init: RequestInit = { method, headers: { 'content-type': 'application/json', ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}) }, signal: ctrl.signal };\n const res = this.fetcher ? await this.fetcher(path, init) : await this.fetchImpl(`${this.baseUrl}${path}`, init);\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) throw new ThrottleInvoicesError({ code: json.error?.code ?? 'unknown_error', message: json.error?.message ?? `HTTP ${res.status}`, statusCode: res.status, details: json.error?.details, responseHeaders: res.headers });\n return json;\n } finally { clearTimeout(timer); }\n }\n async list(params: ListInvoicesParams = {}): Promise<PaginatedInvoices> {\n const q = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) if (v !== undefined && v !== null && v !== '') q.set(k, String(v));\n const suffix = q.toString() ? `?${q}` : '';\n const env = await this.requestEnvelope<Invoice[]>('GET', `/api/v1/invoices${suffix}`);\n return { data: env.data ?? [], pagination: env.meta?.pagination ? { cursor: env.meta.pagination.cursor ?? null, hasMore: Boolean(env.meta.pagination.hasMore) } : undefined };\n }\n async get(id: string): Promise<Invoice> {\n const env = await this.requestEnvelope<Invoice>('GET', `/api/v1/invoices/${encodeURIComponent(id)}`);\n return env.data as Invoice;\n }\n async getDownloadUrl(id: string): Promise<string> {\n const env = await this.requestEnvelope<{ url: string }>('GET', `/api/v1/invoices/${encodeURIComponent(id)}/download?format=json`);\n return (env.data as { url: string }).url;\n }\n}\nexport function createInvoicesClient(opts: InvoicesClientOptions): InvoicesClient { return new InvoicesClient(opts); }\n","import { createContext, useCallback, useContext, useMemo, useReducer, type ReactNode } from 'react';\nimport { InvoicesClient } from './client';\nimport type {\n InvoiceFetcher,\n InvoicesProviderProps,\n InvoicesClientContract,\n} from './types';\n\ninterface InvoiceContextValue {\n client: InvoicesClientContract;\n cacheVersion: number;\n invalidate: () => void;\n}\n\nconst InvoiceContext = createContext<InvoiceContextValue | null>(null);\n\nexport function InvoiceProvider({\n children,\n client,\n fetcher,\n baseUrl,\n timeoutMs,\n}: InvoicesProviderProps) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const resolvedClient = useMemo(() => {\n if (client) return client;\n return new InvoicesClient({\n fetcher: fetcher ?? createInvoiceFetcher('/api/throttle'),\n baseUrl,\n timeoutMs,\n });\n }, [baseUrl, client, fetcher, timeoutMs]);\n\n const value = useMemo(\n () => ({ client: resolvedClient, cacheVersion, invalidate }),\n [cacheVersion, resolvedClient],\n );\n\n return <InvoiceContext.Provider value={value}>{children}</InvoiceContext.Provider>;\n}\n\nexport function useInvoiceClient(): InvoicesClientContract {\n return useInvoiceContext().client;\n}\n\nexport function useInvoiceInvalidation(): () => void {\n return useInvoiceContext().invalidate;\n}\n\nexport function useInvoiceCacheVersion(): number {\n return useInvoiceContext().cacheVersion;\n}\n\nexport function createInvoiceFetcher(basePath: string): InvoiceFetcher {\n const cleanBase = basePath.replace(/\\/+$/, '');\n return (path, init) => {\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return fetch(`${cleanBase}${cleanPath}`, init);\n };\n}\n\nexport function useInvoiceContext(): InvoiceContextValue {\n const ctx = useContext(InvoiceContext);\n if (!ctx) {\n throw new Error(\n '@usethrottle/invoices hooks must be used inside <InvoiceProvider />',\n );\n }\n return ctx;\n}\n\nexport function InvoiceProviderWithClient({\n children,\n client,\n}: {\n children: ReactNode;\n client: InvoicesClientContract;\n}) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const value = useMemo(() => ({ client, cacheVersion, invalidate }), [cacheVersion, client]);\n return <InvoiceContext.Provider value={value}>{children}</InvoiceContext.Provider>;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useInvoiceCacheVersion,\n useInvoiceClient,\n} from './provider';\nimport type {\n Invoice,\n ListInvoicesParams,\n PaginatedInvoices,\n QueryOptions,\n QueryState,\n} from './types';\n\nexport function useInvoices(\n params: ListInvoicesParams = {},\n options: QueryOptions<PaginatedInvoices> = {},\n): QueryState<PaginatedInvoices> {\n const client = useInvoiceClient();\n const v = useInvoiceCacheVersion();\n const p = useStableValue(params);\n return useAsyncQuery(() => client.list(p), [client, p, v], options);\n}\n\nexport function useInvoice(\n id: string | null | undefined,\n options: QueryOptions<Invoice> = {},\n): QueryState<Invoice> {\n const client = useInvoiceClient();\n const v = useInvoiceCacheVersion();\n return useAsyncQuery(\n () => (id ? client.get(id) : Promise.resolve(null)),\n [client, id, v],\n { ...options, enabled: options.enabled ?? Boolean(id) },\n );\n}\n\nexport function useDownloadInvoice() {\n const client = useInvoiceClient();\n return async (id: string) => {\n const url = await client.getDownloadUrl(id);\n if (typeof window !== 'undefined') window.open(url, '_blank');\n return url;\n };\n}\n\nfunction useAsyncQuery<T>(\n load: () => Promise<T | null>,\n deps: readonly unknown[],\n options: QueryOptions<T>,\n): QueryState<T> {\n const enabled = options.enabled ?? true;\n const [data, setData] = useState<T | null>(options.initialData ?? null);\n const [error, setError] = useState<unknown>(null);\n const [isLoading, setIsLoading] = useState(enabled && options.initialData === undefined);\n const [isFetching, setIsFetching] = useState(false);\n const loadRef = useRef(load);\n loadRef.current = load;\n\n const refetch = useCallback(async () => {\n if (!enabled) return data;\n setIsFetching(true);\n setError(null);\n try {\n const next = await loadRef.current();\n setData(next);\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsFetching(false);\n setIsLoading(false);\n }\n }, [data, enabled]);\n\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n let cancelled = false;\n setIsFetching(true);\n setError(null);\n load()\n .then((next) => {\n if (!cancelled) setData(next);\n })\n .catch((err) => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoading(false);\n setIsFetching(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, ...deps]);\n\n return { data, error, isLoading, isFetching, refetch };\n}\n\nfunction useStableValue<T>(value: T): T {\n const key = JSON.stringify(value);\n return useMemo(() => value, [key]);\n}\n","export { InvoicesClient, createInvoicesClient } from './client';\nexport { ThrottleInvoicesError, ThrottleError, isThrottleError } from './errors';\nexport { InvoiceProvider, useInvoiceClient, useInvoiceInvalidation } from './provider';\nexport { useInvoices, useInvoice, useDownloadInvoice } from './hooks';\nexport type * from './types';\n// Money helpers (MC2-R34): amounts are integer minor units of their `currency`.\nexport * as money from '@usethrottle/money';\nexport {\n formatMoney,\n currencySymbol,\n minorUnitsOf,\n toDecimalString,\n toMinor,\n parseMoney,\n moneyValue,\n CURRENCIES,\n isKnownCurrency,\n UnknownCurrencyError,\n} from '@usethrottle/money';\nexport type { CurrencyCode, MoneyValue } from '@usethrottle/money';\n"],"mappings":";AAAA,SAAS,qBAA6C;AAMtD,SAAS,iBAAAA,gBAAe,uBAAuB;AALxC,IAAM,wBAAN,cAAoC,cAAc;AAAA,EACvD,YAAY,MAAwI;AAClJ,UAAM,IAAI;AAAG,SAAK,OAAO;AAAA,EAC3B;AACF;;;ACFO,IAAM,iBAAN,MAAuD;AAAA,EAC3C;AAAA,EAAkC;AAAA,EAClC;AAAA,EAAqD;AAAA,EAA6D;AAAA,EACnI,YAAY,OAA8B,CAAC,GAAG;AAC5C,UAAM,YAAY,KAAK,SAAS,WAAW;AAC3C,QAAI,CAAC,UAAW,OAAM,IAAI,MAAM,mCAAmC;AACnE,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,QAAS,OAAM,IAAI,MAAM,+CAA+C;AAClG,SAAK,SAAS,KAAK;AAAQ,SAAK,WAAW,KAAK,WAAW,+BAA+B,QAAQ,QAAQ,EAAE;AAC5G,SAAK,YAAY;AAAW,SAAK,UAAU,KAAK;AAAS,SAAK,YAAY,KAAK,aAAa;AAAA,EAC9F;AAAA,EACA,MAAc,gBAAmB,QAAgB,MAA4C;AAC3F,UAAM,OAAO,IAAI,gBAAgB;AAAG,UAAM,QAAQ,WAAW,MAAM,KAAK,MAAM,GAAG,KAAK,SAAS;AAC/F,QAAI;AACF,YAAM,OAAoB,EAAE,QAAQ,SAAS,EAAE,gBAAgB,oBAAoB,GAAI,KAAK,SAAS,EAAE,aAAa,KAAK,OAAO,IAAI,CAAC,EAAG,GAAG,QAAQ,KAAK,OAAO;AAC/J,YAAM,MAAM,KAAK,UAAU,MAAM,KAAK,QAAQ,MAAM,IAAI,IAAI,MAAM,KAAK,UAAU,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI,IAAI;AAC/G,YAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC/C,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,sBAAsB,EAAE,MAAM,KAAK,OAAO,QAAQ,iBAAiB,SAAS,KAAK,OAAO,WAAW,QAAQ,IAAI,MAAM,IAAI,YAAY,IAAI,QAAQ,SAAS,KAAK,OAAO,SAAS,iBAAiB,IAAI,QAAQ,CAAC;AACpO,aAAO;AAAA,IACT,UAAE;AAAU,mBAAa,KAAK;AAAA,IAAG;AAAA,EACnC;AAAA,EACA,MAAM,KAAK,SAA6B,CAAC,GAA+B;AACtE,UAAM,IAAI,IAAI,gBAAgB;AAC9B,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,EAAG,KAAI,MAAM,UAAa,MAAM,QAAQ,MAAM,GAAI,GAAE,IAAI,GAAG,OAAO,CAAC,CAAC;AAC9G,UAAM,SAAS,EAAE,SAAS,IAAI,IAAI,CAAC,KAAK;AACxC,UAAM,MAAM,MAAM,KAAK,gBAA2B,OAAO,mBAAmB,MAAM,EAAE;AACpF,WAAO,EAAE,MAAM,IAAI,QAAQ,CAAC,GAAG,YAAY,IAAI,MAAM,aAAa,EAAE,QAAQ,IAAI,KAAK,WAAW,UAAU,MAAM,SAAS,QAAQ,IAAI,KAAK,WAAW,OAAO,EAAE,IAAI,OAAU;AAAA,EAC9K;AAAA,EACA,MAAM,IAAI,IAA8B;AACtC,UAAM,MAAM,MAAM,KAAK,gBAAyB,OAAO,oBAAoB,mBAAmB,EAAE,CAAC,EAAE;AACnG,WAAO,IAAI;AAAA,EACb;AAAA,EACA,MAAM,eAAe,IAA6B;AAChD,UAAM,MAAM,MAAM,KAAK,gBAAiC,OAAO,oBAAoB,mBAAmB,EAAE,CAAC,uBAAuB;AAChI,WAAQ,IAAI,KAAyB;AAAA,EACvC;AACF;AACO,SAAS,qBAAqB,MAA6C;AAAE,SAAO,IAAI,eAAe,IAAI;AAAG;;;ACvCrH,SAAS,eAA4B,YAAY,SAAS,kBAAkC;AAsCnF;AAxBT,IAAM,iBAAiB,cAA0C,IAAI;AAE9D,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,CAAC,cAAc,UAAU,IAAI,WAAW,CAACC,WAAkBA,SAAQ,GAAG,CAAC;AAC7E,QAAM,iBAAiB,QAAQ,MAAM;AACnC,QAAI,OAAQ,QAAO;AACnB,WAAO,IAAI,eAAe;AAAA,MACxB,SAAS,WAAW,qBAAqB,eAAe;AAAA,MACxD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,SAAS,QAAQ,SAAS,SAAS,CAAC;AAExC,QAAM,QAAQ;AAAA,IACZ,OAAO,EAAE,QAAQ,gBAAgB,cAAc,WAAW;AAAA,IAC1D,CAAC,cAAc,cAAc;AAAA,EAC/B;AAEA,SAAO,oBAAC,eAAe,UAAf,EAAwB,OAAe,UAAS;AAC1D;AAEO,SAAS,mBAA2C;AACzD,SAAO,kBAAkB,EAAE;AAC7B;AAEO,SAAS,yBAAqC;AACnD,SAAO,kBAAkB,EAAE;AAC7B;AAEO,SAAS,yBAAiC;AAC/C,SAAO,kBAAkB,EAAE;AAC7B;AAEO,SAAS,qBAAqB,UAAkC;AACrE,QAAM,YAAY,SAAS,QAAQ,QAAQ,EAAE;AAC7C,SAAO,CAAC,MAAM,SAAS;AACrB,UAAM,YAAY,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AACxD,WAAO,MAAM,GAAG,SAAS,GAAG,SAAS,IAAI,IAAI;AAAA,EAC/C;AACF;AAEO,SAAS,oBAAyC;AACvD,QAAM,MAAM,WAAW,cAAc;AACrC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACrEA,SAAS,eAAAC,cAAa,WAAW,WAAAC,UAAS,QAAQ,gBAAgB;AAa3D,SAAS,YACd,SAA6B,CAAC,GAC9B,UAA2C,CAAC,GACb;AAC/B,QAAM,SAAS,iBAAiB;AAChC,QAAM,IAAI,uBAAuB;AACjC,QAAM,IAAI,eAAe,MAAM;AAC/B,SAAO,cAAc,MAAM,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,GAAG,OAAO;AACpE;AAEO,SAAS,WACd,IACA,UAAiC,CAAC,GACb;AACrB,QAAM,SAAS,iBAAiB;AAChC,QAAM,IAAI,uBAAuB;AACjC,SAAO;AAAA,IACL,MAAO,KAAK,OAAO,IAAI,EAAE,IAAI,QAAQ,QAAQ,IAAI;AAAA,IACjD,CAAC,QAAQ,IAAI,CAAC;AAAA,IACd,EAAE,GAAG,SAAS,SAAS,QAAQ,WAAW,QAAQ,EAAE,EAAE;AAAA,EACxD;AACF;AAEO,SAAS,qBAAqB;AACnC,QAAM,SAAS,iBAAiB;AAChC,SAAO,OAAO,OAAe;AAC3B,UAAM,MAAM,MAAM,OAAO,eAAe,EAAE;AAC1C,QAAI,OAAO,WAAW,YAAa,QAAO,KAAK,KAAK,QAAQ;AAC5D,WAAO;AAAA,EACT;AACF;AAEA,SAAS,cACP,MACA,MACA,SACe;AACf,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAmB,QAAQ,eAAe,IAAI;AACtE,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAkB,IAAI;AAChD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,WAAW,QAAQ,gBAAgB,MAAS;AACvF,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,UAAU,OAAO,IAAI;AAC3B,UAAQ,UAAU;AAElB,QAAM,UAAUC,aAAY,YAAY;AACtC,QAAI,CAAC,QAAS,QAAO;AACrB,kBAAc,IAAI;AAClB,aAAS,IAAI;AACb,QAAI;AACF,YAAM,OAAO,MAAM,QAAQ,QAAQ;AACnC,cAAQ,IAAI;AACZ,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,eAAS,GAAG;AACZ,YAAM;AAAA,IACR,UAAE;AACA,oBAAc,KAAK;AACnB,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,MAAM,OAAO,CAAC;AAElB,YAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ,mBAAa,KAAK;AAClB;AAAA,IACF;AACA,QAAI,YAAY;AAChB,kBAAc,IAAI;AAClB,aAAS,IAAI;AACb,SAAK,EACF,KAAK,CAAC,SAAS;AACd,UAAI,CAAC,UAAW,SAAQ,IAAI;AAAA,IAC9B,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,UAAI,CAAC,UAAW,UAAS,GAAG;AAAA,IAC9B,CAAC,EACA,QAAQ,MAAM;AACb,UAAI,CAAC,WAAW;AACd,qBAAa,KAAK;AAClB,sBAAc,KAAK;AAAA,MACrB;AAAA,IACF,CAAC;AAEH,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EAEF,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC;AAErB,SAAO,EAAE,MAAM,OAAO,WAAW,YAAY,QAAQ;AACvD;AAEA,SAAS,eAAkB,OAAa;AACtC,QAAM,MAAM,KAAK,UAAU,KAAK;AAChC,SAAOC,SAAQ,MAAM,OAAO,CAAC,GAAG,CAAC;AACnC;;;ACvGA,YAAY,WAAW;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":["ThrottleError","value","useCallback","useMemo","useCallback","useMemo"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usethrottle/invoices",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "React hooks + server proxy for Throttle customer invoices.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"README.md"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@usethrottle/errors": "^1.
|
|
26
|
+
"@usethrottle/errors": "^1.1.0",
|
|
27
|
+
"@usethrottle/money": "^1.0.0"
|
|
27
28
|
},
|
|
28
29
|
"peerDependencies": {
|
|
29
30
|
"react": ">=18"
|