From 8ae13755019daaccc0ee3052612925d964bfd75c Mon Sep 17 00:00:00 2001 From: roman-nazaruk Date: Tue, 11 Mar 2025 16:39:06 +0100 Subject: [PATCH 1/8] chore: solution brainstroming for ingres_expiry --- src/agent/custom-http-agent.spec.ts | 10 ++++++++ src/agent/custom-http-agent.ts | 33 +++++++++++++++++++++++++-- src/api/signer.api.ts | 3 ++- src/constants/http-agent.constants.ts | 1 + src/utils/crypto.utils.ts | 16 +++++++++++++ src/utils/custom-http-agent.utils.ts | 9 ++++++++ 6 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 src/constants/http-agent.constants.ts create mode 100644 src/utils/crypto.utils.ts create mode 100644 src/utils/custom-http-agent.utils.ts diff --git a/src/agent/custom-http-agent.spec.ts b/src/agent/custom-http-agent.spec.ts index 1855ea30..eddac8ec 100644 --- a/src/agent/custom-http-agent.spec.ts +++ b/src/agent/custom-http-agent.spec.ts @@ -206,6 +206,16 @@ describe('CustomHttpAgent', () => { expect(spyTransform).not.toHaveBeenCalled(); }); + it('should make a request and call transform', async () => { + const spyTransform = vi.spyOn(agent.agent, 'addTransform'); + + await agent.request({ + ...mockRequestPayload + }); + + expect(spyTransform).toHaveBeenCalledOnce(); + }); + describe('Invalid response', () => { it('should throw UndefinedRequestDetailsError if requestDetails is null', async () => { spyCall.mockResolvedValue({ diff --git a/src/agent/custom-http-agent.ts b/src/agent/custom-http-agent.ts index 6a5cefac..528a1b02 100644 --- a/src/agent/custom-http-agent.ts +++ b/src/agent/custom-http-agent.ts @@ -1,9 +1,11 @@ import { Certificate, + Expiry, HttpAgent, Nonce, defaultStrategy, lookupResultToBuffer, + makeExpiryTransform, makeNonceTransform, pollForResponse as pollForResponseAgent, type CallRequest, @@ -13,7 +15,10 @@ import { import {bufFromBufLike} from '@dfinity/candid'; import {Principal} from '@dfinity/principal'; import {base64ToUint8Array, isNullish, nonNullish} from '@dfinity/utils'; +import {DEFAULT_EXPIRY_DURATION} from '../constants/http-agent.constants'; import type {IcrcCallCanisterRequestParams} from '../types/icrc-requests'; +import {generateHash} from '../utils/crypto.utils'; +import {expiryToMs, isTimestampExpired} from '../utils/custom-http-agent.utils'; export type CustomHttpAgentResponse = Pick, 'requestDetails'> & { certificate: Certificate; @@ -30,9 +35,11 @@ export class UndefinedRootKeyError extends Error {} // Therefore, it is cleaner in my opinion to encapsulate the agent rather than extend it. export class CustomHttpAgent { readonly #agent: HttpAgent; + #cache: Map; private constructor(agent: HttpAgent) { this.#agent = agent; + this.#cache = new Map(); } static async create( @@ -55,9 +62,14 @@ export class CustomHttpAgent { arg, canisterId, method: methodName, - nonce - }: Omit): Promise => { + nonce, + sender + }: IcrcCallCanisterRequestParams): Promise => { + const hash = await generateHash({canisterId, sender, method: methodName, arg, nonce}); + const ingressExpiry = this.getIngressExpiry(hash); + this.attachRequestNonce({nonce}); + this.attachAddTransformExpiry(ingressExpiry); const {requestDetails, ...restResponse} = await this.#agent.call(canisterId, { methodName, @@ -210,4 +222,21 @@ export class CustomHttpAgent { makeNonceTransform((): Nonce => base64ToUint8Array(nonce) as Nonce) ); } + private attachAddTransformExpiry(expiry: number): void { + this.#agent.addTransform('update', makeExpiryTransform(expiry)); + } + + private getIngressExpiry(hash: string): number { + const existingExpiry = this.#cache.get(hash); + + if (existingExpiry && !isTimestampExpired(expiryToMs(existingExpiry))) { + const delta = expiryToMs(existingExpiry) - Date.now(); + return delta; + } + + const newExpiry = new Expiry(DEFAULT_EXPIRY_DURATION); + this.#cache.set(hash, newExpiry); + + return DEFAULT_EXPIRY_DURATION; +} } diff --git a/src/api/signer.api.ts b/src/api/signer.api.ts index 004ed9e5..37861df5 100644 --- a/src/api/signer.api.ts +++ b/src/api/signer.api.ts @@ -13,13 +13,14 @@ export class SignerApi extends Icrc21Canister { async call({ owner, host, - params: {canisterId, method, arg, nonce} + params: {canisterId, method, arg, nonce, sender} }: { params: IcrcCallCanisterRequestParams; } & SignerOptions): Promise { const agent = await this.getAgent({host, owner}); const result = await agent.request({ + sender, canisterId, method, arg, diff --git a/src/constants/http-agent.constants.ts b/src/constants/http-agent.constants.ts new file mode 100644 index 00000000..4de9070a --- /dev/null +++ b/src/constants/http-agent.constants.ts @@ -0,0 +1 @@ +export const DEFAULT_EXPIRY_DURATION = 5 * 60 * 1000; diff --git a/src/utils/crypto.utils.ts b/src/utils/crypto.utils.ts new file mode 100644 index 00000000..78f1e2fa --- /dev/null +++ b/src/utils/crypto.utils.ts @@ -0,0 +1,16 @@ +import { IcrcCallCanisterRequestParams } from 'src/types/icrc-requests'; + +export async function generateHash(params: IcrcCallCanisterRequestParams): Promise { + const jsonString = JSON.stringify(params, Object.keys(params).sort()); + + const dataBuffer = new TextEncoder().encode(jsonString); + const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer); + + return bufferToHex(hashBuffer); +} + +function bufferToHex(buffer: ArrayBuffer): string { + return [...new Uint8Array(buffer)] + .map(byte => byte.toString(16).padStart(2, '0')) + .join(''); + } diff --git a/src/utils/custom-http-agent.utils.ts b/src/utils/custom-http-agent.utils.ts new file mode 100644 index 00000000..b1fd3197 --- /dev/null +++ b/src/utils/custom-http-agent.utils.ts @@ -0,0 +1,9 @@ +import {Expiry} from '@dfinity/agent'; + +export function isTimestampExpired(timestamp: number): boolean { + return Date.now() > timestamp; +} + +export function expiryToMs(expiry: Expiry): number { + return Number(expiry['_value'] / 1000000n); +} \ No newline at end of file From 5241ae94667b3f6b24bf1809f539ff81f800871e Mon Sep 17 00:00:00 2001 From: roman-nazaruk Date: Tue, 11 Mar 2025 17:03:07 +0100 Subject: [PATCH 2/8] Removed unnecessary test --- src/agent/custom-http-agent.spec.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/agent/custom-http-agent.spec.ts b/src/agent/custom-http-agent.spec.ts index eddac8ec..1855ea30 100644 --- a/src/agent/custom-http-agent.spec.ts +++ b/src/agent/custom-http-agent.spec.ts @@ -206,16 +206,6 @@ describe('CustomHttpAgent', () => { expect(spyTransform).not.toHaveBeenCalled(); }); - it('should make a request and call transform', async () => { - const spyTransform = vi.spyOn(agent.agent, 'addTransform'); - - await agent.request({ - ...mockRequestPayload - }); - - expect(spyTransform).toHaveBeenCalledOnce(); - }); - describe('Invalid response', () => { it('should throw UndefinedRequestDetailsError if requestDetails is null', async () => { spyCall.mockResolvedValue({ From 7868bfbfb095704b2cf0032e31f22223efa42e65 Mon Sep 17 00:00:00 2001 From: roman-nazaruk Date: Wed, 12 Mar 2025 10:41:48 +0100 Subject: [PATCH 3/8] Refactored and changed logic for ingress expiry --- src/agent/custom-http-agent.ts | 39 +++++++++++++++++++++------- src/utils/crypto.utils.ts | 17 +++++------- src/utils/custom-http-agent.utils.ts | 4 --- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/agent/custom-http-agent.ts b/src/agent/custom-http-agent.ts index 528a1b02..1c9b304f 100644 --- a/src/agent/custom-http-agent.ts +++ b/src/agent/custom-http-agent.ts @@ -18,7 +18,7 @@ import {base64ToUint8Array, isNullish, nonNullish} from '@dfinity/utils'; import {DEFAULT_EXPIRY_DURATION} from '../constants/http-agent.constants'; import type {IcrcCallCanisterRequestParams} from '../types/icrc-requests'; import {generateHash} from '../utils/crypto.utils'; -import {expiryToMs, isTimestampExpired} from '../utils/custom-http-agent.utils'; +import {expiryToMs} from '../utils/custom-http-agent.utils'; export type CustomHttpAgentResponse = Pick, 'requestDetails'> & { certificate: Certificate; @@ -65,9 +65,9 @@ export class CustomHttpAgent { nonce, sender }: IcrcCallCanisterRequestParams): Promise => { - const hash = await generateHash({canisterId, sender, method: methodName, arg, nonce}); - const ingressExpiry = this.getIngressExpiry(hash); - + const hash = await generateHash({canisterId, sender, method: methodName, arg, nonce}); + const ingressExpiry = this.getIngressExpiry({hash, nonce}); + this.attachRequestNonce({nonce}); this.attachAddTransformExpiry(ingressExpiry); @@ -89,6 +89,8 @@ export class CustomHttpAgent { canisterId }); + this.cleanCacheAfterCall(); + // I assume that if we get a result at this point, it means we can respond to the caller. // However, this is not how it's handled in Agent-js. For some reason, regardless of whether they get a result at this point or not, if the response has a status of 202, they overwrite the result with pollForResponse, which seems incorrect. // That is why we return the result if we get one. @@ -226,17 +228,34 @@ export class CustomHttpAgent { this.#agent.addTransform('update', makeExpiryTransform(expiry)); } - private getIngressExpiry(hash: string): number { + private getIngressExpiry({hash, nonce}: {hash: string; nonce?: string}): number { + if (isNullish(nonce)){ + return DEFAULT_EXPIRY_DURATION + }; + const existingExpiry = this.#cache.get(hash); - if (existingExpiry && !isTimestampExpired(expiryToMs(existingExpiry))) { - const delta = expiryToMs(existingExpiry) - Date.now(); - return delta; + // TODO: Should we try with a new expiry or reject the request if the timestamp is expired? + if (!existingExpiry || expiryToMs(existingExpiry) <= Date.now()) { + return this.createAndStoreNewExpiry(hash); } + return expiryToMs(existingExpiry) - Date.now(); + } + + private createAndStoreNewExpiry(hash: string): number { const newExpiry = new Expiry(DEFAULT_EXPIRY_DURATION); this.#cache.set(hash, newExpiry); - return DEFAULT_EXPIRY_DURATION; -} + } + + private cleanCacheAfterCall(): void { + const now = Date.now(); + + for (const [key, expiry] of this.#cache.entries()) { + if (expiryToMs(expiry) <= now) { + this.#cache.delete(key); + } + } + } } diff --git a/src/utils/crypto.utils.ts b/src/utils/crypto.utils.ts index 78f1e2fa..1916fb78 100644 --- a/src/utils/crypto.utils.ts +++ b/src/utils/crypto.utils.ts @@ -1,16 +1,11 @@ -import { IcrcCallCanisterRequestParams } from 'src/types/icrc-requests'; +import {uint8ArrayToHexString} from '@dfinity/utils'; +import {IcrcCallCanisterRequestParams} from 'src/types/icrc-requests'; export async function generateHash(params: IcrcCallCanisterRequestParams): Promise { - const jsonString = JSON.stringify(params, Object.keys(params).sort()); + const jsonString = JSON.stringify(params, Object.keys(params).sort()); - const dataBuffer = new TextEncoder().encode(jsonString); - const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer); + const dataBuffer = new TextEncoder().encode(jsonString); + const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer); - return bufferToHex(hashBuffer); + return uint8ArrayToHexString(new Uint8Array(hashBuffer)); } - -function bufferToHex(buffer: ArrayBuffer): string { - return [...new Uint8Array(buffer)] - .map(byte => byte.toString(16).padStart(2, '0')) - .join(''); - } diff --git a/src/utils/custom-http-agent.utils.ts b/src/utils/custom-http-agent.utils.ts index b1fd3197..d98f417b 100644 --- a/src/utils/custom-http-agent.utils.ts +++ b/src/utils/custom-http-agent.utils.ts @@ -1,9 +1,5 @@ import {Expiry} from '@dfinity/agent'; -export function isTimestampExpired(timestamp: number): boolean { - return Date.now() > timestamp; -} - export function expiryToMs(expiry: Expiry): number { return Number(expiry['_value'] / 1000000n); } \ No newline at end of file From 8bcd5b3a404b44ea25763b8300002de285e752c2 Mon Sep 17 00:00:00 2001 From: roman-nazaruk Date: Wed, 12 Mar 2025 11:07:35 +0100 Subject: [PATCH 4/8] Adjusted condition for nonce --- src/agent/custom-http-agent.ts | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/agent/custom-http-agent.ts b/src/agent/custom-http-agent.ts index 1c9b304f..fe55a472 100644 --- a/src/agent/custom-http-agent.ts +++ b/src/agent/custom-http-agent.ts @@ -65,8 +65,8 @@ export class CustomHttpAgent { nonce, sender }: IcrcCallCanisterRequestParams): Promise => { - const hash = await generateHash({canisterId, sender, method: methodName, arg, nonce}); - const ingressExpiry = this.getIngressExpiry({hash, nonce}); + const hash = nonce ? await generateHash({ canisterId, sender, method: methodName, arg, nonce }) : null; + const ingressExpiry = hash ? this.getIngressExpiry(hash) : DEFAULT_EXPIRY_DURATION; this.attachRequestNonce({nonce}); this.attachAddTransformExpiry(ingressExpiry); @@ -228,19 +228,13 @@ export class CustomHttpAgent { this.#agent.addTransform('update', makeExpiryTransform(expiry)); } - private getIngressExpiry({hash, nonce}: {hash: string; nonce?: string}): number { - if (isNullish(nonce)){ - return DEFAULT_EXPIRY_DURATION - }; - + private getIngressExpiry(hash: string): number { const existingExpiry = this.#cache.get(hash); - // TODO: Should we try with a new expiry or reject the request if the timestamp is expired? - if (!existingExpiry || expiryToMs(existingExpiry) <= Date.now()) { - return this.createAndStoreNewExpiry(hash); - } - - return expiryToMs(existingExpiry) - Date.now(); + // TODO: Should we try with a new expiry or reject the request if the timestamp is expired? + return (!existingExpiry || expiryToMs(existingExpiry) <= Date.now()) + ? this.createAndStoreNewExpiry(hash) + : expiryToMs(existingExpiry) - Date.now(); } private createAndStoreNewExpiry(hash: string): number { From 528bd167b472139af45c2255a666e095cf96a6e4 Mon Sep 17 00:00:00 2001 From: roman-nazaruk Date: Tue, 18 Mar 2025 11:21:05 +0100 Subject: [PATCH 5/8] Moved nonceTransform to customTransform --- src/agent/custom-http-agent.ts | 37 ++++++++++++++-------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/src/agent/custom-http-agent.ts b/src/agent/custom-http-agent.ts index 816b57d9..1258a5de 100644 --- a/src/agent/custom-http-agent.ts +++ b/src/agent/custom-http-agent.ts @@ -3,10 +3,8 @@ import { Expiry, HttpAgent, HttpAgentRequestTransformFn, - Nonce, defaultStrategy, lookupResultToBuffer, - makeNonceTransform, pollForResponse as pollForResponseAgent, type CallRequest, type HttpAgentOptions, @@ -64,17 +62,15 @@ export class CustomHttpAgent { nonce, sender }: IcrcCallCanisterRequestParams): Promise => { - this.attachRequestNonce({nonce}); - const hash = nonce ? await generateHash({ canisterId, sender, method: methodName, arg, nonce }) : null; - const modifiedMethodName = `${methodName}_hash_${hash ?? ''}`; + const modifiedMethodName = `${methodName}_hash_${hash ?? ''}_nonce_${nonce ?? ''}`; const {requestDetails, ...restResponse} = await this.#agent.call(canisterId, { methodName: modifiedMethodName, arg: base64ToUint8Array(arg), // effectiveCanisterId is optional but, actually mandatory according SDK team. effectiveCanisterId: canisterId - }); + }); this.assertRequestDetails(requestDetails); @@ -219,14 +215,16 @@ export class CustomHttpAgent { // eslint-disable-next-line require-await return async (request) => { const modifiedMethodName = request.body.method_name; - const [originalMethodName, hash] = modifiedMethodName.split('_hash_'); + const {originalMethodName, hash, nonce} = this.splitModifiedMethodName(modifiedMethodName); - request.body.method_name = originalMethodName; + request.body.method_name = originalMethodName; - if (!hash) { + if (!hash || !nonce) { return request; - } - + } + + request.body.nonce = base64ToUint8Array(nonce); + const existingExpiry = this.#cache.get(hash); if (!existingExpiry){ @@ -238,7 +236,7 @@ export class CustomHttpAgent { } request.body.ingress_expiry = existingExpiry; - + return request; }; } @@ -251,15 +249,10 @@ export class CustomHttpAgent { } } - private attachRequestNonce({nonce}: Pick): void { - if (isNullish(nonce)) { - // Consumer has not provided a nonce. Therefore, we let agent-js generate one for the request. - return; - } - - this.#agent.addTransform( - 'update', - makeNonceTransform((): Nonce => base64ToUint8Array(nonce) as Nonce) - ); + private splitModifiedMethodName(modifiedMethodName: string) { + const [rest, nonce] = modifiedMethodName.split('_nonce_'); + const [originalMethodName, hash] = rest.split('_hash_'); + + return { originalMethodName, hash, nonce }; } } From 301875d935821b32d917c3d079d1cec7a0fee4ff Mon Sep 17 00:00:00 2001 From: roman-nazaruk Date: Tue, 18 Mar 2025 14:28:03 +0100 Subject: [PATCH 6/8] Removed hash from methodName --- src/agent/custom-http-agent.ts | 70 +++++++++++++++++----------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/src/agent/custom-http-agent.ts b/src/agent/custom-http-agent.ts index 1258a5de..60be9c36 100644 --- a/src/agent/custom-http-agent.ts +++ b/src/agent/custom-http-agent.ts @@ -12,7 +12,13 @@ import { } from '@dfinity/agent'; import {bufFromBufLike} from '@dfinity/candid'; import {Principal} from '@dfinity/principal'; -import {base64ToUint8Array, isNullish, nonNullish, nowInBigIntNanoSeconds} from '@dfinity/utils'; +import { + base64ToUint8Array, + isNullish, + nonNullish, + nowInBigIntNanoSeconds, + uint8ArrayToBase64 +} from '@dfinity/utils'; import type {IcrcCallCanisterRequestParams} from '../types/icrc-requests'; import {generateHash} from '../utils/crypto.utils'; @@ -62,16 +68,18 @@ export class CustomHttpAgent { nonce, sender }: IcrcCallCanisterRequestParams): Promise => { - const hash = nonce ? await generateHash({ canisterId, sender, method: methodName, arg, nonce }) : null; - const modifiedMethodName = `${methodName}_hash_${hash ?? ''}_nonce_${nonce ?? ''}`; + const hash = nonce + ? await generateHash({canisterId, sender, method: methodName, arg, nonce}) + : null; + + const modifiedMethodName = `${methodName}_nonce_${nonce ?? ''}`; const {requestDetails, ...restResponse} = await this.#agent.call(canisterId, { methodName: modifiedMethodName, arg: base64ToUint8Array(arg), // effectiveCanisterId is optional but, actually mandatory according SDK team. effectiveCanisterId: canisterId - }); - + }); this.assertRequestDetails(requestDetails); if (isNullish(requestDetails)) { @@ -87,8 +95,6 @@ export class CustomHttpAgent { this.#cache.set(hash, requestDetails.ingress_expiry); } - this.cleanCacheAfterCall(); - // I assume that if we get a result at this point, it means we can respond to the caller. // However, this is not how it's handled in Agent-js. For some reason, regardless of whether they get a result at this point or not, if the response has a status of 202, they overwrite the result with pollForResponse, which seems incorrect. // That is why we return the result if we get one. @@ -211,48 +217,40 @@ export class CustomHttpAgent { return {certificate, requestDetails}; } - private customTransform(): HttpAgentRequestTransformFn { - // eslint-disable-next-line require-await - return async (request) => { - const modifiedMethodName = request.body.method_name; - const {originalMethodName, hash, nonce} = this.splitModifiedMethodName(modifiedMethodName); + private customTransform(): HttpAgentRequestTransformFn { + return async (request) => { + const {canister_id, sender, method_name, arg} = request.body; + const [originalMethodName, nonce] = method_name.split('_nonce_'); - request.body.method_name = originalMethodName; + request.body.method_name = originalMethodName; - if (!hash || !nonce) { + if (!nonce) { return request; } + const hash = await generateHash({ + canisterId: canister_id.toString(), + sender: sender.toString(), + method: method_name, + arg: uint8ArrayToBase64(arg), + nonce + }); + request.body.nonce = base64ToUint8Array(nonce); - const existingExpiry = this.#cache.get(hash); - - if (!existingExpiry){ + const cachedExpiry = this.#cache.get(hash); + + if (!cachedExpiry) { return request; } - - if (existingExpiry['_value'] < nowInBigIntNanoSeconds()){ - throw Error('Ingress Expiry has been expired') + + if (cachedExpiry['_value'] < nowInBigIntNanoSeconds()) { + throw Error('Ingress Expiry has been expired.'); } - request.body.ingress_expiry = existingExpiry; + request.body.ingress_expiry = cachedExpiry; return request; }; - } - - private cleanCacheAfterCall(): void { - for (const [key, expiry] of this.#cache.entries()) { - if (expiry['_value'] <= nowInBigIntNanoSeconds()) { - this.#cache.delete(key); - } - } - } - - private splitModifiedMethodName(modifiedMethodName: string) { - const [rest, nonce] = modifiedMethodName.split('_nonce_'); - const [originalMethodName, hash] = rest.split('_hash_'); - - return { originalMethodName, hash, nonce }; } } From 6ee04277de550fa79b24acc777b1d160dcb0db1a Mon Sep 17 00:00:00 2001 From: roman-nazaruk Date: Tue, 18 Mar 2025 17:18:46 +0100 Subject: [PATCH 7/8] Updated url --- src/agent/custom-http-agent.ts | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/agent/custom-http-agent.ts b/src/agent/custom-http-agent.ts index 60be9c36..1d3d3eb9 100644 --- a/src/agent/custom-http-agent.ts +++ b/src/agent/custom-http-agent.ts @@ -42,7 +42,6 @@ export class CustomHttpAgent { private constructor(agent: HttpAgent) { this.#agent = agent; this.#cache = new Map(); - this.#agent.addTransform('update', this.customTransform()); } static async create( @@ -65,14 +64,10 @@ export class CustomHttpAgent { arg, canisterId, method: methodName, - nonce, - sender + nonce }: IcrcCallCanisterRequestParams): Promise => { - const hash = nonce - ? await generateHash({canisterId, sender, method: methodName, arg, nonce}) - : null; - - const modifiedMethodName = `${methodName}_nonce_${nonce ?? ''}`; + const modifiedMethodName = `${methodName}::nonce::${nonce ?? ''}`; + this.#agent.addTransform('update', this.customTransform()); const {requestDetails, ...restResponse} = await this.#agent.call(canisterId, { methodName: modifiedMethodName, @@ -80,6 +75,7 @@ export class CustomHttpAgent { // effectiveCanisterId is optional but, actually mandatory according SDK team. effectiveCanisterId: canisterId }); + this.assertRequestDetails(requestDetails); if (isNullish(requestDetails)) { @@ -91,10 +87,6 @@ export class CustomHttpAgent { canisterId }); - if (hash && !this.#cache.has(hash)) { - this.#cache.set(hash, requestDetails.ingress_expiry); - } - // I assume that if we get a result at this point, it means we can respond to the caller. // However, this is not how it's handled in Agent-js. For some reason, regardless of whether they get a result at this point or not, if the response has a status of 202, they overwrite the result with pollForResponse, which seems incorrect. // That is why we return the result if we get one. @@ -219,8 +211,8 @@ export class CustomHttpAgent { private customTransform(): HttpAgentRequestTransformFn { return async (request) => { - const {canister_id, sender, method_name, arg} = request.body; - const [originalMethodName, nonce] = method_name.split('_nonce_'); + const {canister_id, sender, method_name, arg, ingress_expiry} = request.body; + const [originalMethodName, nonce] = method_name.split('::nonce::'); request.body.method_name = originalMethodName; @@ -241,6 +233,7 @@ export class CustomHttpAgent { const cachedExpiry = this.#cache.get(hash); if (!cachedExpiry) { + this.#cache.set(hash, ingress_expiry); return request; } From 376fa286674c6f5d294a49f67ca8926a1a4d0fb5 Mon Sep 17 00:00:00 2001 From: roman-nazaruk Date: Mon, 31 Mar 2025 09:33:19 +0200 Subject: [PATCH 8/8] updated packages --- demo/package-lock.json | 279 +++++++++++++++++------------------------ package-lock.json | 208 +++++++++++++++--------------- package.json | 2 +- 3 files changed, 219 insertions(+), 270 deletions(-) diff --git a/demo/package-lock.json b/demo/package-lock.json index b30f5b3c..67bb5b71 100644 --- a/demo/package-lock.json +++ b/demo/package-lock.json @@ -729,27 +729,27 @@ } }, "node_modules/@dfinity/ledger-icp": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/@dfinity/ledger-icp/-/ledger-icp-2.6.8.tgz", - "integrity": "sha512-5alwvQkTCdb1L918LmrqzHKdDGypJ6VRTkaP915P6Jc5BZEQa4BraJTYE0m1Rck44ld0Hwh0a2uz6lhlphxa9A==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@dfinity/ledger-icp/-/ledger-icp-2.6.11.tgz", + "integrity": "sha512-tug1Gechz9ml4BejVIm/8mXNPL2XcrtRk0Ilxxx7M0P6JAtZ4AfbcG1Q78Y5yIRKflBtdA6sP5WJgtTcz6S6bQ==", "license": "Apache-2.0", "peerDependencies": { "@dfinity/agent": "^2.0.0", "@dfinity/candid": "^2.0.0", "@dfinity/principal": "^2.0.0", - "@dfinity/utils": "^2.10.0" + "@dfinity/utils": "^2.11.0" } }, "node_modules/@dfinity/ledger-icrc": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@dfinity/ledger-icrc/-/ledger-icrc-2.7.3.tgz", - "integrity": "sha512-huJ7+uCbcGmmfGCuBEzkCIog69rVJ0cU5BvUu+3jyIgcx8GJSzq6cRUFLPZ7at/7JRHYT4eSgNHu6LKTMpkYLA==", + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/@dfinity/ledger-icrc/-/ledger-icrc-2.7.6.tgz", + "integrity": "sha512-MjAlVwgWYpIbwoRVdbWsYTlJoJsvRT2ynnoiK5kvkXL3CrHVN3gs99r5hOrKZTXnzjR4P/VzNMPXrUSXU9eJqA==", "license": "Apache-2.0", "peerDependencies": { "@dfinity/agent": "^2.0.0", "@dfinity/candid": "^2.0.0", "@dfinity/principal": "^2.0.0", - "@dfinity/utils": "^2.10.0" + "@dfinity/utils": "^2.11.0" } }, "node_modules/@dfinity/oisy-wallet-signer-demo-relying-party-frontend": { @@ -770,9 +770,9 @@ } }, "node_modules/@dfinity/utils": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@dfinity/utils/-/utils-2.10.0.tgz", - "integrity": "sha512-KDCYpIAkgAE4hK5VTe0XAlDeYxh2fWA5pWkUAD3pe9be0UYbrbojC1M7FoueV228OB9ObBytYKG46kFlKjkumA==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@dfinity/utils/-/utils-2.11.0.tgz", + "integrity": "sha512-meQSoCO/r0oEndAQ0LtWUnDXUHbju9K8UP18tDTMaoEMcMus5qQgZqxeKm7zs5XIpCiymqKSketJKvlhdkdsYQ==", "license": "Apache-2.0", "peerDependencies": { "@dfinity/agent": "^2.0.0", @@ -1497,9 +1497,9 @@ } }, "node_modules/@junobuild/config": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@junobuild/config/-/config-0.1.1.tgz", - "integrity": "sha512-EBZU46Wv80LdXnsX8SkGa9xIkMVFJUF4TDanLT67PeEl/Er+Dqh0bMOfJlbnn8aEFFAEOX/LsX9dUOd7n+QkEQ==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@junobuild/config/-/config-0.1.3.tgz", + "integrity": "sha512-lfuIMEY3c0uoeNI0X1iExxL7XWamWCVsCt9igpYtzwaFT0buYcKMqmVnhU7D0W1TnpyshdTLtpiPa7ctr4esOA==", "dev": true, "license": "MIT" }, @@ -1953,22 +1953,6 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/@playwright/test": { - "version": "1.50.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.50.1.tgz", - "integrity": "sha512-Jii3aBg+CEDpgnuDxEp/h7BimHcUTDlpEtce89xEumlJ5ef2hqepZ+PWp1DDpYC/VO9fmWVI1IlEaoI5fK9FXQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright": "1.50.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@polka/url": { "version": "1.0.0-next.28", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", @@ -2403,13 +2387,6 @@ "tailwindcss": "4.0.15" } }, - "node_modules/@tailwindcss/node/node_modules/tailwindcss": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.7.tgz", - "integrity": "sha512-yH5bPPyapavo7L+547h3c4jcBXcrKwybQRjwdEIVAd9iXRvy/3T1CC6XSQEgZtRySjKfqvo3Cc0ZF1DTheuIdA==", - "dev": true, - "license": "MIT" - }, "node_modules/@tailwindcss/oxide": { "version": "4.0.15", "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.0.15.tgz", @@ -2636,13 +2613,6 @@ "vite": "^5.2.0 || ^6" } }, - "node_modules/@tailwindcss/vite/node_modules/tailwindcss": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.7.tgz", - "integrity": "sha512-yH5bPPyapavo7L+547h3c4jcBXcrKwybQRjwdEIVAd9iXRvy/3T1CC6XSQEgZtRySjKfqvo3Cc0ZF1DTheuIdA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -3261,9 +3231,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", "dev": true, "funding": [ { @@ -3281,11 +3251,11 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", + "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -3438,9 +3408,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, "funding": [ { @@ -3458,10 +3428,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -3569,9 +3539,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001657", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001657.tgz", - "integrity": "sha512-DPbJAlP8/BAXy3IgiWmZKItubb3TYGP0WscQQlVGIfT4s/YlFYVuJgyOsQNP7rJRChx/qdMeLJQJP0Sgg2yjNA==", + "version": "1.0.30001707", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz", + "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==", "dev": true, "funding": [ { @@ -3590,9 +3560,9 @@ "license": "CC-BY-4.0" }, "node_modules/chai": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", - "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", + "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", "dev": true, "license": "MIT", "dependencies": { @@ -3879,6 +3849,7 @@ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, "license": "Apache-2.0", + "optional": true, "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -3924,9 +3895,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.14", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.14.tgz", - "integrity": "sha512-bEfPECb3fJ15eaDnu9LEJ2vPGD6W1vt7vZleSVyFhYuMIKm3vz/g9lt7IvEzgdwj58RjbPKUF2rXTCN/UW47tQ==", + "version": "1.5.128", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.128.tgz", + "integrity": "sha512-bo1A4HH/NS522Ws0QNFIzyPcyUUNV/yyy70Ho1xqfGYzPUme2F/xr4tlEOuM6/A538U1vDA7a4XfCd1CKRegKQ==", "dev": true, "license": "ISC" }, @@ -4146,9 +4117,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -5967,13 +5938,13 @@ } }, "node_modules/lightningcss": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.1.tgz", - "integrity": "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz", + "integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==", "dev": true, "license": "MPL-2.0", "dependencies": { - "detect-libc": "^1.0.3" + "detect-libc": "^2.0.3" }, "engines": { "node": ">= 12.0.0" @@ -5983,22 +5954,22 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-darwin-arm64": "1.29.1", - "lightningcss-darwin-x64": "1.29.1", - "lightningcss-freebsd-x64": "1.29.1", - "lightningcss-linux-arm-gnueabihf": "1.29.1", - "lightningcss-linux-arm64-gnu": "1.29.1", - "lightningcss-linux-arm64-musl": "1.29.1", - "lightningcss-linux-x64-gnu": "1.29.1", - "lightningcss-linux-x64-musl": "1.29.1", - "lightningcss-win32-arm64-msvc": "1.29.1", - "lightningcss-win32-x64-msvc": "1.29.1" + "lightningcss-darwin-arm64": "1.29.2", + "lightningcss-darwin-x64": "1.29.2", + "lightningcss-freebsd-x64": "1.29.2", + "lightningcss-linux-arm-gnueabihf": "1.29.2", + "lightningcss-linux-arm64-gnu": "1.29.2", + "lightningcss-linux-arm64-musl": "1.29.2", + "lightningcss-linux-x64-gnu": "1.29.2", + "lightningcss-linux-x64-musl": "1.29.2", + "lightningcss-win32-arm64-msvc": "1.29.2", + "lightningcss-win32-x64-msvc": "1.29.2" } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz", - "integrity": "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz", + "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==", "cpu": [ "arm64" ], @@ -6017,9 +5988,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.1.tgz", - "integrity": "sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz", + "integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==", "cpu": [ "x64" ], @@ -6038,9 +6009,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.1.tgz", - "integrity": "sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz", + "integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==", "cpu": [ "x64" ], @@ -6059,9 +6030,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.1.tgz", - "integrity": "sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz", + "integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==", "cpu": [ "arm" ], @@ -6080,9 +6051,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.1.tgz", - "integrity": "sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz", + "integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==", "cpu": [ "arm64" ], @@ -6101,9 +6072,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.1.tgz", - "integrity": "sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz", + "integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==", "cpu": [ "arm64" ], @@ -6122,9 +6093,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.1.tgz", - "integrity": "sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz", + "integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==", "cpu": [ "x64" ], @@ -6143,9 +6114,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.1.tgz", - "integrity": "sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz", + "integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==", "cpu": [ "x64" ], @@ -6164,9 +6135,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.1.tgz", - "integrity": "sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz", + "integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==", "cpu": [ "arm64" ], @@ -6185,9 +6156,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz", - "integrity": "sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==", + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz", + "integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==", "cpu": [ "x64" ], @@ -6205,6 +6176,16 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/lightningcss/node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -6388,9 +6369,9 @@ "optional": true }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true, "license": "MIT" }, @@ -6624,9 +6605,9 @@ "peer": true }, "node_modules/pathe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", - "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "dev": true, "license": "MIT" }, @@ -6660,38 +6641,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/playwright": { - "version": "1.50.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.50.1.tgz", - "integrity": "sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright-core": "1.50.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/playwright-core": { - "version": "1.50.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.50.1.tgz", - "integrity": "sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -6704,9 +6653,9 @@ } }, "node_modules/postcss": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", - "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "dev": true, "funding": [ { @@ -6864,9 +6813,9 @@ } }, "node_modules/prettier": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.1.tgz", - "integrity": "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, "license": "MIT", "bin": { @@ -7657,9 +7606,9 @@ } }, "node_modules/svelte-check": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.1.4.tgz", - "integrity": "sha512-v0j7yLbT29MezzaQJPEDwksybTE2Ups9rUxEXy92T06TiA0cbqcO8wAOwNUVkFW6B0hsYHA+oAX3BS8b/2oHtw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.1.5.tgz", + "integrity": "sha512-Gb0T2IqBNe1tLB9EB1Qh+LOe+JB8wt2/rNBDGvkxQVvk8vNeAoG+vZgFB/3P5+zC7RWlyBlzm9dVjZFph/maIg==", "dev": true, "license": "MIT", "dependencies": { @@ -8107,9 +8056,9 @@ "license": "MIT" }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -8127,8 +8076,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" diff --git a/package-lock.json b/package-lock.json index ee65d25b..7320ac3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@types/node": "^22.13.13", "esbuild": "^0.25.1", "jsdom": "^26.0.0", - "prettier": "^3.4.2", + "prettier": "^3.5.3", "prettier-plugin-organize-imports": "^4.1.0", "typescript": "^5.4.5", "vitest": "^3.0.9" @@ -425,9 +425,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", - "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", + "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==", "cpu": [ "ppc64" ], @@ -442,9 +442,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", - "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz", + "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==", "cpu": [ "arm" ], @@ -459,9 +459,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", - "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz", + "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==", "cpu": [ "arm64" ], @@ -476,9 +476,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", - "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz", + "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==", "cpu": [ "x64" ], @@ -493,9 +493,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", - "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz", + "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==", "cpu": [ "arm64" ], @@ -510,9 +510,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", - "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz", + "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==", "cpu": [ "x64" ], @@ -527,9 +527,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", - "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz", + "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==", "cpu": [ "arm64" ], @@ -544,9 +544,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", - "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz", + "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==", "cpu": [ "x64" ], @@ -561,9 +561,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", - "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz", + "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==", "cpu": [ "arm" ], @@ -578,9 +578,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", - "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz", + "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==", "cpu": [ "arm64" ], @@ -595,9 +595,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", - "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz", + "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==", "cpu": [ "ia32" ], @@ -612,9 +612,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", - "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz", + "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==", "cpu": [ "loong64" ], @@ -629,9 +629,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", - "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz", + "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==", "cpu": [ "mips64el" ], @@ -646,9 +646,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", - "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz", + "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==", "cpu": [ "ppc64" ], @@ -663,9 +663,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", - "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz", + "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==", "cpu": [ "riscv64" ], @@ -680,9 +680,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", - "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz", + "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==", "cpu": [ "s390x" ], @@ -697,9 +697,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", - "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz", + "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==", "cpu": [ "x64" ], @@ -714,9 +714,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", - "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz", + "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==", "cpu": [ "arm64" ], @@ -731,9 +731,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", - "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz", + "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==", "cpu": [ "x64" ], @@ -748,9 +748,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", - "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz", + "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==", "cpu": [ "arm64" ], @@ -765,9 +765,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", - "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz", + "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==", "cpu": [ "x64" ], @@ -782,9 +782,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", - "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz", + "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==", "cpu": [ "x64" ], @@ -799,9 +799,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", - "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz", + "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==", "cpu": [ "arm64" ], @@ -816,9 +816,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", - "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz", + "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==", "cpu": [ "ia32" ], @@ -833,9 +833,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", - "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz", + "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==", "cpu": [ "x64" ], @@ -2919,9 +2919,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", - "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz", + "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -2932,31 +2932,31 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.0", - "@esbuild/android-arm": "0.25.0", - "@esbuild/android-arm64": "0.25.0", - "@esbuild/android-x64": "0.25.0", - "@esbuild/darwin-arm64": "0.25.0", - "@esbuild/darwin-x64": "0.25.0", - "@esbuild/freebsd-arm64": "0.25.0", - "@esbuild/freebsd-x64": "0.25.0", - "@esbuild/linux-arm": "0.25.0", - "@esbuild/linux-arm64": "0.25.0", - "@esbuild/linux-ia32": "0.25.0", - "@esbuild/linux-loong64": "0.25.0", - "@esbuild/linux-mips64el": "0.25.0", - "@esbuild/linux-ppc64": "0.25.0", - "@esbuild/linux-riscv64": "0.25.0", - "@esbuild/linux-s390x": "0.25.0", - "@esbuild/linux-x64": "0.25.0", - "@esbuild/netbsd-arm64": "0.25.0", - "@esbuild/netbsd-x64": "0.25.0", - "@esbuild/openbsd-arm64": "0.25.0", - "@esbuild/openbsd-x64": "0.25.0", - "@esbuild/sunos-x64": "0.25.0", - "@esbuild/win32-arm64": "0.25.0", - "@esbuild/win32-ia32": "0.25.0", - "@esbuild/win32-x64": "0.25.0" + "@esbuild/aix-ppc64": "0.25.2", + "@esbuild/android-arm": "0.25.2", + "@esbuild/android-arm64": "0.25.2", + "@esbuild/android-x64": "0.25.2", + "@esbuild/darwin-arm64": "0.25.2", + "@esbuild/darwin-x64": "0.25.2", + "@esbuild/freebsd-arm64": "0.25.2", + "@esbuild/freebsd-x64": "0.25.2", + "@esbuild/linux-arm": "0.25.2", + "@esbuild/linux-arm64": "0.25.2", + "@esbuild/linux-ia32": "0.25.2", + "@esbuild/linux-loong64": "0.25.2", + "@esbuild/linux-mips64el": "0.25.2", + "@esbuild/linux-ppc64": "0.25.2", + "@esbuild/linux-riscv64": "0.25.2", + "@esbuild/linux-s390x": "0.25.2", + "@esbuild/linux-x64": "0.25.2", + "@esbuild/netbsd-arm64": "0.25.2", + "@esbuild/netbsd-x64": "0.25.2", + "@esbuild/openbsd-arm64": "0.25.2", + "@esbuild/openbsd-x64": "0.25.2", + "@esbuild/sunos-x64": "0.25.2", + "@esbuild/win32-arm64": "0.25.2", + "@esbuild/win32-ia32": "0.25.2", + "@esbuild/win32-x64": "0.25.2" } }, "node_modules/escape-string-regexp": { diff --git a/package.json b/package.json index aa1b7465..836014db 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "@types/node": "^22.13.13", "esbuild": "^0.25.1", "jsdom": "^26.0.0", - "prettier": "^3.4.2", + "prettier": "^3.5.3", "prettier-plugin-organize-imports": "^4.1.0", "typescript": "^5.4.5", "vitest": "^3.0.9"