diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 44278cd..82b9ffa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,6 +38,18 @@ jobs: - name: Install dependencies run: pnpm i --frozen-lockfile + - name: Build dependencies + working-directory: . + run: pnpm --filter passkeys --filter passkeys-react build + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: dist-files + path: | + packages/passkeys/dist + packages/passkeys-react/dist + - name: Run ESLint run: pnpm lint @@ -72,6 +84,12 @@ jobs: - name: Install dependencies run: pnpm i --frozen-lockfile + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: dist-files + path: packages + - name: Run build working-directory: apps/signer run: pnpm build diff --git a/apps/signer/package.json b/apps/signer/package.json index e3a4a95..a891f9c 100644 --- a/apps/signer/package.json +++ b/apps/signer/package.json @@ -11,6 +11,8 @@ "lint": "eslint" }, "dependencies": { + "passkeys": "workspace:*", + "passkeys-react": "workspace:*", "@better-fetch/fetch": "^1.1.18", "@jstz-dev/jstz-client": "0.1.1-alpha.5", "@jstz-dev/jstz_sdk": "0.1.1-alpha.5", diff --git a/apps/signer/src/lib/passkeys/constants.ts b/apps/signer/src/lib/constants/RP_ID.ts similarity index 100% rename from apps/signer/src/lib/passkeys/constants.ts rename to apps/signer/src/lib/constants/RP_ID.ts diff --git a/apps/signer/src/lib/passkeys/usePasskeyWallet.ts b/apps/signer/src/lib/passkeys/usePasskeyWallet.ts deleted file mode 100644 index e75f52d..0000000 --- a/apps/signer/src/lib/passkeys/usePasskeyWallet.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { useRef } from "react"; -import { PasskeyWallet } from "./PasskeyWallet"; - -import { RP_ID } from "./constants"; -import { userStore } from "./userStore"; - -export function usePasskeyWallet() { - const wallet = useRef( - new PasskeyWallet(userStore, RP_ID, [`chrome-extension://${chrome.runtime.id}`], 60_000), - ); - - return wallet; -} diff --git a/apps/signer/src/lib/passkeys/userStore.ts b/apps/signer/src/lib/passkeys/userStore.ts index 222d416..a7cd05d 100644 --- a/apps/signer/src/lib/passkeys/userStore.ts +++ b/apps/signer/src/lib/passkeys/userStore.ts @@ -4,7 +4,7 @@ import SuperJSON from "superjson"; import { createStore } from "zustand"; import type { PersistStorage } from "zustand/middleware"; import { devtools, persist } from "zustand/middleware"; -import { RP_ID } from "./constants"; +import { RP_ID } from "~/lib/constants/RP_ID"; interface User { id: string; diff --git a/apps/signer/src/main.tsx b/apps/signer/src/main.tsx index b3f27e0..041dc2b 100644 --- a/apps/signer/src/main.tsx +++ b/apps/signer/src/main.tsx @@ -1,16 +1,21 @@ +import { PasskeyProvider } from "passkeys-react"; import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import { RouterProvider } from "react-router"; +import { WindowContextProvider } from "~/lib/Window.context.tsx"; import "./index.css"; +import { RP_ID } from "./lib/constants/RP_ID"; +import { userStore } from "./lib/passkeys/userStore"; import { router } from "./router"; -import {WindowContextProvider} from "~/lib/Window.context.tsx"; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion createRoot(document.getElementById("app")!).render( - + + - + + , ); diff --git a/apps/signer/src/pages/home/Home.tsx b/apps/signer/src/pages/home/Home.tsx index 2c49ae6..32bf6f5 100644 --- a/apps/signer/src/pages/home/Home.tsx +++ b/apps/signer/src/pages/home/Home.tsx @@ -3,11 +3,11 @@ import * as SimpleWebAuthnBrowser from "@simplewebauthn/browser"; import * as TaquitoUtils from "@taquito/utils"; import { Button, buttonVariants } from "jstz-ui/ui/button"; import { ArrowLeft, ExternalLink } from "lucide-react"; +import { parseKey } from "passkeys"; +import { usePasskeyWallet } from "passkeys-react"; import { Link, redirect, useLocation, useNavigate, type LoaderFunctionArgs } from "react-router"; import { AccountSelect } from "~/components/AccountSelect"; import { StorageKeys } from "~/lib/constants/storage"; -import { parseKey } from "~/lib/passkeys/encode"; -import { usePasskeyWallet } from "~/lib/passkeys/usePasskeyWallet"; import * as Vault from "~/lib/vault"; import { useVault, vault } from "~/lib/vaultStore"; import { loadHomeParams } from "./url-params"; @@ -113,7 +113,7 @@ interface RegisterPasskeyProps { } function RegisterPasskey({ onSuccess }: RegisterPasskeyProps) { - const wallet = usePasskeyWallet(); + const { wallet } = usePasskeyWallet(); const isPopup = (() => { const views = chrome.extension.getViews({ type: "popup" }); @@ -138,7 +138,7 @@ function RegisterPasskey({ onSuccess }: RegisterPasskeyProps) { async function handleCreatePasskeyWallet() { let attResp: RegistrationResponseJSON; try { - const opts = await wallet.current.generateRegistrationOptions(); + const opts = await wallet.generateRegistrationOptions(); attResp = await SimpleWebAuthnBrowser.startRegistration({ optionsJSON: opts }); } catch (err) { @@ -146,7 +146,7 @@ function RegisterPasskey({ onSuccess }: RegisterPasskeyProps) { return; } - const { verified, publicKey } = await wallet.current.verifyRegistration(attResp); + const { verified, publicKey } = await wallet.verifyRegistration(attResp); if (verified) { console.info(`Authenticator registered!`); diff --git a/apps/signer/src/pages/wallet/Wallet.tsx b/apps/signer/src/pages/wallet/Wallet.tsx index fd191f6..b1d6c23 100644 --- a/apps/signer/src/pages/wallet/Wallet.tsx +++ b/apps/signer/src/pages/wallet/Wallet.tsx @@ -8,6 +8,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "jstz-ui/ui/tooltip"; import { cn } from "jstz-ui/utils"; import { Eye, EyeOff } from "lucide-react"; import { useQueryStates } from "nuqs"; +import { usePasskeyWallet } from "passkeys-react"; import { Suspense, useState } from "react"; import { redirect, useParams, type LoaderFunctionArgs } from "react-router"; import SuperJSON from "superjson"; @@ -24,7 +25,6 @@ import { useWindowContext } from "~/lib/Window.context.tsx"; import { StorageKeys, type KeyStorage } from "~/lib/constants/storage"; import { toTezString } from "~/lib/currency.utils.ts"; import { createOperation, sign } from "~/lib/jstz"; -import { usePasskeyWallet } from "~/lib/passkeys/usePasskeyWallet"; import { useVault } from "~/lib/vaultStore"; import { RequestEventTypes, @@ -160,7 +160,7 @@ function OperationSigningDialog({ }: OperationSigningDialogProps) { const { close } = useWindowContext(); - const wallet = usePasskeyWallet(); + const { wallet } = usePasskeyWallet(); async function handleConfirm() { const operation = await createOperation({ @@ -182,7 +182,7 @@ function OperationSigningDialog({ signature: passKeySignature, authenticatorData, clientDataJSON, - } = await wallet.current.passkeySign(operation); + } = await wallet.passkeySign(operation); signature = passKeySignature; diff --git a/apps/signer/tsconfig.json b/apps/signer/tsconfig.json index 613677e..695186b 100644 --- a/apps/signer/tsconfig.json +++ b/apps/signer/tsconfig.json @@ -56,7 +56,7 @@ /* JavaScript Support */ "allowJs": true, - "checkJs": true, + "checkJs": false, // "maxNodeModuleJsDepth": 1, /* Emit */ diff --git a/packages/passkeys-react/package.json b/packages/passkeys-react/package.json new file mode 100644 index 0000000..4dee872 --- /dev/null +++ b/packages/passkeys-react/package.json @@ -0,0 +1,35 @@ +{ + "name": "passkeys-react", + "version": "0.0.1", + "description": "", + "scripts": { + "build": "tsdown", + "dev": "tsdown --watch" + }, + "main": "./dist/index.mjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.mts", + "files": [ + "dist" + ], + "keywords": [], + "author": "", + "license": "ISC", + "packageManager": "pnpm@10.12.4", + "peerDependencies": { + "react": "^19.0.0" + }, + "dependencies": { + "passkeys": "workspace:*" + }, + "devDependencies": { + "@types/react": "^19.2.6", + "react": "~19.2.0", + "tsdown": "^0.16.6", + "typescript": "^5.9.3" + }, + "exports": { + ".": "./dist/index.mjs", + "./package.json": "./package.json" + } +} diff --git a/packages/passkeys-react/src/PasskeyWalletProvider.jsx b/packages/passkeys-react/src/PasskeyWalletProvider.jsx new file mode 100644 index 0000000..58e5bfc --- /dev/null +++ b/packages/passkeys-react/src/PasskeyWalletProvider.jsx @@ -0,0 +1,28 @@ +import { PasskeyWallet } from "passkeys"; +import { createContext, useContext, useMemo, useRef } from "react"; + +/** @import {PropsWithChildren, Context} from "react"; */ +/** @import {UserStore} from "passkeys"; */ + +/** @type {Context<{ wallet: PasskeyWallet }>} */ +const PasskeyContext = createContext(/** @type {{ wallet: PasskeyWallet }} */ ({})); + +/** @param {PropsWithChildren<{ userStore: UserStore; RP_ID: string; extensionId: string }>} props */ +export function PasskeyProvider({ userStore, RP_ID, extensionId, children }) { + const wallet = useRef( + new PasskeyWallet(userStore, RP_ID, [`chrome-extension://${extensionId}`], 60_000), + ); + + const value = useMemo( + () => ({ + wallet: wallet.current, + }), + [], + ); + + return {children}; +} + +export function usePasskeyWallet() { + return useContext(PasskeyContext); +} diff --git a/packages/passkeys-react/src/constants.js b/packages/passkeys-react/src/constants.js new file mode 100644 index 0000000..2453a3d --- /dev/null +++ b/packages/passkeys-react/src/constants.js @@ -0,0 +1,2 @@ +/** Represents the "scope" of websites on which a credential should be usable. */ +export const RP_ID = "localhost"; diff --git a/packages/passkeys-react/src/index.js b/packages/passkeys-react/src/index.js new file mode 100644 index 0000000..0e866ef --- /dev/null +++ b/packages/passkeys-react/src/index.js @@ -0,0 +1 @@ +export * from "./PasskeyWalletProvider.jsx"; diff --git a/packages/passkeys-react/tsconfig.json b/packages/passkeys-react/tsconfig.json new file mode 100644 index 0000000..0fc74f1 --- /dev/null +++ b/packages/passkeys-react/tsconfig.json @@ -0,0 +1,117 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig.json", + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + "incremental": true, + // "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + // "disableSourceOfProjectReferenceRedirect": true, + // "disableSolutionSearching": true, + // "disableReferencedProjectLoad": true, + + /* Language and Environment */ + "target": "ES2024", + "lib": ["ES2024", "DOM", "DOM.Iterable"], + "jsx": "react-jsx", + // "experimentalDecorators": true, + // "emitDecoratorMetadata": true, + // "jsxFactory": "", + // "jsxFragmentFactory": "", + // "jsxImportSource": "", + // "reactNamespace": "", + // "noLib": true, + "useDefineForClassFields": true, + "moduleDetection": "force", + + /* Modules */ + "module": "ES2022", + // "rootDir": "./", + "moduleResolution": "bundler", + "baseUrl": "./", + "paths": { + "~/*": ["src/*"] + }, + // "rootDirs": [], + // "typeRoots": [], + // "types": [], + // "allowUmdGlobalAccess": true, + // "moduleSuffixes": [], + "allowImportingTsExtensions": true, + // "rewriteRelativeImportExtensions": true, + // "resolvePackageJsonExports": true, + // "resolvePackageJsonImports": true, + // "customConditions": [], + // "noUncheckedSideEffectImports": true, + "resolveJsonModule": true, + // "allowArbitraryExtensions": true, + // "noResolve": true, + + /* JavaScript Support */ + "allowJs": true, + "checkJs": true, + // "maxNodeModuleJsDepth": 1, + + /* Emit */ + "declaration": true, + // "declarationMap": true, + "emitDeclarationOnly": true, + // "sourceMap": true, + // "inlineSourceMap": true, + "noEmit": false, + // "outFile": "./", + "outDir": "./dist", + // "removeComments": true, + // "importHelpers": true, + // "downlevelIteration": true, + // "sourceRoot": "", + // "mapRoot": "", + // "inlineSources": true, + // "emitBOM": true, + // "newLine": "crlf", + // "stripInternal": true, + // "noEmitHelpers": true, + // "noEmitOnError": true, + // "preserveConstEnums": true, + // "declarationDir": "./", + + /* Interop Constraints */ + "isolatedModules": true, + "verbatimModuleSyntax": true, + // "isolatedDeclarations": true, + // "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + // "preserveSymlinks": true, + "forceConsistentCasingInFileNames": true, + + /* Type Checking */ + "strict": true, + // "noImplicitAny": true, + // "strictNullChecks": true, + // "strictFunctionTypes": true, + // "strictBindCallApply": true, + // "strictPropertyInitialization": true, + // "strictBuiltinIteratorReturn": true, + // "noImplicitThis": true, + // "useUnknownInCatchVariables": true, + // "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + // "exactOptionalPropertyTypes": true, + // "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + // "noImplicitOverride": true, + // "noPropertyAccessFromIndexSignature": true, + // "allowUnusedLabels": true, + // "allowUnreachableCode": true, + "noUncheckedSideEffectImports": true, + + /* Completeness */ + // "skipDefaultLibCheck": true, + "skipLibCheck": true + }, + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/packages/passkeys-react/tsdown.config.ts b/packages/passkeys-react/tsdown.config.ts new file mode 100644 index 0000000..11c13ca --- /dev/null +++ b/packages/passkeys-react/tsdown.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "tsdown"; + +export default defineConfig({ + entry: ["./src/index.js"], + outDir: "./dist", + dts: true, + format: "esm", + clean: true, + target: false, + platform: "node", + exports: true, +}); diff --git a/packages/passkeys/package.json b/packages/passkeys/package.json new file mode 100644 index 0000000..b2e52bb --- /dev/null +++ b/packages/passkeys/package.json @@ -0,0 +1,35 @@ +{ + "name": "passkeys", + "version": "0.0.1", + "description": "", + "scripts": { + "build": "tsdown", + "dev": "tsdown --watch" + }, + "main": "./dist/index.mjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.mts", + "files": [ + "dist" + ], + "keywords": [], + "author": "", + "license": "ISC", + "packageManager": "pnpm@10.12.4", + "dependencies": { + "@jstz-dev/jstz-client": "0.1.1-alpha.5", + "@jstz-dev/jstz_sdk": "0.1.1-alpha.5", + "@simplewebauthn/browser": "^13.2.2", + "@simplewebauthn/server": "^13.2.2", + "bs58": "^6.0.0", + "cbor": "^10.0.11" + }, + "devDependencies": { + "tsdown": "^0.16.6", + "typescript": "^5.9.3" + }, + "exports": { + ".": "./dist/index.mjs", + "./package.json": "./package.json" + } +} diff --git a/apps/signer/src/lib/passkeys/PasskeyWallet.js b/packages/passkeys/src/PasskeyWallet.js similarity index 98% rename from apps/signer/src/lib/passkeys/PasskeyWallet.js rename to packages/passkeys/src/PasskeyWallet.js index 2910102..55c2a3f 100644 --- a/apps/signer/src/lib/passkeys/PasskeyWallet.js +++ b/packages/passkeys/src/PasskeyWallet.js @@ -1,8 +1,7 @@ /** * @import {Jstz} from "@jstz-dev/jstz-client"; * @import {AuthenticationResponseJSON, GenerateAuthenticationOptionsOpts, GenerateRegistrationOptionsOpts, RegistrationResponseJSON, VerifyAuthenticationResponseOpts, VerifyRegistrationResponseOpts, WebAuthnCredential} from "@simplewebauthn/server"; - * @import {StoreApi} from "zustand"; - * @import {UserState} from "./userStore"; + * @import {UserStore} from "./userStore"; */ import { convert_passkey_signature, hash_operation } from "@jstz-dev/jstz_sdk"; @@ -22,7 +21,7 @@ export class PasskeyWallet { #expectedOrigin; /** - * @param {StoreApi} store + * @param {UserStore} store * @param {string} rpId * @param {string[] | string} expectedOrigin * @param {number} [timeout] diff --git a/apps/signer/src/lib/passkeys/encode.ts b/packages/passkeys/src/encode.js similarity index 61% rename from apps/signer/src/lib/passkeys/encode.ts rename to packages/passkeys/src/encode.js index 08db7e7..bdad975 100644 --- a/apps/signer/src/lib/passkeys/encode.ts +++ b/packages/passkeys/src/encode.js @@ -1,6 +1,24 @@ import bs58 from "bs58"; import * as cbor from "cbor"; +/** + * Helper for concatenating `Uint8Arrays` + * + * @param {Uint8Array[]} arrays + */ +export function concatUint8Arrays(arrays) { + const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0); + const result = new Uint8Array(totalLength); + + let offset = 0; + for (const arr of arrays) { + result.set(arr, offset); + offset += arr.length; + } + + return result; +} + /** * Convert a COSE-encoded (CBOR) public key (EC2) to a raw uncompressed public key. Returns a * base64-encoded string of the raw key: 0x04 || X || Y @@ -9,17 +27,20 @@ import * as cbor from "cbor"; * y-coordinate (byte string) 1: kty (should be 2 for EC2) * * If input is already a raw key, it will be returned as base64. + * + * @param {Uint8Array[]} buffer */ -export function coseToRaw(buffer: ArrayBuffer | Uint8Array | Buffer | string) { +export function coseToRaw(buffer) { // Try decode as CBOR COSE key - const decoded = cbor.decodeAllSync(buffer)[0] as - | Map - | Record - | null; + const decoded = /** @type {Map | Record | null} */ ( + cbor.decodeAllSync(buffer)[0] + ); // decoded may be a Map (with numeric keys) or an object - let x: Uint8Array | undefined; - let y: Uint8Array | undefined; + /** @type {Uint8Array | undefined} */ + let x; + /** @type {Uint8Array | undefined} */ + let y; if (decoded instanceof Map) { const xb = decoded.get(-2); @@ -36,24 +57,36 @@ export function coseToRaw(buffer: ArrayBuffer | Uint8Array | Buffer | string) { throw new TypeError("Could not find x/y coordinates when decoding COSE key"); } - if (x.length !== y.length) { + const xArr = new Uint8Array(x); + const yArr = new Uint8Array(y); + + if (xArr.length !== yArr.length) { // still proceed but warn // pad shorter to match (unlikely for valid keys) - const len = Math.max(x.length, y.length); - const xPad = Buffer.alloc(len); - const yPad = Buffer.alloc(len); - Buffer.from(x).copy(xPad, len - x.length); - Buffer.from(y).copy(yPad, len - y.length); + const len = Math.max(xArr.length, yArr.length); + + const xPad = new Uint8Array(len); + const yPad = new Uint8Array(len); + + xPad.set(xArr, len - xArr.length); + yPad.set(yArr, len - yArr.length); + x = xPad; y = yPad; + } else { + x = xArr; + y = yArr; } - const raw = Buffer.concat([Buffer.from([0x04]), x, y]); - return new Uint8Array(raw); + return concatUint8Arrays([new Uint8Array([0x04]), x, y]); } -/** Parse a COSE-encoded CBOR public key to a base58 string of the raw uncompressed key. */ -export async function parseKey(buffer: ArrayBuffer | Uint8Array | Buffer | string) { +/** + * Parse a COSE-encoded CBOR public key to a base58 string of the raw uncompressed key. + * + * @param {ArrayBuffer | Uint8Array | string} buffer + */ +export async function parseKey(buffer) { const rawKey = coseToRaw(buffer); const compressedKey = compressPublicKey(rawKey); @@ -74,7 +107,8 @@ export async function parseKey(buffer: ArrayBuffer | Uint8Array | Buffer | strin return bs58.encode(result); } -function compressPublicKey(rawKey: Uint8Array) { +/** @param {Uint8Array} rawKey */ +function compressPublicKey(rawKey) { if (rawKey.length !== 65 || rawKey[0] !== 0x04) { throw new Error("Expected uncompressed P-256 key"); } @@ -85,8 +119,8 @@ function compressPublicKey(rawKey: Uint8Array) { // Check parity of Y (last byte determines even/odd) // We're checking above if y[y.length - 1] exists - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const yIsOdd = (y[y.length - 1]! & 1) === 1; + // @ts-ignore + const yIsOdd = (y[y.length - 1] & 1) === 1; const prefix = yIsOdd ? 0x03 : 0x02; const compressed = new Uint8Array(33); diff --git a/packages/passkeys/src/index.ts b/packages/passkeys/src/index.ts new file mode 100644 index 0000000..de4a4b6 --- /dev/null +++ b/packages/passkeys/src/index.ts @@ -0,0 +1,3 @@ +export { parseKey } from "./encode.js"; +export { PasskeyWallet } from "./PasskeyWallet.js"; +export type * from "./userStore.d.ts"; diff --git a/packages/passkeys/src/userStore.d.ts b/packages/passkeys/src/userStore.d.ts new file mode 100644 index 0000000..c9739bb --- /dev/null +++ b/packages/passkeys/src/userStore.d.ts @@ -0,0 +1,19 @@ +import type { WebAuthnCredential } from "@simplewebauthn/browser"; + +export interface User { + id: string; + username: string; + credentials: WebAuthnCredential[]; +} + +interface UserActions { + addCredential: (cred: WebAuthnCredential) => void; + removeCredential: (credId: WebAuthnCredential["id"]) => void; + setCredential: (cred: WebAuthnCredential) => void; +} + +export type UserState = User & UserActions; + +export interface UserStore { + getState(): UserState; +} diff --git a/apps/signer/src/lib/passkeys/utils.js b/packages/passkeys/src/utils.js similarity index 100% rename from apps/signer/src/lib/passkeys/utils.js rename to packages/passkeys/src/utils.js diff --git a/packages/passkeys/tsconfig.json b/packages/passkeys/tsconfig.json new file mode 100644 index 0000000..3f28092 --- /dev/null +++ b/packages/passkeys/tsconfig.json @@ -0,0 +1,116 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig.json", + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + "incremental": true, + // "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + // "disableSourceOfProjectReferenceRedirect": true, + // "disableSolutionSearching": true, + // "disableReferencedProjectLoad": true, + + /* Language and Environment */ + "target": "ES2024", + "lib": ["ES2024", "DOM", "DOM.Iterable"], + // "experimentalDecorators": true, + // "emitDecoratorMetadata": true, + // "jsxFactory": "", + // "jsxFragmentFactory": "", + // "jsxImportSource": "", + // "reactNamespace": "", + // "noLib": true, + "useDefineForClassFields": true, + "moduleDetection": "force", + + /* Modules */ + "module": "ES2022", + // "rootDir": "./", + "moduleResolution": "bundler", + "baseUrl": "./", + "paths": { + "~/*": ["src/*"] + }, + // "rootDirs": [], + // "typeRoots": [], + // "types": [], + // "allowUmdGlobalAccess": true, + // "moduleSuffixes": [], + "allowImportingTsExtensions": true, + // "rewriteRelativeImportExtensions": true, + // "resolvePackageJsonExports": true, + // "resolvePackageJsonImports": true, + // "customConditions": [], + // "noUncheckedSideEffectImports": true, + "resolveJsonModule": true, + // "allowArbitraryExtensions": true, + // "noResolve": true, + + /* JavaScript Support */ + "allowJs": true, + "checkJs": true, + // "maxNodeModuleJsDepth": 1, + + /* Emit */ + "declaration": true, + // "declarationMap": true, + "emitDeclarationOnly": true, + // "sourceMap": true, + // "inlineSourceMap": true, + "noEmit": false, + // "outFile": "./", + "outDir": "./dist", + // "removeComments": true, + // "importHelpers": true, + // "downlevelIteration": true, + // "sourceRoot": "", + // "mapRoot": "", + // "inlineSources": true, + // "emitBOM": true, + // "newLine": "crlf", + // "stripInternal": true, + // "noEmitHelpers": true, + // "noEmitOnError": true, + // "preserveConstEnums": true, + // "declarationDir": "./", + + /* Interop Constraints */ + "isolatedModules": true, + "verbatimModuleSyntax": true, + // "isolatedDeclarations": true, + // "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + // "preserveSymlinks": true, + "forceConsistentCasingInFileNames": true, + + /* Type Checking */ + "strict": true, + // "noImplicitAny": true, + // "strictNullChecks": true, + // "strictFunctionTypes": true, + // "strictBindCallApply": true, + // "strictPropertyInitialization": true, + // "strictBuiltinIteratorReturn": true, + // "noImplicitThis": true, + // "useUnknownInCatchVariables": true, + // "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + // "exactOptionalPropertyTypes": true, + // "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + // "noImplicitOverride": true, + // "noPropertyAccessFromIndexSignature": true, + // "allowUnusedLabels": true, + // "allowUnreachableCode": true, + "noUncheckedSideEffectImports": true, + + /* Completeness */ + // "skipDefaultLibCheck": true, + "skipLibCheck": true + }, + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/packages/passkeys/tsdown.config.ts b/packages/passkeys/tsdown.config.ts new file mode 100644 index 0000000..11c13ca --- /dev/null +++ b/packages/passkeys/tsdown.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "tsdown"; + +export default defineConfig({ + entry: ["./src/index.js"], + outDir: "./dist", + dts: true, + format: "esm", + clean: true, + target: false, + platform: "node", + exports: true, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 839a2bf..cb386bc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -74,6 +74,12 @@ importers: nuqs: specifier: ^2.8.0 version: 2.8.0(react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0) + passkeys: + specifier: workspace:* + version: link:../../packages/passkeys + passkeys-react: + specifier: workspace:* + version: link:../../packages/passkeys-react react: specifier: ~19.2.0 version: 19.2.0 @@ -311,6 +317,53 @@ importers: specifier: ^3.2.4 version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.12)(@vitest/browser@3.2.4)(jiti@2.6.1)(lightningcss@1.30.2) + packages/passkeys: + dependencies: + '@jstz-dev/jstz-client': + specifier: 0.1.1-alpha.5 + version: 0.1.1-alpha.5 + '@jstz-dev/jstz_sdk': + specifier: 0.1.1-alpha.5 + version: 0.1.1-alpha.5 + '@simplewebauthn/browser': + specifier: ^13.2.2 + version: 13.2.2 + '@simplewebauthn/server': + specifier: ^13.2.2 + version: 13.2.2 + bs58: + specifier: ^6.0.0 + version: 6.0.0 + cbor: + specifier: ^10.0.11 + version: 10.0.11 + devDependencies: + tsdown: + specifier: ^0.16.6 + version: 0.16.6(typescript@5.9.3) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + + packages/passkeys-react: + dependencies: + passkeys: + specifier: workspace:* + version: link:../passkeys + devDependencies: + '@types/react': + specifier: ^19.2.6 + version: 19.2.6 + react: + specifier: ~19.2.0 + version: 19.2.0 + tsdown: + specifier: ^0.16.6 + version: 0.16.6(typescript@5.9.3) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + packages: '@adobe/css-tools@4.4.4': @@ -412,6 +465,15 @@ packages: peerDependencies: storybook: ^0.0.0-0 || ^9.0.0 || ^9.1.0-0 || ^9.2.0-0 || ^10.0.0-0 + '@emnapi/core@1.7.1': + resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} + + '@emnapi/runtime@1.7.1': + resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@es-joy/jsdoccomment@0.76.0': resolution: {integrity: sha512-g+RihtzFgGTx2WYCuTHbdOXJeAlGnROws0TeALx9ow/ZmOROOZkVg5wp/B44n0WJgI4SQFP1eWM2iRPlU2Y14w==} engines: {node: '>=20.11.0'} @@ -864,6 +926,9 @@ packages: '@types/react': '>=16' react: '>=16' + '@napi-rs/wasm-runtime@1.0.7': + resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} + '@neoconfetti/react@1.0.0': resolution: {integrity: sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==} @@ -883,6 +948,13 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@oxc-project/runtime@0.96.0': + resolution: {integrity: sha512-34lh4o9CcSw09Hx6fKihPu85+m+4pmDlkXwJrLvN5nMq5JrcGhhihVM415zDqT8j8IixO1PYYdQZRN4SwQCncg==} + engines: {node: ^20.19.0 || >=22.12.0} + + '@oxc-project/types@0.98.0': + resolution: {integrity: sha512-Vzmd6FsqVuz5HQVcRC/hrx7Ujo3WEVeQP7C2UNP5uy1hUY4SQvMB+93jxkI1KRHz9a/6cni3glPOtvteN+zpsw==} + '@peculiar/asn1-android@2.6.0': resolution: {integrity: sha512-cBRCKtYPF7vJGN76/yG8VbxRcHLPF3HnkoHhKOZeHpoVtbMYfY9ROKtH3DtYUY9m8uI1Mh47PRhHf2hSK3xcSQ==} @@ -927,6 +999,9 @@ packages: '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@quansync/fs@0.1.5': + resolution: {integrity: sha512-lNS9hL2aS2NZgNW7BBj+6EBl4rOf8l+tQ0eRY6JWCI8jI2kc53gSoqbjojU0OnAWhzoXiOjFyGsHcDGePB3lhA==} + '@radix-ui/number@1.1.1': resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} @@ -1357,12 +1432,98 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + '@rolldown/binding-android-arm64@1.0.0-beta.51': + resolution: {integrity: sha512-Ctn8FUXKWWQI9pWC61P1yumS9WjQtelNS9riHwV7oCkknPGaAry4o7eFx2KgoLMnI2BgFJYpW7Im8/zX3BuONg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-beta.51': + resolution: {integrity: sha512-EL1aRW2Oq15ShUEkBPsDtLMO8GTqfb/ktM/dFaVzXKQiEE96Ss6nexMgfgQrg8dGnNpndFyffVDb5IdSibsu1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-beta.51': + resolution: {integrity: sha512-uGtYKlFen9pMIPvkHPWZVDtmYhMQi5g5Ddsndg1gf3atScKYKYgs5aDP4DhHeTwGXQglhfBG7lEaOIZ4UAIWww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-beta.51': + resolution: {integrity: sha512-JRoVTQtHYbZj1P07JLiuTuXjiBtIa7ag7/qgKA6CIIXnAcdl4LrOf7nfDuHPJcuRKaP5dzecMgY99itvWfmUFQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.51': + resolution: {integrity: sha512-BKATVnpPZ0TYBW9XfDwyd4kPGgvf964HiotIwUgpMrFOFYWqpZ+9ONNzMV4UFAYC7Hb5C2qgYQk/qj2OnAd4RQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.51': + resolution: {integrity: sha512-xLd7da5jkfbVsBCm1buIRdWtuXY8+hU3+6ESXY/Tk5X5DPHaifrUblhYDgmA34dQt6WyNC2kfXGgrduPEvDI6Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.51': + resolution: {integrity: sha512-EQFXTgHxxTzv3t5EmjUP/DfxzFYx9sMndfLsYaAY4DWF6KsK1fXGYsiupif6qPTViPC9eVmRm78q0pZU/kuIPg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.51': + resolution: {integrity: sha512-p5P6Xpa68w3yFaAdSzIZJbj+AfuDnMDqNSeglBXM7UlJT14Q4zwK+rV+8Mhp9MiUb4XFISZtbI/seBprhkQbiQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.51': + resolution: {integrity: sha512-sNVVyLa8HB8wkFipdfz1s6i0YWinwpbMWk5hO5S+XAYH2UH67YzUT13gs6wZTKg2x/3gtgXzYnHyF5wMIqoDAw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.51': + resolution: {integrity: sha512-e/JMTz9Q8+T3g/deEi8DK44sFWZWGKr9AOCW5e8C8SCVWzAXqYXAG7FXBWBNzWEZK0Rcwo9TQHTQ9Q0gXgdCaA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.51': + resolution: {integrity: sha512-We3LWqSu6J9s5Y0MK+N7fUiiu37aBGPG3Pc347EoaROuAwkCS2u9xJ5dpIyLW4B49CIbS3KaPmn4kTgPb3EyPw==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.51': + resolution: {integrity: sha512-fj56buHRuMM+r/cb6ZYfNjNvO/0xeFybI6cTkTROJatdP4fvmQ1NS8D/Lm10FCSDEOkqIz8hK3TGpbAThbPHsA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.51': + resolution: {integrity: sha512-fkqEqaeEx8AySXiDm54b/RdINb3C0VovzJA3osMhZsbn6FoD73H0AOIiaVAtGr6x63hefruVKTX8irAm4Jkt2w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.51': + resolution: {integrity: sha512-CWuLG/HMtrVcjKGa0C4GnuxONrku89g0+CsH8nT0SNhOtREXuzwgjIXNJImpE/A/DMf9JF+1Xkrq/YRr+F/rCg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@rolldown/pluginutils@1.0.0-beta.43': resolution: {integrity: sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==} '@rolldown/pluginutils@1.0.0-beta.47': resolution: {integrity: sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw==} + '@rolldown/pluginutils@1.0.0-beta.51': + resolution: {integrity: sha512-51/8cNXMrqWqX3o8DZidhwz1uYq0BhHDDSfVygAND1Skx5s1TDw3APSSxCMcFFedwgqGcx34gRouwY+m404BBQ==} + '@rollup/plugin-inject@5.0.5': resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} engines: {node: '>=14.0.0'} @@ -2127,6 +2288,9 @@ packages: svelte: optional: true + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -2449,6 +2613,10 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + are-docs-informative@0.0.2: resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} engines: {node: '>=14'} @@ -2509,6 +2677,10 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-kit@2.2.0: + resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} + engines: {node: '>=20.19.0'} + ast-types@0.16.1: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} @@ -2557,6 +2729,9 @@ packages: bip39@3.1.0: resolution: {integrity: sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==} + birpc@2.8.0: + resolution: {integrity: sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==} + blakejs@1.2.1: resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} @@ -2679,6 +2854,10 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + chromatic@12.2.0: resolution: {integrity: sha512-GswmBW9ZptAoTns1BMyjbm55Z7EsIJnUvYKdQqXIBZIKbGErmpA+p4c0BYA+nzw5B0M+rb3Iqp1IaH8TFwIQew==} hasBin: true @@ -2841,6 +3020,10 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + diff@8.0.2: + resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} + engines: {node: '>=0.3.1'} + diffie-hellman@5.0.3: resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} @@ -2862,6 +3045,15 @@ packages: resolution: {integrity: sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==} engines: {node: '>=10'} + dts-resolver@2.1.3: + resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==} + engines: {node: '>=20.19.0'} + peerDependencies: + oxc-resolver: '>=11.0.0' + peerDependenciesMeta: + oxc-resolver: + optional: true + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -2884,6 +3076,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + enhanced-resolve@5.18.3: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} @@ -3183,6 +3379,9 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -3283,6 +3482,9 @@ packages: hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + html-entities@2.6.0: resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} @@ -3873,6 +4075,9 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + obug@2.1.0: + resolution: {integrity: sha512-uu/tgLPoa75CFA7UDkmqspKbefvZh1WMPwkU3bNr0PY746a/+xwXVgbw5co5C3GvJj3h5u8g/pbxXzI0gd1QFg==} + open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} @@ -4123,6 +4328,9 @@ packages: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + querystring-es3@0.2.1: resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} engines: {node: '>=0.4.x'} @@ -4222,6 +4430,10 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + recast@0.23.11: resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} @@ -4252,6 +4464,9 @@ packages: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.11: resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} @@ -4269,6 +4484,30 @@ packages: resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} engines: {node: '>= 0.8'} + rolldown-plugin-dts@0.18.0: + resolution: {integrity: sha512-2CJtKYa9WPClZxkJeCt4bGUegQvQKQ1VJp9jFJzG0h8I/80XI6qDgoWfVJUOEhT2swbsRQh/42N1RIWvbXT4rA==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@ts-macro/tsc': ^0.3.6 + '@typescript/native-preview': '>=7.0.0-dev.20250601.1' + rolldown: ^1.0.0-beta.51 + typescript: ^5.0.0 + vue-tsc: ~3.1.0 + peerDependenciesMeta: + '@ts-macro/tsc': + optional: true + '@typescript/native-preview': + optional: true + typescript: + optional: true + vue-tsc: + optional: true + + rolldown@1.0.0-beta.51: + resolution: {integrity: sha512-ZRLgPlS91l4JztLYEZnmMcd3Umcla1hkXJgiEiR4HloRJBBoeaX8qogTu5Jfu36rRMVLndzqYv0h+M5gJAkUfg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup@4.52.5: resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -4522,6 +4761,10 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} @@ -4557,6 +4800,10 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + ts-api-utils@2.1.0: resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} @@ -4581,6 +4828,31 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} + tsdown@0.16.6: + resolution: {integrity: sha512-g3xHEnGdfwJTlXhEkqww3Q/KlCfyNFw4rnzuQ9Gqw8T2xjDYrw94qmSw5wYYTAW5zV1sEfWDlfgxZo5mmtu0NQ==} + engines: {node: '>=20.19.0'} + hasBin: true + peerDependencies: + '@arethetypeswrong/core': ^0.18.1 + '@vitejs/devtools': ^0.0.0-alpha.17 + publint: ^0.3.0 + typescript: ^5.0.0 + unplugin-lightningcss: ^0.4.0 + unplugin-unused: ^0.5.0 + peerDependenciesMeta: + '@arethetypeswrong/core': + optional: true + '@vitejs/devtools': + optional: true + publint: + optional: true + typescript: + optional: true + unplugin-lightningcss: + optional: true + unplugin-unused: + optional: true + tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -4646,6 +4918,9 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} + unconfig-core@7.4.1: + resolution: {integrity: sha512-Bp/bPZjV2Vl/fofoA2OYLSnw1Z0MOhCX7zHnVCYrazpfZvseBbGhwcNQMxsg185Mqh7VZQqK3C8hFG/Dyng+yA==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -4667,6 +4942,16 @@ packages: resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} engines: {node: '>=14.0.0'} + unrun@0.2.11: + resolution: {integrity: sha512-HjUuNLRGfRxMvxkwOuO/CpkSzdizTPPApbarLplsTzUm8Kex+nS9eomKU1qgVus6WGWkDYhtf/mgNxGEpyTR6A==} + engines: {node: '>=20.19.0'} + hasBin: true + peerDependencies: + synckit: ^0.11.11 + peerDependenciesMeta: + synckit: + optional: true + update-browserslist-db@1.1.4: resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} hasBin: true @@ -5091,6 +5376,22 @@ snapshots: - '@chromatic-com/cypress' - '@chromatic-com/playwright' + '@emnapi/core@1.7.1': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.7.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + '@es-joy/jsdoccomment@0.76.0': dependencies: '@types/estree': 1.0.8 @@ -5412,6 +5713,13 @@ snapshots: '@types/react': 19.2.2 react: 19.2.0 + '@napi-rs/wasm-runtime@1.0.7': + dependencies: + '@emnapi/core': 1.7.1 + '@emnapi/runtime': 1.7.1 + '@tybys/wasm-util': 0.10.1 + optional: true + '@neoconfetti/react@1.0.0': {} '@noble/hashes@1.8.0': {} @@ -5428,6 +5736,10 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 + '@oxc-project/runtime@0.96.0': {} + + '@oxc-project/types@0.98.0': {} + '@peculiar/asn1-android@2.6.0': dependencies: '@peculiar/asn1-schema': 2.6.0 @@ -5529,6 +5841,10 @@ snapshots: '@polka/url@1.0.0-next.29': {} + '@quansync/fs@0.1.5': + dependencies: + quansync: 0.2.11 + '@radix-ui/number@1.1.1': {} '@radix-ui/primitive@1.1.3': {} @@ -5968,10 +6284,56 @@ snapshots: '@radix-ui/rect@1.1.1': {} + '@rolldown/binding-android-arm64@1.0.0-beta.51': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-beta.51': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-beta.51': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-beta.51': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.51': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.51': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.51': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.51': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.51': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.51': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.51': + dependencies: + '@napi-rs/wasm-runtime': 1.0.7 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.51': + optional: true + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.51': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.51': + optional: true + '@rolldown/pluginutils@1.0.0-beta.43': {} '@rolldown/pluginutils@1.0.0-beta.47': {} + '@rolldown/pluginutils@1.0.0-beta.51': {} + '@rollup/plugin-inject@5.0.5(rollup@4.53.3)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.53.3) @@ -6677,6 +7039,11 @@ snapshots: - supports-color optional: true + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + '@types/aria-query@5.0.4': {} '@types/babel__core@7.20.5': @@ -7094,6 +7461,8 @@ snapshots: ansi-styles@6.2.3: {} + ansis@4.2.0: {} + are-docs-informative@0.0.2: {} argparse@2.0.1: {} @@ -7187,6 +7556,11 @@ snapshots: assertion-error@2.0.1: {} + ast-kit@2.2.0: + dependencies: + '@babel/parser': 7.28.5 + pathe: 2.0.3 + ast-types@0.16.1: dependencies: tslib: 2.8.1 @@ -7223,6 +7597,8 @@ snapshots: dependencies: '@noble/hashes': 1.8.0 + birpc@2.8.0: {} + blakejs@1.2.1: {} bn.js@4.12.2: {} @@ -7377,6 +7753,10 @@ snapshots: check-error@2.1.1: {} + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + chromatic@12.2.0: {} cipher-base@1.0.7: @@ -7535,6 +7915,8 @@ snapshots: dependencies: dequal: 2.0.3 + diff@8.0.2: {} + diffie-hellman@5.0.3: dependencies: bn.js: 4.12.2 @@ -7555,6 +7937,8 @@ snapshots: domain-browser@4.22.0: {} + dts-resolver@2.1.3: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -7584,6 +7968,8 @@ snapshots: emoji-regex@9.2.2: {} + empathic@2.0.0: {} + enhanced-resolve@5.18.3: dependencies: graceful-fs: 4.2.11 @@ -8094,6 +8480,10 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -8195,6 +8585,8 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + hookable@5.5.3: {} + html-entities@2.6.0: {} https-browserify@1.0.0: {} @@ -8828,6 +9220,8 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + obug@2.1.0: {} + open@8.4.2: dependencies: define-lazy-prop: 2.0.0 @@ -9030,6 +9424,8 @@ snapshots: dependencies: side-channel: 1.1.0 + quansync@0.2.11: {} + querystring-es3@0.2.1: {} queue-microtask@1.2.3: {} @@ -9141,6 +9537,8 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readdirp@4.1.2: {} + recast@0.23.11: dependencies: ast-types: 0.16.1 @@ -9186,6 +9584,8 @@ snapshots: resolve-from@4.0.0: {} + resolve-pkg-maps@1.0.0: {} + resolve@1.22.11: dependencies: is-core-module: 2.16.1 @@ -9205,6 +9605,43 @@ snapshots: hash-base: 3.1.2 inherits: 2.0.4 + rolldown-plugin-dts@0.18.0(rolldown@1.0.0-beta.51)(typescript@5.9.3): + dependencies: + '@babel/generator': 7.28.5 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + ast-kit: 2.2.0 + birpc: 2.8.0 + dts-resolver: 2.1.3 + get-tsconfig: 4.13.0 + magic-string: 0.30.21 + obug: 2.1.0 + rolldown: 1.0.0-beta.51 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - oxc-resolver + + rolldown@1.0.0-beta.51: + dependencies: + '@oxc-project/types': 0.98.0 + '@rolldown/pluginutils': 1.0.0-beta.51 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-beta.51 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.51 + '@rolldown/binding-darwin-x64': 1.0.0-beta.51 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.51 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.51 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.51 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.51 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.51 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.51 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.51 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.51 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.51 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.51 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.51 + rollup@4.52.5: dependencies: '@types/estree': 1.0.8 @@ -9552,6 +9989,8 @@ snapshots: tinyexec@0.3.2: {} + tinyexec@1.0.2: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) @@ -9582,6 +10021,8 @@ snapshots: tr46@0.0.3: {} + tree-kill@1.2.2: {} + ts-api-utils@2.1.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -9598,6 +10039,32 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 + tsdown@0.16.6(typescript@5.9.3): + dependencies: + ansis: 4.2.0 + cac: 6.7.14 + chokidar: 4.0.3 + diff: 8.0.2 + empathic: 2.0.0 + hookable: 5.5.3 + obug: 2.1.0 + rolldown: 1.0.0-beta.51 + rolldown-plugin-dts: 0.18.0(rolldown@1.0.0-beta.51)(typescript@5.9.3) + semver: 7.7.3 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + unconfig-core: 7.4.1 + unrun: 0.2.11 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@ts-macro/tsc' + - '@typescript/native-preview' + - oxc-resolver + - synckit + - vue-tsc + tslib@1.14.1: {} tslib@2.8.1: {} @@ -9682,6 +10149,11 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 + unconfig-core@7.4.1: + dependencies: + '@quansync/fs': 0.1.5 + quansync: 0.2.11 + undici-types@6.21.0: {} undici-types@7.16.0: {} @@ -9699,6 +10171,11 @@ snapshots: acorn: 8.15.0 webpack-virtual-modules: 0.6.2 + unrun@0.2.11: + dependencies: + '@oxc-project/runtime': 0.96.0 + rolldown: 1.0.0-beta.51 + update-browserslist-db@1.1.4(browserslist@4.28.0): dependencies: browserslist: 4.28.0