From 9e5e19e523ad8c2ae2fb0b195691d9106f5c0aa9 Mon Sep 17 00:00:00 2001 From: "raul@facturapi.io" Date: Wed, 12 Aug 2026 09:37:00 -0600 Subject: [PATCH 1/3] feat(invoices): add ZIP request methods --- package.json | 4 +- src/resources/invoices.ts | 92 +++++---- src/types/invoice.ts | 190 +++++++++---------- test/node/invoices-zip-requests.node.test.ts | 5 +- 4 files changed, 143 insertions(+), 148 deletions(-) diff --git a/package.json b/package.json index effcd8b..8f95dcd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "facturapi", - "version": "5.1.0", + "version": "5.2.0", "description": "SDK oficial de Facturapi para Node.js y navegadores. Integra facturaci\u00f3n electr\u00f3nica en M\u00e9xico (CFDI) de forma simple y obt\u00e9n una perspectiva fiscal completa de tu operaci\u00f3n, con b\u00fasquedas indexadas, env\u00edo de documentos y trazabilidad.", "main": "dist/index.cjs.js", "module": "dist/index.es.js", @@ -95,4 +95,4 @@ "vite": "8.0.16", "vitest": "^4.1.9" } -} +} \ No newline at end of file diff --git a/src/resources/invoices.ts b/src/resources/invoices.ts index eb1f357..58fafbc 100644 --- a/src/resources/invoices.ts +++ b/src/resources/invoices.ts @@ -11,14 +11,14 @@ import { SendEmailBody, SignedDownloadUrl, ZipRequest, -} from '../types'; -import { WrapperClient } from '../wrapper'; +} from '../types' +import { WrapperClient } from '../wrapper' export default class Invoices { - client: WrapperClient; + client: WrapperClient constructor(client: WrapperClient) { - this.client = client; + this.client = client } /** @@ -31,7 +31,7 @@ export default class Invoices { body: Record, params?: Record | null, ): Promise { - return this.client.post('/invoices', { body, params }); + return this.client.post('/invoices', { body, params }) } /** @@ -40,8 +40,8 @@ export default class Invoices { * @returns Search results object. The object contains a `data` property with the list of invoices. */ list(params?: Record | null): Promise> { - if (!params) params = {}; - return this.client.get('/invoices', { params }); + if (!params) params = {} + return this.client.get('/invoices', { params }) } /** @@ -50,8 +50,8 @@ export default class Invoices { * @returns Invoice object */ retrieve(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')); - return this.client.get('/invoices/' + id); + if (!id) return Promise.reject(new Error('id is required')) + return this.client.get('/invoices/' + id) } /** @@ -67,8 +67,8 @@ export default class Invoices { id: string, params: PaymentSummaryParams, ): Promise { - if (!id) return Promise.reject(new Error('id is required')); - return this.client.get('/invoices/' + id + '/payment-summary', { params }); + if (!id) return Promise.reject(new Error('id is required')) + return this.client.get('/invoices/' + id + '/payment-summary', { params }) } /** @@ -78,7 +78,7 @@ export default class Invoices { * @returns Canceled invoice */ cancel(id: string, params: CancelInvoiceOptions): Promise { - return this.client.delete('/invoices/' + id, { params }); + return this.client.delete('/invoices/' + id, { params }) } /** @@ -89,7 +89,7 @@ export default class Invoices { * @returns Object with 'ok' property set to true if the email was sent successfully */ sendByEmail(id: string, options?: SendEmailBody): Promise { - return this.client.post('/invoices/' + id + '/email', { body: options }); + return this.client.post('/invoices/' + id + '/email', { body: options }) } /** @@ -98,7 +98,7 @@ export default class Invoices { * @returns PDF file in a stream (Node.js) or Blob (browser) */ async downloadPdf(id: string): Promise { - return this.client.get('/invoices/' + id + '/pdf'); + return this.client.get('/invoices/' + id + '/pdf') } /** @@ -107,7 +107,7 @@ export default class Invoices { * @returns XML file in a stream (Node.js) or Blob (browser) */ async downloadXml(id: string): Promise { - return this.client.get('/invoices/' + id + '/xml'); + return this.client.get('/invoices/' + id + '/xml') } /** @@ -116,7 +116,7 @@ export default class Invoices { * @returns ZIP file in a stream (Node.js) or Blob (browser) */ downloadZip(id: string): Promise { - return this.client.get('/invoices/' + id + '/zip'); + return this.client.get('/invoices/' + id + '/zip') } /** @@ -125,20 +125,20 @@ export default class Invoices { * @returns Signed download URL and its metadata */ downloadPdfUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')); - return this.client.get('/invoices/' + id + '/download-url/pdf'); + if (!id) return Promise.reject(new Error('id is required')) + return this.client.get('/invoices/' + id + '/download-url/pdf') } /** Gets a short-lived URL for downloading an invoice XML file. */ downloadXmlUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')); - return this.client.get('/invoices/' + id + '/download-url/xml'); + if (!id) return Promise.reject(new Error('id is required')) + return this.client.get('/invoices/' + id + '/download-url/xml') } /** Gets a short-lived URL for downloading an invoice ZIP file. */ downloadZipUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')); - return this.client.get('/invoices/' + id + '/download-url/zip'); + if (!id) return Promise.reject(new Error('id is required')) + return this.client.get('/invoices/' + id + '/download-url/zip') } /** @@ -147,7 +147,7 @@ export default class Invoices { * @returns ZIP request object */ createZipRequest(data: CreateZipRequestData): Promise { - return this.client.post('/invoices/zip-requests', { body: data }); + return this.client.post('/invoices/zip-requests', { body: data }) } /** @@ -160,7 +160,7 @@ export default class Invoices { ): Promise> { return this.client.get('/invoices/zip-requests', { params: params || {}, - }); + }) } /** @@ -169,8 +169,8 @@ export default class Invoices { * @returns ZIP request object */ retrieveZipRequest(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')); - return this.client.get('/invoices/zip-requests/' + id); + if (!id) return Promise.reject(new Error('id is required')) + return this.client.get('/invoices/zip-requests/' + id) } /** @@ -179,14 +179,14 @@ export default class Invoices { * @returns ZIP file in a stream (Node.js) or Blob (browser) */ downloadZipRequest(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')); - return this.client.get('/invoices/zip-requests/' + id + '/zip'); + if (!id) return Promise.reject(new Error('id is required')) + return this.client.get('/invoices/zip-requests/' + id + '/zip') } /** Gets a short-lived URL for downloading a generated invoice ZIP request. */ downloadZipRequestUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')); - return this.client.get('/invoices/zip-requests/' + id + '/download-url'); + if (!id) return Promise.reject(new Error('id is required')) + return this.client.get('/invoices/zip-requests/' + id + '/download-url') } /** @@ -194,10 +194,8 @@ export default class Invoices { * @param id Invoice Id * @returns XML file in a stream (Node.js) or Blob (browser) */ - downloadCancellationReceiptXml( - id: string, - ): Promise { - return this.client.get('/invoices/' + id + '/cancellation_receipt/xml'); + downloadCancellationReceiptXml(id: string): Promise { + return this.client.get('/invoices/' + id + '/cancellation_receipt/xml') } /** @@ -205,10 +203,8 @@ export default class Invoices { * @param id Invoice Id * @returns PDF file in a stream (Node.js) or Blob (browser) */ - downloadCancellationReceiptPdf( - id: string, - ): Promise { - return this.client.get('/invoices/' + id + '/cancellation_receipt/pdf'); + downloadCancellationReceiptPdf(id: string): Promise { + return this.client.get('/invoices/' + id + '/cancellation_receipt/pdf') } /** @@ -217,18 +213,18 @@ export default class Invoices { * @returns Signed download URL and its metadata */ downloadCancellationReceiptPdfUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')); + if (!id) return Promise.reject(new Error('id is required')) return this.client.get( '/invoices/' + id + '/cancellation_receipt/download-url/pdf', - ); + ) } /** Gets a short-lived URL for downloading a cancellation receipt XML file. */ downloadCancellationReceiptXmlUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')); + if (!id) return Promise.reject(new Error('id is required')) return this.client.get( '/invoices/' + id + '/cancellation_receipt/download-url/xml', - ); + ) } /** @@ -238,7 +234,7 @@ export default class Invoices { * @returns Edited invoice */ updateDraft(id: string, data: Record): Promise { - return this.client.put('/invoices/' + id, { body: data }); + return this.client.put('/invoices/' + id, { body: data }) } /** @@ -251,7 +247,7 @@ export default class Invoices { id: string, params?: Record | null, ): Promise { - return this.client.post('/invoices/' + id + '/stamp', { params }); + return this.client.post('/invoices/' + id + '/stamp', { params }) } /** @@ -260,7 +256,7 @@ export default class Invoices { * @returns Updated invoice */ updateStatus(id: string): Promise { - return this.client.put('/invoices/' + id + '/status'); + return this.client.put('/invoices/' + id + '/status') } /** @@ -269,7 +265,7 @@ export default class Invoices { * @returns Draft invoice */ copyToDraft(id: string): Promise { - return this.client.post('/invoices/' + id + '/copy'); + return this.client.post('/invoices/' + id + '/copy') } /** @@ -278,11 +274,11 @@ export default class Invoices { * @returns PDF file in a stream (Node.js) or Blob (browser) */ previewPdf(body: Record): Promise { - return this.client.post('/invoices/preview/pdf', { body }); + return this.client.post('/invoices/preview/pdf', { body }) } /** Gets a short-lived URL for an invoice PDF preview. */ previewPdfUrl(body: Record): Promise { - return this.client.post('/invoices/preview/pdf/download-url', { body }); + return this.client.post('/invoices/preview/pdf/download-url', { body }) } } diff --git a/src/types/invoice.ts b/src/types/invoice.ts index 46a9e63..295864f 100644 --- a/src/types/invoice.ts +++ b/src/types/invoice.ts @@ -9,115 +9,115 @@ import { IssuingType, PaymentForm, PaymentMethod, -} from '../enums'; +} from '../enums' import { Address, CustomerInfo, InvoiceItem, RelatedDocument, XmlNamespace, -} from './common'; -import { NominaComplementData, PagoComplementData } from './complements'; +} from './common' +import { NominaComplementData, PagoComplementData } from './complements' export interface GlobalInfo { - periodicity: InvoicingPeriod; - months: string; - year: number; + periodicity: InvoicingPeriod + months: string + year: number } export interface InvoiceComplement { - type: InvoiceComplementType; - data: string | PagoComplementData[] | NominaComplementData; + type: InvoiceComplementType + data: string | PagoComplementData[] | NominaComplementData } export interface Invoice { - id: string; - organization: string; - livemode: boolean; - created_at: Date; - date: Date; - issuer_type: IssuingType; - type: InvoiceType; - status: InvoiceStatus; - cfdi_version: number; - issuer_info: CustomerInfo; - payment_form: PaymentForm; - payment_method: PaymentMethod; - currency: string; - exchange: number; - uuid: string; - customer: CustomerInfo; - total: number; - use: InvoiceUse; - folio_number: number | string; - series: string; - is_ready_to_stamp: boolean; - items: InvoiceItem[]; - address: Address; - amount_due?: number | null; - verification_url?: string | null; - verification_carta_porte?: string | null; - cancellation_status: CancellationStatus; - external_id?: string | null; - idempotency_key?: string | null; + id: string + organization: string + livemode: boolean + created_at: Date + date: Date + issuer_type: IssuingType + type: InvoiceType + status: InvoiceStatus + cfdi_version: number + issuer_info: CustomerInfo + payment_form: PaymentForm + payment_method: PaymentMethod + currency: string + exchange: number + uuid: string + customer: CustomerInfo + total: number + use: InvoiceUse + folio_number: number | string + series: string + is_ready_to_stamp: boolean + items: InvoiceItem[] + address: Address + amount_due?: number | null + verification_url?: string | null + verification_carta_porte?: string | null + cancellation_status: CancellationStatus + external_id?: string | null + idempotency_key?: string | null stamp?: { - date: string; - sat_signature: string; - sat_cert_number: string; - signature: string; - complement_string: string; - rfc_provider_cert: string; - } | null; - addenda?: string | null; - conditions: string | null; + date: string + sat_signature: string + sat_cert_number: string + signature: string + complement_string: string + rfc_provider_cert: string + } | null + addenda?: string | null + conditions: string | null - pdf_custom_section: string | null; - export?: string | null; - global?: GlobalInfo | null; + pdf_custom_section: string | null + export?: string | null + global?: GlobalInfo | null cancellation?: { - requested_at: Date; - status: CancellationStatus; - last_checked: Date; - motive: string; - substitutionUUID: string; - } | null; - complements?: InvoiceComplement[] | null; - related_documents?: RelatedDocument[] | null; - namespaces?: XmlNamespace[] | null; - received_payment_ids?: string[] | null; - target_invoice_ids?: string[] | null; + requested_at: Date + status: CancellationStatus + last_checked: Date + motive: string + substitutionUUID: string + } | null + complements?: InvoiceComplement[] | null + related_documents?: RelatedDocument[] | null + namespaces?: XmlNamespace[] | null + received_payment_ids?: string[] | null + target_invoice_ids?: string[] | null } export interface CancelInvoiceOptions { - motive: CancellationMotive; - substitution?: string; + motive: CancellationMotive + substitution?: string } export interface CreateZipRequestData { - year: number; - month: number; - issuer_type: IssuingType; - invoice_types?: InvoiceType[]; + year: number + month: number + issuer_type: IssuingType + invoice_types?: InvoiceType[] } export interface ListZipRequestsParams { - year?: number; - month?: number; - status?: string; - limit?: number; - page?: number; + year?: number + month?: number + status?: string + limit?: number + page?: number } export interface ZipRequest { - id: string; - year: number; - month: number; - issuer_type: IssuingType; - invoice_types: InvoiceType[]; - status: string; - created_at?: Date; - updated_at?: Date; - [key: string]: unknown; + id: string + year: number + month: number + issuer_type: IssuingType + invoice_types: InvoiceType[] + status: string + created_at?: Date + updated_at?: Date + [key: string]: unknown } export interface PaymentSummaryParams { @@ -125,37 +125,37 @@ export interface PaymentSummaryParams { * Amount being paid on the invoice, expressed in the invoice currency. * Cannot exceed the outstanding balance. */ - amount: number; + amount: number } export interface PaymentSummaryTax { /** Tax base prorated to the paid amount */ - base: number; + base: number /** Tax rate or quota */ - rate: number; + rate: number /** Tax type (VAT, income tax, etc.) */ - type: string; + type: string /** Factor type (Rate, Exempt, etc.) */ - factor: string; + factor: string /** Whether this tax is a withholding */ - withholding: boolean; + withholding: boolean } export interface PaymentSummary { /** Invoice UUID */ - uuid: string; - folio_number?: number | null; - series?: string | null; + uuid: string + folio_number?: number | null + series?: string | null /** Installment number corresponding to this payment */ - installment: number; + installment: number /** Invoice outstanding balance before this payment */ - last_balance: number; + last_balance: number /** Invoice total */ - total: number; + total: number /** Invoice currency */ - currency: string; + currency: string /** Amount paid in this installment */ - amount: number; + amount: number /** Invoice taxes prorated to the paid amount */ - taxes: PaymentSummaryTax[]; + taxes: PaymentSummaryTax[] } diff --git a/test/node/invoices-zip-requests.node.test.ts b/test/node/invoices-zip-requests.node.test.ts index 57dc12b..31714cf 100644 --- a/test/node/invoices-zip-requests.node.test.ts +++ b/test/node/invoices-zip-requests.node.test.ts @@ -115,9 +115,8 @@ describe('invoice ZIP requests', () => { }) }) as typeof fetch - const result = await client.invoices.downloadZipRequestUrl( - 'zip_request_123', - ) + const result = + await client.invoices.downloadZipRequestUrl('zip_request_123') expect(result.filename).toBe('2025-03.zip') }) From ecdb73ab1bac15845393b1ede5eb029b7eba04d0 Mon Sep 17 00:00:00 2001 From: "raul@facturapi.io" Date: Thu, 17 Sep 2026 15:38:58 -0600 Subject: [PATCH 2/3] chore(nominaCatalogs): add new methods for nomina catalogs --- .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ .vscode/settings.json | 6 +++++- CHANGELOG.md | 6 ++++++ README.md | 7 +++++++ src/index.ts | 3 +++ src/tools/nominaCatalogs.ts | 17 +++++++++++++++++ 6 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/tools/nominaCatalogs.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2b66753..7699f82 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,30 @@ on: workflow_dispatch: jobs: + quality: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Setup pnpm + uses: pnpm/action-setup@v6 + + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Check formatting + run: pnpm run format:check + + - name: Run linter + run: pnpm run lint + build-dist: runs-on: ubuntu-latest steps: diff --git a/.vscode/settings.json b/.vscode/settings.json index b2a6fed..7290de2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,8 @@ { + "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, - "eslint.enable": true + "eslint.enable": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ad41ee..4c74331 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [5.2.0] 2026-10-07 + +### Added + +- Add `nominaCatalogs.searchDeductions` and `nominaCatalogs.searchPerceptions` to search the SAT payroll deduction and perception catalogs. + ## [5.1.0] 2026-09-12 ### Added diff --git a/README.md b/README.md index 115f762..48bff58 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,13 @@ CommonJS: const Facturapi = require('facturapi').default; ``` +### Payroll catalogs + +```ts +const deductions = await facturapi.nominaCatalogs.searchDeductions({ q: '001' }); +const perceptions = await facturapi.nominaCatalogs.searchPerceptions({ q: '001' }); +``` + ### Create a customer ```ts diff --git a/src/index.ts b/src/index.ts index 13075f8..b357684 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,6 +12,7 @@ import { createWrapper, WrapperClient } from './wrapper'; import { DEFAULT_API_VERSION } from './constants'; import CartaPorteCatalogs from './tools/cartaPorteCatalogs'; import ComercioExteriorCatalogs from './tools/comercioExteriorCatalogs'; +import NominaCatalogs from './tools/nominaCatalogs'; export * from './enums'; export * from './types'; @@ -43,6 +44,7 @@ export default class Facturapi { catalogs: Catalogs; cartaPorteCatalogs: CartaPorteCatalogs; comercioExteriorCatalogs: ComercioExteriorCatalogs; + nominaCatalogs: NominaCatalogs; receipts: Receipts; retentions: Retentions; tools: Tools; @@ -204,6 +206,7 @@ export default class Facturapi { this.catalogs = new Catalogs(this._wrapper); this.cartaPorteCatalogs = new CartaPorteCatalogs(this._wrapper); this.comercioExteriorCatalogs = new ComercioExteriorCatalogs(this._wrapper); + this.nominaCatalogs = new NominaCatalogs(this._wrapper); this.receipts = new Receipts(this._wrapper); this.retentions = new Retentions(this._wrapper); this.tools = new Tools(this._wrapper); diff --git a/src/tools/nominaCatalogs.ts b/src/tools/nominaCatalogs.ts new file mode 100644 index 0000000..7c92e95 --- /dev/null +++ b/src/tools/nominaCatalogs.ts @@ -0,0 +1,17 @@ +import { WrapperClient } from '../wrapper'; + +export default class NominaCatalogs { + client: WrapperClient; + + constructor(client: WrapperClient) { + this.client = client; + } + + searchDeductions(params: { q: string; page?: number; limit?: number }) { + return this.client.get('/catalogs/deductions', { params }); + } + + searchPerceptions(params: { q: string; page?: number; limit?: number }) { + return this.client.get('/catalogs/perceptions', { params }); + } +} From 033ea17fb2cbd9f6b309c3b6914573e68613fe47 Mon Sep 17 00:00:00 2001 From: "raul@facturapi.io" Date: Thu, 8 Oct 2026 11:24:53 -0600 Subject: [PATCH 3/3] chore(eslintConfiguration): add eslint checking and formatting homologation --- .github/workflows/deploy.yml | 4 +- .prettierrc | 2 +- CHANGELOG.md | 21 +- README.md | 17 +- eslint.config.js | 17 +- package.json | 10 +- pnpm-lock.yaml | 2294 ++++++++++++----- src/resources/invoices.ts | 84 +- src/resources/organizations.ts | 52 +- src/resources/products.ts | 5 +- src/resources/receipts.ts | 38 +- src/resources/retentions.ts | 46 +- src/tools/webhooks.ts | 16 +- src/types/common.ts | 6 +- src/types/invoice.ts | 190 +- src/types/receipt.ts | 62 +- src/wrapper.ts | 13 +- test-d/runtime-types.test-d.ts | 110 +- test/browser/runtime-smoke.browser.spec.ts | 9 +- test/certs.spec.js | 16 +- test/index.spec.js | 8 +- .../node/invoice-payment-summary.node.test.ts | 48 +- test/node/invoices-zip-requests.node.test.ts | 116 +- test/node/query-params.node.test.ts | 106 +- test/node/runtime-compat.node.test.ts | 402 ++- test/node/signed-download-urls.node.test.ts | 122 +- test/web/runtime-compat.web.test.ts | 268 +- 27 files changed, 2578 insertions(+), 1504 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d9b0801..0505089 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -23,8 +23,8 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v6 with: - node-version: "24" - registry-url: "https://registry.npmjs.org" + node-version: '24' + registry-url: 'https://registry.npmjs.org' cache: pnpm - name: Install dependencies diff --git a/.prettierrc b/.prettierrc index fd496a8..650cb88 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,4 @@ { "singleQuote": true, - "semi": false + "semi": true } diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c74331..681c5e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,38 +59,53 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add draft support methods for retentions: `retentions.updateDraft`, `retentions.copyToDraft`, and `retentions.stampDraft`. ## [4.18.0] 2026-06-06 + ### Added + - Expose structured API error metadata through `FacturapiError`, including `status`, `code`, `path`, `location`, `errors`, `logId`, and response `headers`. ## [4.17.0] 2026-04-27 + ### Added + - Add support for custom request headers through the `Facturapi` constructor options. - Add `receipts.toInvoice` to create customer invoices from multiple receipt keys. - Add `receipts.previewToInvoicePdf` to generate PDF previews for to-invoice payloads. ## [4.16.0] 2026-04-23 + ### Added + - Add new export catalogs for customs regimes, transport keys, SCT permits, COFEPRIS sectors, pharmaceutical forms, special transport conditions, customs documents, transport types, transport figures, ISTMO registry, loading keys, maritime configurations, rail traffic, containers, rail cars, rail service types, transfer reasons, incoterms, and customs units. - Expose the new enums on the `Facturapi` class as static getters for namespace-style access. ## [4.15.0] 2026-04-13 + ### Added + - Add `organizations.updateDefaultSeries` to set an organization default series by type. ### Fixed -- Return blob if content-type is octet-stream. This is the coverage for zip files + +- Return blob if content-type is octet-stream. This is the coverage for zip files ## [4.14.2] 2026-03-31 + ### Fixed + - Add `TaxFactor.EXENTO` (`"Exento"`) to align SDK enums with the API/OpenAPI allowed tax factor values. ## [4.14.1] 2026-03-31 + ### Fixed + - Fix `organizations.checkDomainIsAvailable` to call `GET /organizations/domain-check` with query params (instead of an unsupported `PUT` payload flow). - Align method input naming to query semantics for clearer usage (`query`). ## [4.14.0] 2026-03-04 + ### Added + - Add `facturapi.comercioExteriorCatalogs.searchTariffFractions` method for Fracción Arancelaria SAT catalog - Add organization team/access management methods under `organizations`: `listTeamAccess`, `retrieveTeamAccess`, `removeTeamAccess`, @@ -105,6 +120,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Include `rfc_provider_cert` in stamp-related invoice typings and responses (thanks to @tetexxr). ### Changed + - Use `PUT` for role reassignment/update methods: `organizations.updateTeamAccessRole` and `organizations.updateTeamRole`. - Use `Authorization: Bearer ` by default in SDK requests (API supports this scheme). @@ -113,6 +129,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Pin `npm` to `10.9.2` in CI/deploy workflows for deterministic lockfile validation across Node versions. ### Fixed + - Improve non-OK HTTP error handling fallback when JSON error bodies are malformed or missing, returning clearer text/status errors. - Handle `ReadableStream` read failures during binary download conversion to Node streams to avoid unhandled rejections. - Strengthen WebCrypto webhook signature validation by using `subtle.verify` and explicit hex signature validation. @@ -144,7 +161,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added -- Add new catalogs for cartaporte +- Add new catalogs for cartaporte - `searchAirTransportCodes`, `searchTransportConfigs`,`searchRightsOfPassage`,`searchCustomsDocuments`,`searchPackagingTypes`,`searchTrailerTypes`, `searchHazardousMaterials`, `searchNavalAuthorizations`, `searchPortStations`, `searchMarineContainers` ## [4.10.0] 2025-09-04 diff --git a/README.md b/README.md index 48bff58..cac1078 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@ If you've used [Stripe](https://stripe.com) or [Conekta](https://conekta.io), yo ## Compatibility -| Runtime | Support | -| --- | --- | -| Node.js | `>=18` (CI tested on 18, 20, 22, 24) | -| Browser | Environments with `fetch`, `FormData`, and `Blob` | +| Runtime | Support | +| ------------ | ------------------------------------------------------------ | +| Node.js | `>=18` (CI tested on 18, 20, 22, 24) | +| Browser | Environments with `fetch`, `FormData`, and `Blob` | | React Native | Versions that provide global `fetch`, `FormData`, and `Blob` | ## Install @@ -47,8 +47,12 @@ const Facturapi = require('facturapi').default; ### Payroll catalogs ```ts -const deductions = await facturapi.nominaCatalogs.searchDeductions({ q: '001' }); -const perceptions = await facturapi.nominaCatalogs.searchPerceptions({ q: '001' }); +const deductions = await facturapi.nominaCatalogs.searchDeductions({ + q: '001', +}); +const perceptions = await facturapi.nominaCatalogs.searchPerceptions({ + q: '001', +}); ``` ### Create a customer @@ -83,6 +87,7 @@ const invoice = await facturapi.invoices.create({ #### Download your invoice `downloadZip`, `downloadPdf` and `downloadXml` return a binary result: + - Node.js: stream-like object - Browser: `Blob` diff --git a/eslint.config.js b/eslint.config.js index 79c6a25..4424981 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,7 +1,7 @@ -const js = require('@eslint/js') -const tseslint = require('typescript-eslint') -const globals = require('globals') -const eslintConfigPrettier = require('eslint-config-prettier') +const js = require('@eslint/js'); +const tseslint = require('typescript-eslint'); +const globals = require('globals'); +const eslintConfigPrettier = require('eslint-config-prettier'); module.exports = [ { @@ -18,7 +18,6 @@ module.exports = [ }, }, rules: { - semi: ['error', 'never'], quotes: ['error', 'single', { avoidEscape: true }], curly: ['error', 'multi-line'], 'space-before-function-paren': ['error', 'always'], @@ -30,4 +29,10 @@ module.exports = [ }, }, eslintConfigPrettier, -] + { + files: ['**/*.{js,cjs,mjs,ts}'], + rules: { + semi: ['error', 'always'], + }, + }, +]; diff --git a/package.json b/package.json index 8f95dcd..b60520a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "facturapi", "version": "5.2.0", - "description": "SDK oficial de Facturapi para Node.js y navegadores. Integra facturaci\u00f3n electr\u00f3nica en M\u00e9xico (CFDI) de forma simple y obt\u00e9n una perspectiva fiscal completa de tu operaci\u00f3n, con b\u00fasquedas indexadas, env\u00edo de documentos y trazabilidad.", + "description": "SDK oficial de Facturapi para Node.js y navegadores. Integra facturación electrónica en México (CFDI) de forma simple y obtén una perspectiva fiscal completa de tu operación, con búsquedas indexadas, envío de documentos y trazabilidad.", "main": "dist/index.cjs.js", "module": "dist/index.es.js", "types": "dist/index.d.ts", @@ -49,13 +49,13 @@ "sat-mexico", "mexico", "sat", - "facturaci\u00f3n", + "facturación", "facturapi" ], - "author": "Facturaci\u00f3n Espacial ", + "author": "Facturación Espacial ", "contributors": [ { - "name": "Ra\u00fal S\u00e1nchez" + "name": "Raúl Sánchez" }, { "name": "Javier Rosas" @@ -95,4 +95,4 @@ "vite": "8.0.16", "vitest": "^4.1.9" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3ee7ef3..d708a8b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,6 @@ settings: excludeLinksFromLockfile: false importers: - .: devDependencies: '@eslint/js': @@ -64,60 +63,95 @@ importers: version: 4.1.11(@types/node@26.0.0)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.0.0)(yaml@2.9.0)) packages: - '@asamuzakjp/css-color@5.1.11': - resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + resolution: + { + integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=24.0.0 } '@asamuzakjp/dom-selector@7.1.1': - resolution: {integrity: sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + resolution: + { + integrity: sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=24.0.0 } '@asamuzakjp/generational-cache@1.0.1': - resolution: {integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + resolution: + { + integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=24.0.0 } '@asamuzakjp/nwsapi@2.3.9': - resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + resolution: + { + integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==, + } '@babel/code-frame@7.29.7': - resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==, + } + engines: { node: '>=6.9.0' } '@babel/helper-validator-identifier@7.29.7': - resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==, + } + engines: { node: '>=6.9.0' } '@bramus/specificity@2.4.2': - resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} + resolution: + { + integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==, + } hasBin: true '@csstools/color-helpers@6.0.2': - resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==} - engines: {node: '>=20.19.0'} + resolution: + { + integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==, + } + engines: { node: '>=20.19.0' } '@csstools/css-calc@3.2.1': - resolution: {integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==} - engines: {node: '>=20.19.0'} + resolution: + { + integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==, + } + engines: { node: '>=20.19.0' } peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 '@csstools/css-tokenizer': ^4.0.0 '@csstools/css-color-parser@4.1.8': - resolution: {integrity: sha512-3chWb7PRLijpJpPIKkDxdu6IBeO5MrFACND57On0j8OPpc0wZibcGc3xAHrSEbOx/KDRyMHoIxGn0w1PhXMYHw==} - engines: {node: '>=20.19.0'} + resolution: + { + integrity: sha512-3chWb7PRLijpJpPIKkDxdu6IBeO5MrFACND57On0j8OPpc0wZibcGc3xAHrSEbOx/KDRyMHoIxGn0w1PhXMYHw==, + } + engines: { node: '>=20.19.0' } peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 '@csstools/css-tokenizer': ^4.0.0 '@csstools/css-parser-algorithms@4.0.0': - resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} - engines: {node: '>=20.19.0'} + resolution: + { + integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==, + } + engines: { node: '>=20.19.0' } peerDependencies: '@csstools/css-tokenizer': ^4.0.0 '@csstools/css-syntax-patches-for-csstree@1.1.5': - resolution: {integrity: sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==} + resolution: + { + integrity: sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==, + } peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -125,43 +159,73 @@ packages: optional: true '@csstools/css-tokenizer@4.0.0': - resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} - engines: {node: '>=20.19.0'} + resolution: + { + integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==, + } + engines: { node: '>=20.19.0' } '@emnapi/core@1.10.0': - resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + resolution: + { + integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==, + } '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + resolution: + { + integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==, + } '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + resolution: + { + integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==, + } '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { + integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + resolution: + { + integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==, + } + engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } '@eslint/config-array@0.23.5': - resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + resolution: + { + integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24 } '@eslint/config-helpers@0.6.0': - resolution: {integrity: sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + resolution: + { + integrity: sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24 } '@eslint/core@1.2.1': - resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + resolution: + { + integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24 } '@eslint/js@10.0.1': - resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + resolution: + { + integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24 } peerDependencies: eslint: ^10.0.0 peerDependenciesMeta: @@ -169,16 +233,25 @@ packages: optional: true '@eslint/object-schema@3.0.5': - resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + resolution: + { + integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24 } '@eslint/plugin-kit@0.7.2': - resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + resolution: + { + integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24 } '@exodus/bytes@1.15.1': - resolution: {integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + resolution: + { + integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=24.0.0 } peerDependencies: '@noble/hashes': ^1.8.0 || ^2.0.0 peerDependenciesMeta: @@ -186,159 +259,249 @@ packages: optional: true '@humanfs/core@0.19.2': - resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} - engines: {node: '>=18.18.0'} + resolution: + { + integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==, + } + engines: { node: '>=18.18.0' } '@humanfs/node@0.16.8': - resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} - engines: {node: '>=18.18.0'} + resolution: + { + integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==, + } + engines: { node: '>=18.18.0' } '@humanfs/types@0.15.0': - resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} - engines: {node: '>=18.18.0'} + resolution: + { + integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==, + } + engines: { node: '>=18.18.0' } '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} + resolution: + { + integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, + } + engines: { node: '>=12.22' } '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} + resolution: + { + integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==, + } + engines: { node: '>=18.18' } '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + resolution: + { + integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, + } '@napi-rs/wasm-runtime@1.1.5': - resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} + resolution: + { + integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==, + } peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, + } + engines: { node: '>= 8' } '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, + } + engines: { node: '>= 8' } '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, + } + engines: { node: '>= 8' } '@oxc-project/types@0.133.0': - resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + resolution: + { + integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==, + } '@playwright/test@1.61.0': - resolution: {integrity: sha512-cKA5B6lpFEMyMGjxF54QihfYpB4FkEGH+qZhtArDEG+wezQAJY8Pq6C7T1SjWz+FFzt3TbyoXBQYk/0292TdJA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-cKA5B6lpFEMyMGjxF54QihfYpB4FkEGH+qZhtArDEG+wezQAJY8Pq6C7T1SjWz+FFzt3TbyoXBQYk/0292TdJA==, + } + engines: { node: '>=18' } hasBin: true '@rolldown/binding-android-arm64@1.0.3': - resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [android] '@rolldown/binding-darwin-arm64@1.0.3': - resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [darwin] '@rolldown/binding-darwin-x64@1.0.3': - resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [darwin] '@rolldown/binding-freebsd-x64@1.0.3': - resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [freebsd] '@rolldown/binding-linux-arm-gnueabihf@1.0.3': - resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm] os: [linux] '@rolldown/binding-linux-arm64-gnu@1.0.3': - resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [linux] libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.0.3': - resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [linux] libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.0.3': - resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [ppc64] os: [linux] libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.0.3': - resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [s390x] os: [linux] libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.0.3': - resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [linux] libc: [glibc] '@rolldown/binding-linux-x64-musl@1.0.3': - resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [linux] libc: [musl] '@rolldown/binding-openharmony-arm64@1.0.3': - resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [openharmony] '@rolldown/binding-wasm32-wasi@1.0.3': - resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [wasm32] '@rolldown/binding-win32-arm64-msvc@1.0.3': - resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [win32] '@rolldown/binding-win32-x64-msvc@1.0.3': - resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [win32] '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + resolution: + { + integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==, + } '@rollup/plugin-commonjs@29.0.3': - resolution: {integrity: sha512-ZaOxZceP7SOUW7Lqw5IRVweSQYWaeIPnXIGLiB690EBA3FGJTO40EEr2L5yZplJWsgTCogILRSpcAe7+U0Otdg==} - engines: {node: '>=16.0.0 || 14 >= 14.17'} + resolution: + { + integrity: sha512-ZaOxZceP7SOUW7Lqw5IRVweSQYWaeIPnXIGLiB690EBA3FGJTO40EEr2L5yZplJWsgTCogILRSpcAe7+U0Otdg==, + } + engines: { node: '>=16.0.0 || 14 >= 14.17' } peerDependencies: rollup: ^2.68.0||^3.0.0||^4.0.0 peerDependenciesMeta: @@ -346,8 +509,11 @@ packages: optional: true '@rollup/plugin-node-resolve@16.0.3': - resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==, + } + engines: { node: '>=14.0.0' } peerDependencies: rollup: ^2.78.0||^3.0.0||^4.0.0 peerDependenciesMeta: @@ -355,8 +521,11 @@ packages: optional: true '@rollup/plugin-replace@6.0.3': - resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==, + } + engines: { node: '>=14.0.0' } peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: @@ -364,8 +533,11 @@ packages: optional: true '@rollup/pluginutils@5.4.0': - resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==, + } + engines: { node: '>=14.0.0' } peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: @@ -373,112 +545,190 @@ packages: optional: true '@sinclair/typebox@0.27.10': - resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} + resolution: + { + integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==, + } '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + resolution: + { + integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==, + } '@tsd/typescript@5.9.3': - resolution: {integrity: sha512-JSSdNiS0wgd8GHhBwnMAI18Y8XPhLVN+dNelPfZCXFhy9Lb3NbnFyp9JKxxr54jSUkEJPk3cidvCoHducSaRMQ==} - engines: {node: '>=14.17'} + resolution: + { + integrity: sha512-JSSdNiS0wgd8GHhBwnMAI18Y8XPhLVN+dNelPfZCXFhy9Lb3NbnFyp9JKxxr54jSUkEJPk3cidvCoHducSaRMQ==, + } + engines: { node: '>=14.17' } '@tybys/wasm-util@0.10.3': - resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + resolution: + { + integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==, + } '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + resolution: + { + integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==, + } '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + resolution: + { + integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==, + } '@types/eslint@7.29.0': - resolution: {integrity: sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==} + resolution: + { + integrity: sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==, + } '@types/esrecurse@4.3.1': - resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + resolution: + { + integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==, + } '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + resolution: + { + integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==, + } '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + resolution: + { + integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==, + } '@types/minimist@1.2.5': - resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + resolution: + { + integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==, + } '@types/node@26.0.0': - resolution: {integrity: sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA==} + resolution: + { + integrity: sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA==, + } '@types/normalize-package-data@2.4.4': - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + resolution: + { + integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==, + } '@types/resolve@1.20.2': - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + resolution: + { + integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==, + } '@typescript-eslint/eslint-plugin@8.62.0': - resolution: {integrity: sha512-o+mpz7EYiMzXoySXiKmzlabIvTVqUuK5yLrAedRPRDA0IpPFMUV1IXt6OqljIxX/kumN6EjUYp41Hqelh6p/Dw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-o+mpz7EYiMzXoySXiKmzlabIvTVqUuK5yLrAedRPRDA0IpPFMUV1IXt6OqljIxX/kumN6EjUYp41Hqelh6p/Dw==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: '@typescript-eslint/parser': ^8.62.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/parser@8.62.0': - resolution: {integrity: sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/project-service@8.62.0': - resolution: {integrity: sha512-wexnCqiTg7BOGtbLDftYpRWlmLq4xfoMd7BKFR6Y75sZS3QmRKLdN3yWLhmIYgqMmP/OXWpj3H8odkb5nGURCQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-wexnCqiTg7BOGtbLDftYpRWlmLq4xfoMd7BKFR6Y75sZS3QmRKLdN3yWLhmIYgqMmP/OXWpj3H8odkb5nGURCQ==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/scope-manager@8.62.0': - resolution: {integrity: sha512-1lX38kNxXIRb8mEc3lbq5mdHq1Pf2+U0nFU65KfT18mtPxxl0fvjuEE92mHuXPuCtElJhOrddOpyMlM3Z0umEA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-1lX38kNxXIRb8mEc3lbq5mdHq1Pf2+U0nFU65KfT18mtPxxl0fvjuEE92mHuXPuCtElJhOrddOpyMlM3Z0umEA==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@typescript-eslint/tsconfig-utils@8.62.0': - resolution: {integrity: sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/type-utils@8.62.0': - resolution: {integrity: sha512-+g5O3j0w2ldzC86Pv6fvbO/xhAonbJFIdf/MKQ1d30gndlsVzUOE83ldfSE15Qrl9fhFjK6AovHs5Wpp6vx86w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-+g5O3j0w2ldzC86Pv6fvbO/xhAonbJFIdf/MKQ1d30gndlsVzUOE83ldfSE15Qrl9fhFjK6AovHs5Wpp6vx86w==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/types@8.62.0': - resolution: {integrity: sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@typescript-eslint/typescript-estree@8.62.0': - resolution: {integrity: sha512-+hVbNxtW64pIcZWDPGbyaKF7vp2IBTVY5ma1blwwksrjdsbdqqEKvJWMGbBofei4F6Dovx1M0RJgoFeNu2279A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-+hVbNxtW64pIcZWDPGbyaKF7vp2IBTVY5ma1blwwksrjdsbdqqEKvJWMGbBofei4F6Dovx1M0RJgoFeNu2279A==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/utils@8.62.0': - resolution: {integrity: sha512-82r66fi9zYwZ+mTq3vKgwjbZ1PVk/DJzrXFLpG6RnBbdvH8TEGVHIs9H4d2drhkOzf0syZuD/OZvvlu6GDbP4g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-82r66fi9zYwZ+mTq3vKgwjbZ1PVk/DJzrXFLpG6RnBbdvH8TEGVHIs9H4d2drhkOzf0syZuD/OZvvlu6GDbP4g==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' '@typescript-eslint/visitor-keys@8.62.0': - resolution: {integrity: sha512-CY3uyFSRbcQv3nnSv8S0+lDftMVz6P963PoRlxrV7ew/Md564g9ut60PYzdLM5qW4jFn93GBF+Soi90ISAN+GQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-CY3uyFSRbcQv3nnSv8S0+lDftMVz6P963PoRlxrV7ew/Md564g9ut60PYzdLM5qW4jFn93GBF+Soi90ISAN+GQ==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@vitest/expect@4.1.11': - resolution: {integrity: sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==} + resolution: + { + integrity: sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==, + } '@vitest/mocker@4.1.11': - resolution: {integrity: sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==} + resolution: + { + integrity: sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==, + } peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -489,140 +739,248 @@ packages: optional: true '@vitest/pretty-format@4.1.11': - resolution: {integrity: sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==} + resolution: + { + integrity: sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==, + } '@vitest/runner@4.1.11': - resolution: {integrity: sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==} + resolution: + { + integrity: sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==, + } '@vitest/snapshot@4.1.11': - resolution: {integrity: sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==} + resolution: + { + integrity: sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==, + } '@vitest/spy@4.1.11': - resolution: {integrity: sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==} + resolution: + { + integrity: sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==, + } '@vitest/utils@4.1.11': - resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==} + resolution: + { + integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==, + } acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + resolution: + { + integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, + } peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 acorn@8.17.0: - resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==, + } + engines: { node: '>=0.4.0' } hasBin: true ajv@6.15.0: - resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + resolution: + { + integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==, + } ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, + } + engines: { node: '>=8' } ansi-escapes@7.3.0: - resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==, + } + engines: { node: '>=18' } ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: '>=8' } ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==, + } + engines: { node: '>=12' } ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: '>=8' } ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, + } + engines: { node: '>=10' } ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==, + } + engines: { node: '>=12' } array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, + } + engines: { node: '>=8' } arrify@1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==, + } + engines: { node: '>=0.10.0' } assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==, + } + engines: { node: '>=12' } balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} + resolution: + { + integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==, + } + engines: { node: 18 || 20 || >=22 } bidi-js@1.0.3: - resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + resolution: + { + integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==, + } brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} - engines: {node: 18 || 20 || >=22} + resolution: + { + integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==, + } + engines: { node: 18 || 20 || >=22 } braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, + } + engines: { node: '>=8' } camelcase-keys@6.2.2: - resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==, + } + engines: { node: '>=8' } camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==, + } + engines: { node: '>=6' } chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==, + } + engines: { node: '>=18' } chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: '>=10' } cli-cursor@5.0.0: - resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==, + } + engines: { node: '>=18' } cli-truncate@5.2.0: - resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==, + } + engines: { node: '>=20' } color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: '>=7.0.0' } color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + resolution: + { + integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==, + } convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + resolution: + { + integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, + } cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, + } + engines: { node: '>= 8' } css-tree@3.2.1: - resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + resolution: + { + integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==, + } + engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0 } data-urls@7.0.0: - resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + resolution: + { + integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=24.0.0 } debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, + } + engines: { node: '>=6.0' } peerDependencies: supports-color: '*' peerDependenciesMeta: @@ -630,91 +988,160 @@ packages: optional: true decamelize-keys@1.1.1: - resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==, + } + engines: { node: '>=0.10.0' } decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==, + } + engines: { node: '>=0.10.0' } decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + resolution: + { + integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==, + } deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + resolution: + { + integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, + } deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==, + } + engines: { node: '>=0.10.0' } detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==, + } + engines: { node: '>=8' } diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, + } + engines: { node: '>=8' } emoji-regex@10.6.0: - resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + resolution: + { + integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==, + } emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } entities@8.0.0: - resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} - engines: {node: '>=20.19.0'} + resolution: + { + integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==, + } + engines: { node: '>=20.19.0' } environment@1.1.0: - resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==, + } + engines: { node: '>=18' } error-ex@1.3.4: - resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + resolution: + { + integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==, + } es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, + } + engines: { node: '>= 0.4' } es-module-lexer@2.3.2: - resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} + resolution: + { + integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==, + } escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, + } + engines: { node: '>=10' } eslint-config-prettier@10.1.8: - resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + resolution: + { + integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==, + } hasBin: true peerDependencies: eslint: '>=7.0.0' eslint-formatter-pretty@4.1.0: - resolution: {integrity: sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==, + } + engines: { node: '>=10' } eslint-rule-docs@1.1.235: - resolution: {integrity: sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==} + resolution: + { + integrity: sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==, + } eslint-scope@9.1.2: - resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + resolution: + { + integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24 } eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { + integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==, + } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } eslint-visitor-keys@5.0.1: - resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + resolution: + { + integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24 } eslint@10.5.0: - resolution: {integrity: sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + resolution: + { + integrity: sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24 } hasBin: true peerDependencies: jiti: '*' @@ -723,57 +1150,102 @@ packages: optional: true espree@11.2.0: - resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} + resolution: + { + integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24 } esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} + resolution: + { + integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==, + } + engines: { node: '>=0.10' } esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==, + } + engines: { node: '>=4.0' } estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, + } + engines: { node: '>=4.0' } estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + resolution: + { + integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, + } estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + resolution: + { + integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, + } esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, + } + engines: { node: '>=0.10.0' } eventemitter3@5.0.4: - resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + resolution: + { + integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==, + } expect-type@1.4.0: - resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==, + } + engines: { node: '>=12.0.0' } fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + resolution: + { + integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, + } fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} + resolution: + { + integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==, + } + engines: { node: '>=8.6.0' } fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + resolution: + { + integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, + } fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + resolution: + { + integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, + } fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + resolution: + { + integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==, + } fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, + } + engines: { node: '>=12.0.0' } peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -781,170 +1253,299 @@ packages: optional: true file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} + resolution: + { + integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==, + } + engines: { node: '>=16.0.0' } fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, + } + engines: { node: '>=8' } find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, + } + engines: { node: '>=8' } find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, + } + engines: { node: '>=10' } flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==, + } + engines: { node: '>=16' } flatted@3.4.2: - resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + resolution: + { + integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==, + } fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { + integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + resolution: + { + integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, + } get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==, + } + engines: { node: '>=18' } glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, + } + engines: { node: '>= 6' } glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, + } + engines: { node: '>=10.13.0' } globals@17.7.0: - resolution: {integrity: sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==, + } + engines: { node: '>=18' } globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==, + } + engines: { node: '>=10' } hard-rejection@2.1.0: - resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==, + } + engines: { node: '>=6' } has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: '>=8' } hasown@2.0.4: - resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==, + } + engines: { node: '>= 0.4' } hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + resolution: + { + integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==, + } hosted-git-info@4.1.0: - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==, + } + engines: { node: '>=10' } html-encoding-sniffer@6.0.0: - resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + resolution: + { + integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=24.0.0 } husky@9.1.7: - resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==, + } + engines: { node: '>=18' } hasBin: true ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, + } + engines: { node: '>= 4' } ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==, + } + engines: { node: '>= 4' } imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} + resolution: + { + integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, + } + engines: { node: '>=0.8.19' } indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==, + } + engines: { node: '>=8' } irregular-plurals@3.5.0: - resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==, + } + engines: { node: '>=8' } is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + resolution: + { + integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, + } is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==, + } + engines: { node: '>= 0.4' } is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, + } + engines: { node: '>=0.10.0' } is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: '>=8' } is-fullwidth-code-point@5.1.0: - resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==, + } + engines: { node: '>=18' } is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, + } + engines: { node: '>=0.10.0' } is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + resolution: + { + integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==, + } is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + resolution: + { + integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, + } + engines: { node: '>=0.12.0' } is-plain-obj@1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==, + } + engines: { node: '>=0.10.0' } is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + resolution: + { + integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==, + } is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + resolution: + { + integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==, + } is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==, + } + engines: { node: '>=10' } isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } jsdom@29.1.1: - resolution: {integrity: sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} + resolution: + { + integrity: sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==, + } + engines: { node: ^20.19.0 || ^22.13.0 || >=24.0.0 } peerDependencies: canvas: ^3.0.0 peerDependenciesMeta: @@ -952,564 +1553,978 @@ packages: optional: true json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + resolution: + { + integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, + } json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + resolution: + { + integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, + } json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + resolution: + { + integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, + } json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + resolution: + { + integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, + } keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + resolution: + { + integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, + } kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, + } + engines: { node: '>=0.10.0' } levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, + } + engines: { node: '>= 0.8.0' } lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==, + } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [android] lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==, + } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [darwin] lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==, + } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [darwin] lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==, + } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [freebsd] lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==, + } + engines: { node: '>= 12.0.0' } cpu: [arm] os: [linux] lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==, + } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [linux] libc: [glibc] lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==, + } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [linux] libc: [musl] lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==, + } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [linux] libc: [glibc] lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==, + } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [linux] libc: [musl] lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==, + } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [win32] lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==, + } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [win32] lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==, + } + engines: { node: '>= 12.0.0' } lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + resolution: + { + integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, + } lint-staged@17.0.8: - resolution: {integrity: sha512-B2P/d+jVW0UXOQ0MVMLrB/9ydA1P+zz6jYfdrbbEd9ur3S2rcbduFWKiUCC02Sm5hbC8nrm7y24WuYMG54HfxA==} - engines: {node: '>=22.22.1'} + resolution: + { + integrity: sha512-B2P/d+jVW0UXOQ0MVMLrB/9ydA1P+zz6jYfdrbbEd9ur3S2rcbduFWKiUCC02Sm5hbC8nrm7y24WuYMG54HfxA==, + } + engines: { node: '>=22.22.1' } hasBin: true listr2@10.2.1: - resolution: {integrity: sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==} - engines: {node: '>=22.13.0'} + resolution: + { + integrity: sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==, + } + engines: { node: '>=22.13.0' } locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, + } + engines: { node: '>=8' } locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, + } + engines: { node: '>=10' } log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==, + } + engines: { node: '>=10' } log-update@6.1.0: - resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==, + } + engines: { node: '>=18' } lru-cache@11.5.1: - resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} - engines: {node: 20 || >=22} + resolution: + { + integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==, + } + engines: { node: 20 || >=22 } lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==, + } + engines: { node: '>=10' } magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + resolution: + { + integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, + } map-obj@1.0.1: - resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==, + } + engines: { node: '>=0.10.0' } map-obj@4.3.0: - resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==, + } + engines: { node: '>=8' } mdn-data@2.27.1: - resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + resolution: + { + integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==, + } meow@9.0.0: - resolution: {integrity: sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==, + } + engines: { node: '>=10' } merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, + } + engines: { node: '>= 8' } micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, + } + engines: { node: '>=8.6' } mimic-function@5.0.1: - resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==, + } + engines: { node: '>=18' } min-indent@1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==, + } + engines: { node: '>=4' } minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} - engines: {node: 18 || 20 || >=22} + resolution: + { + integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==, + } + engines: { node: 18 || 20 || >=22 } minimist-options@4.1.0: - resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==, + } + engines: { node: '>= 6' } ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } nanoid@3.3.15: - resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + resolution: + { + integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } hasBin: true natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + resolution: + { + integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, + } normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + resolution: + { + integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==, + } normalize-package-data@3.0.3: - resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==, + } + engines: { node: '>=10' } obug@2.2.1: - resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} - engines: {node: '>=12.20.0'} + resolution: + { + integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==, + } + engines: { node: '>=12.20.0' } onetime@7.0.0: - resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==, + } + engines: { node: '>=18' } optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==, + } + engines: { node: '>= 0.8.0' } p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, + } + engines: { node: '>=6' } p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, + } + engines: { node: '>=10' } p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, + } + engines: { node: '>=8' } p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, + } + engines: { node: '>=10' } p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, + } + engines: { node: '>=6' } parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, + } + engines: { node: '>=8' } parse5@8.0.1: - resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} + resolution: + { + integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==, + } path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, + } + engines: { node: '>=8' } path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: '>=8' } path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + resolution: + { + integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, + } path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, + } + engines: { node: '>=8' } pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + resolution: + { + integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, + } picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==, + } + engines: { node: '>=8.6' } picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==, + } + engines: { node: '>=12' } picomatch@4.0.7: - resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==, + } + engines: { node: '>=12' } playwright-core@1.61.0: - resolution: {integrity: sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA==, + } + engines: { node: '>=18' } hasBin: true playwright@1.61.0: - resolution: {integrity: sha512-Z+7BeeqQPRRzklHsVFP4KTGIyMxKUmfeRA4WisM6G3/XW6nwGeX6fX9qYaDa+CiUqpOkb2f6X3nar05R3kSuJQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-Z+7BeeqQPRRzklHsVFP4KTGIyMxKUmfeRA4WisM6G3/XW6nwGeX6fX9qYaDa+CiUqpOkb2f6X3nar05R3kSuJQ==, + } + engines: { node: '>=18' } hasBin: true plur@4.0.0: - resolution: {integrity: sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==, + } + engines: { node: '>=10' } postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { + integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==, + } + engines: { node: ^10 || ^12 || >=14 } prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, + } + engines: { node: '>= 0.8.0' } prettier@3.8.4: - resolution: {integrity: sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==, + } + engines: { node: '>=14' } hasBin: true pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + resolution: + { + integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==, + } + engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, + } + engines: { node: '>=6' } queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + resolution: + { + integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, + } quick-lru@4.0.1: - resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==, + } + engines: { node: '>=8' } react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + resolution: + { + integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, + } read-pkg-up@7.0.1: - resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==, + } + engines: { node: '>=8' } read-pkg@5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==, + } + engines: { node: '>=8' } redent@3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==, + } + engines: { node: '>=8' } require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, + } + engines: { node: '>=0.10.0' } resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==, + } + engines: { node: '>= 0.4' } hasBin: true restore-cursor@5.1.0: - resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==, + } + engines: { node: '>=18' } reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + resolution: + { + integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==, + } + engines: { iojs: '>=1.0.0', node: '>=0.10.0' } rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + resolution: + { + integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==, + } rolldown@1.0.3: - resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==, + } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + resolution: + { + integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, + } saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} + resolution: + { + integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==, + } + engines: { node: '>=v12.22.7' } semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + resolution: + { + integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==, + } hasBin: true semver@7.8.5: - resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==, + } + engines: { node: '>=10' } hasBin: true shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: '>=8' } shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: '>=8' } siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + resolution: + { + integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==, + } signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, + } + engines: { node: '>=14' } slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, + } + engines: { node: '>=8' } slice-ansi@7.1.2: - resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==, + } + engines: { node: '>=18' } slice-ansi@8.0.0: - resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==, + } + engines: { node: '>=20' } source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, + } + engines: { node: '>=0.10.0' } spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + resolution: + { + integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==, + } spdx-exceptions@2.5.0: - resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + resolution: + { + integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==, + } spdx-expression-parse@3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + resolution: + { + integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==, + } spdx-license-ids@3.0.23: - resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + resolution: + { + integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==, + } stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + resolution: + { + integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==, + } std-env@4.2.0: - resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} + resolution: + { + integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==, + } string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} + resolution: + { + integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==, + } + engines: { node: '>=0.6.19' } string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: '>=8' } string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==, + } + engines: { node: '>=18' } string-width@8.2.1: - resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==, + } + engines: { node: '>=20' } strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: '>=8' } strip-ansi@7.2.0: - resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==, + } + engines: { node: '>=12' } strip-indent@3.0.0: - resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==, + } + engines: { node: '>=8' } supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: '>=8' } supports-hyperlinks@2.3.0: - resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==, + } + engines: { node: '>=8' } supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, + } + engines: { node: '>= 0.4' } symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + resolution: + { + integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==, + } tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + resolution: + { + integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==, + } tinyexec@1.2.4: - resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==, + } + engines: { node: '>=18' } tinyexec@1.3.1: - resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==, + } + engines: { node: '>=18' } tinyglobby@0.2.17: - resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==, + } + engines: { node: '>=12.0.0' } tinyrainbow@3.1.1: - resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==, + } + engines: { node: '>=14.0.0' } tldts-core@7.4.4: - resolution: {integrity: sha512-vwVLJVvvpslm7vqAH7+XNj/neA/Ynq7DT2EEcMuwc5YzN5XaMyRAqxwU+uX3azZ1FQtB2gvrvnLnAEkvYlVdfg==} + resolution: + { + integrity: sha512-vwVLJVvvpslm7vqAH7+XNj/neA/Ynq7DT2EEcMuwc5YzN5XaMyRAqxwU+uX3azZ1FQtB2gvrvnLnAEkvYlVdfg==, + } tldts@7.4.4: - resolution: {integrity: sha512-kFXFK7O4WPextIUAOk8qtnw9dxR9UIXP9CjuH1cTBVBZMDeQcUPgr/IazGiw1B0Yiw5L75gHLWeW4iD793r90g==} + resolution: + { + integrity: sha512-kFXFK7O4WPextIUAOk8qtnw9dxR9UIXP9CjuH1cTBVBZMDeQcUPgr/IazGiw1B0Yiw5L75gHLWeW4iD793r90g==, + } hasBin: true to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + resolution: + { + integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, + } + engines: { node: '>=8.0' } tough-cookie@6.0.1: - resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==, + } + engines: { node: '>=16' } tr46@6.0.0: - resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==, + } + engines: { node: '>=20' } trim-newlines@3.0.1: - resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==, + } + engines: { node: '>=8' } ts-api-utils@2.5.0: - resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} - engines: {node: '>=18.12'} + resolution: + { + integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==, + } + engines: { node: '>=18.12' } peerDependencies: typescript: '>=4.8.4' tsd@0.33.0: - resolution: {integrity: sha512-/PQtykJFVw90QICG7zyPDMIyueOXKL7jOJVoX5pILnb3Ux+7QqynOxfVvarE+K+yi7BZyOSY4r+OZNWSWRiEwQ==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-/PQtykJFVw90QICG7zyPDMIyueOXKL7jOJVoX5pILnb3Ux+7QqynOxfVvarE+K+yi7BZyOSY4r+OZNWSWRiEwQ==, + } + engines: { node: '>=14.16' } hasBin: true tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + resolution: + { + integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, + } type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + resolution: + { + integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, + } + engines: { node: '>= 0.8.0' } type-fest@0.18.1: - resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==, + } + engines: { node: '>=10' } type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, + } + engines: { node: '>=10' } type-fest@0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==, + } + engines: { node: '>=8' } type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==, + } + engines: { node: '>=8' } typescript-eslint@8.62.0: - resolution: {integrity: sha512-8QxXi+ZACKX0kaqO4gY8kn0RSD9gFfaHDWwjqtEN48aWCBkX4MJaufWN+c3BzlrXLOxfywDL8CaoqUwcRq4j4Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { + integrity: sha512-8QxXi+ZACKX0kaqO4gY8kn0RSD9gFfaHDWwjqtEN48aWCBkX4MJaufWN+c3BzlrXLOxfywDL8CaoqUwcRq4j4Q==, + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' typescript@6.0.3: - resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} - engines: {node: '>=14.17'} + resolution: + { + integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==, + } + engines: { node: '>=14.17' } hasBin: true undici-types@8.3.0: - resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + resolution: + { + integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==, + } undici@7.28.0: - resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} - engines: {node: '>=20.18.1'} + resolution: + { + integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==, + } + engines: { node: '>=20.18.1' } uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + resolution: + { + integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, + } validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + resolution: + { + integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==, + } vite@8.0.16: - resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 @@ -1551,8 +2566,11 @@ packages: optional: true vitest@4.1.11: - resolution: {integrity: sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + resolution: + { + integrity: sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==, + } + engines: { node: ^20.0.0 || ^22.0.0 || >=24.0.0 } hasBin: true peerDependencies: '@edge-runtime/vm': '*' @@ -1592,68 +2610,112 @@ packages: optional: true w3c-xmlserializer@5.0.0: - resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==, + } + engines: { node: '>=18' } webidl-conversions@8.0.1: - resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==, + } + engines: { node: '>=20' } whatwg-mimetype@5.0.0: - resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==, + } + engines: { node: '>=20' } whatwg-url@16.0.1: - resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} - engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + resolution: + { + integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=24.0.0 } which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: '>= 8' } hasBin: true why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==, + } + engines: { node: '>=8' } hasBin: true word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==, + } + engines: { node: '>=0.10.0' } wrap-ansi@10.0.0: - resolution: {integrity: sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==, + } + engines: { node: '>=20' } wrap-ansi@9.0.2: - resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==, + } + engines: { node: '>=18' } xml-name-validator@5.0.0: - resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==, + } + engines: { node: '>=18' } xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + resolution: + { + integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==, + } yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + resolution: + { + integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, + } yaml@2.9.0: - resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} - engines: {node: '>= 14.6'} + resolution: + { + integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==, + } + engines: { node: '>= 14.6' } hasBin: true yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==, + } + engines: { node: '>=10' } yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, + } + engines: { node: '>=10' } snapshots: - '@asamuzakjp/css-color@5.1.11': dependencies: '@asamuzakjp/generational-cache': 1.0.1 diff --git a/src/resources/invoices.ts b/src/resources/invoices.ts index 58fafbc..5bb6783 100644 --- a/src/resources/invoices.ts +++ b/src/resources/invoices.ts @@ -11,14 +11,14 @@ import { SendEmailBody, SignedDownloadUrl, ZipRequest, -} from '../types' -import { WrapperClient } from '../wrapper' +} from '../types'; +import { WrapperClient } from '../wrapper'; export default class Invoices { - client: WrapperClient + client: WrapperClient; constructor(client: WrapperClient) { - this.client = client + this.client = client; } /** @@ -31,7 +31,7 @@ export default class Invoices { body: Record, params?: Record | null, ): Promise { - return this.client.post('/invoices', { body, params }) + return this.client.post('/invoices', { body, params }); } /** @@ -40,8 +40,8 @@ export default class Invoices { * @returns Search results object. The object contains a `data` property with the list of invoices. */ list(params?: Record | null): Promise> { - if (!params) params = {} - return this.client.get('/invoices', { params }) + if (!params) params = {}; + return this.client.get('/invoices', { params }); } /** @@ -50,8 +50,8 @@ export default class Invoices { * @returns Invoice object */ retrieve(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/invoices/' + id) + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/invoices/' + id); } /** @@ -67,8 +67,8 @@ export default class Invoices { id: string, params: PaymentSummaryParams, ): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/invoices/' + id + '/payment-summary', { params }) + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/invoices/' + id + '/payment-summary', { params }); } /** @@ -78,7 +78,7 @@ export default class Invoices { * @returns Canceled invoice */ cancel(id: string, params: CancelInvoiceOptions): Promise { - return this.client.delete('/invoices/' + id, { params }) + return this.client.delete('/invoices/' + id, { params }); } /** @@ -89,7 +89,7 @@ export default class Invoices { * @returns Object with 'ok' property set to true if the email was sent successfully */ sendByEmail(id: string, options?: SendEmailBody): Promise { - return this.client.post('/invoices/' + id + '/email', { body: options }) + return this.client.post('/invoices/' + id + '/email', { body: options }); } /** @@ -98,7 +98,7 @@ export default class Invoices { * @returns PDF file in a stream (Node.js) or Blob (browser) */ async downloadPdf(id: string): Promise { - return this.client.get('/invoices/' + id + '/pdf') + return this.client.get('/invoices/' + id + '/pdf'); } /** @@ -107,7 +107,7 @@ export default class Invoices { * @returns XML file in a stream (Node.js) or Blob (browser) */ async downloadXml(id: string): Promise { - return this.client.get('/invoices/' + id + '/xml') + return this.client.get('/invoices/' + id + '/xml'); } /** @@ -116,7 +116,7 @@ export default class Invoices { * @returns ZIP file in a stream (Node.js) or Blob (browser) */ downloadZip(id: string): Promise { - return this.client.get('/invoices/' + id + '/zip') + return this.client.get('/invoices/' + id + '/zip'); } /** @@ -125,20 +125,20 @@ export default class Invoices { * @returns Signed download URL and its metadata */ downloadPdfUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/invoices/' + id + '/download-url/pdf') + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/invoices/' + id + '/download-url/pdf'); } /** Gets a short-lived URL for downloading an invoice XML file. */ downloadXmlUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/invoices/' + id + '/download-url/xml') + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/invoices/' + id + '/download-url/xml'); } /** Gets a short-lived URL for downloading an invoice ZIP file. */ downloadZipUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/invoices/' + id + '/download-url/zip') + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/invoices/' + id + '/download-url/zip'); } /** @@ -147,7 +147,7 @@ export default class Invoices { * @returns ZIP request object */ createZipRequest(data: CreateZipRequestData): Promise { - return this.client.post('/invoices/zip-requests', { body: data }) + return this.client.post('/invoices/zip-requests', { body: data }); } /** @@ -160,7 +160,7 @@ export default class Invoices { ): Promise> { return this.client.get('/invoices/zip-requests', { params: params || {}, - }) + }); } /** @@ -169,8 +169,8 @@ export default class Invoices { * @returns ZIP request object */ retrieveZipRequest(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/invoices/zip-requests/' + id) + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/invoices/zip-requests/' + id); } /** @@ -179,14 +179,14 @@ export default class Invoices { * @returns ZIP file in a stream (Node.js) or Blob (browser) */ downloadZipRequest(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/invoices/zip-requests/' + id + '/zip') + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/invoices/zip-requests/' + id + '/zip'); } /** Gets a short-lived URL for downloading a generated invoice ZIP request. */ downloadZipRequestUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/invoices/zip-requests/' + id + '/download-url') + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/invoices/zip-requests/' + id + '/download-url'); } /** @@ -195,7 +195,7 @@ export default class Invoices { * @returns XML file in a stream (Node.js) or Blob (browser) */ downloadCancellationReceiptXml(id: string): Promise { - return this.client.get('/invoices/' + id + '/cancellation_receipt/xml') + return this.client.get('/invoices/' + id + '/cancellation_receipt/xml'); } /** @@ -204,7 +204,7 @@ export default class Invoices { * @returns PDF file in a stream (Node.js) or Blob (browser) */ downloadCancellationReceiptPdf(id: string): Promise { - return this.client.get('/invoices/' + id + '/cancellation_receipt/pdf') + return this.client.get('/invoices/' + id + '/cancellation_receipt/pdf'); } /** @@ -213,18 +213,18 @@ export default class Invoices { * @returns Signed download URL and its metadata */ downloadCancellationReceiptPdfUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) + if (!id) return Promise.reject(new Error('id is required')); return this.client.get( '/invoices/' + id + '/cancellation_receipt/download-url/pdf', - ) + ); } /** Gets a short-lived URL for downloading a cancellation receipt XML file. */ downloadCancellationReceiptXmlUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) + if (!id) return Promise.reject(new Error('id is required')); return this.client.get( '/invoices/' + id + '/cancellation_receipt/download-url/xml', - ) + ); } /** @@ -234,7 +234,7 @@ export default class Invoices { * @returns Edited invoice */ updateDraft(id: string, data: Record): Promise { - return this.client.put('/invoices/' + id, { body: data }) + return this.client.put('/invoices/' + id, { body: data }); } /** @@ -247,7 +247,7 @@ export default class Invoices { id: string, params?: Record | null, ): Promise { - return this.client.post('/invoices/' + id + '/stamp', { params }) + return this.client.post('/invoices/' + id + '/stamp', { params }); } /** @@ -256,7 +256,7 @@ export default class Invoices { * @returns Updated invoice */ updateStatus(id: string): Promise { - return this.client.put('/invoices/' + id + '/status') + return this.client.put('/invoices/' + id + '/status'); } /** @@ -265,7 +265,7 @@ export default class Invoices { * @returns Draft invoice */ copyToDraft(id: string): Promise { - return this.client.post('/invoices/' + id + '/copy') + return this.client.post('/invoices/' + id + '/copy'); } /** @@ -274,11 +274,11 @@ export default class Invoices { * @returns PDF file in a stream (Node.js) or Blob (browser) */ previewPdf(body: Record): Promise { - return this.client.post('/invoices/preview/pdf', { body }) + return this.client.post('/invoices/preview/pdf', { body }); } /** Gets a short-lived URL for an invoice PDF preview. */ previewPdfUrl(body: Record): Promise { - return this.client.post('/invoices/preview/pdf/download-url', { body }) + return this.client.post('/invoices/preview/pdf/download-url', { body }); } } diff --git a/src/resources/organizations.ts b/src/resources/organizations.ts index 56bb6c7..64c479e 100644 --- a/src/resources/organizations.ts +++ b/src/resources/organizations.ts @@ -17,7 +17,9 @@ import type { BinaryInput, NodeLikeReadableStream } from '../types'; import { SearchResult } from '../types/common'; import { streamToBytes } from '../utils/streamToBytes'; -function isNodeLikeReadableStream(value: unknown): value is NodeLikeReadableStream { +function isNodeLikeReadableStream( + value: unknown, +): value is NodeLikeReadableStream { return ( typeof value === 'object' && value !== null && @@ -63,14 +65,13 @@ const prepareFile = async ( } const type = file === null ? 'null' : typeof file; - const constructorName = ( + const constructorName = file && typeof file === 'object' && 'constructor' in file && (file as { constructor?: { name?: string } }).constructor?.name - ) - ? ` (${(file as { constructor: { name: string } }).constructor.name})` - : ''; + ? ` (${(file as { constructor: { name: string } }).constructor.name})` + : ''; throw new Error(`Unsupported file input type: ${type}${constructorName}`); }; export default class Organizations { @@ -178,19 +179,13 @@ export default class Organizations { * @param file Logo file * @returns Organization object */ - async uploadLogo( - id: string, - file: BinaryInput, - ): Promise { + async uploadLogo(id: string, file: BinaryInput): Promise { if (typeof FormData === 'undefined') { throw new Error( 'FormData is not available in this runtime. Use Node.js 18+ or provide a FormData implementation.', ); } - const preparedFile = await prepareFile( - file, - 'application/octet-stream', - ); + const preparedFile = await prepareFile(file, 'application/octet-stream'); const formData = new FormData(); formData.append('file', preparedFile, 'file'); return this.client.put('/organizations/' + id + '/logo', { formData }); @@ -469,7 +464,9 @@ export default class Organizations { * @returns Array of organization invite objects */ listSentTeamInvites(organizationId: string): Promise { - return this.client.get('/organizations/' + organizationId + '/team/invites'); + return this.client.get( + '/organizations/' + organizationId + '/team/invites', + ); } /** @@ -482,9 +479,12 @@ export default class Organizations { organizationId: string, data: OrganizationInviteCreateInput, ): Promise { - return this.client.post('/organizations/' + organizationId + '/team/invites', { - body: data, - }); + return this.client.post( + '/organizations/' + organizationId + '/team/invites', + { + body: data, + }, + ); } /** @@ -520,9 +520,12 @@ export default class Organizations { inviteKey: string, data: OrganizationInviteResponseInput, ): Promise<{ ok: boolean }> { - return this.client.post('/organizations/invites/' + inviteKey + '/response', { - body: data, - }); + return this.client.post( + '/organizations/invites/' + inviteKey + '/response', + { + body: data, + }, + ); } /** @@ -583,9 +586,12 @@ export default class Organizations { organizationId: string, data: OrganizationTeamRoleCreateInput, ): Promise { - return this.client.post('/organizations/' + organizationId + '/team/roles', { - body: data, - }); + return this.client.post( + '/organizations/' + organizationId + '/team/roles', + { + body: data, + }, + ); } /** diff --git a/src/resources/products.ts b/src/resources/products.ts index e20afa5..839995b 100644 --- a/src/resources/products.ts +++ b/src/resources/products.ts @@ -1,7 +1,4 @@ -import { - Product, - SearchResult -} from '../types'; +import { Product, SearchResult } from '../types'; import { WrapperClient } from '../wrapper'; export default class Products { diff --git a/src/resources/receipts.ts b/src/resources/receipts.ts index 122e03e..6030877 100644 --- a/src/resources/receipts.ts +++ b/src/resources/receipts.ts @@ -8,13 +8,13 @@ import { SendEmailBody, SignedDownloadUrl, PreviewReceiptsToInvoicePdfInput, -} from '../types' -import { WrapperClient } from '../wrapper' +} from '../types'; +import { WrapperClient } from '../wrapper'; export default class Receipts { - client: WrapperClient + client: WrapperClient; constructor(client: WrapperClient) { - this.client = client + this.client = client; } /** @@ -23,7 +23,7 @@ export default class Receipts { * @returns Receipt object */ create(data: Record): Promise { - return this.client.post('/receipts', { body: data }) + return this.client.post('/receipts', { body: data }); } /** @@ -32,8 +32,8 @@ export default class Receipts { * @returns Search results object. The object contains a `data` property with the list of receipts. */ list(params?: Record | null): Promise> { - if (!params) params = {} - return this.client.get('/receipts', { params }) + if (!params) params = {}; + return this.client.get('/receipts', { params }); } /** @@ -42,8 +42,8 @@ export default class Receipts { * @returns Receipt object */ retrieve(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/receipts/' + id) + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/receipts/' + id); } /** @@ -53,7 +53,7 @@ export default class Receipts { * @returns Invoice object */ invoice(id: string, data: Record): Promise { - return this.client.post('/receipts/' + id + '/invoice', { body: data }) + return this.client.post('/receipts/' + id + '/invoice', { body: data }); } /** @@ -62,7 +62,7 @@ export default class Receipts { * @returns */ createGlobalInvoice(data: Record): Promise { - return this.client.post('/receipts/global-invoice', { body: data }) + return this.client.post('/receipts/global-invoice', { body: data }); } /** @@ -72,7 +72,7 @@ export default class Receipts { * @returns Invoice object or dry-run summary */ toInvoice(data: ReceiptsToInvoiceInput): Promise { - return this.client.post('/receipts/to-invoice', { body: data }) + return this.client.post('/receipts/to-invoice', { body: data }); } /** @@ -85,7 +85,7 @@ export default class Receipts { ): Promise { return this.client.post('/receipts/to-invoice/preview', { body: data, - }) + }); } /** Gets a short-lived URL for a receipts-to-invoice PDF preview. */ @@ -94,7 +94,7 @@ export default class Receipts { ): Promise { return this.client.post('/receipts/to-invoice/preview/download-url', { body: data, - }) + }); } /** @@ -103,7 +103,7 @@ export default class Receipts { * @returns */ cancel(id: string): Promise { - return this.client.delete('/receipts/' + id) + return this.client.delete('/receipts/' + id); } /** @@ -114,7 +114,7 @@ export default class Receipts { * @returns Email sent confirmation */ sendByEmail(id: string, data?: SendEmailBody): Promise { - return this.client.post('/receipts/' + id + '/email', { body: data }) + return this.client.post('/receipts/' + id + '/email', { body: data }); } /** @@ -123,7 +123,7 @@ export default class Receipts { * @returns PDF file in a stream (Node.js) or Blob (browser) */ downloadPdf(id: string): Promise { - return this.client.get('/receipts/' + id + '/pdf') + return this.client.get('/receipts/' + id + '/pdf'); } /** @@ -136,7 +136,7 @@ export default class Receipts { * @returns Signed download URL and its metadata */ downloadPdfUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/receipts/' + id + '/download-url/pdf') + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/receipts/' + id + '/download-url/pdf'); } } diff --git a/src/resources/retentions.ts b/src/resources/retentions.ts index 81e0e86..758197d 100644 --- a/src/resources/retentions.ts +++ b/src/resources/retentions.ts @@ -5,13 +5,13 @@ import { SearchResult, SendEmailBody, SignedDownloadUrl, -} from '../types' -import { WrapperClient } from '../wrapper' +} from '../types'; +import { WrapperClient } from '../wrapper'; export default class Retentions { - client: WrapperClient + client: WrapperClient; constructor(client: WrapperClient) { - this.client = client + this.client = client; } /** @@ -20,7 +20,7 @@ export default class Retentions { * @returns */ create(data: Record): Promise { - return this.client.post('/retentions', { body: data }) + return this.client.post('/retentions', { body: data }); } /** @@ -29,8 +29,8 @@ export default class Retentions { * @returns */ list(params?: Record | null): Promise> { - if (!params) params = {} - return this.client.get('/retentions', { params }) + if (!params) params = {}; + return this.client.get('/retentions', { params }); } /** @@ -39,8 +39,8 @@ export default class Retentions { * @returns */ retrieve(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/retentions/' + id) + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/retentions/' + id); } /** @@ -50,7 +50,7 @@ export default class Retentions { * @returns */ cancel(id: string, params?: Record): Promise { - return this.client.delete('/retentions/' + id, { params }) + return this.client.delete('/retentions/' + id, { params }); } /** @@ -60,7 +60,7 @@ export default class Retentions { * @returns Edited retention */ updateDraft(id: string, data: Record): Promise { - return this.client.put('/retentions/' + id, { body: data }) + return this.client.put('/retentions/' + id, { body: data }); } /** @@ -69,7 +69,7 @@ export default class Retentions { * @returns Stamped retention */ stampDraft(id: string): Promise { - return this.client.post('/retentions/' + id + '/stamp') + return this.client.post('/retentions/' + id + '/stamp'); } /** @@ -78,7 +78,7 @@ export default class Retentions { * @returns Draft retention */ copyToDraft(id: string): Promise { - return this.client.post('/retentions/' + id + '/copy') + return this.client.post('/retentions/' + id + '/copy'); } /** @@ -89,7 +89,7 @@ export default class Retentions { * @returns */ sendByEmail(id: string, data?: SendEmailBody): Promise { - return this.client.post('/retentions/' + id + '/email', { body: data }) + return this.client.post('/retentions/' + id + '/email', { body: data }); } /** @@ -98,7 +98,7 @@ export default class Retentions { * @returns PDF file in a stream (Node.js) or Blob (browser) */ downloadPdf(id: string): Promise { - return this.client.get('/retentions/' + id + '/pdf') + return this.client.get('/retentions/' + id + '/pdf'); } /** @@ -107,7 +107,7 @@ export default class Retentions { * @returns XML file in a stream (Node.js) or Blob (browser) */ downloadXml(id: string): Promise { - return this.client.get('/retentions/' + id + '/xml') + return this.client.get('/retentions/' + id + '/xml'); } /** @@ -116,7 +116,7 @@ export default class Retentions { * @returns ZIP file in a stream (Node.js) or Blob (browser) */ downloadZip(id: string): Promise { - return this.client.get('/retentions/' + id + '/zip') + return this.client.get('/retentions/' + id + '/zip'); } /** @@ -126,19 +126,19 @@ export default class Retentions { * @returns Signed download URL and its metadata */ downloadPdfUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/retentions/' + id + '/download-url/pdf') + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/retentions/' + id + '/download-url/pdf'); } /** Gets a short-lived URL for downloading a retention XML file. */ downloadXmlUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/retentions/' + id + '/download-url/xml') + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/retentions/' + id + '/download-url/xml'); } /** Gets a short-lived URL for downloading a retention ZIP file. */ downloadZipUrl(id: string): Promise { - if (!id) return Promise.reject(new Error('id is required')) - return this.client.get('/retentions/' + id + '/download-url/zip') + if (!id) return Promise.reject(new Error('id is required')); + return this.client.get('/retentions/' + id + '/download-url/zip'); } } diff --git a/src/tools/webhooks.ts b/src/tools/webhooks.ts index 66731e1..59475e9 100644 --- a/src/tools/webhooks.ts +++ b/src/tools/webhooks.ts @@ -1,9 +1,4 @@ -import { - SearchResult, - Webhook, - ApiEvent, - ApiEventType, -} from '../types'; +import { SearchResult, Webhook, ApiEvent, ApiEventType } from '../types'; import { WrapperClient } from '../wrapper'; function hasBuffer(): boolean { @@ -112,10 +107,7 @@ export default class Webhooks { payloadString = new TextDecoder().decode(payload); } else if (payload instanceof ArrayBuffer) { payloadString = new TextDecoder().decode(new Uint8Array(payload)); - } else if ( - typeof Buffer !== 'undefined' && - Buffer.isBuffer(payload) - ) { + } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(payload)) { payloadString = payload.toString('utf8'); } else if (typeof payload === 'object') { payloadString = JSON.stringify(payload); @@ -133,9 +125,7 @@ export default class Webhooks { if (nodeCrypto) { const hmac = nodeCrypto.createHmac('sha256', secret); - const digestBuffer = hmac - .update(payloadString) - .digest(); + const digestBuffer = hmac.update(payloadString).digest(); // Compare the digest with the signature and prevent timing attacks // by using a constant-time comparison const signatureBuffer = Buffer.from(signature, 'hex'); diff --git a/src/types/common.ts b/src/types/common.ts index c1d01a8..e72a280 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -36,7 +36,11 @@ export type PageSearchParams = ({ pagination?: 'page' } | { page: number }) & Record; /** Params that select cursor pagination (page mode is the default). */ -export type CursorSearchParams = ({ pagination: 'cursor' } | { after: string } | { before: string }) & +export type CursorSearchParams = ( + | { pagination: 'cursor' } + | { after: string } + | { before: string } +) & Record; export interface InvoiceItemPart { diff --git a/src/types/invoice.ts b/src/types/invoice.ts index 295864f..46a9e63 100644 --- a/src/types/invoice.ts +++ b/src/types/invoice.ts @@ -9,115 +9,115 @@ import { IssuingType, PaymentForm, PaymentMethod, -} from '../enums' +} from '../enums'; import { Address, CustomerInfo, InvoiceItem, RelatedDocument, XmlNamespace, -} from './common' -import { NominaComplementData, PagoComplementData } from './complements' +} from './common'; +import { NominaComplementData, PagoComplementData } from './complements'; export interface GlobalInfo { - periodicity: InvoicingPeriod - months: string - year: number + periodicity: InvoicingPeriod; + months: string; + year: number; } export interface InvoiceComplement { - type: InvoiceComplementType - data: string | PagoComplementData[] | NominaComplementData + type: InvoiceComplementType; + data: string | PagoComplementData[] | NominaComplementData; } export interface Invoice { - id: string - organization: string - livemode: boolean - created_at: Date - date: Date - issuer_type: IssuingType - type: InvoiceType - status: InvoiceStatus - cfdi_version: number - issuer_info: CustomerInfo - payment_form: PaymentForm - payment_method: PaymentMethod - currency: string - exchange: number - uuid: string - customer: CustomerInfo - total: number - use: InvoiceUse - folio_number: number | string - series: string - is_ready_to_stamp: boolean - items: InvoiceItem[] - address: Address - amount_due?: number | null - verification_url?: string | null - verification_carta_porte?: string | null - cancellation_status: CancellationStatus - external_id?: string | null - idempotency_key?: string | null + id: string; + organization: string; + livemode: boolean; + created_at: Date; + date: Date; + issuer_type: IssuingType; + type: InvoiceType; + status: InvoiceStatus; + cfdi_version: number; + issuer_info: CustomerInfo; + payment_form: PaymentForm; + payment_method: PaymentMethod; + currency: string; + exchange: number; + uuid: string; + customer: CustomerInfo; + total: number; + use: InvoiceUse; + folio_number: number | string; + series: string; + is_ready_to_stamp: boolean; + items: InvoiceItem[]; + address: Address; + amount_due?: number | null; + verification_url?: string | null; + verification_carta_porte?: string | null; + cancellation_status: CancellationStatus; + external_id?: string | null; + idempotency_key?: string | null; stamp?: { - date: string - sat_signature: string - sat_cert_number: string - signature: string - complement_string: string - rfc_provider_cert: string - } | null - addenda?: string | null - conditions: string | null + date: string; + sat_signature: string; + sat_cert_number: string; + signature: string; + complement_string: string; + rfc_provider_cert: string; + } | null; + addenda?: string | null; + conditions: string | null; - pdf_custom_section: string | null - export?: string | null - global?: GlobalInfo | null + pdf_custom_section: string | null; + export?: string | null; + global?: GlobalInfo | null; cancellation?: { - requested_at: Date - status: CancellationStatus - last_checked: Date - motive: string - substitutionUUID: string - } | null - complements?: InvoiceComplement[] | null - related_documents?: RelatedDocument[] | null - namespaces?: XmlNamespace[] | null - received_payment_ids?: string[] | null - target_invoice_ids?: string[] | null + requested_at: Date; + status: CancellationStatus; + last_checked: Date; + motive: string; + substitutionUUID: string; + } | null; + complements?: InvoiceComplement[] | null; + related_documents?: RelatedDocument[] | null; + namespaces?: XmlNamespace[] | null; + received_payment_ids?: string[] | null; + target_invoice_ids?: string[] | null; } export interface CancelInvoiceOptions { - motive: CancellationMotive - substitution?: string + motive: CancellationMotive; + substitution?: string; } export interface CreateZipRequestData { - year: number - month: number - issuer_type: IssuingType - invoice_types?: InvoiceType[] + year: number; + month: number; + issuer_type: IssuingType; + invoice_types?: InvoiceType[]; } export interface ListZipRequestsParams { - year?: number - month?: number - status?: string - limit?: number - page?: number + year?: number; + month?: number; + status?: string; + limit?: number; + page?: number; } export interface ZipRequest { - id: string - year: number - month: number - issuer_type: IssuingType - invoice_types: InvoiceType[] - status: string - created_at?: Date - updated_at?: Date - [key: string]: unknown + id: string; + year: number; + month: number; + issuer_type: IssuingType; + invoice_types: InvoiceType[]; + status: string; + created_at?: Date; + updated_at?: Date; + [key: string]: unknown; } export interface PaymentSummaryParams { @@ -125,37 +125,37 @@ export interface PaymentSummaryParams { * Amount being paid on the invoice, expressed in the invoice currency. * Cannot exceed the outstanding balance. */ - amount: number + amount: number; } export interface PaymentSummaryTax { /** Tax base prorated to the paid amount */ - base: number + base: number; /** Tax rate or quota */ - rate: number + rate: number; /** Tax type (VAT, income tax, etc.) */ - type: string + type: string; /** Factor type (Rate, Exempt, etc.) */ - factor: string + factor: string; /** Whether this tax is a withholding */ - withholding: boolean + withholding: boolean; } export interface PaymentSummary { /** Invoice UUID */ - uuid: string - folio_number?: number | null - series?: string | null + uuid: string; + folio_number?: number | null; + series?: string | null; /** Installment number corresponding to this payment */ - installment: number + installment: number; /** Invoice outstanding balance before this payment */ - last_balance: number + last_balance: number; /** Invoice total */ - total: number + total: number; /** Invoice currency */ - currency: string + currency: string; /** Amount paid in this installment */ - amount: number + amount: number; /** Invoice taxes prorated to the paid amount */ - taxes: PaymentSummaryTax[] + taxes: PaymentSummaryTax[]; } diff --git a/src/types/receipt.ts b/src/types/receipt.ts index 1b6891c..1ba1212 100644 --- a/src/types/receipt.ts +++ b/src/types/receipt.ts @@ -1,40 +1,40 @@ -import type { ReceiptStatus } from '../enums' -import type { InvoiceItem } from './common' -import type { Invoice } from './invoice' +import type { ReceiptStatus } from '../enums'; +import type { InvoiceItem } from './common'; +import type { Invoice } from './invoice'; export interface Receipt { - id: string - created_at: Date - date: Date - api_version: number - livemode: boolean - organization: string - folio_number?: number - external_id?: string - idempotency_key?: string - branch: string - payment_form: string - items: InvoiceItem[] - currency: string - exchange: number - total: number - invoice: string - expires_at: Date - key: string - status: ReceiptStatus - self_invoice_url: string + id: string; + created_at: Date; + date: Date; + api_version: number; + livemode: boolean; + organization: string; + folio_number?: number; + external_id?: string; + idempotency_key?: string; + branch: string; + payment_form: string; + items: InvoiceItem[]; + currency: string; + exchange: number; + total: number; + invoice: string; + expires_at: Date; + key: string; + status: ReceiptStatus; + self_invoice_url: string; } export interface ReceiptsToInvoiceInput { - keys: string[] - customer?: string | Record - use?: string - dry_run?: boolean - payment_form?: string | null + keys: string[]; + customer?: string | Record; + use?: string; + dry_run?: boolean; + payment_form?: string | null; } export interface PreviewReceiptsToInvoicePdfInput { - keys: string[] - customer?: string | Record | null - use?: string + keys: string[]; + customer?: string | Record | null; + use?: string; } diff --git a/src/wrapper.ts b/src/wrapper.ts index 6dc4070..b11055f 100644 --- a/src/wrapper.ts +++ b/src/wrapper.ts @@ -1,8 +1,4 @@ -import { - BASE_URL, - BASE_URL_V1, - DEFAULT_API_VERSION, -} from './constants'; +import { BASE_URL, BASE_URL_V1, DEFAULT_API_VERSION } from './constants'; const getRuntimeFetch = () => { const runtimeFetch = globalThis.fetch; @@ -137,7 +133,6 @@ const buildQueryString = (params: Record): string => { return pairs.length ? new URLSearchParams(pairs).toString() : ''; }; - const stringFrom = (value: unknown): string | undefined => typeof value === 'string' ? value : undefined; @@ -192,8 +187,7 @@ const responseInterceptor = async (response: Response) => { }); } const contentType = response.headers.get('content-type') || ''; - const contentDisposition = - response.headers.get('content-disposition') || ''; + const contentDisposition = response.headers.get('content-disposition') || ''; const looksLikeZip = /filename=.*\.zip\b/i.test(contentDisposition); const looksLikeDownload = /attachment/i.test(contentDisposition) || looksLikeZip; @@ -214,7 +208,8 @@ const responseInterceptor = async (response: Response) => { const { Readable } = await import('stream'); return new Readable({ read() { - reader.read() + reader + .read() .then(({ done, value }) => { if (done) { this.push(null); // end stream diff --git a/test-d/runtime-types.test-d.ts b/test-d/runtime-types.test-d.ts index bd5ab13..1fce739 100644 --- a/test-d/runtime-types.test-d.ts +++ b/test-d/runtime-types.test-d.ts @@ -1,4 +1,4 @@ -import { expectAssignable, expectType, expectError } from 'tsd' +import { expectAssignable, expectType, expectError } from 'tsd'; import Facturapi, { BinaryDownload, CursorSearchParams, @@ -13,12 +13,12 @@ import Facturapi, { SignedDownloadUrl, TaxFactor, ZipRequest, -} from '../dist' +} from '../dist'; -const client = new Facturapi('sk_test_123') +const client = new Facturapi('sk_test_123'); -const zipPromise = client.invoices.downloadZip('inv_123') -expectType>(zipPromise) +const zipPromise = client.invoices.downloadZip('inv_123'); +expectType>(zipPromise); expectType>( client.invoices.createZipRequest({ @@ -27,7 +27,7 @@ expectType>( issuer_type: IssuingType.ISSUING, invoice_types: [InvoiceType.INGRESO, InvoiceType.EGRESO], }), -) +); expectType>>( client.invoices.listZipRequests({ year: 2025, @@ -36,106 +36,106 @@ expectType>>( limit: 20, page: 1, }), -) +); expectType>( client.invoices.retrieveZipRequest('zip_request_123'), -) +); expectType>( client.invoices.downloadZipRequest('zip_request_123'), -) +); -declare const signedDownloadUrl: SignedDownloadUrl -expectType(signedDownloadUrl.url) -expectType(signedDownloadUrl.expires_at) -expectType(signedDownloadUrl.content_type) -expectType(signedDownloadUrl.filename) +declare const signedDownloadUrl: SignedDownloadUrl; +expectType(signedDownloadUrl.url); +expectType(signedDownloadUrl.expires_at); +expectType(signedDownloadUrl.content_type); +expectType(signedDownloadUrl.filename); expectType>( client.invoices.downloadPdfUrl('inv_123'), -) +); expectType>( client.invoices.downloadXmlUrl('inv_123'), -) +); expectType>( client.invoices.downloadZipUrl('inv_123'), -) +); expectType>( client.invoices.downloadCancellationReceiptPdfUrl('inv_123'), -) +); expectType>( client.invoices.downloadCancellationReceiptXmlUrl('inv_123'), -) +); expectType>( client.invoices.downloadZipRequestUrl('zip_request_123'), -) +); expectType>( client.invoices.previewPdfUrl({ customer: 'cus_123', items: [] }), -) +); expectType>( client.receipts.downloadPdfUrl('rec_123'), -) +); expectType>( client.receipts.previewToInvoicePdfUrl({ keys: ['receipt-key'] }), -) +); expectType>( client.retentions.downloadPdfUrl('ret_123'), -) +); expectType>( client.retentions.downloadXmlUrl('ret_123'), -) +); expectType>( client.retentions.downloadZipUrl('ret_123'), -) +); -declare const nodeLike: NodeLikeReadableStream +declare const nodeLike: NodeLikeReadableStream; nodeLike.on('data', (chunk) => { - expectType(chunk) -}) + expectType(chunk); +}); if (nodeLike.pipe) { - const destination = { write: (_chunk: unknown) => undefined } - expectType(nodeLike.pipe(destination)) + const destination = { write: (_chunk: unknown) => undefined }; + expectType(nodeLike.pipe(destination)); } -declare const binary: BinaryDownload -expectError(binary.pipe({})) +declare const binary: BinaryDownload; +expectError(binary.pipe({})); if ('pipe' in binary && typeof binary.pipe === 'function') { - const destination = { write: (_chunk: unknown) => undefined } - expectType(binary.pipe(destination)) + const destination = { write: (_chunk: unknown) => undefined }; + expectType(binary.pipe(destination)); } -expectAssignable(TaxFactor.EXENTO) +expectAssignable(TaxFactor.EXENTO); -declare const invoiceItem: InvoiceItem -expectType(invoiceItem.property_tax_account) +declare const invoiceItem: InvoiceItem; +expectType(invoiceItem.property_tax_account); -declare const apiError: FacturapiError -expectType(apiError.status) -expectType(apiError.code) -expectType(apiError.path) -expectType(apiError.location) -expectType(apiError.logId) -expectType>(apiError.headers) +declare const apiError: FacturapiError; +expectType(apiError.status); +expectType(apiError.code); +expectType(apiError.path); +expectType(apiError.location); +expectType(apiError.logId); +expectType>(apiError.headers); // Pagination params document the two modes; both return the same envelope. -expectAssignable({ page: 2 }) -expectAssignable({ pagination: 'cursor', limit: 50 }) +expectAssignable({ page: 2 }); +expectAssignable({ pagination: 'cursor', limit: 50 }); expectType>>( client.invoices.list({ page: 2, limit: 50 }), -) +); expectType>>( client.invoices.list({ pagination: 'cursor', limit: 50 }), -) +); expectType>>( client.invoices.list({ after: 'cursor-token' }), -) -const looseParams: Record = { page: 2 } -expectType>>(client.invoices.list(looseParams)) -expectType>>(client.invoices.list()) +); +const looseParams: Record = { page: 2 }; +expectType>>(client.invoices.list(looseParams)); +expectType>>(client.invoices.list()); // Totals and cursors are optional because cursor pages omit them. expectType>( client.invoices.list({ page: 1 }).then((result) => result.total_results), -) +); expectType>( client.invoices.list({ after: 'token' }).then((result) => result.next_cursor), -) +); diff --git a/test/browser/runtime-smoke.browser.spec.ts b/test/browser/runtime-smoke.browser.spec.ts index 57e7940..81ea557 100644 --- a/test/browser/runtime-smoke.browser.spec.ts +++ b/test/browser/runtime-smoke.browser.spec.ts @@ -58,7 +58,10 @@ test.describe('browser smoke (real chromium)', () => { return; } - if (url === '/api/v2/organizations/org_123/logo' && req.method === 'PUT') { + if ( + url === '/api/v2/organizations/org_123/logo' && + req.method === 'PUT' + ) { latestUploadContentType = req.headers['content-type']; req.on('data', () => undefined); req.on('end', () => { @@ -129,7 +132,9 @@ test.describe('browser smoke (real chromium)', () => { expect(latestUploadContentType).not.toContain('application/json'); }); - test('non-ok JSON errors surface message in browser runtime', async ({ page }) => { + test('non-ok JSON errors surface message in browser runtime', async ({ + page, + }) => { await page.goto(`${baseUrl}/index.html`); const message = await page.evaluate(async () => { diff --git a/test/certs.spec.js b/test/certs.spec.js index b5f4370..0966d1c 100644 --- a/test/certs.spec.js +++ b/test/certs.spec.js @@ -1,23 +1,19 @@ const Facturapi = require('..'); -const facturapi = new Facturapi( - 'YOUR_API_KEY_HERE' -); -const fs = require('fs') +const facturapi = new Facturapi('YOUR_API_KEY_HERE'); +const fs = require('fs'); const createInvoice = async () => { - const cerFileStream = fs.createReadStream('fake_csd.cer'); - const keyFileStream = fs.createReadStream('fake_csd.key'); - + const cerFileStream = fs.createReadStream('fake_csd.cer'); + const keyFileStream = fs.createReadStream('fake_csd.key'); - await facturapi.organizations.uploadCertificate( + await facturapi.organizations.uploadCertificate( 'RANDOM_ORG_ID_HERE', cerFileStream, keyFileStream, - '12345678a' + '12345678a', ); }; createInvoice() .then(() => console.log('certs done')) .catch(console.error); - diff --git a/test/index.spec.js b/test/index.spec.js index f9d4080..af09501 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -1,17 +1,11 @@ const Facturapi = require('..'); -const facturapi = new Facturapi( - 'YOUR_API_KEY_HERE' - -); +const facturapi = new Facturapi('YOUR_API_KEY_HERE'); const run = async () => { const results = await facturapi.catalogs.searchUnits({ q: 'pulgada' }); console.log(results?.data); }; - - - run() .then(() => console.log('done')) .catch(console.error); diff --git a/test/node/invoice-payment-summary.node.test.ts b/test/node/invoice-payment-summary.node.test.ts index 753fb42..56f3b97 100644 --- a/test/node/invoice-payment-summary.node.test.ts +++ b/test/node/invoice-payment-summary.node.test.ts @@ -1,29 +1,29 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' +import { afterEach, describe, expect, it, vi } from 'vitest'; -import Facturapi from '../../src' +import Facturapi from '../../src'; -const originalFetch = globalThis.fetch +const originalFetch = globalThis.fetch; function createClient() { - const client = new Facturapi('sk_test_123') - client.BASE_URL = 'https://api.test.local/v2' - return client + const client = new Facturapi('sk_test_123'); + client.BASE_URL = 'https://api.test.local/v2'; + return client; } afterEach(() => { - globalThis.fetch = originalFetch - vi.restoreAllMocks() -}) + globalThis.fetch = originalFetch; + vi.restoreAllMocks(); +}); describe('invoice payment summary', () => { it('requests the payment summary with the amount as a query parameter', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url, options) => { expect(url).toBe( 'https://api.test.local/v2/invoices/58e93bd8e86eb318b019743d/payment-summary?amount=100', - ) - expect(options?.method).toBe('GET') + ); + expect(options?.method).toBe('GET'); return Response.json({ uuid: '6CF6CE33-1BD2-4F88-A443-33013C069169', folio_number: 20, @@ -42,23 +42,23 @@ describe('invoice payment summary', () => { withholding: false, }, ], - }) - }) as typeof fetch + }); + }) as typeof fetch; const summary = await client.invoices.paymentSummary( '58e93bd8e86eb318b019743d', { amount: 100 }, - ) - expect(summary.installment).toBe(1) - expect(summary.last_balance).toBe(100) - expect(summary.taxes[0].type).toBe('IVA') - expect(summary.taxes[0].withholding).toBe(false) - }) + ); + expect(summary.installment).toBe(1); + expect(summary.last_balance).toBe(100); + expect(summary.taxes[0].type).toBe('IVA'); + expect(summary.taxes[0].withholding).toBe(false); + }); it('rejects when no id is provided', async () => { - const client = createClient() + const client = createClient(); await expect( client.invoices.paymentSummary('', { amount: 100 }), - ).rejects.toThrow('id is required') - }) -}) + ).rejects.toThrow('id is required'); + }); +}); diff --git a/test/node/invoices-zip-requests.node.test.ts b/test/node/invoices-zip-requests.node.test.ts index 31714cf..5a10ef4 100644 --- a/test/node/invoices-zip-requests.node.test.ts +++ b/test/node/invoices-zip-requests.node.test.ts @@ -1,60 +1,60 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' +import { afterEach, describe, expect, it, vi } from 'vitest'; -import Facturapi, { InvoiceType, IssuingType } from '../../src' +import Facturapi, { InvoiceType, IssuingType } from '../../src'; -const originalFetch = globalThis.fetch +const originalFetch = globalThis.fetch; function createClient() { - const client = new Facturapi('sk_test_123') - client.BASE_URL = 'https://api.test.local/v2' - return client + const client = new Facturapi('sk_test_123'); + client.BASE_URL = 'https://api.test.local/v2'; + return client; } afterEach(() => { - globalThis.fetch = originalFetch - vi.restoreAllMocks() -}) + globalThis.fetch = originalFetch; + vi.restoreAllMocks(); +}); describe('invoice ZIP requests', () => { it('creates or retrieves a ZIP request', async () => { - const client = createClient() + const client = createClient(); const data = { year: 2025, month: 3, issuer_type: IssuingType.ISSUING, invoice_types: [InvoiceType.INGRESO, InvoiceType.EGRESO], - } + }; globalThis.fetch = vi.fn(async (url, options) => { - expect(url).toBe('https://api.test.local/v2/invoices/zip-requests') - expect(options?.method).toBe('POST') - expect(options?.body).toBe(JSON.stringify(data)) + expect(url).toBe('https://api.test.local/v2/invoices/zip-requests'); + expect(options?.method).toBe('POST'); + expect(options?.body).toBe(JSON.stringify(data)); return Response.json({ id: 'zip_request_123', ...data, status: 'pending', - }) - }) as typeof fetch + }); + }) as typeof fetch; - const result = await client.invoices.createZipRequest(data) - expect(result.id).toBe('zip_request_123') - }) + const result = await client.invoices.createZipRequest(data); + expect(result.id).toBe('zip_request_123'); + }); it('lists ZIP requests with query parameters', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url, options) => { expect(url).toBe( 'https://api.test.local/v2/invoices/zip-requests?year=2025&month=3&status=finished&limit=20&page=1', - ) - expect(options?.method).toBe('GET') + ); + expect(options?.method).toBe('GET'); return Response.json({ page: 1, total_pages: 1, total_results: 0, data: [], - }) - }) as typeof fetch + }); + }) as typeof fetch; const result = await client.invoices.listZipRequests({ year: 2025, @@ -62,75 +62,75 @@ describe('invoice ZIP requests', () => { status: 'finished', limit: 20, page: 1, - }) - expect(result.data).toEqual([]) - }) + }); + expect(result.data).toEqual([]); + }); it('retrieves a ZIP request', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url, options) => { expect(url).toBe( 'https://api.test.local/v2/invoices/zip-requests/zip_request_123', - ) - expect(options?.method).toBe('GET') - return Response.json({ id: 'zip_request_123' }) - }) as typeof fetch + ); + expect(options?.method).toBe('GET'); + return Response.json({ id: 'zip_request_123' }); + }) as typeof fetch; - const result = await client.invoices.retrieveZipRequest('zip_request_123') - expect(result.id).toBe('zip_request_123') - }) + const result = await client.invoices.retrieveZipRequest('zip_request_123'); + expect(result.id).toBe('zip_request_123'); + }); it('downloads the generated ZIP', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url, options) => { expect(url).toBe( 'https://api.test.local/v2/invoices/zip-requests/zip_request_123/zip', - ) - expect(options?.method).toBe('GET') + ); + expect(options?.method).toBe('GET'); return new Response(new Blob([Buffer.from('zip-binary-content')]), { headers: { 'content-type': 'application/zip' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - const zip = await client.invoices.downloadZipRequest('zip_request_123') - expect(zip instanceof Blob).toBe(false) - expect(typeof (zip as { pipe?: unknown }).pipe).toBe('function') - }) + const zip = await client.invoices.downloadZipRequest('zip_request_123'); + expect(zip instanceof Blob).toBe(false); + expect(typeof (zip as { pipe?: unknown }).pipe).toBe('function'); + }); it('gets a URL for downloading the generated ZIP', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url, options) => { expect(url).toBe( 'https://api.test.local/v2/invoices/zip-requests/zip_request_123/download-url', - ) - expect(options?.method).toBe('GET') + ); + expect(options?.method).toBe('GET'); return Response.json({ url: 'https://storage.googleapis.com/signed-download', expires_at: '2030-01-01T00:00:00.000Z', content_type: 'application/zip', filename: '2025-03.zip', - }) - }) as typeof fetch + }); + }) as typeof fetch; const result = - await client.invoices.downloadZipRequestUrl('zip_request_123') - expect(result.filename).toBe('2025-03.zip') - }) + await client.invoices.downloadZipRequestUrl('zip_request_123'); + expect(result.filename).toBe('2025-03.zip'); + }); it('requires an id to retrieve or download a ZIP request', async () => { - const client = createClient() + const client = createClient(); await expect(client.invoices.retrieveZipRequest('')).rejects.toThrow( 'id is required', - ) + ); await expect(client.invoices.downloadZipRequest('')).rejects.toThrow( 'id is required', - ) + ); await expect(client.invoices.downloadZipRequestUrl('')).rejects.toThrow( 'id is required', - ) - }) -}) + ); + }); +}); diff --git a/test/node/query-params.node.test.ts b/test/node/query-params.node.test.ts index a9bcd66..0ed1a75 100644 --- a/test/node/query-params.node.test.ts +++ b/test/node/query-params.node.test.ts @@ -1,67 +1,67 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' +import { afterEach, describe, expect, it, vi } from 'vitest'; -import Facturapi from '../../src' +import Facturapi from '../../src'; -const originalFetch = globalThis.fetch +const originalFetch = globalThis.fetch; function createClient() { - const client = new Facturapi('sk_test_123') - client.BASE_URL = 'https://api.test.local/v2' - return client + const client = new Facturapi('sk_test_123'); + client.BASE_URL = 'https://api.test.local/v2'; + return client; } afterEach(() => { - globalThis.fetch = originalFetch - vi.restoreAllMocks() -}) + globalThis.fetch = originalFetch; + vi.restoreAllMocks(); +}); describe('query param serialization', () => { it('serializes a nested date range object with bracket notation', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url) => { expect(url).toBe( 'https://api.test.local/v2/invoices?limit=100&q=laboratorio+ramos&date%5Bgte%5D=2026-01-01&date%5Blt%5D=2026-02-01', - ) + ); return new Response(JSON.stringify({ data: [] }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; await client.invoices.list({ limit: 100, q: 'laboratorio ramos', date: { gte: '2026-01-01', lt: '2026-02-01' }, - }) - }) + }); + }); it('serializes arrays as repeated keys', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url) => { expect(url).toBe( 'https://api.test.local/v2/invoices?status=valid&status=canceled', - ) + ); return new Response(JSON.stringify({ data: [] }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - await client.invoices.list({ status: ['valid', 'canceled'] }) - }) + await client.invoices.list({ status: ['valid', 'canceled'] }); + }); it('skips null, undefined, and empty collections', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url) => { - expect(url).toBe('https://api.test.local/v2/invoices?page=2') + expect(url).toBe('https://api.test.local/v2/invoices?page=2'); return new Response(JSON.stringify({ data: [] }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; await client.invoices.list({ page: 2, @@ -69,70 +69,72 @@ describe('query param serialization', () => { date: undefined, status: [], empty: {}, - }) - }) + }); + }); it('serializes Date values as ISO 8601 strings', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url) => { expect(url).toBe( 'https://api.test.local/v2/invoices?date%5Bgte%5D=2026-01-01T00%3A00%3A00.000Z', - ) + ); return new Response(JSON.stringify({ data: [] }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; await client.invoices.list({ date: { gte: new Date('2026-01-01T00:00:00.000Z') }, - }) - }) + }); + }); it('keeps flat params encoded exactly as before', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url) => { expect(url).toBe( 'https://api.test.local/v2/organizations/domain-check?domain=empresa-demo', - ) + ); return new Response(JSON.stringify({ available: true }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; await client.organizations.checkDomainIsAvailable({ domain: 'empresa-demo', - }) - }) + }); + }); it('does not append a query delimiter when every value is omitted', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url) => { - expect(url).toBe('https://api.test.local/v2/invoices') + expect(url).toBe('https://api.test.local/v2/invoices'); return new Response(JSON.stringify({ data: [] }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - await client.invoices.list({ status: [], q: null, date: undefined }) - }) + await client.invoices.list({ status: [], q: null, date: undefined }); + }); it('keeps string conversion for non-plain object values', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url) => { - expect(new URLSearchParams(url.split('?')[1]).get('q')).toBe('/walmart/i') + expect(new URLSearchParams(url.split('?')[1]).get('q')).toBe( + '/walmart/i', + ); return new Response(JSON.stringify({ data: [] }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - await client.invoices.list({ q: /walmart/i as unknown as string }) - }) -}) + await client.invoices.list({ q: /walmart/i as unknown as string }); + }); +}); diff --git a/test/node/runtime-compat.node.test.ts b/test/node/runtime-compat.node.test.ts index ab7f622..3184b48 100644 --- a/test/node/runtime-compat.node.test.ts +++ b/test/node/runtime-compat.node.test.ts @@ -1,53 +1,53 @@ -import crypto from 'node:crypto' -import { Writable } from 'node:stream' -import { afterEach, describe, expect, it, vi } from 'vitest' +import crypto from 'node:crypto'; +import { Writable } from 'node:stream'; +import { afterEach, describe, expect, it, vi } from 'vitest'; -import Facturapi, { FacturapiError } from '../../src' +import Facturapi, { FacturapiError } from '../../src'; -const originalFetch = globalThis.fetch +const originalFetch = globalThis.fetch; function createClient() { - const client = new Facturapi('sk_test_123') - client.BASE_URL = 'https://api.test.local/v2' - return client + const client = new Facturapi('sk_test_123'); + client.BASE_URL = 'https://api.test.local/v2'; + return client; } function getHeader( headers: HeadersInit | undefined, name: string, ): string | undefined { - if (!headers) return undefined - if (headers instanceof Headers) return headers.get(name) || undefined + if (!headers) return undefined; + if (headers instanceof Headers) return headers.get(name) || undefined; if (Array.isArray(headers)) { const match = headers.find( ([key]) => key.toLowerCase() === name.toLowerCase(), - ) - return match?.[1] + ); + return match?.[1]; } - const map = headers as Record - return map[name] || map[name.toLowerCase()] + const map = headers as Record; + return map[name] || map[name.toLowerCase()]; } afterEach(() => { - globalThis.fetch = originalFetch - vi.restoreAllMocks() -}) + globalThis.fetch = originalFetch; + vi.restoreAllMocks(); +}); describe('runtime compatibility (node)', () => { it('sends bearer auth header in Node', async () => { - const client = createClient() - const expected = 'Bearer sk_test_123' + const client = createClient(); + const expected = 'Bearer sk_test_123'; globalThis.fetch = vi.fn(async (_url, options) => { - expect(getHeader(options?.headers, 'Authorization')).toBe(expected) + expect(getHeader(options?.headers, 'Authorization')).toBe(expected); return new Response(JSON.stringify({ id: 'inv_123' }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - await client.invoices.retrieve('inv_123') - }) + await client.invoices.retrieve('inv_123'); + }); it('sends custom headers in Node', async () => { const client = new Facturapi('sk_test_123', { @@ -56,39 +56,39 @@ describe('runtime compatibility (node)', () => { authorization: 'Bearer ignored', 'content-type': 'text/plain', }, - }) - client.BASE_URL = 'https://api.test.local/v2' + }); + client.BASE_URL = 'https://api.test.local/v2'; globalThis.fetch = vi.fn(async (_url, options) => { expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) - expect(getHeader(options?.headers, 'x-facturapi-client')).toBe('MCP') + ); + expect(getHeader(options?.headers, 'x-facturapi-client')).toBe('MCP'); expect(getHeader(options?.headers, 'Content-Type')).toBe( 'application/json', - ) + ); return new Response(JSON.stringify({ id: 'org_123' }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - await client.organizations.me() - }) + await client.organizations.me(); + }); it('parses JSON responses and sends auth header', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url, options) => { - expect(url).toBe('https://api.test.local/v2/invoices/inv_123') - expect(options?.method).toBe('GET') + expect(url).toBe('https://api.test.local/v2/invoices/inv_123'); + expect(options?.method).toBe('GET'); expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) + ); expect(getHeader(options?.headers, 'Content-Type')).toBe( 'application/json', - ) + ); return new Response( JSON.stringify({ @@ -99,112 +99,110 @@ describe('runtime compatibility (node)', () => { status: 200, headers: { 'content-type': 'application/json' }, }, - ) - }) as typeof fetch + ); + }) as typeof fetch; - const invoice = await client.invoices.retrieve('inv_123') - expect(invoice.id).toBe('inv_123') - }) + const invoice = await client.invoices.retrieve('inv_123'); + expect(invoice.id).toBe('inv_123'); + }); it('checks domain availability via GET query params', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url, options) => { expect(url).toBe( 'https://api.test.local/v2/organizations/domain-check?domain=empresa-demo', - ) - expect(options?.method).toBe('GET') + ); + expect(options?.method).toBe('GET'); expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) + ); return new Response(JSON.stringify({ available: true }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; const result = await client.organizations.checkDomainIsAvailable({ domain: 'empresa-demo', - }) + }); - expect(result.available).toBe(true) - }) + expect(result.available).toBe(true); + }); it('posts multiple receipts to invoice payload to receipts endpoint', async () => { - const client = createClient() + const client = createClient(); const payload = { keys: ['rcp_key_1', 'rcp_key_2'], dry_run: true, use: 'G03', - } + }; globalThis.fetch = vi.fn(async (url, options) => { - expect(url).toBe('https://api.test.local/v2/receipts/to-invoice') - expect(options?.method).toBe('POST') + expect(url).toBe('https://api.test.local/v2/receipts/to-invoice'); + expect(options?.method).toBe('POST'); expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) + ); expect(getHeader(options?.headers, 'Content-Type')).toBe( 'application/json', - ) - expect(options?.body).toBe(JSON.stringify(payload)) + ); + expect(options?.body).toBe(JSON.stringify(payload)); return new Response(JSON.stringify({ total: 1234 }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - const result = await client.receipts.toInvoice(payload) - expect((result as Record).total).toBe(1234) - }) + const result = await client.receipts.toInvoice(payload); + expect((result as Record).total).toBe(1234); + }); it('downloads multiple receipts to invoice preview pdf', async () => { - const client = createClient() + const client = createClient(); const payload = { keys: ['rcp_key_1'], use: 'G03', - } + }; globalThis.fetch = vi.fn(async (url, options) => { - expect(url).toBe( - 'https://api.test.local/v2/receipts/to-invoice/preview', - ) - expect(options?.method).toBe('POST') + expect(url).toBe('https://api.test.local/v2/receipts/to-invoice/preview'); + expect(options?.method).toBe('POST'); expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) + ); expect(getHeader(options?.headers, 'Content-Type')).toBe( 'application/json', - ) - expect(options?.body).toBe(JSON.stringify(payload)) + ); + expect(options?.body).toBe(JSON.stringify(payload)); return new Response(new Blob([Buffer.from('pdf-binary-content')]), { status: 200, headers: { 'content-type': 'application/pdf' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - const pdf = await client.receipts.previewToInvoicePdf(payload) + const pdf = await client.receipts.previewToInvoicePdf(payload); - expect(pdf instanceof Blob).toBe(false) - expect(typeof (pdf as any).pipe).toBe('function') + expect(pdf instanceof Blob).toBe(false); + expect(typeof (pdf as any).pipe).toBe('function'); - const chunks: Buffer[] = [] + const chunks: Buffer[] = []; await new Promise((resolve, reject) => { - ;(pdf as any).on('data', (chunk: unknown) => { - chunks.push(Buffer.from(chunk as Uint8Array)) - }) - ;(pdf as any).on('error', reject) - ;(pdf as any).on('end', resolve) - }) + (pdf as any).on('data', (chunk: unknown) => { + chunks.push(Buffer.from(chunk as Uint8Array)); + }); + (pdf as any).on('error', reject); + (pdf as any).on('end', resolve); + }); - expect(Buffer.concat(chunks).toString('utf8')).toBe('pdf-binary-content') - }) + expect(Buffer.concat(chunks).toString('utf8')).toBe('pdf-binary-content'); + }); it('surfaces API message from non-OK JSON responses', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async () => { return new Response( @@ -215,16 +213,16 @@ describe('runtime compatibility (node)', () => { status: 404, headers: { 'content-type': 'application/json' }, }, - ) - }) as typeof fetch + ); + }) as typeof fetch; await expect(client.invoices.retrieve('inv_123')).rejects.toThrow( 'invoice not found', - ) - }) + ); + }); it('surfaces structured API errors and response headers in Node', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async () => { return new Response( @@ -251,22 +249,22 @@ describe('runtime compatibility (node)', () => { 'x-facturapi-log-id': 'log_123', }, }, - ) - }) as typeof fetch + ); + }) as typeof fetch; try { - await client.invoices.retrieve('inv_123') - throw new Error('Expected request to fail') + await client.invoices.retrieve('inv_123'); + throw new Error('Expected request to fail'); } catch (error) { - expect(error).toBeInstanceOf(FacturapiError) + expect(error).toBeInstanceOf(FacturapiError); expect((error as FacturapiError).message).toBe( 'Se excedió el límite de solicitudes.', - ) - expect((error as FacturapiError).status).toBe(429) - expect((error as FacturapiError).code).toBe('RATE_LIMIT_EXCEEDED') - expect((error as FacturapiError).path).toBe('date') - expect((error as FacturapiError).location).toBe('query') - expect((error as FacturapiError).logId).toBe('log_123') + ); + expect((error as FacturapiError).status).toBe(429); + expect((error as FacturapiError).code).toBe('RATE_LIMIT_EXCEEDED'); + expect((error as FacturapiError).path).toBe('date'); + expect((error as FacturapiError).location).toBe('query'); + expect((error as FacturapiError).logId).toBe('log_123'); expect((error as FacturapiError).errors).toEqual([ { code: 'required', @@ -274,104 +272,104 @@ describe('runtime compatibility (node)', () => { path: 'date', location: 'query', }, - ]) - expect((error as FacturapiError).headers['retry-after']).toBe('3') + ]); + expect((error as FacturapiError).headers['retry-after']).toBe('3'); expect((error as FacturapiError).headers['x-facturapi-log-id']).toBe( 'log_123', - ) + ); } - }) + }); it('falls back to raw text when non-OK JSON body is malformed', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async () => { return new Response('not-a-json-body', { status: 500, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; await expect(client.invoices.retrieve('inv_123')).rejects.toThrow( 'not-a-json-body', - ) - }) + ); + }); it('falls back to status text when non-OK body is empty', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async () => { return new Response('', { status: 400, statusText: 'Bad Request', headers: { 'content-type': 'text/plain' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; await expect(client.invoices.retrieve('inv_123')).rejects.toThrow( 'Bad Request', - ) - }) + ); + }); it('returns a pipeable stream-like object for binary downloads', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async () => { return new Response(new Blob([Buffer.from('zip-binary-content')]), { status: 200, headers: { 'content-type': 'application/zip' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - const zip = await client.invoices.downloadZip('inv_123') + const zip = await client.invoices.downloadZip('inv_123'); - expect(zip instanceof Blob).toBe(false) - expect(typeof (zip as any).pipe).toBe('function') + expect(zip instanceof Blob).toBe(false); + expect(typeof (zip as any).pipe).toBe('function'); - const chunks: Buffer[] = [] + const chunks: Buffer[] = []; await new Promise((resolve, reject) => { - ;(zip as any).on('data', (chunk: unknown) => { - chunks.push(Buffer.from(chunk as Uint8Array)) - }) - ;(zip as any).on('error', reject) - ;(zip as any).on('end', resolve) - }) + (zip as any).on('data', (chunk: unknown) => { + chunks.push(Buffer.from(chunk as Uint8Array)); + }); + (zip as any).on('error', reject); + (zip as any).on('end', resolve); + }); - expect(Buffer.concat(chunks).toString('utf8')).toBe('zip-binary-content') - }) + expect(Buffer.concat(chunks).toString('utf8')).toBe('zip-binary-content'); + }); it('pipes binary downloads to a Node writable stream', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async () => { return new Response(new Blob([Buffer.from('zip-binary-content')]), { status: 200, headers: { 'content-type': 'application/zip' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - const zip = await client.invoices.downloadZip('inv_123') + const zip = await client.invoices.downloadZip('inv_123'); - const written: Buffer[] = [] + const written: Buffer[] = []; const writable = new Writable({ write(chunk, _encoding, callback) { - written.push(Buffer.from(chunk)) - callback() + written.push(Buffer.from(chunk)); + callback(); }, - }) + }); await new Promise((resolve, reject) => { - writable.on('finish', resolve) - writable.on('error', reject) - ;(zip as any).on('error', reject) - ;(zip as any).pipe(writable) - }) + writable.on('finish', resolve); + writable.on('error', reject); + (zip as any).on('error', reject); + (zip as any).pipe(writable); + }); - expect(Buffer.concat(written).toString('utf8')).toBe('zip-binary-content') - }) + expect(Buffer.concat(written).toString('utf8')).toBe('zip-binary-content'); + }); it('propagates stream reader errors for binary downloads', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async () => { return { @@ -380,57 +378,57 @@ describe('runtime compatibility (node)', () => { get(name: string) { return name.toLowerCase() === 'content-type' ? 'application/zip' - : null + : null; }, }, body: { getReader() { return { read: async () => { - throw new Error('reader failed') + throw new Error('reader failed'); }, cancel: async () => undefined, - } + }; }, }, async blob() { - return new Blob(['fallback']) + return new Blob(['fallback']); }, async json() { - return {} + return {}; }, async text() { - return '' + return ''; }, - } as unknown as Response - }) as typeof fetch + } as unknown as Response; + }) as typeof fetch; - const zip = await client.invoices.downloadZip('inv_123') + const zip = await client.invoices.downloadZip('inv_123'); await expect( new Promise((resolve, reject) => { - ;(zip as any).on('error', reject) - ;(zip as any).on('end', resolve) - ;(zip as any).on('close', resolve) - ;(zip as any).on('data', () => undefined) + (zip as any).on('error', reject); + (zip as any).on('end', resolve); + (zip as any).on('close', resolve); + (zip as any).on('data', () => undefined); }), - ).rejects.toThrow('reader failed') - }) + ).rejects.toThrow('reader failed'); + }); it('validates webhook signatures locally in Node crypto', async () => { - const client = createClient() - const payload = '{"id":"evt_123","type":"invoice.created"}' - const secret = 'whsec_test_fixed' + const client = createClient(); + const payload = '{"id":"evt_123","type":"invoice.created"}'; + const secret = 'whsec_test_fixed'; const precomputedSignature = - 'cebe006de72ff7836e0a39b2dcb7c6304f27039441ae21b52fba413f24516d6e' + 'cebe006de72ff7836e0a39b2dcb7c6304f27039441ae21b52fba413f24516d6e'; const event = await client.webhooks.validateSignature({ secret, signature: precomputedSignature, payload, - }) + }); - expect(event.id).toBe('evt_123') - expect(event.type).toBe('invoice.created') + expect(event.id).toBe('evt_123'); + expect(event.type).toBe('invoice.created'); await expect( client.webhooks.validateSignature({ @@ -441,81 +439,81 @@ describe('runtime compatibility (node)', () => { .digest('hex'), payload, }), - ).rejects.toThrow('Invalid signature') - }) + ).rejects.toThrow('Invalid signature'); + }); it('falls back to API validation when local crypto is unavailable', async () => { - const client = createClient() - const originalBuffer = (globalThis as any).Buffer + const client = createClient(); + const originalBuffer = (globalThis as any).Buffer; const cryptoDescriptor = Object.getOwnPropertyDescriptor( globalThis, 'crypto', - ) + ); - ;(globalThis as any).Buffer = undefined + (globalThis as any).Buffer = undefined; Object.defineProperty(globalThis, 'crypto', { value: undefined, configurable: true, writable: true, - }) + }); globalThis.fetch = vi.fn(async (url, options) => { - expect(url).toBe('https://api.test.local/v2/webhooks/validate-signature') - expect(options?.method).toBe('POST') + expect(url).toBe('https://api.test.local/v2/webhooks/validate-signature'); + expect(options?.method).toBe('POST'); expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) + ); return { ok: true, headers: { get(name: string) { return name.toLowerCase() === 'content-type' ? 'application/json' - : null + : null; }, }, async json() { return { id: 'evt_remote_123', type: 'invoice.created', - } + }; }, async text() { - return '' + return ''; }, - } as unknown as Response - }) as typeof fetch + } as unknown as Response; + }) as typeof fetch; try { const event = await client.webhooks.validateSignature({ secret: 'whsec_test', signature: 'deadbeef', payload: '{"id":"evt_remote_123","type":"invoice.created"}', - }) - expect(event.id).toBe('evt_remote_123') - expect(event.type).toBe('invoice.created') + }); + expect(event.id).toBe('evt_remote_123'); + expect(event.type).toBe('invoice.created'); } finally { - ;(globalThis as any).Buffer = originalBuffer + (globalThis as any).Buffer = originalBuffer; if (cryptoDescriptor) { - Object.defineProperty(globalThis, 'crypto', cryptoDescriptor) + Object.defineProperty(globalThis, 'crypto', cryptoDescriptor); } } - }) + }); it('rejects unsupported upload inputs with a clear error', async () => { - const client = createClient() + const client = createClient(); await expect( client.organizations.uploadLogo('org_123', { invalid: true } as any), - ).rejects.toThrow(/Unsupported file input type/) - }) + ).rejects.toThrow(/Unsupported file input type/); + }); it('serializes flat params with URLSearchParams encoding and arrays with repeated keys', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (url) => { expect(url).toBe( 'https://api.test.local/v2/invoices?search=a+b&page=2&active=true&empty=&tags=x&tags=y', - ) + ); return new Response( JSON.stringify({ data: [], @@ -524,8 +522,8 @@ describe('runtime compatibility (node)', () => { status: 200, headers: { 'content-type': 'application/json' }, }, - ) - }) as typeof fetch + ); + }) as typeof fetch; await client.invoices.list({ search: 'a b', @@ -533,6 +531,6 @@ describe('runtime compatibility (node)', () => { active: true, empty: '', tags: ['x', 'y'] as unknown as string, - }) - }) -}) + }); + }); +}); diff --git a/test/node/signed-download-urls.node.test.ts b/test/node/signed-download-urls.node.test.ts index 510bbff..5b3bd05 100644 --- a/test/node/signed-download-urls.node.test.ts +++ b/test/node/signed-download-urls.node.test.ts @@ -1,8 +1,8 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' +import { afterEach, describe, expect, it, vi } from 'vitest'; -import Facturapi from '../../src' +import Facturapi from '../../src'; -const originalFetch = globalThis.fetch +const originalFetch = globalThis.fetch; const signedUrlResponse = (contentType: string, filename: string): Response => new Response( @@ -13,12 +13,12 @@ const signedUrlResponse = (contentType: string, filename: string): Response => filename, }), { status: 200, headers: { 'content-type': 'application/json' } }, - ) + ); afterEach(() => { - globalThis.fetch = originalFetch - vi.restoreAllMocks() -}) + globalThis.fetch = originalFetch; + vi.restoreAllMocks(); +}); describe('signed download URLs', () => { it.each([ @@ -43,26 +43,26 @@ describe('signed download URLs', () => { ])( 'requests a signed URL for an invoice %s', async (_label, format, contentType, download) => { - const client = new Facturapi('sk_test_123') - client.BASE_URL = 'https://api.test.local/v2' + const client = new Facturapi('sk_test_123'); + client.BASE_URL = 'https://api.test.local/v2'; globalThis.fetch = vi.fn(async (url, options) => { expect(url).toBe( `https://api.test.local/v2/invoices/inv_123/download-url/${format}`, - ) - expect(options?.method).toBe('GET') - return signedUrlResponse(contentType, `invoice.${format}`) - }) as typeof fetch + ); + expect(options?.method).toBe('GET'); + return signedUrlResponse(contentType, `invoice.${format}`); + }) as typeof fetch; - const result = await download(client) + const result = await download(client); expect(result).toEqual( expect.objectContaining({ content_type: contentType, filename: `invoice.${format}`, }), - ) + ); }, - ) + ); it.each([ [ @@ -82,38 +82,38 @@ describe('signed download URLs', () => { ])( 'requests a signed URL for a cancellation receipt %s', async (_label, format, contentType, download) => { - const client = new Facturapi('sk_test_123') - client.BASE_URL = 'https://api.test.local/v2' + const client = new Facturapi('sk_test_123'); + client.BASE_URL = 'https://api.test.local/v2'; globalThis.fetch = vi.fn(async (url) => { expect(url).toBe( `https://api.test.local/v2/invoices/inv_123/cancellation_receipt/download-url/${format}`, - ) + ); return signedUrlResponse( contentType, `cancellation_receipt_invoice.${format}`, - ) - }) as typeof fetch + ); + }) as typeof fetch; - const result = await download(client) + const result = await download(client); - expect(result.content_type).toBe(contentType) + expect(result.content_type).toBe(contentType); }, - ) + ); it('requests a signed URL for the receipt PDF', async () => { - const client = new Facturapi('sk_test_123') - client.BASE_URL = 'https://api.test.local/v2' + const client = new Facturapi('sk_test_123'); + client.BASE_URL = 'https://api.test.local/v2'; globalThis.fetch = vi.fn(async (url) => { expect(url).toBe( 'https://api.test.local/v2/receipts/rec_123/download-url/pdf', - ) - return signedUrlResponse('application/pdf', 'receipt.pdf') - }) as typeof fetch + ); + return signedUrlResponse('application/pdf', 'receipt.pdf'); + }) as typeof fetch; - const result = await client.receipts.downloadPdfUrl('rec_123') + const result = await client.receipts.downloadPdfUrl('rec_123'); - expect(result.filename).toBe('receipt.pdf') - }) + expect(result.filename).toBe('receipt.pdf'); + }); it.each([ [ @@ -137,57 +137,57 @@ describe('signed download URLs', () => { ])( 'requests a signed URL for a retention %s', async (_label, format, contentType, download) => { - const client = new Facturapi('sk_test_123') - client.BASE_URL = 'https://api.test.local/v2' + const client = new Facturapi('sk_test_123'); + client.BASE_URL = 'https://api.test.local/v2'; globalThis.fetch = vi.fn(async (url) => { expect(url).toBe( `https://api.test.local/v2/retentions/ret_123/download-url/${format}`, - ) - return signedUrlResponse(contentType, `retention.${format}`) - }) as typeof fetch + ); + return signedUrlResponse(contentType, `retention.${format}`); + }) as typeof fetch; - const result = await download(client) + const result = await download(client); - expect(result.content_type).toBe(contentType) + expect(result.content_type).toBe(contentType); }, - ) + ); it('requests signed URLs for PDF previews', async () => { - const client = new Facturapi('sk_test_123') - client.BASE_URL = 'https://api.test.local/v2' - const requests: string[] = [] + const client = new Facturapi('sk_test_123'); + client.BASE_URL = 'https://api.test.local/v2'; + const requests: string[] = []; globalThis.fetch = vi.fn(async (url, options) => { - requests.push(String(url)) - expect(options?.method).toBe('POST') - return signedUrlResponse('application/pdf', 'invoice-preview.pdf') - }) as typeof fetch + requests.push(String(url)); + expect(options?.method).toBe('POST'); + return signedUrlResponse('application/pdf', 'invoice-preview.pdf'); + }) as typeof fetch; - await client.invoices.previewPdfUrl({ customer: 'cus_123', items: [] }) - await client.receipts.previewToInvoicePdfUrl({ keys: ['receipt-key'] }) + await client.invoices.previewPdfUrl({ customer: 'cus_123', items: [] }); + await client.receipts.previewToInvoicePdfUrl({ keys: ['receipt-key'] }); expect(requests).toEqual([ 'https://api.test.local/v2/invoices/preview/pdf/download-url', 'https://api.test.local/v2/receipts/to-invoice/preview/download-url', - ]) - }) + ]); + }); it('rejects missing ids before making a request', async () => { - const fetchMock = vi.fn() - globalThis.fetch = fetchMock - const client = new Facturapi('sk_test_123') + const fetchMock = vi.fn(); + globalThis.fetch = fetchMock; + const client = new Facturapi('sk_test_123'); await expect(client.invoices.downloadPdfUrl('')).rejects.toThrow( 'id is required', - ) + ); await expect( client.invoices.downloadCancellationReceiptXmlUrl(''), - ).rejects.toThrow('id is required') + ).rejects.toThrow('id is required'); await expect(client.receipts.downloadPdfUrl('')).rejects.toThrow( 'id is required', - ) + ); await expect(client.retentions.downloadZipUrl('')).rejects.toThrow( 'id is required', - ) - expect(fetchMock).not.toHaveBeenCalled() - }) -}) + ); + expect(fetchMock).not.toHaveBeenCalled(); + }); +}); diff --git a/test/web/runtime-compat.web.test.ts b/test/web/runtime-compat.web.test.ts index 9d928c2..fe98f88 100644 --- a/test/web/runtime-compat.web.test.ts +++ b/test/web/runtime-compat.web.test.ts @@ -1,66 +1,66 @@ -import { afterEach, describe, expect, it, vi } from 'vitest' +import { afterEach, describe, expect, it, vi } from 'vitest'; -import Facturapi, { FacturapiError } from '../../src' +import Facturapi, { FacturapiError } from '../../src'; -const originalFetch = globalThis.fetch -const originalBuffer = (globalThis as any).Buffer +const originalFetch = globalThis.fetch; +const originalBuffer = (globalThis as any).Buffer; function createClient() { - const client = new Facturapi('sk_test_123') - client.BASE_URL = 'https://api.test.local/v2' - return client + const client = new Facturapi('sk_test_123'); + client.BASE_URL = 'https://api.test.local/v2'; + return client; } function getHeader( headers: HeadersInit | undefined, name: string, ): string | undefined { - if (!headers) return undefined - if (headers instanceof Headers) return headers.get(name) || undefined + if (!headers) return undefined; + if (headers instanceof Headers) return headers.get(name) || undefined; if (Array.isArray(headers)) { const match = headers.find( ([key]) => key.toLowerCase() === name.toLowerCase(), - ) - return match?.[1] + ); + return match?.[1]; } - const map = headers as Record - return map[name] || map[name.toLowerCase()] + const map = headers as Record; + return map[name] || map[name.toLowerCase()]; } afterEach(() => { - globalThis.fetch = originalFetch - ;(globalThis as any).Buffer = originalBuffer - vi.restoreAllMocks() -}) + globalThis.fetch = originalFetch; + (globalThis as any).Buffer = originalBuffer; + vi.restoreAllMocks(); +}); describe('runtime compatibility (web simulation)', () => { it('sends bearer auth header in web-like runtime', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async (_url, options) => { expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) + ); return { ok: true, headers: { get(name: string) { return name.toLowerCase() === 'content-type' ? 'application/json' - : null + : null; }, }, async json() { - return { id: 'inv_123' } + return { id: 'inv_123' }; }, async text() { - return '' + return ''; }, - } as unknown as Response - }) as typeof fetch + } as unknown as Response; + }) as typeof fetch; - await client.invoices.retrieve('inv_123') - }) + await client.invoices.retrieve('inv_123'); + }); it('sends custom headers in web-like runtime', async () => { const client = new Facturapi('sk_test_123', { @@ -69,17 +69,17 @@ describe('runtime compatibility (web simulation)', () => { authorization: 'Bearer ignored', 'content-type': 'text/plain', }, - }) - client.BASE_URL = 'https://api.test.local/v2' + }); + client.BASE_URL = 'https://api.test.local/v2'; globalThis.fetch = vi.fn(async (_url, options) => { expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) - expect(getHeader(options?.headers, 'x-facturapi-client')).toBe('MCP') + ); + expect(getHeader(options?.headers, 'x-facturapi-client')).toBe('MCP'); expect(getHeader(options?.headers, 'Content-Type')).toBe( 'application/json', - ) + ); return { ok: true, @@ -87,23 +87,23 @@ describe('runtime compatibility (web simulation)', () => { get(name: string) { return name.toLowerCase() === 'content-type' ? 'application/json' - : null + : null; }, }, async json() { - return { id: 'org_123' } + return { id: 'org_123' }; }, async text() { - return '' + return ''; }, - } as unknown as Response - }) as typeof fetch + } as unknown as Response; + }) as typeof fetch; - await client.organizations.me() - }) + await client.organizations.me(); + }); it('surfaces API message from non-OK JSON responses in web-sim', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async () => { return { @@ -113,22 +113,22 @@ describe('runtime compatibility (web simulation)', () => { get(name: string) { return name.toLowerCase() === 'content-type' ? 'application/json' - : null + : null; }, }, async text() { - return '{"message":"invoice not found"}' + return '{"message":"invoice not found"}'; }, - } as unknown as Response - }) as typeof fetch + } as unknown as Response; + }) as typeof fetch; await expect(client.invoices.retrieve('inv_123')).rejects.toThrow( 'invoice not found', - ) - }) + ); + }); it('surfaces structured API errors and exposed headers in web-like runtime', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async () => { return { @@ -141,8 +141,8 @@ describe('runtime compatibility (web simulation)', () => { 'content-type': 'application/json', 'retry-after': '3', 'x-facturapi-log-id': 'log_123', - } - return values[name.toLowerCase()] || null + }; + return values[name.toLowerCase()] || null; }, }, async text() { @@ -150,75 +150,73 @@ describe('runtime compatibility (web simulation)', () => { message: 'Se excedió el límite de solicitudes.', status: 429, code: 'RATE_LIMIT_EXCEEDED', - }) + }); }, - } as unknown as Response - }) as typeof fetch + } as unknown as Response; + }) as typeof fetch; try { - await client.invoices.retrieve('inv_123') - throw new Error('Expected request to fail') + await client.invoices.retrieve('inv_123'); + throw new Error('Expected request to fail'); } catch (error) { - expect(error).toBeInstanceOf(FacturapiError) - expect((error as FacturapiError).status).toBe(429) - expect((error as FacturapiError).code).toBe('RATE_LIMIT_EXCEEDED') - expect((error as FacturapiError).logId).toBe('log_123') - expect((error as FacturapiError).headers['retry-after']).toBe('3') + expect(error).toBeInstanceOf(FacturapiError); + expect((error as FacturapiError).status).toBe(429); + expect((error as FacturapiError).code).toBe('RATE_LIMIT_EXCEEDED'); + expect((error as FacturapiError).logId).toBe('log_123'); + expect((error as FacturapiError).headers['retry-after']).toBe('3'); expect((error as FacturapiError).headers['x-facturapi-log-id']).toBe( 'log_123', - ) + ); } - }) + }); it('posts multiple receipts to invoice payload in web-like runtime', async () => { - const client = createClient() + const client = createClient(); const payload = { keys: ['rcp_key_1', 'rcp_key_2'], dry_run: true, use: 'G03', - } + }; globalThis.fetch = vi.fn(async (url, options) => { - expect(url).toBe('https://api.test.local/v2/receipts/to-invoice') - expect(options?.method).toBe('POST') + expect(url).toBe('https://api.test.local/v2/receipts/to-invoice'); + expect(options?.method).toBe('POST'); expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) + ); expect(getHeader(options?.headers, 'Content-Type')).toBe( 'application/json', - ) - expect(options?.body).toBe(JSON.stringify(payload)) + ); + expect(options?.body).toBe(JSON.stringify(payload)); return new Response(JSON.stringify({ total: 1234 }), { status: 200, headers: { 'content-type': 'application/json' }, - }) - }) as typeof fetch + }); + }) as typeof fetch; - const result = await client.receipts.toInvoice(payload) - expect((result as Record).total).toBe(1234) - }) + const result = await client.receipts.toInvoice(payload); + expect((result as Record).total).toBe(1234); + }); it('returns Blob receipts to-invoice preview pdf in web-like runtime', async () => { - const client = createClient() - ;(globalThis as any).Buffer = undefined + const client = createClient(); + (globalThis as any).Buffer = undefined; const payload = { keys: ['rcp_key_1'], use: 'G03', - } + }; globalThis.fetch = vi.fn(async (url, options) => { - expect(url).toBe( - 'https://api.test.local/v2/receipts/to-invoice/preview', - ) - expect(options?.method).toBe('POST') + expect(url).toBe('https://api.test.local/v2/receipts/to-invoice/preview'); + expect(options?.method).toBe('POST'); expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) + ); expect(getHeader(options?.headers, 'Content-Type')).toBe( 'application/json', - ) - expect(options?.body).toBe(JSON.stringify(payload)) + ); + expect(options?.body).toBe(JSON.stringify(payload)); return { ok: true, @@ -226,29 +224,29 @@ describe('runtime compatibility (web simulation)', () => { get(name: string) { return name.toLowerCase() === 'content-type' ? 'application/pdf' - : null + : null; }, }, body: undefined, async blob() { - return new Blob(['pdf-binary-content']) + return new Blob(['pdf-binary-content']); }, async json() { - return {} + return {}; }, async text() { - return '' + return ''; }, - } as unknown as Response - }) as typeof fetch + } as unknown as Response; + }) as typeof fetch; - const pdf = await client.receipts.previewToInvoicePdf(payload) - expect(pdf instanceof Blob).toBe(true) - expect(await (pdf as Blob).text()).toBe('pdf-binary-content') - }) + const pdf = await client.receipts.previewToInvoicePdf(payload); + expect(pdf instanceof Blob).toBe(true); + expect(await (pdf as Blob).text()).toBe('pdf-binary-content'); + }); it('falls back to raw text on malformed JSON error bodies in web-sim', async () => { - const client = createClient() + const client = createClient(); globalThis.fetch = vi.fn(async () => { return { @@ -258,23 +256,23 @@ describe('runtime compatibility (web simulation)', () => { get(name: string) { return name.toLowerCase() === 'content-type' ? 'application/json' - : null + : null; }, }, async text() { - return 'not-a-json-body' + return 'not-a-json-body'; }, - } as unknown as Response - }) as typeof fetch + } as unknown as Response; + }) as typeof fetch; await expect(client.invoices.retrieve('inv_123')).rejects.toThrow( 'not-a-json-body', - ) - }) + ); + }); it('returns Blob for binary downloads when Buffer is unavailable', async () => { - const client = createClient() - ;(globalThis as any).Buffer = undefined + const client = createClient(); + (globalThis as any).Buffer = undefined; globalThis.fetch = vi.fn(async () => { return { @@ -283,26 +281,26 @@ describe('runtime compatibility (web simulation)', () => { get(name: string) { return name.toLowerCase() === 'content-type' ? 'application/zip' - : null + : null; }, }, body: undefined, async blob() { - return new Blob(['zip-binary-content']) + return new Blob(['zip-binary-content']); }, async json() { - return {} + return {}; }, async text() { - return '' + return ''; }, - } as unknown as Response - }) as typeof fetch + } as unknown as Response; + }) as typeof fetch; - const zip = await client.invoices.downloadZip('inv_123') - expect(zip instanceof Blob).toBe(true) - expect(await (zip as Blob).text()).toBe('zip-binary-content') - }) + const zip = await client.invoices.downloadZip('inv_123'); + expect(zip instanceof Blob).toBe(true); + expect(await (zip as Blob).text()).toBe('zip-binary-content'); + }); it('sends multipart FormData without forcing content-type header', async () => { const client = new Facturapi('sk_test_123', { @@ -310,18 +308,18 @@ describe('runtime compatibility (web simulation)', () => { 'x-facturapi-client': 'MCP', 'content-type': 'text/plain', }, - }) - client.BASE_URL = 'https://api.test.local/v2' + }); + client.BASE_URL = 'https://api.test.local/v2'; globalThis.fetch = vi.fn(async (url, options) => { - expect(url).toBe('https://api.test.local/v2/organizations/org_123/logo') - expect(options?.method).toBe('PUT') - expect(options?.body instanceof FormData).toBe(true) - expect(getHeader(options?.headers, 'Content-Type')).toBeUndefined() + expect(url).toBe('https://api.test.local/v2/organizations/org_123/logo'); + expect(options?.method).toBe('PUT'); + expect(options?.body instanceof FormData).toBe(true); + expect(getHeader(options?.headers, 'Content-Type')).toBeUndefined(); expect(getHeader(options?.headers, 'Authorization')).toBe( 'Bearer sk_test_123', - ) - expect(getHeader(options?.headers, 'x-facturapi-client')).toBe('MCP') + ); + expect(getHeader(options?.headers, 'x-facturapi-client')).toBe('MCP'); return new Response( JSON.stringify({ @@ -332,34 +330,34 @@ describe('runtime compatibility (web simulation)', () => { status: 200, headers: { 'content-type': 'application/json' }, }, - ) - }) as typeof fetch + ); + }) as typeof fetch; const organization = await client.organizations.uploadLogo( 'org_123', new Uint8Array([1, 2, 3]), - ) + ); - expect(organization.id).toBe('org_123') - }) + expect(organization.id).toBe('org_123'); + }); it('validates webhook signatures through WebCrypto path', async () => { - const client = createClient() - ;(globalThis as any).Buffer = undefined + const client = createClient(); + (globalThis as any).Buffer = undefined; - const payload = '{"id":"evt_web_123","type":"invoice.created"}' - const secret = 'whsec_web_fixed' + const payload = '{"id":"evt_web_123","type":"invoice.created"}'; + const secret = 'whsec_web_fixed'; const precomputedSignature = - 'adffbea89398760c226a664f8e14d9e66b5105b84dabe8a2868638c650b05721' + 'adffbea89398760c226a664f8e14d9e66b5105b84dabe8a2868638c650b05721'; const event = await client.webhooks.validateSignature({ secret, signature: precomputedSignature, payload, - }) + }); - expect(event.id).toBe('evt_web_123') - expect(event.type).toBe('invoice.created') + expect(event.id).toBe('evt_web_123'); + expect(event.type).toBe('invoice.created'); await expect( client.webhooks.validateSignature({ @@ -367,6 +365,6 @@ describe('runtime compatibility (web simulation)', () => { signature: 'deadbeef', payload, }), - ).rejects.toThrow('Invalid signature') - }) -}) + ).rejects.toThrow('Invalid signature'); + }); +});