From cfeeb98d053ea255c4983ced9ab11719ce4966a3 Mon Sep 17 00:00:00 2001 From: Cristian Velasquez Ramos Date: Tue, 9 May 2023 19:37:51 -0400 Subject: [PATCH] add onError, onSuccess, CacheClient (like tanstack-query),CacheClient Provider, and CacheClientOptionsProvider --- .changeset/README.md | 8 + .changeset/blue-fireants-move.md | 5 + .changeset/config.json | 11 + .github/workflows/main.yml | 20 + .github/workflows/publish.yml | 30 + lib/cache-client.test.tsx | 829 ++++++++++++++++ lib/cache-client.tsx | 481 +++++++++ lib/cache.ts | 177 +++- lib/hooks.ts | 78 +- lib/index.ts | 16 +- lib/types.ts | 131 ++- lib/utils.ts | 18 +- package.json | 7 +- pnpm-lock.yaml | 1596 +++++++++++++++++++++++++++++- 14 files changed, 3262 insertions(+), 145 deletions(-) create mode 100644 .changeset/README.md create mode 100644 .changeset/blue-fireants-move.md create mode 100644 .changeset/config.json create mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/publish.yml create mode 100644 lib/cache-client.test.tsx create mode 100644 lib/cache-client.tsx diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..e5b6d8d --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/blue-fireants-move.md b/.changeset/blue-fireants-move.md new file mode 100644 index 0000000..23a4080 --- /dev/null +++ b/.changeset/blue-fireants-move.md @@ -0,0 +1,5 @@ +--- +"pausa": minor +--- + +add onError, onSuccess, CacheClient (like tanstack-query),CacheClient Provider, and CacheClientOptionsProvider diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..cee6df8 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..d777c54 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,20 @@ +name: CI +on: + push: + branches: + - "**" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 7 + - uses: actions/setup-node@v3 + with: + node-version: 18.16.0 + cache: "pnpm" + + - run: pnpm install --frozen-lockfile diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..fcbcedb --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,30 @@ +name: Publish +on: + push: + branches: + - "main" + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2 + with: + version: 7 + - uses: actions/setup-node@v3 + with: + node-version: 18.16.0 + cache: "pnpm" + + - run: pnpm install --frozen-lockfile + - name: Create Release Pull Request or Publish + id: changesets + uses: changesets/action@v1 + with: + publish: pnpm run release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/lib/cache-client.test.tsx b/lib/cache-client.test.tsx new file mode 100644 index 0000000..eaf3040 --- /dev/null +++ b/lib/cache-client.test.tsx @@ -0,0 +1,829 @@ +import * as React from "react"; +import { createRoot } from "react-dom/client"; +import { act } from "react-dom/test-utils"; +import { + CacheProvider, + MissingLoaderError, + CacheClient, + CacheClientOptions, + makeCacheKey, + CacheOptionsProvider, +} from "./cache-client"; +import { ErrorBoundary } from "./test-utils"; +import { + CacheLoadContext, + CacheStatus, + Deferred, + MutationStatus, +} from "./types"; +import { defer, isPromiseLike } from "./utils"; + +describe("CacheClient", () => { + let container: HTMLDivElement | undefined; + const key = "key"; + + let onSuccess = vi.fn(); + let onError = vi.fn(); + let client = new CacheClient({ + onSuccess, + onError, + }); + + let lastThrownError: Error | undefined; + let suspenseCount = 0; + let renderCount = 0; + + function Fallback() { + suspenseCount++; + return null; + } + + async function mount(component: React.ReactNode) { + container = document.createElement("div"); + const root = createRoot(container); + await act(async () => { + root.render( + + { + lastThrownError = e; + }} + > + }>{component} + + + ); + }); + } + + beforeEach(() => { + // @ts-ignore + global.IS_REACT_ACT_ENVIRONMENT = true; + + lastThrownError = undefined; + suspenseCount = 0; + renderCount = 0; + + onSuccess = vi.fn(); + onError = vi.fn(); + client = new CacheClient({ + onSuccess, + onError, + }); + }); + + describe("options", () => { + it("should prime the cache with the default options", async () => { + let key1Load = vi.fn(async () => "value1"); + let key2Load = vi.fn(async () => "value2"); + let key3Load = vi.fn(async () => "value3"); + let primer: CacheClientOptions["primer"] = { + key1: { + load: key1Load, + }, + key2: { + load: key2Load, + }, + key3: { + load: key3Load, + }, + }; + + let client = new CacheClient({ + primer, + }); + + expect(client.cacheMap.size).toBe(3); + expect(client.cacheMap.get("key1")).toBeDefined(); + expect(isPromiseLike(client.get(["key1"]))).toBe(true); + expect(key1Load).toHaveBeenCalled(); + + key1Load = vi.fn(async () => "value1"); + key2Load = vi.fn(async () => "value2"); + key3Load = vi.fn(async () => "value3"); + + primer = { + key1: { + load: key1Load, + initialData: "value1", + }, + key2: { + load: key2Load, + initialData: "value2", + }, + key3: { + load: key3Load, + initialData: "value3", + }, + }; + + client = new CacheClient({ + primer, + }); + + expect(client.cacheMap.size).toBe(3); + expect(client.cacheMap.get("key1")).toBeDefined(); + expect(client.get(["key1"])).toBe("value1"); + expect(key1Load).not.toHaveBeenCalled(); + }); + + it("should prime the cache with non simple keys", async () => { + let load = vi.fn(async () => "value"); + const key = ["key1", { id: 1 }] as const; + let primer: CacheClientOptions["primer"] = { + [makeCacheKey(key)]: { + load, + initialData: "value1", + }, + }; + + let client = new CacheClient({ + primer, + }); + + expect(client.cacheMap.size).toBe(1); + expect(client.get(key)).toBe("value1"); + }); + }); + + describe("suspend", () => { + let lastRenderedValue: string | undefined; + beforeEach(() => { + lastRenderedValue = undefined; + }); + + function Component({ fn }: { fn?: () => Promise }) { + const value = client.suspend([key], { + load: fn, + }); + lastRenderedValue = value; + renderCount++; + return null; + } + + it("should trigger the onSuccess callback when the cache item loads successfully", async () => { + const deferred = defer(); + const trigger = () => deferred.resolve("value"); + await mount( deferred.promise} />); + expect(lastRenderedValue).toBeUndefined(); + expect(suspenseCount).toBe(1); + expect(onSuccess).not.toHaveBeenCalled(); + await act(async () => { + trigger(); + }); + expect(lastRenderedValue).toBe("value"); + expect(onSuccess).toHaveBeenCalledWith("value"); + }); + + it("should suspend when cache is missing", async () => { + const deferred = defer(); + const trigger = () => deferred.resolve("value"); + await mount( deferred.promise} />); + expect(lastRenderedValue).toBeUndefined(); + expect(suspenseCount).toBe(1); + await act(async () => { + trigger(); + }); + expect(lastRenderedValue).toBe("value"); + }); + + it("should not update if the cache is updated", async () => { + const deferred = defer(); + const trigger = () => deferred.resolve("value"); + const load = () => deferred.promise; + await mount(); + expect(lastRenderedValue).toBeUndefined(); + expect(suspenseCount).toBe(1); + await act(async () => { + trigger(); + }); + expect(lastRenderedValue).toBe("value"); + const cache = client.cacheMap.get(key); + await act(async () => { + cache!.set("value2"); + }); + expect(lastRenderedValue).toBe("value"); + expect(suspenseCount).toBe(1); + expect(renderCount).toBe(1); + }); + + it("should return a cached value for a key if it exists without a load function", async () => { + const deferred = defer(); + const trigger = () => deferred.resolve("value"); + await mount( deferred.promise} />); + expect(lastRenderedValue).toBeUndefined(); + expect(suspenseCount).toBe(1); + await act(async () => { + trigger(); + }); + expect(lastRenderedValue).toBe("value"); + + await mount(); + expect(lastRenderedValue).toBe("value"); + expect(suspenseCount).toBe(1); + expect(renderCount).toBe(2); + }); + + it("should should throw a CacheMissingLoaderError for a given key if no load function exists", async () => { + let old = console.error; + console.error = () => {}; + await mount(); + expect(lastRenderedValue).toBe(undefined); + expect(lastThrownError).toEqual(new MissingLoaderError(key).message); + expect(suspenseCount).toBe(0); + expect(renderCount).toBe(0); + console.error = old; + }); + + it("should render the error boundary if the load function throws", async () => { + let old = console.error; + console.error = () => {}; + const load = async () => { + throw new Error("error"); + }; + await mount(); + expect(lastRenderedValue).toBeUndefined(); + expect(lastThrownError).toEqual("error"); + console.error = old; + }); + }); + + describe("read", () => { + let lastRenderedValue: [string, boolean] | undefined; + beforeEach(() => { + lastRenderedValue = undefined; + }); + + function Component({ fn }: { fn?: () => Promise }) { + const value = client.read([key], { + load: fn, + }); + lastRenderedValue = value; + renderCount++; + return null; + } + + it("should suspend when cache is missing", async () => { + const deferred = defer(); + const trigger = () => deferred.resolve("value"); + await mount( deferred.promise} />); + expect(lastRenderedValue).toBeUndefined(); + expect(suspenseCount).toBe(1); + await act(async () => { + trigger(); + }); + expect(lastRenderedValue).toEqual(["value", false]); + }); + + it("should update if the cache is updated", async () => { + let deferred: Deferred; + const trigger = () => deferred.resolve("value"); + const load = vi.fn(() => { + deferred = defer(); + return deferred.promise; + }); + await mount(); + expect(lastRenderedValue).toBeUndefined(); + expect(suspenseCount).toBe(1); + await act(async () => { + trigger(); + }); + expect(lastRenderedValue).toEqual(["value", false]); + const cache = client.cacheMap.get(key); + + await act(async () => { + cache!.invalidate(); + }); + expect(lastRenderedValue).toEqual(["value", true]); + await act(async () => { + deferred.resolve("value2"); + }); + + expect(lastRenderedValue).toEqual(["value2", false]); + }); + + it("should return a cached value for a key if it exists without a load function", async () => { + const deferred = defer(); + const trigger = () => deferred.resolve("value"); + await mount( deferred.promise} />); + expect(lastRenderedValue).toBeUndefined(); + expect(suspenseCount).toBe(1); + await act(async () => { + trigger(); + }); + expect(lastRenderedValue).toEqual(["value", false]); + + await mount(); + expect(lastRenderedValue).toEqual(["value", false]); + }); + + it("should should throw a CacheMissingLoaderError for a given key if no load function exists", async () => { + let old = console.error; + console.error = () => {}; + await mount(); + expect(lastRenderedValue).toBe(undefined); + expect(lastThrownError).toEqual(new MissingLoaderError(key).message); + expect(suspenseCount).toBe(0); + expect(renderCount).toBe(0); + console.error = old; + }); + + it("should render the error boundary if the load function throws", async () => { + let old = console.error; + console.error = () => {}; + const load = async () => { + throw new Error("error"); + }; + await mount(); + expect(lastRenderedValue).toBeUndefined(); + expect(lastThrownError).toEqual("error"); + console.error = old; + }); + }); + + describe("useMutation", () => { + const numberKey = "cacheNumber"; + const stringKey = "cacheString"; + let load = vi.fn(async (_: CacheLoadContext) => { + const deferred = defer(); + + pendingDeferred.push(deferred); + + return deferred.promise; + }); + let client = new CacheClient({ + primer: { + [stringKey]: { load }, + [numberKey]: { load }, + }, + }); + + let container: HTMLDivElement | null = null; + + let pendingDeferred: Deferred[] = []; + + beforeEach(() => { + // @ts-ignore + global.IS_REACT_ACT_ENVIRONMENT = true; + + load = vi.fn(async (_: CacheLoadContext) => { + const deferred = defer(); + + pendingDeferred.push(deferred); + + return deferred.promise; + }); + + client = new CacheClient({ + primer: { + [stringKey]: { load }, + [numberKey]: { load }, + }, + }); + + container = null; + pendingDeferred = []; + }); + + async function mount(component: React.ReactNode) { + container = document.createElement("div"); + const root = createRoot(container); + await act(async () => { + root.render({component}); + }); + } + + it("should return the correct status", async () => { + let status: MutationStatus | undefined = undefined; + let trigger: (() => Promise) | undefined = undefined; + let reset: (() => void) | undefined = undefined; + + const deferredMutator = defer(); + + function Component(): any { + let result = client.useMutation( + [[stringKey]], + () => deferredMutator.promise + ); + + status = result.status; + trigger = result.trigger; + reset = result.reset; + + return null; + } + + await mount(); + + expect(status).toBe(MutationStatus.IDLE); + + await act(async () => { + trigger!(); + }); + + expect(status).toBe(MutationStatus.PENDING); + + await act(async () => { + deferredMutator.resolve(); + }); + + expect(status).toBe(MutationStatus.RESOLVED); + await act(async () => { + reset!(); + }); + + expect(status).toBe(MutationStatus.IDLE); + }); + + it("should invalidate the provided caches on successful mutation", async () => { + let status: MutationStatus | undefined = undefined; + let trigger: (() => Promise) | undefined = undefined; + + const deferredMutator = defer(); + + client.set("1", [stringKey]); + client.set(1, [numberKey]); + + function Component(): any { + let result = client.useMutation( + [[stringKey], [numberKey]], + () => deferredMutator.promise + ); + + status = result.status; + trigger = result.trigger; + + return null; + } + + await mount(); + + expect(status).toBe(MutationStatus.IDLE); + + await act(async () => { + trigger!(); + }); + + expect(status).toBe(MutationStatus.PENDING); + + await act(async () => { + deferredMutator.resolve(); + }); + + expect(status).toBe(MutationStatus.RESOLVED); + + expect(client.getStatus([stringKey])).toBe(CacheStatus.REVALIDATING); + expect(client.getStatus([numberKey])).toBe(CacheStatus.REVALIDATING); + }); + + it("should not invalidate the provided caches on failed mutation", async () => { + let status: MutationStatus | undefined = undefined; + let trigger: (() => Promise) | undefined = undefined; + + const deferredMutator = defer(); + + client.set("1", [stringKey]); + client.set(1, [numberKey]); + + function Component(): any { + let result = client.useMutation( + [[stringKey], [numberKey]], + () => deferredMutator.promise + ); + + status = result.status; + trigger = result.trigger; + + return null; + } + + await mount(); + + expect(status).toBe(MutationStatus.IDLE); + + await act(async () => { + trigger!().catch(() => {}); + }); + + expect(status).toBe(MutationStatus.PENDING); + + await act(async () => { + deferredMutator.reject("reject"); + }); + + expect(status).toBe(MutationStatus.REJECTED); + + expect(client.getStatus([stringKey])).toBe(CacheStatus.RESOLVED); + expect(client.getStatus([numberKey])).toBe(CacheStatus.RESOLVED); + }); + + it("should update the provided update caches with the result of the mutation", async () => { + let status: MutationStatus | undefined = undefined; + let trigger: (() => Promise) | undefined = undefined; + + const deferredMutator = defer(); + + client.set("1", [stringKey]); + client.set(1, [numberKey]); + + function Component(): any { + let result = client.useMutation( + [[stringKey], [numberKey]], + () => deferredMutator.promise, + { + updates: [[stringKey]], + } + ); + + status = result.status; + trigger = result.trigger; + + return null; + } + + await mount(); + + expect(status).toBe(MutationStatus.IDLE); + + await act(async () => { + trigger!(); + }); + + expect(status).toBe(MutationStatus.PENDING); + + await act(async () => { + deferredMutator.resolve("resolved"); + }); + + expect(status).toBe(MutationStatus.RESOLVED); + + expect(client.get([stringKey])).toBe("resolved"); + expect(client.get([numberKey])).toBe(1); + }); + + it("should optimistically update the provided update caches with the provided value", async () => { + let status: MutationStatus | undefined = undefined; + let trigger: (() => Promise) | undefined = undefined; + + const deferredMutator = defer(); + + client.set("1", [stringKey]); + client.set(1, [numberKey]); + + function MutatingComponent(): any { + let result = client.useMutation( + [[stringKey], [numberKey]], + () => deferredMutator.promise, + { + updates: [[stringKey]], + optimisticData: "optimistic", + } + ); + + status = result.status; + trigger = result.trigger; + + return null; + } + + let lastRenderedValue: string | undefined = undefined; + let renderCount = 0; + function CacheReadingComponent(): any { + const key = [stringKey] as const; + let [value] = client.read([stringKey]); + lastRenderedValue = value; + renderCount++; + return null; + } + + await mount( + <> + + + + + + ); + + expect(status).toBe(MutationStatus.IDLE); + + await act(async () => { + trigger!(); + }); + + expect(status).toBe(MutationStatus.PENDING); + expect(lastRenderedValue).toBe("optimistic"); + expect(renderCount).toBe(2); + + expect(client.get([stringKey])).toBe("optimistic"); + + expect(client.get([numberKey])).toBe(1); + + await act(async () => { + deferredMutator.resolve("new-value"); + }); + + expect(status).toBe(MutationStatus.RESOLVED); + + expect(client.get([stringKey])).toBe("new-value"); + expect(client.get([numberKey])).toBe(1); + + expect(lastRenderedValue).toBe("new-value"); + expect(renderCount).toBe(3); + }); + + it("should rollback the provided update caches on a failed mutation with an optimistic update", async () => { + let status: MutationStatus | undefined = undefined; + let trigger: (() => Promise) | undefined = undefined; + + const deferredMutator = defer(); + + client.set("1", [stringKey]); + client.set(1, [numberKey]); + + function Component(): any { + let result = client.useMutation( + [[stringKey], [numberKey]], + () => deferredMutator.promise, + { + updates: [[stringKey]], + optimisticData: "optimistic", + } + ); + + status = result.status; + trigger = result.trigger; + + return null; + } + + await mount(); + + expect(status).toBe(MutationStatus.IDLE); + + await act(async () => { + trigger!().catch(() => {}); + }); + + expect(status).toBe(MutationStatus.PENDING); + + expect(client.get([stringKey])).toBe("optimistic"); + expect(client.get([numberKey])).toBe(1); + + await act(async () => { + deferredMutator.reject("rejected"); + }); + + expect(status).toBe(MutationStatus.REJECTED); + + expect(client.get([stringKey])).toBe("1"); + expect(client.get([numberKey])).toBe(1); + }); + + it("should invalidate instead of rollback the provided caches with an optimistic update on a failed mutation if the original status was not resolved", async () => { + const promise = client.get([stringKey]); + + pendingDeferred[0]!.reject("rejected"); + await (promise as Promise).catch(() => {}); + + expect(client.getStatus([stringKey])).toBe(CacheStatus.REJECTED); + + let status: MutationStatus | undefined = undefined; + let trigger: (() => Promise) | undefined = undefined; + + const deferredMutator = defer(); + + function Component(): any { + let result = client.useMutation( + [[stringKey]], + () => deferredMutator.promise, + { + updates: [[stringKey]], + optimisticData: "optimistic", + } + ); + + status = result.status; + trigger = result.trigger; + + return null; + } + + await mount(); + + expect(status).toBe(MutationStatus.IDLE); + + await act(async () => { + trigger!().catch(() => {}); + }); + + expect(status).toBe(MutationStatus.PENDING); + expect(client.getStatus([stringKey])).toBe(CacheStatus.RESOLVED); + + await act(async () => { + deferredMutator.reject("rejected"); + }); + + expect(status).toBe(MutationStatus.REJECTED); + + expect(client.getStatus([stringKey])).toBe(CacheStatus.REVALIDATING); + }); + }); + + describe("CacheOptionsProvider", () => { + let load = vi.fn(async () => "value"); + let onError = vi.fn(); + let onSuccess = vi.fn(); + let getCache = vi.fn(() => new Map()); + let client = new CacheClient({ + primer: { + key: { + load, + }, + }, + onError, + onSuccess, + getCache, + }); + + async function mount(component: React.ReactNode) { + container = document.createElement("div"); + const root = createRoot(container); + await act(async () => { + root.render( + + { + lastThrownError = e; + console.log(e); + }} + > + {component} + + + ); + }); + } + + function Suspender() { + suspenseCount++; + return null; + } + + function Component() { + const value = client.suspend(["key"]); + + return
{value}
; + } + + beforeEach(() => { + load = vi.fn(async () => "value"); + onError = vi.fn(); + onSuccess = vi.fn(); + getCache = vi.fn(() => new Map()); + client = new CacheClient({ + primer: { + key: { + load, + }, + }, + onError, + onSuccess, + getCache, + }); + }); + it("should provide the cache options, overriding the default ones", async () => { + let ownLoad = vi.fn(async () => "ownValue"); + let ownOnError = vi.fn(); + let ownOnSuccess = vi.fn(); + let ownGetCache = vi.fn(() => new Map()); + + await mount( + + }> + + + + ); + + expect(load).not.toHaveBeenCalled(); + expect(ownLoad).toHaveBeenCalled(); + expect(onError).not.toHaveBeenCalled(); + expect(ownOnError).not.toHaveBeenCalled(); + expect(onSuccess).not.toHaveBeenCalled(); + expect(ownOnSuccess).toHaveBeenCalled(); + expect(ownGetCache).toHaveBeenCalled(); + }); + }); +}); diff --git a/lib/cache-client.tsx b/lib/cache-client.tsx new file mode 100644 index 0000000..edb6fb6 --- /dev/null +++ b/lib/cache-client.tsx @@ -0,0 +1,481 @@ +import * as React from "react"; + +import { cache, SuspenseCache } from "./cache"; +import { + CacheLoadContext, + CacheStatus, + CacheValueResult, + MutationStatus, + SuspenseCacheOptions, +} from "./types"; +import { useMutation as _useMutation } from "./hooks"; + +type Params = readonly [key: string, ...params: any[]]; + +export type CacheClientOptions = { + primer?: Record< + string, + Partial< + Omit + > & { + load: ( + ctx: CacheLoadContext, + ...args: any[] + ) => PromiseLike | unknown; + initialData?: unknown; + } + >; +} & Partial>; + +type CacheDefaults = Partial>; + +export class CacheClient { + readonly loadMap: WeakMap<(...params: any[]) => any, SuspenseCache> = + new WeakMap(); + readonly cacheMap: Map; + readonly cacheDefaults?: CacheDefaults; + + constructor({ primer, ...cacheDefaults }: CacheClientOptions = {}) { + const cacheMap = new Map(); + if (primer) { + Object.entries(primer).forEach(([k, { load, ...options }]) => { + const [key, ...args] = decodeKey(k); + + const suspenseCache = cache(load, { + ...cacheDefaults, + ...options, + } satisfies Partial); + cacheMap.set(key, suspenseCache); + if (options.initialData) { + suspenseCache.set(options.initialData, ...args); + } + }); + } + this.cacheMap = cacheMap; + this.cacheDefaults = cacheDefaults; + } + + invalidate(params: Params): void { + const [key, ...args] = params; + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.invalidate(...args); + } + throw new CacheMissing(key); + } + + invalidateAll(): void { + this.cacheMap.forEach((cache) => cache.invalidateAll()); + } + + peek(params: Params): T | undefined { + const [key, ...args] = params; + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.peek(...args) as T | undefined; + } + throw new CacheMissing(key); + } + + getStatus(params: Params): CacheStatus { + const [key, ...args] = params; + + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.getStatus(...args); + } + + throw new CacheMissing(key); + } + + subscribeToStatus( + params: Params, + callback: (status: CacheStatus) => void + ): () => void { + const [key, ...args] = params; + + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.subscribeToStatus(callback, ...args); + } + throw new CacheMissing(key); + } + + get(params: Params): PromiseLike | T { + const [key, ...args] = params; + + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.get(...args) as PromiseLike | T; + } + throw new CacheMissing(key); + } + + set(value: unknown, params: Params): void { + const [key, ...args] = params; + + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.set(value, ...args); + } + throw new CacheMissing(key); + } + + has(params: Params): boolean { + const [key, ...args] = params; + + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.has(...args); + } + throw new CacheMissing(key); + } + + clear(key: string): void { + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.clear(); + } + + throw new CacheMissing(key); + } + + delete(params: Params): boolean { + const [key, ...args] = params; + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.delete(...args); + } + + throw new CacheMissing(key); + } + + deleteIf(params: Params, predicate: (value: unknown) => boolean): boolean { + const [key, ...args] = params; + + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.deleteIf(predicate, ...args); + } + + throw new CacheMissing(key); + } + + preload(params: Params): void { + const [key, ...args] = params; + + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.preload(...args); + } + + throw new CacheMissing(key); + } + + abort(params: Params): boolean { + const [key, ...args] = params; + + const maybeCache = this.cacheMap.get(key); + if (maybeCache) { + return maybeCache.abort(...args); + } + throw new CacheMissing(key); + } + + read( + params: TParams, + { + load, + ..._options + }: Partial< + Omit + > & { + load?: ( + ctx: CacheLoadContext, + ...args: ExtractArgs + ) => T | PromiseLike; + } = {} + ): [T, boolean] { + const client = this; + const defaults = useCacheDefaults(); + const options = { + ...defaults, + ..._options, + }; + const [key, ...args] = params; + + if (!load) { + const maybeCache = client.cacheMap.get(key); + if (maybeCache) { + return maybeCache.read(...args) as [T, boolean]; + } + + throw new MissingLoaderError(key); + } + const loadCache = this.loadMap.get(load); + if (loadCache) { + return loadCache.read(...args) as [T, boolean]; + } + + const suspenseCache = cache(load, options); + + // @ts-expect-error + client.cacheMap.set(key, suspenseCache); + // @ts-expect-error + client.loadMap.set(load, suspenseCache); + + return suspenseCache.read(...args) as [T, boolean]; + } + + suspend( + params: TParams, + { + load, + ..._options + }: Partial< + Omit + > & { + load?: ( + ctx: CacheLoadContext, + ...args: ExtractArgs + ) => T | PromiseLike; + } = {} + ): T { + const client = this; + const defaults = useCacheDefaults(); + const options = { + ...defaults, + ..._options, + }; + const [key, ...args] = params; + + if (!load) { + const maybeCache = client.cacheMap.get(key); + if (maybeCache) { + return maybeCache.suspend(...args) as T; + } + + throw new MissingLoaderError(key); + } + + const loadCache = this.loadMap.get(load); + if (loadCache) { + return loadCache.suspend(...args) as T; + } + + const suspenseCache = cache(load, options); + + // @ts-expect-error + client.cacheMap.set(key, suspenseCache); + // @ts-expect-error + client.loadMap.set(load, suspenseCache); + + return suspenseCache.suspend(...args) as T; + } + + useStatus(params: Params): CacheStatus { + const client = this; + const [key, ...args] = params; + + const maybeCache = client.cacheMap.get(key); + if (!maybeCache) { + return CacheStatus.MISSING; + } + return maybeCache.useStatus(...args); + } + + useValue( + params: TParams, + { + load, + ..._options + }: Partial< + Omit + > & { + load?: ( + ctx: CacheLoadContext, + ...args: ExtractArgs + ) => T | PromiseLike; + } = {} + ): CacheValueResult { + const client = this; + const defaults = useCacheDefaults(); + const options = { + ...defaults, + ..._options, + }; + const [key, ...args] = params; + + if (!load) { + const maybeCache = client.cacheMap.get(key); + if (maybeCache) { + return maybeCache.useValue(...args) as CacheValueResult; + } + + throw new MissingLoaderError(key); + } + + const loadCache = this.loadMap.get(load); + + if (loadCache) { + return loadCache.useValue(...args) as CacheValueResult; + } + + const suspenseCache = cache(load, options); + + // @ts-expect-error + client.cacheMap.set(key, suspenseCache); + // @ts-expect-error + client.loadMap.set(load, suspenseCache); + + return suspenseCache.useValue(...(params as any)) as CacheValueResult; + } + + useMutation< + TValue, + TParams extends any[], + TMutationResult extends TValue | void + >( + keys: Params[], + mutator: (...params: TParams) => Promise, + options?: { + updates: Params[]; + optimisticData?: TValue; + } + ): { + status: MutationStatus; + trigger: (...params: TParams) => Promise; + reset: () => void; + } { + const makeClosuredCacheForKey = useMakeClosuredCacheForKey(); + return _useMutation( + keys.map((key) => makeClosuredCacheForKey(key)), + mutator, + options + ? { + ...options, + updates: options?.updates?.map((key) => + makeClosuredCacheForKey(key) + ), + } + : undefined + ); + } +} + +export class MissingLoaderError extends Error { + constructor(key: string) { + super(`Cache missing loader for key: ${key}`); + } +} + +export class CacheMissing extends Error { + constructor(key: string) { + super(`Cache missing for key: ${key}`); + } +} + +const CacheContext = React.createContext(new CacheClient()); +const CacheOptionsContext = React.createContext( + undefined +); + +export function CacheProvider({ + children, + client, +}: { + children: React.ReactNode; + client: CacheClient; +}) { + return ( + {children} + ); +} + +let weakSet: WeakSet = new WeakSet(); + +export function CacheOptionsProvider({ + children, + options: { primer, ...cacheDefaults }, +}: { + children: React.ReactNode; + options: CacheClientOptions; +}) { + const client = useCacheClient(); + React.useState(() => { + if (primer && !weakSet.has(primer)) { + Object.entries(primer).forEach(([k, { load, ...options }]) => { + const [key, ...args] = decodeKey(k); + + const suspenseCache = cache(load, { + ...client.cacheDefaults, + ...cacheDefaults, + ...options, + }); + client.cacheMap.set(key, suspenseCache); + if (options.initialData) { + suspenseCache.set(options.initialData, ...args); + } + }); + + weakSet.add(primer); + } + }); + + return ( + + {children} + + ); +} + +export function useCacheClient(): CacheClient { + return React.useContext(CacheContext); +} + +function useCacheDefaults(): CacheDefaults { + const client = useCacheClient(); + return { ...client.cacheDefaults, ...React.useContext(CacheOptionsContext) }; +} + +export function useMakeClosuredCacheForKey(): (key: Params) => { + id: string; + getStatus: () => CacheStatus; + subscribeToStatus: (callback: () => void) => () => void; + suspend: () => any; + invalidate: () => void; + peek: () => any; + set: (value: any) => void; +} { + const client = useCacheClient(); + return (key: Params) => ({ + id: makeCacheKey(key), + getStatus: () => client.getStatus(key), + subscribeToStatus: (callback: () => void) => + client.subscribeToStatus(key, callback), + suspend: () => client.suspend(key), + invalidate: () => client.invalidate(key), + peek: () => client.peek(key), + set: (value: any) => client.set(value, key), + }); +} + +const delimiter = ":@:"; + +export function makeCacheKey(params: Params): string { + const args = params; + return args.map((x) => JSON.stringify(x)).join(delimiter); +} + +function decodeKey(key: string): Params { + if (!key.includes(delimiter)) { + return [key]; + } + return key.split(delimiter).map((x) => { + return JSON.parse(x); + }) as any; +} + +type ExtractArgs = T extends readonly [infer _Key, ...infer Args] + ? Args + : never; diff --git a/lib/cache.ts b/lib/cache.ts index cbedb2f..5baf54c 100644 --- a/lib/cache.ts +++ b/lib/cache.ts @@ -1,9 +1,9 @@ /* eslint-disable react-hooks/rules-of-hooks */ /* eslint-disable @typescript-eslint/no-floating-promises */ -import * as React from 'react'; +import * as React from "react"; -import { useForceUpdate } from './hooks'; -import { CacheRecord, CacheStatus } from './types'; +import { useForceUpdate } from "./hooks"; +import { CacheRecord, CacheStatus } from "./types"; import type { CacheLoadContext, CacheMap, @@ -15,12 +15,16 @@ import type { SubscribeCallback, SuspenseCacheOptions, UnsubscribeFromCacheStatusFunction, -} from './types'; -import { isPromiseLike } from './utils'; +} from "./types"; +import { cacheKeyDelimiter, isPromiseLike } from "./utils"; // this acts as a cache for the results of the fetchValue function // with the key being the args passed to the fetchValue function -export class SuspenseCache { +export class SuspenseCache< + TParams extends any[] = any[], + TError = unknown, + TValue = unknown +> { private recordCache: CacheMap>; // this is used to store the args for a given cache key after a load has been triggered // to be used when invalidateAll is called @@ -36,7 +40,10 @@ export class SuspenseCache { this.debugLog = (...args: any[]) => { if (this.options.debug) { // eslint-disable-next-line no-console - console.log(`SuspenseCache(${this.options.debugLabel ?? this.options.load.name})`, ...args); + console.log( + `SuspenseCache(${this.options.debugLabel ?? this.options.load.name})`, + ...args + ); } }; } @@ -58,7 +65,10 @@ export class SuspenseCache { if (!record) { record = CacheRecord.makePending(); - this.debugLog('getOrCreateRecord():: record created', { cacheKey, record }); + this.debugLog("getOrCreateRecord():: record created", { + cacheKey, + record, + }); this.recordCache.set(cacheKey, record); @@ -66,7 +76,10 @@ export class SuspenseCache { this.loadValue(cacheKey, record, ...args); } else { - this.debugLog('getOrCreateRecord():: record returned', { cacheKey, record }); + this.debugLog("getOrCreateRecord():: record returned", { + cacheKey, + record, + }); } return record; @@ -74,28 +87,38 @@ export class SuspenseCache { private async loadValue( cacheKey: string, - record: PendingCacheRecord | RevalidatingCacheRecord, + record: + | PendingCacheRecord + | RevalidatingCacheRecord, ...args: TParams ): Promise { this.invalidationArgs.set(cacheKey, args); const signal = record.data.controller.signal; try { const valueOrPromise = this.options.load(record.data.controller, ...args); - const value = isPromiseLike(valueOrPromise) ? await valueOrPromise : valueOrPromise; - this.debugLog('loadValue():: value resolved', { value, record, aborted: signal.aborted }); + const value = isPromiseLike(valueOrPromise) + ? await valueOrPromise + : valueOrPromise; + this.debugLog("loadValue():: value resolved", { + value, + record, + aborted: signal.aborted, + }); if (!signal.aborted) { + this.options.onSuccess?.(value); CacheRecord.resolve(record, value); - this.debugLog('loadValue():: record resolved', { record }); + this.debugLog("loadValue():: record resolved", { record }); } } catch (error) { if (!signal.aborted) { + this.options.onError?.(error as TError); CacheRecord.reject(record, error as TError); - this.debugLog('loadValue():: record rejected', { record }); + this.debugLog("loadValue():: record rejected", { record }); } } finally { if (!signal.aborted) { - this.debugLog('loadValue():: notifying subscribers'); + this.debugLog("loadValue():: notifying subscribers"); this.notifySubscribers(cacheKey); } } @@ -125,17 +148,26 @@ export class SuspenseCache { const cacheKey = this.options.getKey(...args); let record = this.recordCache.get(cacheKey); if (record) { - this.debugLog('invalidate():: record found', { cacheKey, record }); + this.debugLog("invalidate():: record found", { cacheKey, record }); if (CacheRecord.isPending(record) || CacheRecord.isRevalidating(record)) { - this.debugLog('invalidate():: aborting', { cacheKey, record }); + this.debugLog("invalidate():: aborting", { cacheKey, record }); record.data.controller.abort(); } - if (CacheRecord.isResolved(record) || CacheRecord.isRevalidating(record)) { - this.debugLog('invalidate():: transitioning to revalidating', { cacheKey, record }); + if ( + CacheRecord.isResolved(record) || + CacheRecord.isRevalidating(record) + ) { + this.debugLog("invalidate():: transitioning to revalidating", { + cacheKey, + record, + }); CacheRecord.revalidate(record); } else { - this.debugLog('invalidate():: transitioning to pending', { cacheKey, record }); + this.debugLog("invalidate():: transitioning to pending", { + cacheKey, + record, + }); CacheRecord.pend(record); } @@ -151,17 +183,29 @@ export class SuspenseCache { this.recordCache.forEach((record, cacheKey) => { const args = this.invalidationArgs.get(cacheKey); if (args) { - this.debugLog('invalidateAll():: record found', { cacheKey, record }); - if (CacheRecord.isPending(record) || CacheRecord.isRevalidating(record)) { - this.debugLog('invalidateAll():: aborting', { cacheKey, record }); + this.debugLog("invalidateAll():: record found", { cacheKey, record }); + if ( + CacheRecord.isPending(record) || + CacheRecord.isRevalidating(record) + ) { + this.debugLog("invalidateAll():: aborting", { cacheKey, record }); record.data.controller.abort(); } - if (CacheRecord.isResolved(record) || CacheRecord.isRevalidating(record)) { - this.debugLog('invalidateAll():: transitioning to revalidating', { cacheKey, record }); + if ( + CacheRecord.isResolved(record) || + CacheRecord.isRevalidating(record) + ) { + this.debugLog("invalidateAll():: transitioning to revalidating", { + cacheKey, + record, + }); CacheRecord.revalidate(record); } else { - this.debugLog('invalidateAll():: transitioning to pending', { cacheKey, record }); + this.debugLog("invalidateAll():: transitioning to pending", { + cacheKey, + record, + }); CacheRecord.pend(record); } @@ -176,7 +220,7 @@ export class SuspenseCache { const cacheKey = this.options.getKey(...args); const record = this.recordCache.get(cacheKey); - this.debugLog('peek()::', { cacheKey, record }); + this.debugLog("peek()::", { cacheKey, record }); if (record) { if (CacheRecord.isResolved(record)) { @@ -200,7 +244,7 @@ export class SuspenseCache { getStatus(...args: Key): CacheStatus { const cacheKey = this.options.getKey(...args); const status = this.getStatusInternal(cacheKey); - this.debugLog('getStatus()::', { cacheKey, status }); + this.debugLog("getStatus()::", { cacheKey, status }); return status; } @@ -227,7 +271,7 @@ export class SuspenseCache { get(...args: Key): PromiseLike | TValue { const record = this.getOrCreateRecord(...args); - this.debugLog('get()::', { args, record }); + this.debugLog("get()::", { args, record }); if (CacheRecord.isPending(record)) { return record.data.value.promise; } @@ -249,7 +293,7 @@ export class SuspenseCache { */ set(value: TValue, ...args: Key): void { const cacheKey = this.options.getKey(...args); - this.debugLog('set():: creating', { cacheKey, value }); + this.debugLog("set():: creating", { cacheKey, value }); this.recordCache.set(cacheKey, CacheRecord.makeResolved(value)); this.invalidationArgs.set(cacheKey, args); this.notifySubscribers(cacheKey); @@ -267,7 +311,7 @@ export class SuspenseCache { this.recordCache.clear(); this.invalidationArgs.clear(); this.subscriberMap.forEach((set) => - set.forEach((subscriber) => subscriber(CacheStatus.MISSING)), + set.forEach((subscriber) => subscriber(CacheStatus.MISSING)) ); } @@ -284,7 +328,10 @@ export class SuspenseCache { return deleted; } - deleteIf(predicate: (value: CacheStatus) => boolean, ...args: Key): boolean { + deleteIf( + predicate: (value: CacheStatus) => boolean, + ...args: Key + ): boolean { if (predicate(this.getStatus(...args))) { return this.delete(...args); } @@ -315,7 +362,9 @@ export class SuspenseCache { * and re-renders the component when the status changes. * This will not suspend the component nor will it throw an error. */ - useValue(...args: Key): CacheValueResult { + useValue( + ...args: Key + ): CacheValueResult { const cache = this; const status = cache.useStatus(...args); @@ -332,9 +381,17 @@ export class SuspenseCache { // but the result of peek will match the status type const value = cache.peek(...args); if (value) { - return [status as typeof CacheStatus.RESOLVED | typeof CacheStatus.REVALIDATING, value]; + return [ + status as + | typeof CacheStatus.RESOLVED + | typeof CacheStatus.REVALIDATING, + value, + ]; } - return [status as typeof CacheStatus.MISSING | typeof CacheStatus.PENDING, undefined]; + return [ + status as typeof CacheStatus.MISSING | typeof CacheStatus.PENDING, + undefined, + ]; } catch (err) { return [status as typeof CacheStatus.REJECTED, err as TError]; } @@ -378,7 +435,10 @@ export class SuspenseCache { abort(...args: Key): boolean { const cacheKey = this.options.getKey(...args); const record = this.recordCache.get(cacheKey); - if (record && (CacheRecord.isPending(record) || CacheRecord.isRevalidating(record))) { + if ( + record && + (CacheRecord.isPending(record) || CacheRecord.isRevalidating(record)) + ) { record.data.controller.abort(); if (CacheRecord.isPending(record)) { return this.delete(...args); @@ -394,11 +454,15 @@ export class SuspenseCache { } export function cache( - load: (cacheLoadContext: CacheLoadContext, ...args: TParams) => PromiseLike | TValue, - options?: Partial, 'load'>>, + load: ( + cacheLoadContext: CacheLoadContext, + ...args: TParams + ) => PromiseLike | TValue, + options?: Partial, "load">> ): SuspenseCache { return new SuspenseCache({ - getKey: (...args: TParams) => args.join(','), + getKey: (...args: TParams) => + args.map((x) => JSON.stringify(x)).join(cacheKeyDelimiter), getCache: () => new Map(), debug: false, ...options, @@ -418,7 +482,7 @@ export interface SuspenseResourceCache< }, TResourceValues extends { [key in keyof TResource]: Awaited>; - }, + } > extends SuspenseCache< any, TResourceErrors[keyof TResource], @@ -482,7 +546,10 @@ export interface SuspenseResourceCache< useValue( key: TResourceKey, ...args: TResourceParams[TResourceKey] - ): CacheValueResult; + ): CacheValueResult< + TResourceErrors[TResourceKey], + TResourceValues[TResourceKey] + >; useStatus( key: TResourceKey, @@ -515,7 +582,7 @@ export function cacheResource< }, TResourceValues extends { [key in keyof TResource]: Awaited>; - }, + } >( resource: TResource, options?: Partial< @@ -525,14 +592,19 @@ export function cacheResource< TResourceErrors[keyof TResource], TResourceValues[keyof TResource] >, - 'load' | 'getKey' + "load" | "getKey" > & { getKey: { [key in keyof TResource]: (...args: TResourceParams[key]) => string; }; } - >, -): SuspenseResourceCache { + > +): SuspenseResourceCache< + TResource, + TResourceParams, + TResourceErrors, + TResourceValues +> { const getKey = options?.getKey; return new SuspenseCache< [keyof TResource, ...TResourceParams[keyof TResource]], @@ -541,19 +613,26 @@ export function cacheResource< >({ getCache: () => new Map(), debug: false, - debugLabel: `resource(${Object.keys(resource).join(',')})`, + debugLabel: `resource(${Object.keys(resource).join(",")})`, ...options, getKey: (...args) => { const [method, ...rest] = args; const methodGetKey = getKey?.[method]; const key = methodGetKey ? methodGetKey(...(rest as TResourceParams[keyof TResource])) - : rest.join(','); - return `${typeof method !== 'string' ? method.toString() : method}:${key}`; + : rest.join(cacheKeyDelimiter); + return `${ + typeof method !== "string" ? method.toString() : method + }:${key}`; }, load: (cacheLoadContext, ...args) => { const [method, ...rest] = args; return resource[method](cacheLoadContext, ...rest); }, - }) as SuspenseResourceCache; + }) as SuspenseResourceCache< + TResource, + TResourceParams, + TResourceErrors, + TResourceValues + >; } diff --git a/lib/hooks.ts b/lib/hooks.ts index 00f03ec..4b6940b 100644 --- a/lib/hooks.ts +++ b/lib/hooks.ts @@ -1,8 +1,8 @@ /* eslint-disable no-empty */ -import * as React from 'react'; +import * as React from "react"; -import { CacheStatus, MutationStatus } from './types'; -import { all } from './utils'; +import { CacheStatus, MutationStatus } from "./types"; +import { all } from "./utils"; // we call these "closured" because they are meant to capture the cache instance with its arguments // already applied. makes typing easier and avoids having to pass the arguments to the hooks @@ -26,19 +26,25 @@ type ClosuredUpdateCache = { getStatus: () => CacheStatus; }; -export function useMutation( +export function useMutation< + TValue, + TParams extends any[], + TMutationResult extends TValue | void +>( cachesToInvalidate: ClosuredInvalidationCache[], mutator: (...args: TParams) => Promise, options?: { updates: ClosuredUpdateCache[]; optimisticData?: TValue; - }, + } ): { status: MutationStatus; trigger: (...args: TParams) => Promise; reset: () => void; } { - const [status, setStatus] = React.useState(MutationStatus.IDLE); + const [status, setStatus] = React.useState( + MutationStatus.IDLE + ); return { reset: React.useCallback(() => setStatus(MutationStatus.IDLE), []), status, @@ -64,14 +70,16 @@ export function useMutation { if (options?.updates) { - return options.updates.every(({ id: updateId }) => invalidationId !== updateId); + return options.updates.every( + ({ id: updateId }) => invalidationId !== updateId + ); } return true; }) .forEach((cache) => { cache.invalidate(); }); - if (options?.updates && res !== undefined) { + if (options?.updates) { options.updates.forEach((cache) => { cache.set(res); }); @@ -99,9 +107,9 @@ export function useMutation>( - cache: Cache, -): ReturnType { +export function useSuspend>( + cache: Cache +): ReturnType { const forceUpdate = useForceUpdate(); React.useEffect(() => { const unsub = cache.subscribeToStatus(forceUpdate); @@ -112,29 +120,33 @@ export function useSuspend>( // this provides a way to get the up to date suspense reads concurrently export function useSuspendAll( - caches: Caches, + caches: Caches ): { - [K in keyof Caches]: ReturnType; + [K in keyof Caches]: ReturnType; } { const forceUpdate = useForceUpdate(); React.useEffect(() => { - const unsubs = caches.map(({ subscribeToStatus }) => subscribeToStatus(forceUpdate)); + const unsubs = caches.map(({ subscribeToStatus }) => + subscribeToStatus(forceUpdate) + ); return () => unsubs.forEach((unsub) => unsub()); }, [caches, forceUpdate]); return all(caches.map((cache) => cache.suspend)) as any; } -export function useSuspendAllProps>( - caches: Caches, +export function useSuspendAllProps< + Caches extends Record +>( + caches: Caches ): { - [K in keyof Caches]: ReturnType; + [K in keyof Caches]: ReturnType; } { const forceUpdate = useForceUpdate(); React.useEffect(() => { const unsubs = Object.values(caches).map(({ subscribeToStatus }) => - subscribeToStatus(forceUpdate), + subscribeToStatus(forceUpdate) ); return () => unsubs.forEach((unsub) => unsub()); }, [caches, forceUpdate]); @@ -142,39 +154,45 @@ export function useSuspendAllProps> // eslint-disable-next-line compat/compat -- this is polyfilled in gcn return Object.fromEntries( all( - Object.entries(caches).map(([key, cache]) => () => [key, cache.suspend()]), - ), + Object.entries(caches).map(([key, cache]) => () => [key, cache.suspend()]) + ) ); } export function useReadAll( - caches: Caches, + caches: Caches ): { - [K in keyof Caches]: [ReturnType, boolean]; + [K in keyof Caches]: [ReturnType, boolean]; } { const forceUpdate = useForceUpdate(); React.useEffect(() => { - const unsubs = caches.map(({ subscribeToStatus }) => subscribeToStatus(forceUpdate)); + const unsubs = caches.map(({ subscribeToStatus }) => + subscribeToStatus(forceUpdate) + ); return () => unsubs.forEach((unsub) => unsub()); }, [caches, forceUpdate]); return all( caches.map( - (cache) => () => [cache.suspend(), cache.getStatus() === CacheStatus.REVALIDATING] as const, - ), + (cache) => () => + [ + cache.suspend(), + cache.getStatus() === CacheStatus.REVALIDATING, + ] as const + ) ) as any; } export function useReadAllProps>( - caches: Caches, + caches: Caches ): { - [K in keyof Caches]: [ReturnType, boolean]; + [K in keyof Caches]: [ReturnType, boolean]; } { const forceUpdate = useForceUpdate(); React.useEffect(() => { const unsubs = Object.values(caches).map(({ subscribeToStatus }) => - subscribeToStatus(forceUpdate), + subscribeToStatus(forceUpdate) ); return () => unsubs.forEach((unsub) => unsub()); }, [caches, forceUpdate]); @@ -185,8 +203,8 @@ export function useReadAllProps>( Object.entries(caches).map(([key, cache]) => () => [ key, [cache.suspend(), cache.getStatus() === CacheStatus.REVALIDATING], - ]), - ), + ]) + ) ); } diff --git a/lib/index.ts b/lib/index.ts index 303d569..c63305f 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,5 +1,11 @@ -export { CacheStatus, MutationStatus } from './types'; -export type { CacheLoadContext, Resource, SuspenseCacheOptions, CacheRecord } from './types'; -export { cache, cacheResource } from './cache'; -export * from './utils'; -export * from './hooks'; +export { CacheStatus, MutationStatus } from "./types"; +export type { + CacheLoadContext, + Resource, + SuspenseCacheOptions, + CacheRecord, +} from "./types"; +export { cache, cacheResource } from "./cache"; +export * from "./utils"; +export * from "./hooks"; +export * from "./cache-client"; diff --git a/lib/types.ts b/lib/types.ts index c1605de..89997f4 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -1,12 +1,13 @@ -import { defer } from './utils'; +import { defer } from "./utils"; export const DeferredStatus = { - PENDING: 'pending', - RESOLVED: 'resolved', - REJECTED: 'rejected', + PENDING: "pending", + RESOLVED: "resolved", + REJECTED: "rejected", } as const; -export type DeferredStatus = (typeof DeferredStatus)[keyof typeof DeferredStatus]; +export type DeferredStatus = + (typeof DeferredStatus)[keyof typeof DeferredStatus]; export interface Deferred { promise: Promise; @@ -17,8 +18,8 @@ export interface Deferred { export const CacheStatus = { ...DeferredStatus, - REVALIDATING: 'revalidating', - MISSING: 'missing', + REVALIDATING: "revalidating", + MISSING: "missing", } as const; export type CacheStatus = (typeof CacheStatus)[keyof typeof CacheStatus]; @@ -65,34 +66,40 @@ export type CacheRecord = type CacheRecordStatic = { makePending(): PendingCacheRecord; - makeResolved(value: TValue): ResolvedCacheRecord; - makeRejected(error: TError): RejectedCacheRecord; - makeRevalidating(value: TValue): RevalidatingCacheRecord; + makeResolved( + value: TValue + ): ResolvedCacheRecord; + makeRejected( + error: TError + ): RejectedCacheRecord; + makeRevalidating( + value: TValue + ): RevalidatingCacheRecord; isPending( - record: CacheRecord, + record: CacheRecord ): record is PendingCacheRecord; isResolved( - record: CacheRecord, + record: CacheRecord ): record is ResolvedCacheRecord; isRejected( - record: CacheRecord, + record: CacheRecord ): record is RejectedCacheRecord; isRevalidating( - record: CacheRecord, + record: CacheRecord ): record is RevalidatingCacheRecord; resolve( record: CacheRecord, - value: TValue, + value: TValue ): asserts record is ResolvedCacheRecord; reject( record: CacheRecord, - error: TError, + error: TError ): asserts record is RejectedCacheRecord; revalidate( - record: CacheRecord, + record: CacheRecord ): asserts record is RevalidatingCacheRecord; pend( - record: CacheRecord, + record: CacheRecord ): asserts record is PendingCacheRecord; }; @@ -108,7 +115,9 @@ export const CacheRecord: CacheRecordStatic = { }; }, - makeResolved(value: TValue): ResolvedCacheRecord { + makeResolved( + value: TValue + ): ResolvedCacheRecord { return { data: { status: CacheStatus.RESOLVED, @@ -117,7 +126,9 @@ export const CacheRecord: CacheRecordStatic = { }; }, - makeRejected(error: TError): RejectedCacheRecord { + makeRejected( + error: TError + ): RejectedCacheRecord { return { data: { status: CacheStatus.REJECTED, @@ -126,7 +137,9 @@ export const CacheRecord: CacheRecordStatic = { }; }, - makeRevalidating(value: TValue): RevalidatingCacheRecord { + makeRevalidating( + value: TValue + ): RevalidatingCacheRecord { return { data: { status: CacheStatus.REVALIDATING, @@ -138,32 +151,34 @@ export const CacheRecord: CacheRecordStatic = { }, isPending( - record: CacheRecord, + record: CacheRecord ): record is PendingCacheRecord { return record.data.status === CacheStatus.PENDING; }, isResolved( - record: CacheRecord, + record: CacheRecord ): record is ResolvedCacheRecord { return record.data.status === CacheStatus.RESOLVED; }, isRejected( - record: CacheRecord, + record: CacheRecord ): record is RejectedCacheRecord { return record.data.status === CacheStatus.REJECTED; }, isRevalidating( - record: CacheRecord, + record: CacheRecord ): record is RevalidatingCacheRecord { return record.data.status === CacheStatus.REVALIDATING; }, resolve(record: CacheRecord, value: TValue) { if (!CacheRecord.isPending(record) && !CacheRecord.isRevalidating(record)) { - throw new Error('Cannot resolve a record that is not pending or revalidating'); + throw new Error( + "Cannot resolve a record that is not pending or revalidating" + ); } const deferred = record.data.value; deferred.resolve(value); @@ -175,7 +190,9 @@ export const CacheRecord: CacheRecordStatic = { reject(record: CacheRecord, error: TError) { if (!CacheRecord.isPending(record) && !CacheRecord.isRevalidating(record)) { - throw new Error('Cannot reject a record that is not pending or revalidating'); + throw new Error( + "Cannot reject a record that is not pending or revalidating" + ); } const deferred = record.data.value; deferred.reject(error); @@ -186,22 +203,32 @@ export const CacheRecord: CacheRecordStatic = { }, revalidate( - record: ResolvedCacheRecord | RevalidatingCacheRecord, + record: + | ResolvedCacheRecord + | RevalidatingCacheRecord ) { - if (!CacheRecord.isResolved(record) && !CacheRecord.isRevalidating(record)) { - throw new Error('Cannot revalidate a record that is not resolved or revalidating'); + if ( + !CacheRecord.isResolved(record) && + !CacheRecord.isRevalidating(record) + ) { + throw new Error( + "Cannot revalidate a record that is not resolved or revalidating" + ); } record.data = { status: CacheStatus.REVALIDATING, value: defer(), controller: new AbortController(), - cached: record.data.status === 'resolved' ? record.data.value : record.data.cached, + cached: + record.data.status === "resolved" + ? record.data.value + : record.data.cached, }; }, pend(record: CacheRecord) { if (!CacheRecord.isPending(record) && !CacheRecord.isRejected(record)) { - throw new Error('Cannot pend a record that is not pending or rejected'); + throw new Error("Cannot pend a record that is not pending or rejected"); } record.data = { @@ -213,18 +240,25 @@ export const CacheRecord: CacheRecordStatic = { }; export type CacheValueResult = - | [status: typeof CacheStatus.PENDING | typeof CacheStatus.MISSING, value: undefined] + | [ + status: typeof CacheStatus.PENDING | typeof CacheStatus.MISSING, + value: undefined + ] | [status: typeof CacheStatus.REJECTED, error: TError] - | [status: typeof CacheStatus.RESOLVED | typeof CacheStatus.REVALIDATING, value: TValue]; + | [ + status: typeof CacheStatus.RESOLVED | typeof CacheStatus.REVALIDATING, + value: TValue + ]; export const MutationStatus = { PENDING: CacheStatus.PENDING, RESOLVED: CacheStatus.RESOLVED, REJECTED: CacheStatus.REJECTED, - IDLE: 'idle', + IDLE: "idle", } as const; -export type MutationStatus = (typeof MutationStatus)[keyof typeof MutationStatus]; +export type MutationStatus = + (typeof MutationStatus)[keyof typeof MutationStatus]; type onEviction = (key: Key) => void; @@ -234,15 +268,28 @@ export interface CacheMap { get(key: Key): Value | undefined; has(key: Key): boolean; set(key: Key, value: Value): this; - forEach(callbackfn: (value: Value, key: Key, map: CacheMap) => void): void; + forEach( + callbackfn: (value: Value, key: Key, map: CacheMap) => void + ): void; } -export type SuspenseCacheOptions = { +export type SuspenseCacheOptions< + TParams extends any[] = any[], + TError = unknown, + TValue = unknown +> = { getKey: (...args: TParams) => string; - getCache: (onEviction: onEviction) => CacheMap>; - load: (context: CacheLoadContext, ...args: TParams) => PromiseLike | TValue; + getCache: ( + onEviction: onEviction + ) => CacheMap>; + load: ( + context: CacheLoadContext, + ...args: TParams + ) => PromiseLike | TValue; debug: boolean; debugLabel?: string; + onSuccess?: (value: TValue) => void; + onError?: (error: TError) => void; }; export type AnyFunction = (...args: any[]) => ReturnType; @@ -251,7 +298,9 @@ export type CacheLoadContext = { signal: AbortSignal; }; -export type ResourceParameters = T extends (...args: [infer _cacheContext, ...infer args]) => any +export type ResourceParameters = T extends ( + ...args: [infer _cacheContext, ...infer args] +) => any ? args : never; diff --git a/lib/utils.ts b/lib/utils.ts index da27dfb..450ffc0 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,12 +1,12 @@ -import type { AnyFunction, Deferred } from './types'; -import { CacheStatus, DeferredStatus } from './types'; +import type { AnyFunction, Deferred } from "./types"; +import { CacheStatus, DeferredStatus } from "./types"; export function isPromiseLike(value: unknown): value is PromiseLike { return ( - typeof value === 'object' && + typeof value === "object" && value !== null && - 'then' in value && - typeof value.then === 'function' + "then" in value && + typeof value.then === "function" ); } @@ -60,7 +60,7 @@ type Suspender = (...args: any[]) => T; // Helper function to read from multiple Suspense caches in parallel. // This method will re-throw any thrown value, but only after also calling subsequent caches. export function all[]>( - suspenders: [...Func], + suspenders: [...Func] ): { [K in keyof Func]: ReturnType>> } { const values: any[] = []; let thrownValue = null; @@ -80,7 +80,9 @@ export function all[]>( return values as any; } -export function allProps>>(props: Props) { +export function allProps>>( + props: Props +) { const keys = Object.keys(props); const values = all(keys.map((key) => props[key])); @@ -109,3 +111,5 @@ export function cacheValueIsPending(status: CacheStatus): boolean { export function cacheValueIsMissing(status: CacheStatus): boolean { return status === CacheStatus.MISSING; } + +export const cacheKeyDelimiter = ":@:"; diff --git a/package.json b/package.json index 0cf1636..ae34e0b 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "test": "vitest run", "test:watch": "vitest", "compile": "tsup", - "prepare": "" + "prepare": "npm run compile && npm run test" }, "author": "Cristian Ramos ", "license": "ISC", @@ -30,8 +30,9 @@ "react-dom": "^18" }, "devDependencies": { - "@types/react": "^18.2.5", - "@types/react-dom": "^18.2.3", + "@changesets/cli": "^2.26.1", + "@types/react": "^18.2.6", + "@types/react-dom": "^18.2.4", "happy-dom": "^9.10.9", "lru-cache": "^9.1.1", "react": "^18.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e330036..7c3c482 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,12 +1,15 @@ lockfileVersion: '6.0' devDependencies: + '@changesets/cli': + specifier: ^2.26.1 + version: 2.26.1 '@types/react': - specifier: ^18.2.5 - version: 18.2.5 + specifier: ^18.2.6 + version: 18.2.6 '@types/react-dom': - specifier: ^18.2.3 - version: 18.2.3 + specifier: ^18.2.4 + version: 18.2.4 happy-dom: specifier: ^9.10.9 version: 9.10.9 @@ -31,6 +34,218 @@ devDependencies: packages: + /@babel/code-frame@7.21.4: + resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.18.6 + dev: true + + /@babel/helper-validator-identifier@7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/highlight@7.18.6: + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/runtime@7.21.5: + resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 + dev: true + + /@changesets/apply-release-plan@6.1.3: + resolution: {integrity: sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/config': 2.3.0 + '@changesets/get-version-range-type': 0.3.2 + '@changesets/git': 2.0.0 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 5.7.1 + dev: true + + /@changesets/assemble-release-plan@5.2.3: + resolution: {integrity: sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.5 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + semver: 5.7.1 + dev: true + + /@changesets/changelog-git@0.1.14: + resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} + dependencies: + '@changesets/types': 5.2.1 + dev: true + + /@changesets/cli@2.26.1: + resolution: {integrity: sha512-XnTa+b51vt057fyAudvDKGB0Sh72xutQZNAdXkCqPBKO2zvs2yYZx5hFZj1u9cbtpwM6Sxtcr02/FQJfZOzemQ==} + hasBin: true + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/apply-release-plan': 6.1.3 + '@changesets/assemble-release-plan': 5.2.3 + '@changesets/changelog-git': 0.1.14 + '@changesets/config': 2.3.0 + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.5 + '@changesets/get-release-plan': 3.0.16 + '@changesets/git': 2.0.0 + '@changesets/logger': 0.0.5 + '@changesets/pre': 1.0.14 + '@changesets/read': 0.5.9 + '@changesets/types': 5.2.1 + '@changesets/write': 0.2.3 + '@manypkg/get-packages': 1.1.3 + '@types/is-ci': 3.0.0 + '@types/semver': 6.2.3 + ansi-colors: 4.1.3 + chalk: 2.4.2 + enquirer: 2.3.6 + external-editor: 3.1.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + is-ci: 3.0.1 + meow: 6.1.1 + outdent: 0.5.0 + p-limit: 2.3.0 + preferred-pm: 3.0.3 + resolve-from: 5.0.0 + semver: 5.7.1 + spawndamnit: 2.0.0 + term-size: 2.2.1 + tty-table: 4.2.1 + dev: true + + /@changesets/config@2.3.0: + resolution: {integrity: sha512-EgP/px6mhCx8QeaMAvWtRrgyxW08k/Bx2tpGT+M84jEdX37v3VKfh4Cz1BkwrYKuMV2HZKeHOh8sHvja/HcXfQ==} + dependencies: + '@changesets/errors': 0.1.4 + '@changesets/get-dependents-graph': 1.3.5 + '@changesets/logger': 0.0.5 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.5 + dev: true + + /@changesets/errors@0.1.4: + resolution: {integrity: sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==} + dependencies: + extendable-error: 0.1.7 + dev: true + + /@changesets/get-dependents-graph@1.3.5: + resolution: {integrity: sha512-w1eEvnWlbVDIY8mWXqWuYE9oKhvIaBhzqzo4ITSJY9hgoqQ3RoBqwlcAzg11qHxv/b8ReDWnMrpjpKrW6m1ZTA==} + dependencies: + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + chalk: 2.4.2 + fs-extra: 7.0.1 + semver: 5.7.1 + dev: true + + /@changesets/get-release-plan@3.0.16: + resolution: {integrity: sha512-OpP9QILpBp1bY2YNIKFzwigKh7Qe9KizRsZomzLe6pK8IUo8onkAAVUD8+JRKSr8R7d4+JRuQrfSSNlEwKyPYg==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/assemble-release-plan': 5.2.3 + '@changesets/config': 2.3.0 + '@changesets/pre': 1.0.14 + '@changesets/read': 0.5.9 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + dev: true + + /@changesets/get-version-range-type@0.3.2: + resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} + dev: true + + /@changesets/git@2.0.0: + resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/errors': 0.1.4 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.5 + spawndamnit: 2.0.0 + dev: true + + /@changesets/logger@0.0.5: + resolution: {integrity: sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==} + dependencies: + chalk: 2.4.2 + dev: true + + /@changesets/parse@0.3.16: + resolution: {integrity: sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==} + dependencies: + '@changesets/types': 5.2.1 + js-yaml: 3.14.1 + dev: true + + /@changesets/pre@1.0.14: + resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/errors': 0.1.4 + '@changesets/types': 5.2.1 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + dev: true + + /@changesets/read@0.5.9: + resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/git': 2.0.0 + '@changesets/logger': 0.0.5 + '@changesets/parse': 0.3.16 + '@changesets/types': 5.2.1 + chalk: 2.4.2 + fs-extra: 7.0.1 + p-filter: 2.1.0 + dev: true + + /@changesets/types@4.1.0: + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + dev: true + + /@changesets/types@5.2.1: + resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} + dev: true + + /@changesets/write@0.2.3: + resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/types': 5.2.1 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + dev: true + /@esbuild/android-arm64@0.17.18: resolution: {integrity: sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==} engines: {node: '>=12'} @@ -263,6 +478,26 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true + /@manypkg/find-root@1.1.0: + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + dependencies: + '@babel/runtime': 7.21.5 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + dev: true + + /@manypkg/get-packages@1.1.3: + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + dependencies: + '@babel/runtime': 7.21.5 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + dev: true + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -294,22 +529,40 @@ packages: resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} dev: true + /@types/is-ci@3.0.0: + resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} + dependencies: + ci-info: 3.8.0 + dev: true + + /@types/minimist@1.2.2: + resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} + dev: true + + /@types/node@12.20.55: + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + dev: true + /@types/node@18.16.3: resolution: {integrity: sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==} dev: true + /@types/normalize-package-data@2.4.1: + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + dev: true + /@types/prop-types@15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} dev: true - /@types/react-dom@18.2.3: - resolution: {integrity: sha512-hxXEXWxFJXbY0LMj/T69mznqOZJXNtQMqVxIiirVAZnnpeYiD4zt+lPsgcr/cfWg2VLsxZ1y26vigG03prYB+Q==} + /@types/react-dom@18.2.4: + resolution: {integrity: sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw==} dependencies: - '@types/react': 18.2.5 + '@types/react': 18.2.6 dev: true - /@types/react@18.2.5: - resolution: {integrity: sha512-RuoMedzJ5AOh23Dvws13LU9jpZHIc/k90AgmK7CecAYeWmSr3553L4u5rk4sWAPBuQosfT7HmTfG4Rg5o4nGEA==} + /@types/react@18.2.6: + resolution: {integrity: sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA==} dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.3 @@ -320,6 +573,10 @@ packages: resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} dev: true + /@types/semver@6.2.3: + resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} + dev: true + /@vitest/expect@0.31.0: resolution: {integrity: sha512-Jlm8ZTyp6vMY9iz9Ny9a0BHnCG4fqBa8neCF6Pk/c/6vkUk49Ls6UBlgGAU82QnzzoaUs9E/mUhq/eq9uMOv/g==} dependencies: @@ -370,11 +627,30 @@ packages: hasBin: true dev: true + /ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + dev: true + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} dev: true + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + /ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} @@ -392,19 +668,59 @@ packages: picomatch: 2.3.1 dev: true + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.2 + is-array-buffer: 3.0.2 + dev: true + /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true + /array.prototype.flat@1.3.1: + resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + es-shim-unscopables: 1.0.0 + dev: true + + /arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + dev: true + /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true + /better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + dependencies: + is-windows: 1.0.2 + dev: true + /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} @@ -428,6 +744,12 @@ packages: fill-range: 7.0.1 dev: true + /breakword@1.0.5: + resolution: {integrity: sha512-ex5W9DoOQ/LUEU3PMdLs9ua/CYZl1678NUkKOdUSi8Aw5F1idieaiRURCBFJCwVcrD1J8Iy3vfWSloaMwO2qFg==} + dependencies: + wcwidth: 1.0.1 + dev: true + /bundle-require@4.0.1(esbuild@0.17.18): resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -443,6 +765,27 @@ packages: engines: {node: '>=8'} dev: true + /call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.0 + dev: true + + /camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + /chai@4.3.7: resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} engines: {node: '>=4'} @@ -456,6 +799,27 @@ packages: type-detect: 4.0.8 dev: true + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + dev: true + /check-error@1.0.2: resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} dev: true @@ -475,6 +839,54 @@ packages: fsevents: 2.3.2 dev: true + /ci-info@3.8.0: + resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + engines: {node: '>=8'} + dev: true + + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -498,6 +910,14 @@ packages: well-known-symbols: 2.0.0 dev: true + /cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + dev: true + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -515,6 +935,28 @@ packages: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} dev: true + /csv-generate@3.4.3: + resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} + dev: true + + /csv-parse@4.16.3: + resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==} + dev: true + + /csv-stringify@5.6.5: + resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==} + dev: true + + /csv@5.5.3: + resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} + engines: {node: '>= 0.1.90'} + dependencies: + csv-generate: 3.4.3 + csv-parse: 4.16.3 + csv-stringify: 5.6.5 + stream-transform: 2.1.3 + dev: true + /date-time@3.1.0: resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} engines: {node: '>=6'} @@ -534,6 +976,19 @@ packages: ms: 2.1.2 dev: true + /decamelize-keys@1.1.1: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} + engines: {node: '>=0.10.0'} + dependencies: + decamelize: 1.2.0 + map-obj: 1.0.1 + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + /deep-eql@4.1.3: resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} engines: {node: '>=6'} @@ -541,6 +996,25 @@ packages: type-detect: 4.0.8 dev: true + /defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + dependencies: + clone: 1.0.4 + dev: true + + /define-properties@1.2.0: + resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} + engines: {node: '>= 0.4'} + dependencies: + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + + /detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + dev: true + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -548,6 +1022,87 @@ packages: path-type: 4.0.0 dev: true + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.3 + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract@1.21.2: + resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + es-set-tostringtag: 2.0.1 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.5 + get-intrinsic: 1.2.0 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.10 + is-weakref: 1.0.2 + object-inspect: 1.12.3 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.0 + safe-regex-test: 1.0.0 + string.prototype.trim: 1.2.7 + string.prototype.trimend: 1.0.6 + string.prototype.trimstart: 1.0.6 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.9 + dev: true + + /es-set-tostringtag@2.0.1: + resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.0 + has: 1.0.3 + has-tostringtag: 1.0.0 + dev: true + + /es-shim-unscopables@1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + /esbuild@0.17.18: resolution: {integrity: sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==} engines: {node: '>=12'} @@ -578,6 +1133,22 @@ packages: '@esbuild/win32-x64': 0.17.18 dev: true + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -598,6 +1169,19 @@ packages: strip-final-newline: 2.0.0 dev: true + /extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + dev: true + + /external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: true + /fast-diff@1.2.0: resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} dev: true @@ -626,6 +1210,53 @@ packages: to-regex-range: 5.0.1 dev: true + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /find-yarn-workspace-root2@1.2.16: + resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + dependencies: + micromatch: 4.0.5 + pkg-dir: 4.2.0 + dev: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true @@ -638,16 +1269,55 @@ packages: dev: true optional: true + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /function.prototype.name@1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + /get-func-name@2.0.0: resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} dev: true + /get-intrinsic@1.2.0: + resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + dev: true + /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} dev: true - /glob-parent@5.1.2: + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + dev: true + + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} dependencies: @@ -665,6 +1335,13 @@ packages: path-is-absolute: 1.0.1 dev: true + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.0 + dev: true + /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -677,6 +1354,20 @@ packages: slash: 3.0.0 dev: true + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.0 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + dev: true + /happy-dom@9.10.9: resolution: {integrity: sha512-3RnOyu6buPMpDAyOpp8yfR5Xi/k2p5MhrDwlG/dgpVHkptFN5IqubdbGOQU5luB7ANh6a08GOuiB+Bo9JCzCBw==} dependencies: @@ -688,16 +1379,80 @@ packages: whatwg-mimetype: 3.0.0 dev: true + /hard-rejection@2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors@1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.2.0 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + /he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true dev: true + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + dev: true + /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} dev: true + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -710,6 +1465,11 @@ packages: engines: {node: '>= 4'} dev: true + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -721,6 +1481,33 @@ packages: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: true + /internal-slot@1.0.5: + resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.0 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + is-typed-array: 1.1.10 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -728,11 +1515,49 @@ packages: binary-extensions: 2.2.0 dev: true + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + dependencies: + ci-info: 3.8.0 + dev: true + + /is-core-module@2.12.0: + resolution: {integrity: sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==} + dependencies: + has: 1.0.3 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} dev: true + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -740,16 +1565,90 @@ packages: is-extglob: 2.1.1 dev: true + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} dev: true + /is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} dev: true + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + dependencies: + better-path-resolve: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.10: + resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true @@ -768,10 +1667,38 @@ packages: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: true + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} dev: true + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -786,15 +1713,43 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true + /load-yaml-file@0.2.0: + resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} + engines: {node: '>=6'} + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + dev: true + /local-pkg@0.4.3: resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} engines: {node: '>=14'} dev: true + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + /lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} dev: true + /lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + dev: true + /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: true @@ -812,6 +1767,13 @@ packages: get-func-name: 2.0.0 dev: true + /lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + dev: true + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -831,6 +1793,16 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + dev: true + + /map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + dev: true + /md5-hex@3.0.1: resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} engines: {node: '>=8'} @@ -838,6 +1810,23 @@ packages: blueimp-md5: 2.19.0 dev: true + /meow@6.1.1: + resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} + engines: {node: '>=8'} + dependencies: + '@types/minimist': 1.2.2 + camelcase-keys: 6.2.2 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 2.5.0 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.13.1 + yargs-parser: 18.1.3 + dev: true + /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true @@ -860,12 +1849,31 @@ packages: engines: {node: '>=6'} dev: true + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 dev: true + /minimist-options@4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + kind-of: 6.0.3 + dev: true + + /mixme@0.5.9: + resolution: {integrity: sha512-VC5fg6ySUscaWUpI4gxCBTQMH2RdUpNrk+MsbpCYtIvf9SBJdiUey4qE7BXviJsJR4nDQxCZ+3yaYNW3guz/Pw==} + engines: {node: '>= 8.0.0'} + dev: true + /mlly@1.2.0: resolution: {integrity: sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==} dependencies: @@ -893,6 +1901,15 @@ packages: hasBin: true dev: true + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.2 + semver: 5.7.1 + validate-npm-package-license: 3.0.4 + dev: true + /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -910,6 +1927,25 @@ packages: engines: {node: '>=0.10.0'} dev: true + /object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -923,6 +1959,36 @@ packages: mimic-fn: 2.1.0 dev: true + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: true + + /outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + dev: true + + /p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + dependencies: + p-map: 2.1.0 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + /p-limit@4.0.0: resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -930,6 +1996,45 @@ packages: yocto-queue: 1.0.0 dev: true + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.21.4 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -940,6 +2045,10 @@ packages: engines: {node: '>=8'} dev: true + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -962,11 +2071,23 @@ packages: engines: {node: '>=8.6'} dev: true + /pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + dev: true + /pirates@4.0.5: resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} engines: {node: '>= 6'} dev: true + /pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + /pkg-types@1.0.3: resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} dependencies: @@ -1000,6 +2121,22 @@ packages: source-map-js: 1.0.2 dev: true + /preferred-pm@3.0.3: + resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} + engines: {node: '>=10'} + dependencies: + find-up: 5.0.0 + find-yarn-workspace-root2: 1.2.16 + path-exists: 4.0.0 + which-pm: 2.0.0 + dev: true + + /prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + /pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -1009,6 +2146,10 @@ packages: react-is: 17.0.2 dev: true + /pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + dev: true + /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} @@ -1018,6 +2159,11 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true + /quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + dev: true + /react-dom@18.2.0(react@18.2.0): resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -1039,6 +2185,35 @@ packages: loose-envify: 1.4.0 dev: true + /read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + dev: true + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -1046,11 +2221,50 @@ packages: picomatch: 2.3.1 dev: true + /redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + dev: true + + /regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + dev: true + + /regexp.prototype.flags@1.5.0: + resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + functions-have-names: 1.2.3 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + /resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} dev: true + /resolve@1.22.2: + resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} + hasBin: true + dependencies: + is-core-module: 2.12.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -1070,6 +2284,14 @@ packages: queue-microtask: 1.2.3 dev: true + /safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + is-regex: 1.1.4 + dev: true + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: true @@ -1080,6 +2302,11 @@ packages: loose-envify: 1.4.0 dev: true + /semver@5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + dev: true + /semver@7.5.0: resolution: {integrity: sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==} engines: {node: '>=10'} @@ -1088,6 +2315,17 @@ packages: lru-cache: 6.0.0 dev: true + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + + /shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + dependencies: + shebang-regex: 1.0.0 + dev: true + /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1095,11 +2333,24 @@ packages: shebang-regex: 3.0.0 dev: true + /shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + dev: true + /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} dev: true + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + object-inspect: 1.12.3 + dev: true + /siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} dev: true @@ -1113,6 +2364,19 @@ packages: engines: {node: '>=8'} dev: true + /smartwrap@2.0.2: + resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} + engines: {node: '>=6'} + hasBin: true + dependencies: + array.prototype.flat: 1.3.1 + breakword: 1.0.5 + grapheme-splitter: 1.0.4 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + yargs: 15.4.1 + dev: true + /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -1125,6 +2389,39 @@ packages: whatwg-url: 7.1.0 dev: true + /spawndamnit@2.0.0: + resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + dependencies: + cross-spawn: 5.1.0 + signal-exit: 3.0.7 + dev: true + + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.13 + dev: true + + /spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.13 + dev: true + + /spdx-license-ids@3.0.13: + resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + /stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true @@ -1133,11 +2430,70 @@ packages: resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==} dev: true + /stream-transform@2.1.3: + resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} + dependencies: + mixme: 0.5.9 + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string.prototype.trim@1.2.7: + resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + dev: true + + /string.prototype.trimend@1.0.6: + resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + dev: true + + /string.prototype.trimstart@1.0.6: + resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + /strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} dev: true + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + /strip-literal@1.0.1: resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} dependencies: @@ -1158,6 +2514,30 @@ packages: ts-interface-checker: 0.1.13 dev: true + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + dev: true + /thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -1190,6 +2570,13 @@ packages: engines: {node: '>=14.0.0'} dev: true + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: true + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -1208,6 +2595,11 @@ packages: hasBin: true dev: true + /trim-newlines@3.0.1: + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} + engines: {node: '>=8'} + dev: true + /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true @@ -1248,11 +2640,48 @@ packages: - ts-node dev: true + /tty-table@4.2.1: + resolution: {integrity: sha512-xz0uKo+KakCQ+Dxj1D/tKn2FSyreSYWzdkL/BYhgN6oMW808g8QRMuh1atAV9fjTPbWBjfbkKQpI/5rEcnAc7g==} + engines: {node: '>=8.0.0'} + hasBin: true + dependencies: + chalk: 4.1.2 + csv: 5.5.3 + kleur: 4.1.5 + smartwrap: 2.0.2 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + yargs: 17.7.2 + dev: true + /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} dev: true + /type-fest@0.13.1: + resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /typed-array-length@1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + is-typed-array: 1.1.10 + dev: true + /typescript@5.0.4: resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} engines: {node: '>=12.20'} @@ -1263,6 +2692,27 @@ packages: resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} dev: true + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + /vite-node@0.31.0(@types/node@18.16.3): resolution: {integrity: sha512-8x1x1LNuPvE2vIvkSB7c1mApX5oqlgsxzHQesYF7l5n1gKrEmrClIiZuOFbFDQcjLsmcWSwwmrWrcGWm9Fxc/g==} engines: {node: '>=v14.18.0'} @@ -1383,6 +2833,12 @@ packages: - terser dev: true + /wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + dependencies: + defaults: 1.0.4 + dev: true + /webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} dev: true @@ -1417,6 +2873,47 @@ packages: webidl-conversions: 4.0.2 dev: true + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: true + + /which-pm@2.0.0: + resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} + engines: {node: '>=8.15'} + dependencies: + load-yaml-file: 0.2.0 + path-exists: 4.0.0 + dev: true + + /which-typed-array@1.1.9: + resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + is-typed-array: 1.1.10 + dev: true + + /which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -1434,10 +2931,41 @@ packages: stackback: 0.0.2 dev: true + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + dev: true + /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true @@ -1447,6 +2975,54 @@ packages: engines: {node: '>= 6'} dev: true + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + /yocto-queue@1.0.0: resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} engines: {node: '>=12.20'}