├── .eslintrc.js ├── .github └── workflows │ ├── main.yml │ └── size.yml ├── .gitignore ├── .prettierrc ├── LICENSE ├── README.md ├── examples ├── nextjs │ ├── .eslintrc.json │ ├── .gitignore │ ├── README.md │ ├── next.config.js │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── mockServiceWorker.js │ │ ├── next.svg │ │ ├── thirteen.svg │ │ └── vercel.svg │ ├── src │ │ ├── components │ │ │ ├── auth-screen.tsx │ │ │ ├── ui.tsx │ │ │ └── user-info.tsx │ │ ├── lib │ │ │ ├── api.ts │ │ │ ├── auth.ts │ │ │ └── utils.ts │ │ ├── mocks │ │ │ ├── browser.ts │ │ │ ├── db.ts │ │ │ ├── handlers.ts │ │ │ ├── index.ts │ │ │ └── server.ts │ │ ├── pages │ │ │ ├── _app.tsx │ │ │ ├── _document.tsx │ │ │ ├── api │ │ │ │ └── hello.ts │ │ │ └── index.tsx │ │ └── styles │ │ │ ├── Home.module.css │ │ │ └── globals.css │ ├── tsconfig.json │ └── yarn.lock └── vite │ ├── index.html │ ├── index.tsx │ ├── package.json │ ├── public │ └── mockServiceWorker.js │ ├── src │ ├── App.tsx │ ├── components │ │ ├── auth-screen.tsx │ │ ├── ui.tsx │ │ └── user-info.tsx │ ├── lib │ │ ├── api.ts │ │ ├── auth.ts │ │ └── utils.ts │ └── mocks │ │ ├── api-server.ts │ │ └── db.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ ├── vite.config.js │ └── yarn.lock ├── jest.config.js ├── package.json ├── src └── index.tsx ├── test └── index.test.tsx ├── tsconfig.json ├── tsup.config.ts └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | }, 6 | extends: [ 7 | 'eslint:recommended', 8 | 'plugin:react/recommended', 9 | 'plugin:@typescript-eslint/recommended', 10 | 'prettier', 11 | ], 12 | overrides: [], 13 | parser: '@typescript-eslint/parser', 14 | parserOptions: { 15 | ecmaVersion: 'latest', 16 | sourceType: 'module', 17 | }, 18 | plugins: ['react', '@typescript-eslint'], 19 | rules: {}, 20 | settings: { 21 | react: { 22 | version: 'detect', 23 | }, 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | jobs: 4 | build: 5 | name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }} 6 | 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | node: ['16.x', '18.x'] 11 | os: [ubuntu-latest, windows-latest, macOS-latest] 12 | 13 | steps: 14 | - name: Checkout repo 15 | uses: actions/checkout@v3 16 | 17 | - name: Use Node ${{ matrix.node }} 18 | uses: actions/setup-node@v3 19 | with: 20 | node-version: ${{ matrix.node }} 21 | 22 | - name: Install deps and build (with cache) 23 | uses: bahmutov/npm-install@v1 24 | 25 | - name: Lint 26 | run: yarn lint 27 | 28 | - name: Test 29 | run: yarn test --ci --coverage --maxWorkers=2 30 | 31 | - name: Build 32 | run: yarn build 33 | -------------------------------------------------------------------------------- /.github/workflows/size.yml: -------------------------------------------------------------------------------- 1 | name: size 2 | on: [pull_request] 3 | jobs: 4 | size: 5 | runs-on: ubuntu-latest 6 | env: 7 | CI_JOB_NUMBER: 1 8 | steps: 9 | - uses: actions/checkout@v3 10 | - uses: andresz1/size-limit-action@v1 11 | with: 12 | github_token: ${{ secrets.GITHUB_TOKEN }} 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .DS_Store 3 | node_modules 4 | .cache 5 | dist 6 | .yalc 7 | yalc.lock -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "semi": true, 4 | "singleQuote": true, 5 | "trailingComma": "es5", 6 | "endOfLine": "auto" 7 | } 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Alan Alickovic 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-query-auth 2 | 3 | [![NPM](https://img.shields.io/npm/v/react-query-auth.svg)](https://www.npmjs.com/package/react-query-auth) 4 | 5 | Authenticate your react applications easily with [React Query](https://tanstack.com/query/v4/docs/react). 6 | 7 | ## Introduction 8 | 9 | Using React Query has allowed us to significantly reduce the size of our codebase by caching server state. However, we still need to consider where to store user data, which is a type of global application state that we need to access from many parts of the app, but is also a server state since it is obtained from a server. This library makes it easy to manage user authentication, and can be adapted to work with any API or authentication method. 10 | 11 | ## Installation 12 | 13 | ``` 14 | $ npm install @tanstack/react-query react-query-auth 15 | ``` 16 | 17 | Or if you use Yarn: 18 | 19 | ``` 20 | $ yarn add @tanstack/react-query react-query-auth 21 | ``` 22 | 23 | ## Usage 24 | 25 | To use this library, you will need to provide it with functions for fetching the current user, logging in, registering, and logging out. You can do this using the `configureAuth` function: 26 | 27 | ```ts 28 | import { configureAuth } from 'react-query-auth'; 29 | 30 | const { useUser, useLogin, useRegister, useLogout } = configureAuth({ 31 | userFn: () => api.get('/me'), 32 | loginFn: (credentials) => api.post('/login', credentials), 33 | registerFn: (credentials) => api.post('/register', credentials), 34 | logoutFn: () => api.post('/logout'), 35 | }); 36 | ``` 37 | 38 | With these hooks, you can then add authentication functionality to your app. For example, you could use the `useUser` hook to access the authenticated user in a component. 39 | 40 | You can also use the `useLogin`, `useRegister`, and `useLogout` hooks to allow users to authenticate and log out. 41 | 42 | ```tsx 43 | function UserInfo() { 44 | const user = useUser(); 45 | const logout = useLogout(); 46 | 47 | if (user.isLoading) { 48 | return
Loading ...
; 49 | } 50 | 51 | if (user.error) { 52 | return
{JSON.stringify(user.error, null, 2)}
; 53 | } 54 | 55 | if (!user.data) { 56 | return
Not logged in
; 57 | } 58 | 59 | return ( 60 |
61 |
Logged in as {user.data.email}
62 | 65 |
66 | ); 67 | } 68 | ``` 69 | 70 | The library also provides the `AuthLoader` component that can be used to handle loading states when fetching the authenticated user. You can use it like this: 71 | 72 | ```tsx 73 | function MyApp() { 74 | return ( 75 |
Loading ...
} 77 | renderUnauthenticated={() => } 78 | > 79 | 80 |
81 | ); 82 | } 83 | ``` 84 | 85 | **NOTE: All hooks and components must be used within `QueryClientProvider`.** 86 | 87 | ## API Reference: 88 | 89 | ### `configureAuth`: 90 | 91 | The `configureAuth` function takes in a configuration object and returns a set of custom hooks for handling authentication. 92 | 93 | #### The `configureAuth` configuration object: 94 | 95 | A configuration object that specifies the functions and keys to be used for various authentication actions. It accepts the following properties: 96 | 97 | - **`userFn`:** 98 | A function that is used to retrieve the authenticated user. It should return a Promise that resolves to the user object, or null if the user is not authenticated. 99 | 100 | - **`loginFn`:** 101 | A function that is used to log the user in. It should accept login credentials as its argument and return a Promise that resolves to the user object. 102 | 103 | - **`registerFn`:** 104 | A function that is used to register a new user. It should accept registration credentials as its argument and return a Promise that resolves to the new user object. 105 | 106 | - **`logoutFn`:** 107 | A function that is used to log the user out. It should return a Promise that resolves when the logout action is complete. 108 | 109 | - **`userKey`:** 110 | An optional key that is used to store the authenticated user in the react-query cache. The default value is `['authenticated-user']`. 111 | 112 | #### The `configureAuth` returned object: 113 | 114 | `configureAuth` returns an object with the following properties: 115 | 116 | - **`useUser`:** 117 | A custom hook that retrieves the authenticated user. It is a wrapper around [useQuery](https://tanstack.com/query/v4/docs/react/reference/useQuery) that uses the `userFn` and `userKey` specified in the `configAuth` configuration. The hook accepts the same options as [useQuery](https://tanstack.com/query/v4/docs/react/reference/useQuery), except for `queryKey` and `queryFn`, which are predefined by the configuration. 118 | 119 | - **`useLogin`:** 120 | A custom hook that logs the user in. It is a wrapper around [useMutation](https://tanstack.com/query/v4/docs/react/reference/useMutation) that uses the `loginFn` specified in the configuration. The hook accepts the same options as [useMutation](https://tanstack.com/query/v4/docs/react/reference/useMutation), except for `mutationFn`, which is set by the configuration. On success, the hook updates the authenticated user in the React Query cache using the `userKey` specified in the configuration. 121 | 122 | - **`useRegister`:** 123 | A custom hook that registers a new user. It is a wrapper around [useMutation](https://tanstack.com/query/v4/docs/react/reference/useMutation) that uses the `registerFn` specified in the configuration. The hook accepts the same options as [useMutation](https://tanstack.com/query/v4/docs/react/reference/useMutation), except for `mutationFn`, which is set by the configuration. On success, the hook updates the authenticated user in the React Query cache using the `userKey` specified in the configuration. 124 | 125 | - **`useLogout`:** 126 | A custom hook that logs the user out. It is a wrapper around [useMutation](https://tanstack.com/query/v4/docs/react/reference/useMutation) that uses the `logoutFn` specified in the configuration. The hook accepts the same options as [useMutation](https://tanstack.com/query/v4/docs/react/reference/useMutation), except for `mutationFn`, which is set by the configuration. On success, the hook removes the authenticated user from the React Query cache using the `userKey` specified in the configuration. 127 | 128 | - **`AuthLoader`:** 129 | 130 | A component that can be used to handle loading states when fetching the authenticated user. It accepts the following props: 131 | 132 | - **`renderLoading`**: 133 | A function that is called when the authenticated user is being fetched. It should return a React node that is rendered while the user is being fetched. 134 | 135 | - **`renderUnauthenticated`**: 136 | A function that is called when the authenticated user is not authenticated. It should return a React node that is rendered when the user is not authenticated. 137 | 138 | - **`renderError`**: 139 | A function that is called when an error is thrown during the authentication request. It should return a React node that is rendered when the error occurs. It receives the `Error` object which can be used during rendering. Defaults to `(error: Error) => <>{JSON.stringify(error)}`. 140 | 141 | - **`children`**: 142 | A React node that is rendered when the authenticated user is successfully fetched. 143 | 144 | If you need a more custom loading implementation, you can create your own `AuthLoader` component and use the `useUser` hook to fetch the authenticated user and handle the loading and error states yourself. 145 | 146 | ## Examples: 147 | 148 | To try out the library, check out the `examples` folder. 149 | 150 | ## Contributing 151 | 152 | 1. Clone this repo 153 | 2. Create a branch: `git checkout -b your-feature` 154 | 3. Make some changes 155 | 4. Test your changes 156 | 5. Push your branch and open a Pull Request 157 | 158 | ## LICENSE 159 | 160 | MIT 161 | -------------------------------------------------------------------------------- /examples/nextjs/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /examples/nextjs/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /examples/nextjs/README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | # or 12 | pnpm dev 13 | ``` 14 | 15 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 16 | 17 | You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file. 18 | 19 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`. 20 | 21 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. 22 | 23 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. 24 | 25 | ## Learn More 26 | 27 | To learn more about Next.js, take a look at the following resources: 28 | 29 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 30 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 31 | 32 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 33 | 34 | ## Deploy on Vercel 35 | 36 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 37 | 38 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 39 | -------------------------------------------------------------------------------- /examples/nextjs/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | experimental: { 5 | externalDir: true, 6 | }, 7 | }; 8 | 9 | module.exports = nextConfig; 10 | -------------------------------------------------------------------------------- /examples/nextjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@next/font": "13.1.6", 13 | "@tanstack/react-query": "^4.24.6", 14 | "@tanstack/react-query-devtools": "^4.24.6", 15 | "@types/node": "18.13.0", 16 | "@types/react": "18.0.28", 17 | "@types/react-dom": "18.0.11", 18 | "eslint": "8.34.0", 19 | "eslint-config-next": "13.1.6", 20 | "msw": "^1.0.1", 21 | "next": "13.1.6", 22 | "react": "18.2.0", 23 | "react-dom": "18.2.0", 24 | "react-query-auth": "^2.1.1", 25 | "typescript": "4.9.5" 26 | }, 27 | "msw": { 28 | "workerDirectory": "public" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/nextjs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnfrench3/react-query/065ad8e8d8f994a97d8c0dd526ea2dac2e2ef4b2/examples/nextjs/public/favicon.ico -------------------------------------------------------------------------------- /examples/nextjs/public/mockServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* tslint:disable */ 3 | 4 | /** 5 | * Mock Service Worker (1.0.1). 6 | * @see https://github.com/mswjs/msw 7 | * - Please do NOT modify this file. 8 | * - Please do NOT serve this file on production. 9 | */ 10 | 11 | const INTEGRITY_CHECKSUM = '3d6b9f06410d179a7f7404d4bf4c3c70' 12 | const activeClientIds = new Set() 13 | 14 | self.addEventListener('install', function () { 15 | self.skipWaiting() 16 | }) 17 | 18 | self.addEventListener('activate', function (event) { 19 | event.waitUntil(self.clients.claim()) 20 | }) 21 | 22 | self.addEventListener('message', async function (event) { 23 | const clientId = event.source.id 24 | 25 | if (!clientId || !self.clients) { 26 | return 27 | } 28 | 29 | const client = await self.clients.get(clientId) 30 | 31 | if (!client) { 32 | return 33 | } 34 | 35 | const allClients = await self.clients.matchAll({ 36 | type: 'window', 37 | }) 38 | 39 | switch (event.data) { 40 | case 'KEEPALIVE_REQUEST': { 41 | sendToClient(client, { 42 | type: 'KEEPALIVE_RESPONSE', 43 | }) 44 | break 45 | } 46 | 47 | case 'INTEGRITY_CHECK_REQUEST': { 48 | sendToClient(client, { 49 | type: 'INTEGRITY_CHECK_RESPONSE', 50 | payload: INTEGRITY_CHECKSUM, 51 | }) 52 | break 53 | } 54 | 55 | case 'MOCK_ACTIVATE': { 56 | activeClientIds.add(clientId) 57 | 58 | sendToClient(client, { 59 | type: 'MOCKING_ENABLED', 60 | payload: true, 61 | }) 62 | break 63 | } 64 | 65 | case 'MOCK_DEACTIVATE': { 66 | activeClientIds.delete(clientId) 67 | break 68 | } 69 | 70 | case 'CLIENT_CLOSED': { 71 | activeClientIds.delete(clientId) 72 | 73 | const remainingClients = allClients.filter((client) => { 74 | return client.id !== clientId 75 | }) 76 | 77 | // Unregister itself when there are no more clients 78 | if (remainingClients.length === 0) { 79 | self.registration.unregister() 80 | } 81 | 82 | break 83 | } 84 | } 85 | }) 86 | 87 | self.addEventListener('fetch', function (event) { 88 | const { request } = event 89 | const accept = request.headers.get('accept') || '' 90 | 91 | // Bypass server-sent events. 92 | if (accept.includes('text/event-stream')) { 93 | return 94 | } 95 | 96 | // Bypass navigation requests. 97 | if (request.mode === 'navigate') { 98 | return 99 | } 100 | 101 | // Opening the DevTools triggers the "only-if-cached" request 102 | // that cannot be handled by the worker. Bypass such requests. 103 | if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { 104 | return 105 | } 106 | 107 | // Bypass all requests when there are no active clients. 108 | // Prevents the self-unregistered worked from handling requests 109 | // after it's been deleted (still remains active until the next reload). 110 | if (activeClientIds.size === 0) { 111 | return 112 | } 113 | 114 | // Generate unique request ID. 115 | const requestId = Math.random().toString(16).slice(2) 116 | 117 | event.respondWith( 118 | handleRequest(event, requestId).catch((error) => { 119 | if (error.name === 'NetworkError') { 120 | console.warn( 121 | '[MSW] Successfully emulated a network error for the "%s %s" request.', 122 | request.method, 123 | request.url, 124 | ) 125 | return 126 | } 127 | 128 | // At this point, any exception indicates an issue with the original request/response. 129 | console.error( 130 | `\ 131 | [MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`, 132 | request.method, 133 | request.url, 134 | `${error.name}: ${error.message}`, 135 | ) 136 | }), 137 | ) 138 | }) 139 | 140 | async function handleRequest(event, requestId) { 141 | const client = await resolveMainClient(event) 142 | const response = await getResponse(event, client, requestId) 143 | 144 | // Send back the response clone for the "response:*" life-cycle events. 145 | // Ensure MSW is active and ready to handle the message, otherwise 146 | // this message will pend indefinitely. 147 | if (client && activeClientIds.has(client.id)) { 148 | ;(async function () { 149 | const clonedResponse = response.clone() 150 | sendToClient(client, { 151 | type: 'RESPONSE', 152 | payload: { 153 | requestId, 154 | type: clonedResponse.type, 155 | ok: clonedResponse.ok, 156 | status: clonedResponse.status, 157 | statusText: clonedResponse.statusText, 158 | body: 159 | clonedResponse.body === null ? null : await clonedResponse.text(), 160 | headers: Object.fromEntries(clonedResponse.headers.entries()), 161 | redirected: clonedResponse.redirected, 162 | }, 163 | }) 164 | })() 165 | } 166 | 167 | return response 168 | } 169 | 170 | // Resolve the main client for the given event. 171 | // Client that issues a request doesn't necessarily equal the client 172 | // that registered the worker. It's with the latter the worker should 173 | // communicate with during the response resolving phase. 174 | async function resolveMainClient(event) { 175 | const client = await self.clients.get(event.clientId) 176 | 177 | if (client?.frameType === 'top-level') { 178 | return client 179 | } 180 | 181 | const allClients = await self.clients.matchAll({ 182 | type: 'window', 183 | }) 184 | 185 | return allClients 186 | .filter((client) => { 187 | // Get only those clients that are currently visible. 188 | return client.visibilityState === 'visible' 189 | }) 190 | .find((client) => { 191 | // Find the client ID that's recorded in the 192 | // set of clients that have registered the worker. 193 | return activeClientIds.has(client.id) 194 | }) 195 | } 196 | 197 | async function getResponse(event, client, requestId) { 198 | const { request } = event 199 | const clonedRequest = request.clone() 200 | 201 | function passthrough() { 202 | // Clone the request because it might've been already used 203 | // (i.e. its body has been read and sent to the client). 204 | const headers = Object.fromEntries(clonedRequest.headers.entries()) 205 | 206 | // Remove MSW-specific request headers so the bypassed requests 207 | // comply with the server's CORS preflight check. 208 | // Operate with the headers as an object because request "Headers" 209 | // are immutable. 210 | delete headers['x-msw-bypass'] 211 | 212 | return fetch(clonedRequest, { headers }) 213 | } 214 | 215 | // Bypass mocking when the client is not active. 216 | if (!client) { 217 | return passthrough() 218 | } 219 | 220 | // Bypass initial page load requests (i.e. static assets). 221 | // The absence of the immediate/parent client in the map of the active clients 222 | // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet 223 | // and is not ready to handle requests. 224 | if (!activeClientIds.has(client.id)) { 225 | return passthrough() 226 | } 227 | 228 | // Bypass requests with the explicit bypass header. 229 | // Such requests can be issued by "ctx.fetch()". 230 | if (request.headers.get('x-msw-bypass') === 'true') { 231 | return passthrough() 232 | } 233 | 234 | // Notify the client that a request has been intercepted. 235 | const clientMessage = await sendToClient(client, { 236 | type: 'REQUEST', 237 | payload: { 238 | id: requestId, 239 | url: request.url, 240 | method: request.method, 241 | headers: Object.fromEntries(request.headers.entries()), 242 | cache: request.cache, 243 | mode: request.mode, 244 | credentials: request.credentials, 245 | destination: request.destination, 246 | integrity: request.integrity, 247 | redirect: request.redirect, 248 | referrer: request.referrer, 249 | referrerPolicy: request.referrerPolicy, 250 | body: await request.text(), 251 | bodyUsed: request.bodyUsed, 252 | keepalive: request.keepalive, 253 | }, 254 | }) 255 | 256 | switch (clientMessage.type) { 257 | case 'MOCK_RESPONSE': { 258 | return respondWithMock(clientMessage.data) 259 | } 260 | 261 | case 'MOCK_NOT_FOUND': { 262 | return passthrough() 263 | } 264 | 265 | case 'NETWORK_ERROR': { 266 | const { name, message } = clientMessage.data 267 | const networkError = new Error(message) 268 | networkError.name = name 269 | 270 | // Rejecting a "respondWith" promise emulates a network error. 271 | throw networkError 272 | } 273 | } 274 | 275 | return passthrough() 276 | } 277 | 278 | function sendToClient(client, message) { 279 | return new Promise((resolve, reject) => { 280 | const channel = new MessageChannel() 281 | 282 | channel.port1.onmessage = (event) => { 283 | if (event.data && event.data.error) { 284 | return reject(event.data.error) 285 | } 286 | 287 | resolve(event.data) 288 | } 289 | 290 | client.postMessage(message, [channel.port2]) 291 | }) 292 | } 293 | 294 | function sleep(timeMs) { 295 | return new Promise((resolve) => { 296 | setTimeout(resolve, timeMs) 297 | }) 298 | } 299 | 300 | async function respondWithMock(response) { 301 | await sleep(response.delay) 302 | return new Response(response.body, response) 303 | } 304 | -------------------------------------------------------------------------------- /examples/nextjs/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/nextjs/public/thirteen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/nextjs/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/nextjs/src/components/auth-screen.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { 4 | LoginCredentials, 5 | RegisterCredentials, 6 | useLogin, 7 | useRegister, 8 | } from '../lib/auth'; 9 | 10 | import { Button, Form, Input } from './ui'; 11 | 12 | export const AuthScreen = () => { 13 | const [mode, setMode] = React.useState<'register' | 'login'>('register'); 14 | 15 | return ( 16 |
17 | {mode === 'login' && ( 18 | <> 19 | 20 | 21 | 22 | )} 23 | {mode === 'register' && ( 24 | <> 25 | 26 | 27 | 28 | )} 29 |
30 | ); 31 | }; 32 | 33 | const useForm = >(initialValues?: V) => { 34 | const [values, setValues] = React.useState(initialValues || {}); 35 | 36 | const onChange = (e: React.ChangeEvent) => { 37 | setValues((v) => ({ ...v, [e.target.name]: e.target.value })); 38 | }; 39 | 40 | return { 41 | values: values as V, 42 | onChange, 43 | }; 44 | }; 45 | 46 | const RegisterForm = () => { 47 | const register = useRegister(); 48 | const { values, onChange } = useForm(); 49 | 50 | return ( 51 |
{ 54 | e.preventDefault(); 55 | register.mutate(values, { 56 | onSuccess: () => console.log('registered'), 57 | }); 58 | }} 59 | error={register.error} 60 | > 61 | 68 | 69 | 75 | 78 |
79 | ); 80 | }; 81 | 82 | const LoginForm = () => { 83 | const login = useLogin(); 84 | const { values, onChange } = useForm(); 85 | 86 | return ( 87 |
{ 90 | e.preventDefault(); 91 | login.mutate(values); 92 | }} 93 | error={login.error} 94 | > 95 | 102 | 108 | 111 |
112 | ); 113 | }; 114 | -------------------------------------------------------------------------------- /examples/nextjs/src/components/ui.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export const Button = ( 4 | props: React.ButtonHTMLAttributes 5 | ) => { 6 | return ( 7 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /examples/nextjs/src/lib/api.ts: -------------------------------------------------------------------------------- 1 | import { storage } from './utils'; 2 | 3 | export interface AuthResponse { 4 | user: User; 5 | jwt: string; 6 | } 7 | 8 | export interface User { 9 | id: string; 10 | email: string; 11 | name?: string; 12 | } 13 | 14 | export async function handleApiResponse(response: Response) { 15 | const data = await response.json(); 16 | 17 | if (response.ok) { 18 | return data; 19 | } else { 20 | console.error(JSON.stringify(data, null, 2)); 21 | return Promise.reject(data); 22 | } 23 | } 24 | 25 | export function getUserProfile(): Promise<{ user: User | undefined }> { 26 | return fetch('/auth/me', { 27 | headers: { 28 | Authorization: storage.getToken(), 29 | }, 30 | }).then(handleApiResponse); 31 | } 32 | 33 | export function loginWithEmailAndPassword( 34 | data: unknown 35 | ): Promise { 36 | return fetch('/auth/login', { 37 | method: 'POST', 38 | body: JSON.stringify(data), 39 | }).then(handleApiResponse); 40 | } 41 | 42 | export function registerWithEmailAndPassword( 43 | data: unknown 44 | ): Promise { 45 | return fetch('/auth/register', { 46 | method: 'POST', 47 | body: JSON.stringify(data), 48 | }).then(handleApiResponse); 49 | } 50 | 51 | export function logout(): Promise<{ message: string }> { 52 | return fetch('/auth/logout', { method: 'POST' }).then(handleApiResponse); 53 | } 54 | -------------------------------------------------------------------------------- /examples/nextjs/src/lib/auth.ts: -------------------------------------------------------------------------------- 1 | import { configureAuth } from 'react-query-auth'; 2 | import { 3 | getUserProfile, 4 | registerWithEmailAndPassword, 5 | loginWithEmailAndPassword, 6 | AuthResponse, 7 | logout, 8 | } from './api'; 9 | import { storage } from './utils'; 10 | 11 | export type LoginCredentials = { 12 | email: string; 13 | password: string; 14 | }; 15 | 16 | export type RegisterCredentials = { 17 | email: string; 18 | name: string; 19 | password: string; 20 | }; 21 | 22 | async function handleUserResponse(data: AuthResponse) { 23 | const { jwt, user } = data; 24 | storage.setToken(jwt); 25 | return user; 26 | } 27 | 28 | async function userFn() { 29 | const { user } = await getUserProfile(); 30 | return user ?? null; 31 | } 32 | 33 | async function loginFn(data: LoginCredentials) { 34 | const response = await loginWithEmailAndPassword(data); 35 | const user = await handleUserResponse(response); 36 | return user; 37 | } 38 | 39 | async function registerFn(data: RegisterCredentials) { 40 | const response = await registerWithEmailAndPassword(data); 41 | const user = await handleUserResponse(response); 42 | return user; 43 | } 44 | 45 | async function logoutFn() { 46 | await logout(); 47 | } 48 | 49 | export const { useUser, useLogin, useRegister, useLogout, AuthLoader } = 50 | configureAuth({ 51 | userFn, 52 | loginFn, 53 | registerFn, 54 | logoutFn, 55 | }); 56 | -------------------------------------------------------------------------------- /examples/nextjs/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | export const storage = { 2 | getToken: () => JSON.parse(window.localStorage.getItem('token') || 'null'), 3 | setToken: (token: string) => 4 | window.localStorage.setItem('token', JSON.stringify(token)), 5 | clearToken: () => window.localStorage.removeItem('token'), 6 | }; 7 | -------------------------------------------------------------------------------- /examples/nextjs/src/mocks/browser.ts: -------------------------------------------------------------------------------- 1 | import { setupWorker } from 'msw'; 2 | import { handlers } from './handlers'; 3 | 4 | export const worker = setupWorker(...handlers); 5 | -------------------------------------------------------------------------------- /examples/nextjs/src/mocks/db.ts: -------------------------------------------------------------------------------- 1 | export type DBUser = { 2 | email: string; 3 | name: string; 4 | password: string; 5 | }; 6 | 7 | const users: Record = JSON.parse( 8 | typeof window !== 'undefined' 9 | ? window.localStorage.getItem('db_users') || '{}' 10 | : '{}' 11 | ); 12 | 13 | export function setUser(data: DBUser) { 14 | if (data?.email) { 15 | users[data.email] = data; 16 | window.localStorage.setItem('db_users', JSON.stringify(users)); 17 | return data; 18 | } else { 19 | return null; 20 | } 21 | } 22 | 23 | export function getUser(email: string | null) { 24 | if (email) { 25 | return users[email]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/nextjs/src/mocks/handlers.ts: -------------------------------------------------------------------------------- 1 | import { rest } from 'msw'; 2 | import { storage } from '../lib/utils'; 3 | import { DBUser, getUser, setUser } from './db'; 4 | 5 | export const handlers = [ 6 | rest.get('/auth/me', (req, res, ctx) => { 7 | const user = getUser(req.headers.get('Authorization')); 8 | 9 | return res(ctx.delay(1000), ctx.json({ user })); 10 | }), 11 | rest.post('/auth/login', async (req, res, ctx) => { 12 | const parsedBody = (await req.json()) as DBUser; 13 | const user = getUser(parsedBody.email); 14 | if (user && user.password === parsedBody.password) { 15 | return res( 16 | ctx.delay(1000), 17 | ctx.json({ 18 | jwt: user.email, 19 | user, 20 | }) 21 | ); 22 | } else { 23 | return res( 24 | ctx.delay(1000), 25 | ctx.status(401), 26 | ctx.json({ message: 'Unauthorized' }) 27 | ); 28 | } 29 | }), 30 | rest.post('/auth/register', async (req, res, ctx) => { 31 | const parsedBody = (await req.json()) as DBUser; 32 | const user = getUser(parsedBody?.email); 33 | if (!user && parsedBody) { 34 | const newUser = setUser(parsedBody); 35 | if (newUser) { 36 | return res( 37 | ctx.delay(1000), 38 | ctx.json({ 39 | jwt: newUser.email, 40 | user: getUser(newUser.email), 41 | }) 42 | ); 43 | } 44 | return res( 45 | ctx.delay(1000), 46 | ctx.status(403), 47 | ctx.json({ message: 'Registration failed!' }) 48 | ); 49 | } else { 50 | return res( 51 | ctx.delay(1000), 52 | ctx.status(400), 53 | ctx.json({ message: 'The user already exists!' }) 54 | ); 55 | } 56 | }), 57 | rest.post('/auth/logout', (req, res, ctx) => { 58 | storage.clearToken(); 59 | return res(ctx.delay(1000), ctx.json({ message: 'Logged out' })); 60 | }), 61 | ]; 62 | -------------------------------------------------------------------------------- /examples/nextjs/src/mocks/index.ts: -------------------------------------------------------------------------------- 1 | async function initMocks() { 2 | if (typeof window === 'undefined') { 3 | const { server } = await import('./server'); 4 | server.listen(); 5 | } else { 6 | const { worker } = await import('./browser'); 7 | worker.start(); 8 | } 9 | } 10 | 11 | initMocks(); 12 | 13 | export {}; 14 | -------------------------------------------------------------------------------- /examples/nextjs/src/mocks/server.ts: -------------------------------------------------------------------------------- 1 | import { setupServer } from 'msw/node'; 2 | import { handlers } from './handlers'; 3 | 4 | export const server = setupServer(...handlers); 5 | -------------------------------------------------------------------------------- /examples/nextjs/src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; 2 | import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; 3 | import type { AppProps } from 'next/app'; 4 | import React from 'react'; 5 | 6 | require('../mocks'); 7 | 8 | export default function App({ Component, pageProps }: AppProps) { 9 | const [queryClient] = React.useState(() => new QueryClient()); 10 | 11 | return ( 12 | 13 | 14 | 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /examples/nextjs/src/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from 'next/document' 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /examples/nextjs/src/pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | import type { NextApiRequest, NextApiResponse } from 'next' 3 | 4 | type Data = { 5 | name: string 6 | } 7 | 8 | export default function handler( 9 | req: NextApiRequest, 10 | res: NextApiResponse 11 | ) { 12 | res.status(200).json({ name: 'John Doe' }) 13 | } 14 | -------------------------------------------------------------------------------- /examples/nextjs/src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { Container } from '@/components/ui'; 2 | import { AuthLoader } from '@/lib/auth'; 3 | import { AuthScreen } from '@/components/auth-screen'; 4 | import { UserInfo } from '@/components/user-info'; 5 | 6 | export default function Home() { 7 | return ( 8 | 9 |
Loading ...
} 11 | renderUnauthenticated={() => } 12 | > 13 | 14 |
15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /examples/nextjs/src/styles/Home.module.css: -------------------------------------------------------------------------------- 1 | .main { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: space-between; 5 | align-items: center; 6 | padding: 6rem; 7 | min-height: 100vh; 8 | } 9 | 10 | .description { 11 | display: inherit; 12 | justify-content: inherit; 13 | align-items: inherit; 14 | font-size: 0.85rem; 15 | max-width: var(--max-width); 16 | width: 100%; 17 | z-index: 2; 18 | font-family: var(--font-mono); 19 | } 20 | 21 | .description a { 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | gap: 0.5rem; 26 | } 27 | 28 | .description p { 29 | position: relative; 30 | margin: 0; 31 | padding: 1rem; 32 | background-color: rgba(var(--callout-rgb), 0.5); 33 | border: 1px solid rgba(var(--callout-border-rgb), 0.3); 34 | border-radius: var(--border-radius); 35 | } 36 | 37 | .code { 38 | font-weight: 700; 39 | font-family: var(--font-mono); 40 | } 41 | 42 | .grid { 43 | display: grid; 44 | grid-template-columns: repeat(4, minmax(25%, auto)); 45 | width: var(--max-width); 46 | max-width: 100%; 47 | } 48 | 49 | .card { 50 | padding: 1rem 1.2rem; 51 | border-radius: var(--border-radius); 52 | background: rgba(var(--card-rgb), 0); 53 | border: 1px solid rgba(var(--card-border-rgb), 0); 54 | transition: background 200ms, border 200ms; 55 | } 56 | 57 | .card span { 58 | display: inline-block; 59 | transition: transform 200ms; 60 | } 61 | 62 | .card h2 { 63 | font-weight: 600; 64 | margin-bottom: 0.7rem; 65 | } 66 | 67 | .card p { 68 | margin: 0; 69 | opacity: 0.6; 70 | font-size: 0.9rem; 71 | line-height: 1.5; 72 | max-width: 30ch; 73 | } 74 | 75 | .center { 76 | display: flex; 77 | justify-content: center; 78 | align-items: center; 79 | position: relative; 80 | padding: 4rem 0; 81 | } 82 | 83 | .center::before { 84 | background: var(--secondary-glow); 85 | border-radius: 50%; 86 | width: 480px; 87 | height: 360px; 88 | margin-left: -400px; 89 | } 90 | 91 | .center::after { 92 | background: var(--primary-glow); 93 | width: 240px; 94 | height: 180px; 95 | z-index: -1; 96 | } 97 | 98 | .center::before, 99 | .center::after { 100 | content: ''; 101 | left: 50%; 102 | position: absolute; 103 | filter: blur(45px); 104 | transform: translateZ(0); 105 | } 106 | 107 | .logo, 108 | .thirteen { 109 | position: relative; 110 | } 111 | 112 | .thirteen { 113 | display: flex; 114 | justify-content: center; 115 | align-items: center; 116 | width: 75px; 117 | height: 75px; 118 | padding: 25px 10px; 119 | margin-left: 16px; 120 | transform: translateZ(0); 121 | border-radius: var(--border-radius); 122 | overflow: hidden; 123 | box-shadow: 0px 2px 8px -1px #0000001a; 124 | } 125 | 126 | .thirteen::before, 127 | .thirteen::after { 128 | content: ''; 129 | position: absolute; 130 | z-index: -1; 131 | } 132 | 133 | /* Conic Gradient Animation */ 134 | .thirteen::before { 135 | animation: 6s rotate linear infinite; 136 | width: 200%; 137 | height: 200%; 138 | background: var(--tile-border); 139 | } 140 | 141 | /* Inner Square */ 142 | .thirteen::after { 143 | inset: 0; 144 | padding: 1px; 145 | border-radius: var(--border-radius); 146 | background: linear-gradient( 147 | to bottom right, 148 | rgba(var(--tile-start-rgb), 1), 149 | rgba(var(--tile-end-rgb), 1) 150 | ); 151 | background-clip: content-box; 152 | } 153 | 154 | /* Enable hover only on non-touch devices */ 155 | @media (hover: hover) and (pointer: fine) { 156 | .card:hover { 157 | background: rgba(var(--card-rgb), 0.1); 158 | border: 1px solid rgba(var(--card-border-rgb), 0.15); 159 | } 160 | 161 | .card:hover span { 162 | transform: translateX(4px); 163 | } 164 | } 165 | 166 | @media (prefers-reduced-motion) { 167 | .thirteen::before { 168 | animation: none; 169 | } 170 | 171 | .card:hover span { 172 | transform: none; 173 | } 174 | } 175 | 176 | /* Mobile */ 177 | @media (max-width: 700px) { 178 | .content { 179 | padding: 4rem; 180 | } 181 | 182 | .grid { 183 | grid-template-columns: 1fr; 184 | margin-bottom: 120px; 185 | max-width: 320px; 186 | text-align: center; 187 | } 188 | 189 | .card { 190 | padding: 1rem 2.5rem; 191 | } 192 | 193 | .card h2 { 194 | margin-bottom: 0.5rem; 195 | } 196 | 197 | .center { 198 | padding: 8rem 0 6rem; 199 | } 200 | 201 | .center::before { 202 | transform: none; 203 | height: 300px; 204 | } 205 | 206 | .description { 207 | font-size: 0.8rem; 208 | } 209 | 210 | .description a { 211 | padding: 1rem; 212 | } 213 | 214 | .description p, 215 | .description div { 216 | display: flex; 217 | justify-content: center; 218 | position: fixed; 219 | width: 100%; 220 | } 221 | 222 | .description p { 223 | align-items: center; 224 | inset: 0 0 auto; 225 | padding: 2rem 1rem 1.4rem; 226 | border-radius: 0; 227 | border: none; 228 | border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); 229 | background: linear-gradient( 230 | to bottom, 231 | rgba(var(--background-start-rgb), 1), 232 | rgba(var(--callout-rgb), 0.5) 233 | ); 234 | background-clip: padding-box; 235 | backdrop-filter: blur(24px); 236 | } 237 | 238 | .description div { 239 | align-items: flex-end; 240 | pointer-events: none; 241 | inset: auto 0 0; 242 | padding: 2rem; 243 | height: 200px; 244 | background: linear-gradient( 245 | to bottom, 246 | transparent 0%, 247 | rgb(var(--background-end-rgb)) 40% 248 | ); 249 | z-index: 1; 250 | } 251 | } 252 | 253 | /* Tablet and Smaller Desktop */ 254 | @media (min-width: 701px) and (max-width: 1120px) { 255 | .grid { 256 | grid-template-columns: repeat(2, 50%); 257 | } 258 | } 259 | 260 | @media (prefers-color-scheme: dark) { 261 | .vercelLogo { 262 | filter: invert(1); 263 | } 264 | 265 | .logo, 266 | .thirteen img { 267 | filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); 268 | } 269 | } 270 | 271 | @keyframes rotate { 272 | from { 273 | transform: rotate(360deg); 274 | } 275 | to { 276 | transform: rotate(0deg); 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /examples/nextjs/src/styles/globals.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --max-width: 1100px; 3 | --border-radius: 12px; 4 | --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 5 | 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', 6 | 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace; 7 | 8 | --foreground-rgb: 0, 0, 0; 9 | --background-start-rgb: 214, 219, 220; 10 | --background-end-rgb: 255, 255, 255; 11 | 12 | --primary-glow: conic-gradient( 13 | from 180deg at 50% 50%, 14 | #16abff33 0deg, 15 | #0885ff33 55deg, 16 | #54d6ff33 120deg, 17 | #0071ff33 160deg, 18 | transparent 360deg 19 | ); 20 | --secondary-glow: radial-gradient( 21 | rgba(255, 255, 255, 1), 22 | rgba(255, 255, 255, 0) 23 | ); 24 | 25 | --tile-start-rgb: 239, 245, 249; 26 | --tile-end-rgb: 228, 232, 233; 27 | --tile-border: conic-gradient( 28 | #00000080, 29 | #00000040, 30 | #00000030, 31 | #00000020, 32 | #00000010, 33 | #00000010, 34 | #00000080 35 | ); 36 | 37 | --callout-rgb: 238, 240, 241; 38 | --callout-border-rgb: 172, 175, 176; 39 | --card-rgb: 180, 185, 188; 40 | --card-border-rgb: 131, 134, 135; 41 | } 42 | 43 | @media (prefers-color-scheme: dark) { 44 | :root { 45 | --foreground-rgb: 255, 255, 255; 46 | --background-start-rgb: 0, 0, 0; 47 | --background-end-rgb: 0, 0, 0; 48 | 49 | --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); 50 | --secondary-glow: linear-gradient( 51 | to bottom right, 52 | rgba(1, 65, 255, 0), 53 | rgba(1, 65, 255, 0), 54 | rgba(1, 65, 255, 0.3) 55 | ); 56 | 57 | --tile-start-rgb: 2, 13, 46; 58 | --tile-end-rgb: 2, 5, 19; 59 | --tile-border: conic-gradient( 60 | #ffffff80, 61 | #ffffff40, 62 | #ffffff30, 63 | #ffffff20, 64 | #ffffff10, 65 | #ffffff10, 66 | #ffffff80 67 | ); 68 | 69 | --callout-rgb: 20, 20, 20; 70 | --callout-border-rgb: 108, 108, 108; 71 | --card-rgb: 100, 100, 100; 72 | --card-border-rgb: 200, 200, 200; 73 | } 74 | } 75 | 76 | * { 77 | box-sizing: border-box; 78 | padding: 0; 79 | margin: 0; 80 | } 81 | 82 | html, 83 | body { 84 | max-width: 100vw; 85 | overflow-x: hidden; 86 | } 87 | 88 | body { 89 | color: rgb(var(--foreground-rgb)); 90 | background: linear-gradient( 91 | to bottom, 92 | transparent, 93 | rgb(var(--background-end-rgb)) 94 | ) 95 | rgb(var(--background-start-rgb)); 96 | } 97 | 98 | a { 99 | color: inherit; 100 | text-decoration: none; 101 | } 102 | 103 | @media (prefers-color-scheme: dark) { 104 | html { 105 | color-scheme: dark; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /examples/nextjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@/*": ["./src/*"] 20 | } 21 | }, 22 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 23 | "exclude": ["node_modules"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/vite/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Playground 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/vite/index.tsx: -------------------------------------------------------------------------------- 1 | import 'react-app-polyfill/ie11'; 2 | import * as React from 'react'; 3 | import * as ReactDOM from 'react-dom'; 4 | 5 | import App from '@/App'; 6 | import { worker } from '@/mocks/api-server'; 7 | 8 | worker.start(); 9 | 10 | ReactDOM.render(, document.getElementById('root')); 11 | -------------------------------------------------------------------------------- /examples/vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "private": true, 4 | "version": "1.0.0", 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "cross-env NODE_ENV=production vite --port=3000", 8 | "build": "vite build" 9 | }, 10 | "dependencies": { 11 | "@tanstack/react-query": "^4.24.6", 12 | "@tanstack/react-query-devtools": "^4.24.6", 13 | "cross-env": "^7.0.3", 14 | "msw": "^1.0.1", 15 | "react-app-polyfill": "^3.0.0", 16 | "react-query-auth": "2.1.1" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "^18.14.0", 20 | "@types/react": "^18.0.28", 21 | "@types/react-dom": "^18.0.11", 22 | "react": "^18.2.0", 23 | "react-dom": "^18.2.0", 24 | "typescript": "^4", 25 | "vite": "latest", 26 | "vite-preset-react": "latest" 27 | }, 28 | "msw": { 29 | "workerDirectory": "public" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/vite/public/mockServiceWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* tslint:disable */ 3 | 4 | /** 5 | * Mock Service Worker (1.0.1). 6 | * @see https://github.com/mswjs/msw 7 | * - Please do NOT modify this file. 8 | * - Please do NOT serve this file on production. 9 | */ 10 | 11 | const INTEGRITY_CHECKSUM = '3d6b9f06410d179a7f7404d4bf4c3c70' 12 | const activeClientIds = new Set() 13 | 14 | self.addEventListener('install', function () { 15 | self.skipWaiting() 16 | }) 17 | 18 | self.addEventListener('activate', function (event) { 19 | event.waitUntil(self.clients.claim()) 20 | }) 21 | 22 | self.addEventListener('message', async function (event) { 23 | const clientId = event.source.id 24 | 25 | if (!clientId || !self.clients) { 26 | return 27 | } 28 | 29 | const client = await self.clients.get(clientId) 30 | 31 | if (!client) { 32 | return 33 | } 34 | 35 | const allClients = await self.clients.matchAll({ 36 | type: 'window', 37 | }) 38 | 39 | switch (event.data) { 40 | case 'KEEPALIVE_REQUEST': { 41 | sendToClient(client, { 42 | type: 'KEEPALIVE_RESPONSE', 43 | }) 44 | break 45 | } 46 | 47 | case 'INTEGRITY_CHECK_REQUEST': { 48 | sendToClient(client, { 49 | type: 'INTEGRITY_CHECK_RESPONSE', 50 | payload: INTEGRITY_CHECKSUM, 51 | }) 52 | break 53 | } 54 | 55 | case 'MOCK_ACTIVATE': { 56 | activeClientIds.add(clientId) 57 | 58 | sendToClient(client, { 59 | type: 'MOCKING_ENABLED', 60 | payload: true, 61 | }) 62 | break 63 | } 64 | 65 | case 'MOCK_DEACTIVATE': { 66 | activeClientIds.delete(clientId) 67 | break 68 | } 69 | 70 | case 'CLIENT_CLOSED': { 71 | activeClientIds.delete(clientId) 72 | 73 | const remainingClients = allClients.filter((client) => { 74 | return client.id !== clientId 75 | }) 76 | 77 | // Unregister itself when there are no more clients 78 | if (remainingClients.length === 0) { 79 | self.registration.unregister() 80 | } 81 | 82 | break 83 | } 84 | } 85 | }) 86 | 87 | self.addEventListener('fetch', function (event) { 88 | const { request } = event 89 | const accept = request.headers.get('accept') || '' 90 | 91 | // Bypass server-sent events. 92 | if (accept.includes('text/event-stream')) { 93 | return 94 | } 95 | 96 | // Bypass navigation requests. 97 | if (request.mode === 'navigate') { 98 | return 99 | } 100 | 101 | // Opening the DevTools triggers the "only-if-cached" request 102 | // that cannot be handled by the worker. Bypass such requests. 103 | if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { 104 | return 105 | } 106 | 107 | // Bypass all requests when there are no active clients. 108 | // Prevents the self-unregistered worked from handling requests 109 | // after it's been deleted (still remains active until the next reload). 110 | if (activeClientIds.size === 0) { 111 | return 112 | } 113 | 114 | // Generate unique request ID. 115 | const requestId = Math.random().toString(16).slice(2) 116 | 117 | event.respondWith( 118 | handleRequest(event, requestId).catch((error) => { 119 | if (error.name === 'NetworkError') { 120 | console.warn( 121 | '[MSW] Successfully emulated a network error for the "%s %s" request.', 122 | request.method, 123 | request.url, 124 | ) 125 | return 126 | } 127 | 128 | // At this point, any exception indicates an issue with the original request/response. 129 | console.error( 130 | `\ 131 | [MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`, 132 | request.method, 133 | request.url, 134 | `${error.name}: ${error.message}`, 135 | ) 136 | }), 137 | ) 138 | }) 139 | 140 | async function handleRequest(event, requestId) { 141 | const client = await resolveMainClient(event) 142 | const response = await getResponse(event, client, requestId) 143 | 144 | // Send back the response clone for the "response:*" life-cycle events. 145 | // Ensure MSW is active and ready to handle the message, otherwise 146 | // this message will pend indefinitely. 147 | if (client && activeClientIds.has(client.id)) { 148 | ;(async function () { 149 | const clonedResponse = response.clone() 150 | sendToClient(client, { 151 | type: 'RESPONSE', 152 | payload: { 153 | requestId, 154 | type: clonedResponse.type, 155 | ok: clonedResponse.ok, 156 | status: clonedResponse.status, 157 | statusText: clonedResponse.statusText, 158 | body: 159 | clonedResponse.body === null ? null : await clonedResponse.text(), 160 | headers: Object.fromEntries(clonedResponse.headers.entries()), 161 | redirected: clonedResponse.redirected, 162 | }, 163 | }) 164 | })() 165 | } 166 | 167 | return response 168 | } 169 | 170 | // Resolve the main client for the given event. 171 | // Client that issues a request doesn't necessarily equal the client 172 | // that registered the worker. It's with the latter the worker should 173 | // communicate with during the response resolving phase. 174 | async function resolveMainClient(event) { 175 | const client = await self.clients.get(event.clientId) 176 | 177 | if (client?.frameType === 'top-level') { 178 | return client 179 | } 180 | 181 | const allClients = await self.clients.matchAll({ 182 | type: 'window', 183 | }) 184 | 185 | return allClients 186 | .filter((client) => { 187 | // Get only those clients that are currently visible. 188 | return client.visibilityState === 'visible' 189 | }) 190 | .find((client) => { 191 | // Find the client ID that's recorded in the 192 | // set of clients that have registered the worker. 193 | return activeClientIds.has(client.id) 194 | }) 195 | } 196 | 197 | async function getResponse(event, client, requestId) { 198 | const { request } = event 199 | const clonedRequest = request.clone() 200 | 201 | function passthrough() { 202 | // Clone the request because it might've been already used 203 | // (i.e. its body has been read and sent to the client). 204 | const headers = Object.fromEntries(clonedRequest.headers.entries()) 205 | 206 | // Remove MSW-specific request headers so the bypassed requests 207 | // comply with the server's CORS preflight check. 208 | // Operate with the headers as an object because request "Headers" 209 | // are immutable. 210 | delete headers['x-msw-bypass'] 211 | 212 | return fetch(clonedRequest, { headers }) 213 | } 214 | 215 | // Bypass mocking when the client is not active. 216 | if (!client) { 217 | return passthrough() 218 | } 219 | 220 | // Bypass initial page load requests (i.e. static assets). 221 | // The absence of the immediate/parent client in the map of the active clients 222 | // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet 223 | // and is not ready to handle requests. 224 | if (!activeClientIds.has(client.id)) { 225 | return passthrough() 226 | } 227 | 228 | // Bypass requests with the explicit bypass header. 229 | // Such requests can be issued by "ctx.fetch()". 230 | if (request.headers.get('x-msw-bypass') === 'true') { 231 | return passthrough() 232 | } 233 | 234 | // Notify the client that a request has been intercepted. 235 | const clientMessage = await sendToClient(client, { 236 | type: 'REQUEST', 237 | payload: { 238 | id: requestId, 239 | url: request.url, 240 | method: request.method, 241 | headers: Object.fromEntries(request.headers.entries()), 242 | cache: request.cache, 243 | mode: request.mode, 244 | credentials: request.credentials, 245 | destination: request.destination, 246 | integrity: request.integrity, 247 | redirect: request.redirect, 248 | referrer: request.referrer, 249 | referrerPolicy: request.referrerPolicy, 250 | body: await request.text(), 251 | bodyUsed: request.bodyUsed, 252 | keepalive: request.keepalive, 253 | }, 254 | }) 255 | 256 | switch (clientMessage.type) { 257 | case 'MOCK_RESPONSE': { 258 | return respondWithMock(clientMessage.data) 259 | } 260 | 261 | case 'MOCK_NOT_FOUND': { 262 | return passthrough() 263 | } 264 | 265 | case 'NETWORK_ERROR': { 266 | const { name, message } = clientMessage.data 267 | const networkError = new Error(message) 268 | networkError.name = name 269 | 270 | // Rejecting a "respondWith" promise emulates a network error. 271 | throw networkError 272 | } 273 | } 274 | 275 | return passthrough() 276 | } 277 | 278 | function sendToClient(client, message) { 279 | return new Promise((resolve, reject) => { 280 | const channel = new MessageChannel() 281 | 282 | channel.port1.onmessage = (event) => { 283 | if (event.data && event.data.error) { 284 | return reject(event.data.error) 285 | } 286 | 287 | resolve(event.data) 288 | } 289 | 290 | client.postMessage(message, [channel.port2]) 291 | }) 292 | } 293 | 294 | function sleep(timeMs) { 295 | return new Promise((resolve) => { 296 | setTimeout(resolve, timeMs) 297 | }) 298 | } 299 | 300 | async function respondWithMock(response) { 301 | await sleep(response.delay) 302 | return new Response(response.body, response) 303 | } 304 | -------------------------------------------------------------------------------- /examples/vite/src/App.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; 3 | import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; 4 | import { AuthScreen } from '@/components/auth-screen'; 5 | import { UserInfo } from '@/components/user-info'; 6 | import { AuthLoader } from '@/lib/auth'; 7 | import { Container } from '@/components/ui'; 8 | 9 | const SampleApp = () => { 10 | const [queryClient] = React.useState(() => new QueryClient()); 11 | 12 | return ( 13 | 14 | 15 | 16 |
Loading ...
} 18 | renderUnauthenticated={() => } 19 | > 20 | 21 |
22 |
23 |
24 | ); 25 | }; 26 | 27 | export default SampleApp; 28 | -------------------------------------------------------------------------------- /examples/vite/src/components/auth-screen.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { 4 | LoginCredentials, 5 | RegisterCredentials, 6 | useLogin, 7 | useRegister, 8 | } from '@/lib/auth'; 9 | 10 | import { Button, Form, Input } from './ui'; 11 | 12 | export const AuthScreen = () => { 13 | const [mode, setMode] = React.useState<'register' | 'login'>('register'); 14 | 15 | return ( 16 |
17 | {mode === 'login' && ( 18 | <> 19 | 20 | 21 | 22 | )} 23 | {mode === 'register' && ( 24 | <> 25 | 26 | 27 | 28 | )} 29 |
30 | ); 31 | }; 32 | 33 | const useForm = >(initialValues?: V) => { 34 | const [values, setValues] = React.useState(initialValues || {}); 35 | 36 | const onChange = (e: React.ChangeEvent) => { 37 | setValues((v) => ({ ...v, [e.target.name]: e.target.value })); 38 | }; 39 | 40 | return { 41 | values: values as V, 42 | onChange, 43 | }; 44 | }; 45 | 46 | const RegisterForm = () => { 47 | const register = useRegister(); 48 | const { values, onChange } = useForm(); 49 | 50 | return ( 51 |
{ 54 | e.preventDefault(); 55 | register.mutate(values, { 56 | onSuccess: () => console.log('registered'), 57 | }); 58 | }} 59 | error={register.error} 60 | > 61 | 68 | 69 | 75 | 78 |
79 | ); 80 | }; 81 | 82 | const LoginForm = () => { 83 | const login = useLogin(); 84 | const { values, onChange } = useForm(); 85 | 86 | return ( 87 |
{ 90 | e.preventDefault(); 91 | login.mutate(values); 92 | }} 93 | error={login.error} 94 | > 95 | 102 | 108 | 111 |
112 | ); 113 | }; 114 | -------------------------------------------------------------------------------- /examples/vite/src/components/ui.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export const Button = ( 4 | props: React.ButtonHTMLAttributes 5 | ) => { 6 | return ( 7 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /examples/vite/src/lib/api.ts: -------------------------------------------------------------------------------- 1 | import { storage } from './utils'; 2 | 3 | export interface AuthResponse { 4 | user: User; 5 | jwt: string; 6 | } 7 | 8 | export interface User { 9 | id: string; 10 | email: string; 11 | name?: string; 12 | } 13 | 14 | export async function handleApiResponse(response: Response) { 15 | const data = await response.json(); 16 | 17 | if (response.ok) { 18 | return data; 19 | } else { 20 | console.error(JSON.stringify(data, null, 2)); 21 | return Promise.reject(data); 22 | } 23 | } 24 | 25 | export function getUserProfile(): Promise<{ user: User | undefined }> { 26 | return fetch('/auth/me', { 27 | headers: { 28 | Authorization: storage.getToken(), 29 | }, 30 | }).then(handleApiResponse); 31 | } 32 | 33 | export function loginWithEmailAndPassword( 34 | data: unknown 35 | ): Promise { 36 | return fetch('/auth/login', { 37 | method: 'POST', 38 | body: JSON.stringify(data), 39 | }).then(handleApiResponse); 40 | } 41 | 42 | export function registerWithEmailAndPassword( 43 | data: unknown 44 | ): Promise { 45 | return fetch('/auth/register', { 46 | method: 'POST', 47 | body: JSON.stringify(data), 48 | }).then(handleApiResponse); 49 | } 50 | 51 | export function logout(): Promise<{ message: string }> { 52 | return fetch('/auth/logout', { method: 'POST' }).then(handleApiResponse); 53 | } 54 | -------------------------------------------------------------------------------- /examples/vite/src/lib/auth.ts: -------------------------------------------------------------------------------- 1 | import { configureAuth } from 'react-query-auth'; 2 | import { 3 | getUserProfile, 4 | registerWithEmailAndPassword, 5 | loginWithEmailAndPassword, 6 | AuthResponse, 7 | logout, 8 | } from './api'; 9 | import { storage } from './utils'; 10 | 11 | export type LoginCredentials = { 12 | email: string; 13 | password: string; 14 | }; 15 | 16 | export type RegisterCredentials = { 17 | email: string; 18 | name: string; 19 | password: string; 20 | }; 21 | 22 | async function handleUserResponse(data: AuthResponse) { 23 | const { jwt, user } = data; 24 | storage.setToken(jwt); 25 | return user; 26 | } 27 | 28 | async function userFn() { 29 | const { user } = await getUserProfile(); 30 | return user ?? null; 31 | } 32 | 33 | async function loginFn(data: LoginCredentials) { 34 | const response = await loginWithEmailAndPassword(data); 35 | const user = await handleUserResponse(response); 36 | return user; 37 | } 38 | 39 | async function registerFn(data: RegisterCredentials) { 40 | const response = await registerWithEmailAndPassword(data); 41 | const user = await handleUserResponse(response); 42 | return user; 43 | } 44 | 45 | async function logoutFn() { 46 | await logout(); 47 | } 48 | 49 | export const { useUser, useLogin, useRegister, useLogout, AuthLoader } = 50 | configureAuth({ 51 | userFn, 52 | loginFn, 53 | registerFn, 54 | logoutFn, 55 | }); 56 | -------------------------------------------------------------------------------- /examples/vite/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | export const storage = { 2 | getToken: () => JSON.parse(window.localStorage.getItem('token') || 'null'), 3 | setToken: (token: string) => 4 | window.localStorage.setItem('token', JSON.stringify(token)), 5 | clearToken: () => window.localStorage.removeItem('token'), 6 | }; 7 | -------------------------------------------------------------------------------- /examples/vite/src/mocks/api-server.ts: -------------------------------------------------------------------------------- 1 | import { setupWorker, rest } from 'msw'; 2 | import { storage } from '@/lib/utils'; 3 | import { DBUser, getUser, setUser } from './db'; 4 | 5 | const handlers = [ 6 | rest.get('/auth/me', (req, res, ctx) => { 7 | const user = getUser(req.headers.get('Authorization')); 8 | 9 | return res(ctx.delay(1000), ctx.json({ user })); 10 | }), 11 | rest.post('/auth/login', async (req, res, ctx) => { 12 | const parsedBody = (await req.json()) as DBUser; 13 | const user = getUser(parsedBody.email); 14 | if (user && user.password === parsedBody.password) { 15 | return res( 16 | ctx.delay(1000), 17 | ctx.json({ 18 | jwt: user.email, 19 | user, 20 | }) 21 | ); 22 | } else { 23 | return res( 24 | ctx.delay(1000), 25 | ctx.status(401), 26 | ctx.json({ message: 'Unauthorized' }) 27 | ); 28 | } 29 | }), 30 | rest.post('/auth/register', async (req, res, ctx) => { 31 | const parsedBody = (await req.json()) as DBUser; 32 | const user = getUser(parsedBody?.email); 33 | if (!user && parsedBody) { 34 | const newUser = setUser(parsedBody); 35 | if (newUser) { 36 | return res( 37 | ctx.delay(1000), 38 | ctx.json({ 39 | jwt: newUser.email, 40 | user: getUser(newUser.email), 41 | }) 42 | ); 43 | } 44 | return res( 45 | ctx.delay(1000), 46 | ctx.status(403), 47 | ctx.json({ message: 'Registration failed!' }) 48 | ); 49 | } else { 50 | return res( 51 | ctx.delay(1000), 52 | ctx.status(400), 53 | ctx.json({ message: 'The user already exists!' }) 54 | ); 55 | } 56 | }), 57 | rest.post('/auth/logout', (req, res, ctx) => { 58 | storage.clearToken(); 59 | return res(ctx.delay(1000), ctx.json({ message: 'Logged out' })); 60 | }), 61 | ]; 62 | 63 | export const worker = setupWorker(...handlers); 64 | -------------------------------------------------------------------------------- /examples/vite/src/mocks/db.ts: -------------------------------------------------------------------------------- 1 | export type DBUser = { 2 | email: string; 3 | name: string; 4 | password: string; 5 | }; 6 | 7 | const users: Record = JSON.parse( 8 | window.localStorage.getItem('db_users') || '{}' 9 | ); 10 | 11 | export function setUser(data: DBUser) { 12 | if (data?.email) { 13 | users[data.email] = data; 14 | window.localStorage.setItem('db_users', JSON.stringify(users)); 15 | return data; 16 | } else { 17 | return null; 18 | } 19 | } 20 | 21 | export function getUser(email: string | null) { 22 | if (email) { 23 | return users[email]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "react-jsx", 16 | "incremental": true, 17 | "types": ["node", "vite/client"], 18 | "baseUrl": ".", 19 | "paths": { 20 | "@/*": ["./src/*"] 21 | } 22 | }, 23 | "include": ["src"], 24 | "exclude": ["node_modules"], 25 | "references": [{ "path": "./tsconfig.node.json" }] 26 | } 27 | -------------------------------------------------------------------------------- /examples/vite/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/vite/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import ReactPlugin from 'vite-preset-react'; 3 | import path from 'path'; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [ 8 | ReactPlugin({ 9 | injectReact: false, 10 | }), 11 | ], 12 | resolve: { 13 | alias: { 14 | '@': path.resolve(__dirname, 'src'), 15 | }, 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /examples/vite/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@ampproject/remapping@^2.2.0": 6 | version "2.2.0" 7 | resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" 8 | integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== 9 | dependencies: 10 | "@jridgewell/gen-mapping" "^0.1.0" 11 | "@jridgewell/trace-mapping" "^0.3.9" 12 | 13 | "@babel/code-frame@^7.18.6": 14 | version "7.18.6" 15 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" 16 | integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== 17 | dependencies: 18 | "@babel/highlight" "^7.18.6" 19 | 20 | "@babel/compat-data@^7.20.5": 21 | version "7.21.0" 22 | resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.0.tgz#c241dc454e5b5917e40d37e525e2f4530c399298" 23 | integrity sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g== 24 | 25 | "@babel/core@^7.17.10": 26 | version "7.21.0" 27 | resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.0.tgz#1341aefdcc14ccc7553fcc688dd8986a2daffc13" 28 | integrity sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA== 29 | dependencies: 30 | "@ampproject/remapping" "^2.2.0" 31 | "@babel/code-frame" "^7.18.6" 32 | "@babel/generator" "^7.21.0" 33 | "@babel/helper-compilation-targets" "^7.20.7" 34 | "@babel/helper-module-transforms" "^7.21.0" 35 | "@babel/helpers" "^7.21.0" 36 | "@babel/parser" "^7.21.0" 37 | "@babel/template" "^7.20.7" 38 | "@babel/traverse" "^7.21.0" 39 | "@babel/types" "^7.21.0" 40 | convert-source-map "^1.7.0" 41 | debug "^4.1.0" 42 | gensync "^1.0.0-beta.2" 43 | json5 "^2.2.2" 44 | semver "^6.3.0" 45 | 46 | "@babel/generator@^7.21.0": 47 | version "7.21.1" 48 | resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.1.tgz#951cc626057bc0af2c35cd23e9c64d384dea83dd" 49 | integrity sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA== 50 | dependencies: 51 | "@babel/types" "^7.21.0" 52 | "@jridgewell/gen-mapping" "^0.3.2" 53 | "@jridgewell/trace-mapping" "^0.3.17" 54 | jsesc "^2.5.1" 55 | 56 | "@babel/helper-annotate-as-pure@^7.18.6": 57 | version "7.18.6" 58 | resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" 59 | integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== 60 | dependencies: 61 | "@babel/types" "^7.18.6" 62 | 63 | "@babel/helper-compilation-targets@^7.20.7": 64 | version "7.20.7" 65 | resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb" 66 | integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ== 67 | dependencies: 68 | "@babel/compat-data" "^7.20.5" 69 | "@babel/helper-validator-option" "^7.18.6" 70 | browserslist "^4.21.3" 71 | lru-cache "^5.1.1" 72 | semver "^6.3.0" 73 | 74 | "@babel/helper-environment-visitor@^7.18.9": 75 | version "7.18.9" 76 | resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" 77 | integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== 78 | 79 | "@babel/helper-function-name@^7.21.0": 80 | version "7.21.0" 81 | resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" 82 | integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== 83 | dependencies: 84 | "@babel/template" "^7.20.7" 85 | "@babel/types" "^7.21.0" 86 | 87 | "@babel/helper-hoist-variables@^7.18.6": 88 | version "7.18.6" 89 | resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" 90 | integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== 91 | dependencies: 92 | "@babel/types" "^7.18.6" 93 | 94 | "@babel/helper-module-imports@^7.18.6": 95 | version "7.18.6" 96 | resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" 97 | integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== 98 | dependencies: 99 | "@babel/types" "^7.18.6" 100 | 101 | "@babel/helper-module-transforms@^7.21.0": 102 | version "7.21.0" 103 | resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.0.tgz#89a8f86ad748870e3d024e470b2e8405e869db67" 104 | integrity sha512-eD/JQ21IG2i1FraJnTMbUarAUkA7G988ofehG5MDCRXaUU91rEBJuCeSoou2Sk1y4RbLYXzqEg1QLwEmRU4qcQ== 105 | dependencies: 106 | "@babel/helper-environment-visitor" "^7.18.9" 107 | "@babel/helper-module-imports" "^7.18.6" 108 | "@babel/helper-simple-access" "^7.20.2" 109 | "@babel/helper-split-export-declaration" "^7.18.6" 110 | "@babel/helper-validator-identifier" "^7.19.1" 111 | "@babel/template" "^7.20.7" 112 | "@babel/traverse" "^7.21.0" 113 | "@babel/types" "^7.21.0" 114 | 115 | "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2": 116 | version "7.20.2" 117 | resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" 118 | integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== 119 | 120 | "@babel/helper-simple-access@^7.20.2": 121 | version "7.20.2" 122 | resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" 123 | integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== 124 | dependencies: 125 | "@babel/types" "^7.20.2" 126 | 127 | "@babel/helper-split-export-declaration@^7.18.6": 128 | version "7.18.6" 129 | resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" 130 | integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== 131 | dependencies: 132 | "@babel/types" "^7.18.6" 133 | 134 | "@babel/helper-string-parser@^7.19.4": 135 | version "7.19.4" 136 | resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" 137 | integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== 138 | 139 | "@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": 140 | version "7.19.1" 141 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" 142 | integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== 143 | 144 | "@babel/helper-validator-option@^7.18.6": 145 | version "7.21.0" 146 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" 147 | integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== 148 | 149 | "@babel/helpers@^7.21.0": 150 | version "7.21.0" 151 | resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" 152 | integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== 153 | dependencies: 154 | "@babel/template" "^7.20.7" 155 | "@babel/traverse" "^7.21.0" 156 | "@babel/types" "^7.21.0" 157 | 158 | "@babel/highlight@^7.18.6": 159 | version "7.18.6" 160 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" 161 | integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== 162 | dependencies: 163 | "@babel/helper-validator-identifier" "^7.18.6" 164 | chalk "^2.0.0" 165 | js-tokens "^4.0.0" 166 | 167 | "@babel/parser@^7.20.7", "@babel/parser@^7.21.0": 168 | version "7.21.1" 169 | resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.1.tgz#a8f81ee2fe872af23faea4b17a08fcc869de7bcc" 170 | integrity sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg== 171 | 172 | "@babel/plugin-syntax-jsx@^7.18.6": 173 | version "7.18.6" 174 | resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" 175 | integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== 176 | dependencies: 177 | "@babel/helper-plugin-utils" "^7.18.6" 178 | 179 | "@babel/plugin-transform-react-jsx-development@^7.16.7": 180 | version "7.18.6" 181 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" 182 | integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== 183 | dependencies: 184 | "@babel/plugin-transform-react-jsx" "^7.18.6" 185 | 186 | "@babel/plugin-transform-react-jsx-self@^7.16.7": 187 | version "7.21.0" 188 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.21.0.tgz#ec98d4a9baafc5a1eb398da4cf94afbb40254a54" 189 | integrity sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA== 190 | dependencies: 191 | "@babel/helper-plugin-utils" "^7.20.2" 192 | 193 | "@babel/plugin-transform-react-jsx-source@^7.16.7": 194 | version "7.19.6" 195 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.19.6.tgz#88578ae8331e5887e8ce28e4c9dc83fb29da0b86" 196 | integrity sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ== 197 | dependencies: 198 | "@babel/helper-plugin-utils" "^7.19.0" 199 | 200 | "@babel/plugin-transform-react-jsx@^7.17.3", "@babel/plugin-transform-react-jsx@^7.18.6": 201 | version "7.21.0" 202 | resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz#656b42c2fdea0a6d8762075d58ef9d4e3c4ab8a2" 203 | integrity sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg== 204 | dependencies: 205 | "@babel/helper-annotate-as-pure" "^7.18.6" 206 | "@babel/helper-module-imports" "^7.18.6" 207 | "@babel/helper-plugin-utils" "^7.20.2" 208 | "@babel/plugin-syntax-jsx" "^7.18.6" 209 | "@babel/types" "^7.21.0" 210 | 211 | "@babel/template@^7.20.7": 212 | version "7.20.7" 213 | resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" 214 | integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== 215 | dependencies: 216 | "@babel/code-frame" "^7.18.6" 217 | "@babel/parser" "^7.20.7" 218 | "@babel/types" "^7.20.7" 219 | 220 | "@babel/traverse@^7.21.0": 221 | version "7.21.0" 222 | resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.0.tgz#0e1807abd5db98e6a19c204b80ed1e3f5bca0edc" 223 | integrity sha512-Xdt2P1H4LKTO8ApPfnO1KmzYMFpp7D/EinoXzLYN/cHcBNrVCAkAtGUcXnHXrl/VGktureU6fkQrHSBE2URfoA== 224 | dependencies: 225 | "@babel/code-frame" "^7.18.6" 226 | "@babel/generator" "^7.21.0" 227 | "@babel/helper-environment-visitor" "^7.18.9" 228 | "@babel/helper-function-name" "^7.21.0" 229 | "@babel/helper-hoist-variables" "^7.18.6" 230 | "@babel/helper-split-export-declaration" "^7.18.6" 231 | "@babel/parser" "^7.21.0" 232 | "@babel/types" "^7.21.0" 233 | debug "^4.1.0" 234 | globals "^11.1.0" 235 | 236 | "@babel/types@^7.18.6", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.21.0": 237 | version "7.21.0" 238 | resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.0.tgz#1da00d89c2f18b226c9207d96edbeb79316a1819" 239 | integrity sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow== 240 | dependencies: 241 | "@babel/helper-string-parser" "^7.19.4" 242 | "@babel/helper-validator-identifier" "^7.19.1" 243 | to-fast-properties "^2.0.0" 244 | 245 | "@esbuild/android-arm64@0.16.17": 246 | version "0.16.17" 247 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz#cf91e86df127aa3d141744edafcba0abdc577d23" 248 | integrity sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg== 249 | 250 | "@esbuild/android-arm@0.16.17": 251 | version "0.16.17" 252 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz#025b6246d3f68b7bbaa97069144fb5fb70f2fff2" 253 | integrity sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw== 254 | 255 | "@esbuild/android-x64@0.16.17": 256 | version "0.16.17" 257 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.17.tgz#c820e0fef982f99a85c4b8bfdd582835f04cd96e" 258 | integrity sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ== 259 | 260 | "@esbuild/darwin-arm64@0.16.17": 261 | version "0.16.17" 262 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz#edef4487af6b21afabba7be5132c26d22379b220" 263 | integrity sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w== 264 | 265 | "@esbuild/darwin-x64@0.16.17": 266 | version "0.16.17" 267 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz#42829168730071c41ef0d028d8319eea0e2904b4" 268 | integrity sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg== 269 | 270 | "@esbuild/freebsd-arm64@0.16.17": 271 | version "0.16.17" 272 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz#1f4af488bfc7e9ced04207034d398e793b570a27" 273 | integrity sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw== 274 | 275 | "@esbuild/freebsd-x64@0.16.17": 276 | version "0.16.17" 277 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz#636306f19e9bc981e06aa1d777302dad8fddaf72" 278 | integrity sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug== 279 | 280 | "@esbuild/linux-arm64@0.16.17": 281 | version "0.16.17" 282 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz#a003f7ff237c501e095d4f3a09e58fc7b25a4aca" 283 | integrity sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g== 284 | 285 | "@esbuild/linux-arm@0.16.17": 286 | version "0.16.17" 287 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz#b591e6a59d9c4fe0eeadd4874b157ab78cf5f196" 288 | integrity sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ== 289 | 290 | "@esbuild/linux-ia32@0.16.17": 291 | version "0.16.17" 292 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz#24333a11027ef46a18f57019450a5188918e2a54" 293 | integrity sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg== 294 | 295 | "@esbuild/linux-loong64@0.16.17": 296 | version "0.16.17" 297 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz#d5ad459d41ed42bbd4d005256b31882ec52227d8" 298 | integrity sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ== 299 | 300 | "@esbuild/linux-mips64el@0.16.17": 301 | version "0.16.17" 302 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz#4e5967a665c38360b0a8205594377d4dcf9c3726" 303 | integrity sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw== 304 | 305 | "@esbuild/linux-ppc64@0.16.17": 306 | version "0.16.17" 307 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz#206443a02eb568f9fdf0b438fbd47d26e735afc8" 308 | integrity sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g== 309 | 310 | "@esbuild/linux-riscv64@0.16.17": 311 | version "0.16.17" 312 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz#c351e433d009bf256e798ad048152c8d76da2fc9" 313 | integrity sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw== 314 | 315 | "@esbuild/linux-s390x@0.16.17": 316 | version "0.16.17" 317 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz#661f271e5d59615b84b6801d1c2123ad13d9bd87" 318 | integrity sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w== 319 | 320 | "@esbuild/linux-x64@0.16.17": 321 | version "0.16.17" 322 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz#e4ba18e8b149a89c982351443a377c723762b85f" 323 | integrity sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw== 324 | 325 | "@esbuild/netbsd-x64@0.16.17": 326 | version "0.16.17" 327 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz#7d4f4041e30c5c07dd24ffa295c73f06038ec775" 328 | integrity sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA== 329 | 330 | "@esbuild/openbsd-x64@0.16.17": 331 | version "0.16.17" 332 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz#970fa7f8470681f3e6b1db0cc421a4af8060ec35" 333 | integrity sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg== 334 | 335 | "@esbuild/sunos-x64@0.16.17": 336 | version "0.16.17" 337 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz#abc60e7c4abf8b89fb7a4fe69a1484132238022c" 338 | integrity sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw== 339 | 340 | "@esbuild/win32-arm64@0.16.17": 341 | version "0.16.17" 342 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz#7b0ff9e8c3265537a7a7b1fd9a24e7bd39fcd87a" 343 | integrity sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw== 344 | 345 | "@esbuild/win32-ia32@0.16.17": 346 | version "0.16.17" 347 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz#e90fe5267d71a7b7567afdc403dfd198c292eb09" 348 | integrity sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig== 349 | 350 | "@esbuild/win32-x64@0.16.17": 351 | version "0.16.17" 352 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz#c5a1a4bfe1b57f0c3e61b29883525c6da3e5c091" 353 | integrity sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q== 354 | 355 | "@jridgewell/gen-mapping@^0.1.0": 356 | version "0.1.1" 357 | resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" 358 | integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== 359 | dependencies: 360 | "@jridgewell/set-array" "^1.0.0" 361 | "@jridgewell/sourcemap-codec" "^1.4.10" 362 | 363 | "@jridgewell/gen-mapping@^0.3.2": 364 | version "0.3.2" 365 | resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" 366 | integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== 367 | dependencies: 368 | "@jridgewell/set-array" "^1.0.1" 369 | "@jridgewell/sourcemap-codec" "^1.4.10" 370 | "@jridgewell/trace-mapping" "^0.3.9" 371 | 372 | "@jridgewell/resolve-uri@3.1.0": 373 | version "3.1.0" 374 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" 375 | integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== 376 | 377 | "@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": 378 | version "1.1.2" 379 | resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" 380 | integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== 381 | 382 | "@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": 383 | version "1.4.14" 384 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" 385 | integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== 386 | 387 | "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": 388 | version "0.3.17" 389 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" 390 | integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== 391 | dependencies: 392 | "@jridgewell/resolve-uri" "3.1.0" 393 | "@jridgewell/sourcemap-codec" "1.4.14" 394 | 395 | "@mswjs/cookies@^0.2.2": 396 | version "0.2.2" 397 | resolved "https://registry.yarnpkg.com/@mswjs/cookies/-/cookies-0.2.2.tgz#b4e207bf6989e5d5427539c2443380a33ebb922b" 398 | integrity sha512-mlN83YSrcFgk7Dm1Mys40DLssI1KdJji2CMKN8eOlBqsTADYzj2+jWzsANsUTFbxDMWPD5e9bfA1RGqBpS3O1g== 399 | dependencies: 400 | "@types/set-cookie-parser" "^2.4.0" 401 | set-cookie-parser "^2.4.6" 402 | 403 | "@mswjs/interceptors@^0.17.5": 404 | version "0.17.7" 405 | resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.17.7.tgz#3a41c6a56ddf236eddc0afd513026559ae4a1e5c" 406 | integrity sha512-dPInyLEF6ybLxfKGY99euI+mbT6ls4PVO9qPgGIsRk3+2VZVfT7fo9Sq6Q8eKT9W38QtUyhG74hN7xMtKWioGw== 407 | dependencies: 408 | "@open-draft/until" "^1.0.3" 409 | "@types/debug" "^4.1.7" 410 | "@xmldom/xmldom" "^0.8.3" 411 | debug "^4.3.3" 412 | headers-polyfill "^3.1.0" 413 | outvariant "^1.2.1" 414 | strict-event-emitter "^0.2.4" 415 | web-encoding "^1.1.5" 416 | 417 | "@open-draft/until@^1.0.3": 418 | version "1.0.3" 419 | resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-1.0.3.tgz#db9cc719191a62e7d9200f6e7bab21c5b848adca" 420 | integrity sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q== 421 | 422 | "@rollup/pluginutils@^4.2.1": 423 | version "4.2.1" 424 | resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" 425 | integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== 426 | dependencies: 427 | estree-walker "^2.0.1" 428 | picomatch "^2.2.2" 429 | 430 | "@tanstack/match-sorter-utils@^8.7.0": 431 | version "8.7.6" 432 | resolved "https://registry.yarnpkg.com/@tanstack/match-sorter-utils/-/match-sorter-utils-8.7.6.tgz#ccf54a37447770e0cf0fe49a579c595fd2655b16" 433 | integrity sha512-2AMpRiA6QivHOUiBpQAVxjiHAA68Ei23ZUMNaRJrN6omWiSFLoYrxGcT6BXtuzp0Jw4h6HZCmGGIM/gbwebO2A== 434 | dependencies: 435 | remove-accents "0.4.2" 436 | 437 | "@tanstack/query-core@4.24.9": 438 | version "4.24.9" 439 | resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.24.9.tgz#52a5981d46f48e85630bcf5a645318e405493ce1" 440 | integrity sha512-pZQ2NpdaHzx8gPPkAPh06d6zRkjfonUzILSYBXrdHDapP2eaBbGsx5L4/dMF+fyAglFzQZdDDzZgAykbM20QVw== 441 | 442 | "@tanstack/react-query-devtools@^4.24.6": 443 | version "4.24.9" 444 | resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-4.24.9.tgz#039281a1ef0ac6ad1fdb6082e95ae013795a736d" 445 | integrity sha512-NPsVf3pLMjH/XNTT5iP1q6isEBNE4kWF/IBSbxNUt0tDWK1nS1qgWr9ySTXwimsAHOWMjHkFuUF8VBRmz+axKg== 446 | dependencies: 447 | "@tanstack/match-sorter-utils" "^8.7.0" 448 | superjson "^1.10.0" 449 | use-sync-external-store "^1.2.0" 450 | 451 | "@tanstack/react-query@^4.24.6": 452 | version "4.24.9" 453 | resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.24.9.tgz#8ec7e22dd3a858e174a90e81d20c85908f2ea653" 454 | integrity sha512-6WLwUT9mrngIinRtcZjrWOUENOuLbWvQpKmU6DZCo2iPQVA+qvv3Ji90Amme4AkUyWQ8ZSSRTnAFq8V2tj2ACg== 455 | dependencies: 456 | "@tanstack/query-core" "4.24.9" 457 | use-sync-external-store "^1.2.0" 458 | 459 | "@types/cookie@^0.4.1": 460 | version "0.4.1" 461 | resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" 462 | integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== 463 | 464 | "@types/debug@^4.1.7": 465 | version "4.1.7" 466 | resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" 467 | integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== 468 | dependencies: 469 | "@types/ms" "*" 470 | 471 | "@types/js-levenshtein@^1.1.1": 472 | version "1.1.1" 473 | resolved "https://registry.yarnpkg.com/@types/js-levenshtein/-/js-levenshtein-1.1.1.tgz#ba05426a43f9e4e30b631941e0aa17bf0c890ed5" 474 | integrity sha512-qC4bCqYGy1y/NP7dDVr7KJarn+PbX1nSpwA7JXdu0HxT3QYjO8MJ+cntENtHFVy2dRAyBV23OZ6MxsW1AM1L8g== 475 | 476 | "@types/ms@*": 477 | version "0.7.31" 478 | resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" 479 | integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== 480 | 481 | "@types/node@*", "@types/node@^18.14.0": 482 | version "18.14.0" 483 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.0.tgz#94c47b9217bbac49d4a67a967fdcdeed89ebb7d0" 484 | integrity sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A== 485 | 486 | "@types/prop-types@*": 487 | version "15.7.5" 488 | resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" 489 | integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== 490 | 491 | "@types/react-dom@^18.0.11": 492 | version "18.0.11" 493 | resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.11.tgz#321351c1459bc9ca3d216aefc8a167beec334e33" 494 | integrity sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw== 495 | dependencies: 496 | "@types/react" "*" 497 | 498 | "@types/react@*", "@types/react@^18.0.28": 499 | version "18.0.28" 500 | resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.28.tgz#accaeb8b86f4908057ad629a26635fe641480065" 501 | integrity sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew== 502 | dependencies: 503 | "@types/prop-types" "*" 504 | "@types/scheduler" "*" 505 | csstype "^3.0.2" 506 | 507 | "@types/scheduler@*": 508 | version "0.16.2" 509 | resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" 510 | integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== 511 | 512 | "@types/set-cookie-parser@^2.4.0": 513 | version "2.4.2" 514 | resolved "https://registry.yarnpkg.com/@types/set-cookie-parser/-/set-cookie-parser-2.4.2.tgz#b6a955219b54151bfebd4521170723df5e13caad" 515 | integrity sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w== 516 | dependencies: 517 | "@types/node" "*" 518 | 519 | "@vitejs/plugin-react@^1.3.2": 520 | version "1.3.2" 521 | resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-1.3.2.tgz#2fcf0b6ce9bcdcd4cec5c760c199779d5657ece1" 522 | integrity sha512-aurBNmMo0kz1O4qRoY+FM4epSA39y3ShWGuqfLRA/3z0oEJAdtoSfgA3aO98/PCCHAqMaduLxIxErWrVKIFzXA== 523 | dependencies: 524 | "@babel/core" "^7.17.10" 525 | "@babel/plugin-transform-react-jsx" "^7.17.3" 526 | "@babel/plugin-transform-react-jsx-development" "^7.16.7" 527 | "@babel/plugin-transform-react-jsx-self" "^7.16.7" 528 | "@babel/plugin-transform-react-jsx-source" "^7.16.7" 529 | "@rollup/pluginutils" "^4.2.1" 530 | react-refresh "^0.13.0" 531 | resolve "^1.22.0" 532 | 533 | "@xmldom/xmldom@^0.8.3": 534 | version "0.8.6" 535 | resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.6.tgz#8a1524eb5bd5e965c1e3735476f0262469f71440" 536 | integrity sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg== 537 | 538 | "@zxing/text-encoding@0.9.0": 539 | version "0.9.0" 540 | resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b" 541 | integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA== 542 | 543 | ansi-escapes@^4.2.1: 544 | version "4.3.2" 545 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" 546 | integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== 547 | dependencies: 548 | type-fest "^0.21.3" 549 | 550 | ansi-regex@^5.0.1: 551 | version "5.0.1" 552 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 553 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 554 | 555 | ansi-styles@^3.2.1: 556 | version "3.2.1" 557 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 558 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 559 | dependencies: 560 | color-convert "^1.9.0" 561 | 562 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 563 | version "4.3.0" 564 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 565 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 566 | dependencies: 567 | color-convert "^2.0.1" 568 | 569 | anymatch@~3.1.2: 570 | version "3.1.3" 571 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" 572 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== 573 | dependencies: 574 | normalize-path "^3.0.0" 575 | picomatch "^2.0.4" 576 | 577 | asap@~2.0.6: 578 | version "2.0.6" 579 | resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" 580 | integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== 581 | 582 | available-typed-arrays@^1.0.5: 583 | version "1.0.5" 584 | resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" 585 | integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== 586 | 587 | base64-js@^1.3.1: 588 | version "1.5.1" 589 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" 590 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 591 | 592 | binary-extensions@^2.0.0: 593 | version "2.2.0" 594 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 595 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 596 | 597 | bl@^4.1.0: 598 | version "4.1.0" 599 | resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" 600 | integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== 601 | dependencies: 602 | buffer "^5.5.0" 603 | inherits "^2.0.4" 604 | readable-stream "^3.4.0" 605 | 606 | braces@~3.0.2: 607 | version "3.0.2" 608 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 609 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 610 | dependencies: 611 | fill-range "^7.0.1" 612 | 613 | browserslist@^4.21.3: 614 | version "4.21.5" 615 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" 616 | integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== 617 | dependencies: 618 | caniuse-lite "^1.0.30001449" 619 | electron-to-chromium "^1.4.284" 620 | node-releases "^2.0.8" 621 | update-browserslist-db "^1.0.10" 622 | 623 | buffer@^5.5.0: 624 | version "5.7.1" 625 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" 626 | integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== 627 | dependencies: 628 | base64-js "^1.3.1" 629 | ieee754 "^1.1.13" 630 | 631 | call-bind@^1.0.2: 632 | version "1.0.2" 633 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" 634 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== 635 | dependencies: 636 | function-bind "^1.1.1" 637 | get-intrinsic "^1.0.2" 638 | 639 | caniuse-lite@^1.0.30001449: 640 | version "1.0.30001457" 641 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz#6af34bb5d720074e2099432aa522c21555a18301" 642 | integrity sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA== 643 | 644 | chalk@4.1.1: 645 | version "4.1.1" 646 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" 647 | integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== 648 | dependencies: 649 | ansi-styles "^4.1.0" 650 | supports-color "^7.1.0" 651 | 652 | chalk@^2.0.0: 653 | version "2.4.2" 654 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 655 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 656 | dependencies: 657 | ansi-styles "^3.2.1" 658 | escape-string-regexp "^1.0.5" 659 | supports-color "^5.3.0" 660 | 661 | chalk@^4.1.0, chalk@^4.1.1: 662 | version "4.1.2" 663 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 664 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 665 | dependencies: 666 | ansi-styles "^4.1.0" 667 | supports-color "^7.1.0" 668 | 669 | chardet@^0.7.0: 670 | version "0.7.0" 671 | resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" 672 | integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== 673 | 674 | chokidar@^3.4.2: 675 | version "3.5.3" 676 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 677 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 678 | dependencies: 679 | anymatch "~3.1.2" 680 | braces "~3.0.2" 681 | glob-parent "~5.1.2" 682 | is-binary-path "~2.1.0" 683 | is-glob "~4.0.1" 684 | normalize-path "~3.0.0" 685 | readdirp "~3.6.0" 686 | optionalDependencies: 687 | fsevents "~2.3.2" 688 | 689 | cli-cursor@^3.1.0: 690 | version "3.1.0" 691 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" 692 | integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== 693 | dependencies: 694 | restore-cursor "^3.1.0" 695 | 696 | cli-spinners@^2.5.0: 697 | version "2.7.0" 698 | resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" 699 | integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== 700 | 701 | cli-width@^3.0.0: 702 | version "3.0.0" 703 | resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" 704 | integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== 705 | 706 | cliui@^8.0.1: 707 | version "8.0.1" 708 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" 709 | integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== 710 | dependencies: 711 | string-width "^4.2.0" 712 | strip-ansi "^6.0.1" 713 | wrap-ansi "^7.0.0" 714 | 715 | clone@^1.0.2: 716 | version "1.0.4" 717 | resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" 718 | integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== 719 | 720 | color-convert@^1.9.0: 721 | version "1.9.3" 722 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 723 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 724 | dependencies: 725 | color-name "1.1.3" 726 | 727 | color-convert@^2.0.1: 728 | version "2.0.1" 729 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 730 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 731 | dependencies: 732 | color-name "~1.1.4" 733 | 734 | color-name@1.1.3: 735 | version "1.1.3" 736 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 737 | integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== 738 | 739 | color-name@~1.1.4: 740 | version "1.1.4" 741 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 742 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 743 | 744 | convert-source-map@^1.7.0: 745 | version "1.9.0" 746 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" 747 | integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== 748 | 749 | cookie@^0.4.2: 750 | version "0.4.2" 751 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" 752 | integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== 753 | 754 | copy-anything@^3.0.2: 755 | version "3.0.3" 756 | resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-3.0.3.tgz#206767156f08da0e02efd392f71abcdf79643559" 757 | integrity sha512-fpW2W/BqEzqPp29QS+MwwfisHCQZtiduTe/m8idFo0xbti9fIZ2WVhAsCv4ggFVH3AgCkVdpoOCtQC6gBrdhjw== 758 | dependencies: 759 | is-what "^4.1.8" 760 | 761 | core-js@^3.19.2: 762 | version "3.28.0" 763 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.28.0.tgz#ed8b9e99c273879fdfff0edfc77ee709a5800e4a" 764 | integrity sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw== 765 | 766 | cross-env@^7.0.3: 767 | version "7.0.3" 768 | resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" 769 | integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== 770 | dependencies: 771 | cross-spawn "^7.0.1" 772 | 773 | cross-spawn@^7.0.1: 774 | version "7.0.3" 775 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 776 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 777 | dependencies: 778 | path-key "^3.1.0" 779 | shebang-command "^2.0.0" 780 | which "^2.0.1" 781 | 782 | csstype@^3.0.2: 783 | version "3.1.1" 784 | resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" 785 | integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== 786 | 787 | debug@^4.1.0, debug@^4.3.3: 788 | version "4.3.4" 789 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 790 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 791 | dependencies: 792 | ms "2.1.2" 793 | 794 | defaults@^1.0.3: 795 | version "1.0.4" 796 | resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" 797 | integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== 798 | dependencies: 799 | clone "^1.0.2" 800 | 801 | electron-to-chromium@^1.4.284: 802 | version "1.4.304" 803 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.304.tgz#d6eb7fea4073aacc471cf117df08b4b4978dc6ad" 804 | integrity sha512-6c8M+ojPgDIXN2NyfGn8oHASXYnayj+gSEnGeLMKb9zjsySeVB/j7KkNAAG9yDcv8gNlhvFg5REa1N/kQU6pgA== 805 | 806 | emoji-regex@^8.0.0: 807 | version "8.0.0" 808 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 809 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 810 | 811 | esbuild@^0.16.14: 812 | version "0.16.17" 813 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.17.tgz#fc2c3914c57ee750635fee71b89f615f25065259" 814 | integrity sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg== 815 | optionalDependencies: 816 | "@esbuild/android-arm" "0.16.17" 817 | "@esbuild/android-arm64" "0.16.17" 818 | "@esbuild/android-x64" "0.16.17" 819 | "@esbuild/darwin-arm64" "0.16.17" 820 | "@esbuild/darwin-x64" "0.16.17" 821 | "@esbuild/freebsd-arm64" "0.16.17" 822 | "@esbuild/freebsd-x64" "0.16.17" 823 | "@esbuild/linux-arm" "0.16.17" 824 | "@esbuild/linux-arm64" "0.16.17" 825 | "@esbuild/linux-ia32" "0.16.17" 826 | "@esbuild/linux-loong64" "0.16.17" 827 | "@esbuild/linux-mips64el" "0.16.17" 828 | "@esbuild/linux-ppc64" "0.16.17" 829 | "@esbuild/linux-riscv64" "0.16.17" 830 | "@esbuild/linux-s390x" "0.16.17" 831 | "@esbuild/linux-x64" "0.16.17" 832 | "@esbuild/netbsd-x64" "0.16.17" 833 | "@esbuild/openbsd-x64" "0.16.17" 834 | "@esbuild/sunos-x64" "0.16.17" 835 | "@esbuild/win32-arm64" "0.16.17" 836 | "@esbuild/win32-ia32" "0.16.17" 837 | "@esbuild/win32-x64" "0.16.17" 838 | 839 | escalade@^3.1.1: 840 | version "3.1.1" 841 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 842 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 843 | 844 | escape-string-regexp@^1.0.5: 845 | version "1.0.5" 846 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 847 | integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 848 | 849 | estree-walker@^2.0.1: 850 | version "2.0.2" 851 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" 852 | integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== 853 | 854 | events@^3.3.0: 855 | version "3.3.0" 856 | resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" 857 | integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== 858 | 859 | external-editor@^3.0.3: 860 | version "3.1.0" 861 | resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" 862 | integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== 863 | dependencies: 864 | chardet "^0.7.0" 865 | iconv-lite "^0.4.24" 866 | tmp "^0.0.33" 867 | 868 | figures@^3.0.0: 869 | version "3.2.0" 870 | resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" 871 | integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== 872 | dependencies: 873 | escape-string-regexp "^1.0.5" 874 | 875 | fill-range@^7.0.1: 876 | version "7.0.1" 877 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 878 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 879 | dependencies: 880 | to-regex-range "^5.0.1" 881 | 882 | for-each@^0.3.3: 883 | version "0.3.3" 884 | resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" 885 | integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== 886 | dependencies: 887 | is-callable "^1.1.3" 888 | 889 | fsevents@~2.3.2: 890 | version "2.3.2" 891 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 892 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 893 | 894 | function-bind@^1.1.1: 895 | version "1.1.1" 896 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 897 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 898 | 899 | gensync@^1.0.0-beta.2: 900 | version "1.0.0-beta.2" 901 | resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" 902 | integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== 903 | 904 | get-caller-file@^2.0.5: 905 | version "2.0.5" 906 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 907 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 908 | 909 | get-intrinsic@^1.0.2, get-intrinsic@^1.1.3: 910 | version "1.2.0" 911 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" 912 | integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== 913 | dependencies: 914 | function-bind "^1.1.1" 915 | has "^1.0.3" 916 | has-symbols "^1.0.3" 917 | 918 | glob-parent@~5.1.2: 919 | version "5.1.2" 920 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 921 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 922 | dependencies: 923 | is-glob "^4.0.1" 924 | 925 | globals@^11.1.0: 926 | version "11.12.0" 927 | resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" 928 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== 929 | 930 | gopd@^1.0.1: 931 | version "1.0.1" 932 | resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" 933 | integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== 934 | dependencies: 935 | get-intrinsic "^1.1.3" 936 | 937 | "graphql@^15.0.0 || ^16.0.0": 938 | version "16.6.0" 939 | resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" 940 | integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== 941 | 942 | has-flag@^3.0.0: 943 | version "3.0.0" 944 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 945 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== 946 | 947 | has-flag@^4.0.0: 948 | version "4.0.0" 949 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 950 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 951 | 952 | has-symbols@^1.0.2, has-symbols@^1.0.3: 953 | version "1.0.3" 954 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" 955 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== 956 | 957 | has-tostringtag@^1.0.0: 958 | version "1.0.0" 959 | resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" 960 | integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== 961 | dependencies: 962 | has-symbols "^1.0.2" 963 | 964 | has@^1.0.3: 965 | version "1.0.3" 966 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 967 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 968 | dependencies: 969 | function-bind "^1.1.1" 970 | 971 | headers-polyfill@^3.1.0: 972 | version "3.1.2" 973 | resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-3.1.2.tgz#9a4dcb545c5b95d9569592ef7ec0708aab763fbe" 974 | integrity sha512-tWCK4biJ6hcLqTviLXVR9DTRfYGQMXEIUj3gwJ2rZ5wO/at3XtkI4g8mCvFdUF9l1KMBNCfmNAdnahm1cgavQA== 975 | 976 | iconv-lite@^0.4.24: 977 | version "0.4.24" 978 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 979 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 980 | dependencies: 981 | safer-buffer ">= 2.1.2 < 3" 982 | 983 | ieee754@^1.1.13: 984 | version "1.2.1" 985 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" 986 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 987 | 988 | inherits@^2.0.3, inherits@^2.0.4: 989 | version "2.0.4" 990 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 991 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 992 | 993 | inquirer@^8.2.0: 994 | version "8.2.5" 995 | resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.5.tgz#d8654a7542c35a9b9e069d27e2df4858784d54f8" 996 | integrity sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ== 997 | dependencies: 998 | ansi-escapes "^4.2.1" 999 | chalk "^4.1.1" 1000 | cli-cursor "^3.1.0" 1001 | cli-width "^3.0.0" 1002 | external-editor "^3.0.3" 1003 | figures "^3.0.0" 1004 | lodash "^4.17.21" 1005 | mute-stream "0.0.8" 1006 | ora "^5.4.1" 1007 | run-async "^2.4.0" 1008 | rxjs "^7.5.5" 1009 | string-width "^4.1.0" 1010 | strip-ansi "^6.0.0" 1011 | through "^2.3.6" 1012 | wrap-ansi "^7.0.0" 1013 | 1014 | is-arguments@^1.0.4: 1015 | version "1.1.1" 1016 | resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" 1017 | integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== 1018 | dependencies: 1019 | call-bind "^1.0.2" 1020 | has-tostringtag "^1.0.0" 1021 | 1022 | is-binary-path@~2.1.0: 1023 | version "2.1.0" 1024 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 1025 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 1026 | dependencies: 1027 | binary-extensions "^2.0.0" 1028 | 1029 | is-callable@^1.1.3: 1030 | version "1.2.7" 1031 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" 1032 | integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== 1033 | 1034 | is-core-module@^2.9.0: 1035 | version "2.11.0" 1036 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" 1037 | integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== 1038 | dependencies: 1039 | has "^1.0.3" 1040 | 1041 | is-extglob@^2.1.1: 1042 | version "2.1.1" 1043 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 1044 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 1045 | 1046 | is-fullwidth-code-point@^3.0.0: 1047 | version "3.0.0" 1048 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 1049 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 1050 | 1051 | is-generator-function@^1.0.7: 1052 | version "1.0.10" 1053 | resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" 1054 | integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== 1055 | dependencies: 1056 | has-tostringtag "^1.0.0" 1057 | 1058 | is-glob@^4.0.1, is-glob@~4.0.1: 1059 | version "4.0.3" 1060 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 1061 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 1062 | dependencies: 1063 | is-extglob "^2.1.1" 1064 | 1065 | is-interactive@^1.0.0: 1066 | version "1.0.0" 1067 | resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" 1068 | integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== 1069 | 1070 | is-node-process@^1.0.1: 1071 | version "1.0.1" 1072 | resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.0.1.tgz#4fc7ac3a91e8aac58175fe0578abbc56f2831b23" 1073 | integrity sha512-5IcdXuf++TTNt3oGl9EBdkvndXA8gmc4bz/Y+mdEpWh3Mcn/+kOw6hI7LD5CocqJWMzeb0I0ClndRVNdEPuJXQ== 1074 | 1075 | is-number@^7.0.0: 1076 | version "7.0.0" 1077 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 1078 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 1079 | 1080 | is-typed-array@^1.1.10, is-typed-array@^1.1.3: 1081 | version "1.1.10" 1082 | resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" 1083 | integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== 1084 | dependencies: 1085 | available-typed-arrays "^1.0.5" 1086 | call-bind "^1.0.2" 1087 | for-each "^0.3.3" 1088 | gopd "^1.0.1" 1089 | has-tostringtag "^1.0.0" 1090 | 1091 | is-unicode-supported@^0.1.0: 1092 | version "0.1.0" 1093 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 1094 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 1095 | 1096 | is-what@^4.1.8: 1097 | version "4.1.8" 1098 | resolved "https://registry.yarnpkg.com/is-what/-/is-what-4.1.8.tgz#0e2a8807fda30980ddb2571c79db3d209b14cbe4" 1099 | integrity sha512-yq8gMao5upkPoGEU9LsB2P+K3Kt8Q3fQFCGyNCWOAnJAMzEXVV9drYb0TXr42TTliLLhKIBvulgAXgtLLnwzGA== 1100 | 1101 | isexe@^2.0.0: 1102 | version "2.0.0" 1103 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 1104 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 1105 | 1106 | js-levenshtein@^1.1.6: 1107 | version "1.1.6" 1108 | resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" 1109 | integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== 1110 | 1111 | "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: 1112 | version "4.0.0" 1113 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 1114 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 1115 | 1116 | jsesc@^2.5.1: 1117 | version "2.5.2" 1118 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" 1119 | integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== 1120 | 1121 | json5@^2.2.2: 1122 | version "2.2.3" 1123 | resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" 1124 | integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== 1125 | 1126 | lodash@^4.17.21: 1127 | version "4.17.21" 1128 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 1129 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 1130 | 1131 | log-symbols@^4.1.0: 1132 | version "4.1.0" 1133 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" 1134 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 1135 | dependencies: 1136 | chalk "^4.1.0" 1137 | is-unicode-supported "^0.1.0" 1138 | 1139 | loose-envify@^1.1.0: 1140 | version "1.4.0" 1141 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" 1142 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== 1143 | dependencies: 1144 | js-tokens "^3.0.0 || ^4.0.0" 1145 | 1146 | lru-cache@^5.1.1: 1147 | version "5.1.1" 1148 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" 1149 | integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== 1150 | dependencies: 1151 | yallist "^3.0.2" 1152 | 1153 | mimic-fn@^2.1.0: 1154 | version "2.1.0" 1155 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" 1156 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 1157 | 1158 | ms@2.1.2: 1159 | version "2.1.2" 1160 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1161 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1162 | 1163 | msw@^1.0.1: 1164 | version "1.0.1" 1165 | resolved "https://registry.yarnpkg.com/msw/-/msw-1.0.1.tgz#f55b36b3d7e911ee75a73d6346585e01af3fbcfb" 1166 | integrity sha512-fBwQRCmf+jh0zlGlasBfpCaxLqb4QLMsY1Q+nkXkO0nnUYopl50NcNRvP4V+TAiqOwJSd0LrQ5NcJqwbrnTBqw== 1167 | dependencies: 1168 | "@mswjs/cookies" "^0.2.2" 1169 | "@mswjs/interceptors" "^0.17.5" 1170 | "@open-draft/until" "^1.0.3" 1171 | "@types/cookie" "^0.4.1" 1172 | "@types/js-levenshtein" "^1.1.1" 1173 | chalk "4.1.1" 1174 | chokidar "^3.4.2" 1175 | cookie "^0.4.2" 1176 | graphql "^15.0.0 || ^16.0.0" 1177 | headers-polyfill "^3.1.0" 1178 | inquirer "^8.2.0" 1179 | is-node-process "^1.0.1" 1180 | js-levenshtein "^1.1.6" 1181 | node-fetch "^2.6.7" 1182 | outvariant "^1.3.0" 1183 | path-to-regexp "^6.2.0" 1184 | strict-event-emitter "^0.4.3" 1185 | type-fest "^2.19.0" 1186 | yargs "^17.3.1" 1187 | 1188 | mute-stream@0.0.8: 1189 | version "0.0.8" 1190 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" 1191 | integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== 1192 | 1193 | nanoid@^3.3.4: 1194 | version "3.3.4" 1195 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" 1196 | integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== 1197 | 1198 | node-fetch@^2.6.7: 1199 | version "2.6.9" 1200 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" 1201 | integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== 1202 | dependencies: 1203 | whatwg-url "^5.0.0" 1204 | 1205 | node-releases@^2.0.8: 1206 | version "2.0.10" 1207 | resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" 1208 | integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== 1209 | 1210 | normalize-path@^3.0.0, normalize-path@~3.0.0: 1211 | version "3.0.0" 1212 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 1213 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1214 | 1215 | object-assign@^4.1.1: 1216 | version "4.1.1" 1217 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1218 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 1219 | 1220 | onetime@^5.1.0: 1221 | version "5.1.2" 1222 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" 1223 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 1224 | dependencies: 1225 | mimic-fn "^2.1.0" 1226 | 1227 | ora@^5.4.1: 1228 | version "5.4.1" 1229 | resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" 1230 | integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== 1231 | dependencies: 1232 | bl "^4.1.0" 1233 | chalk "^4.1.0" 1234 | cli-cursor "^3.1.0" 1235 | cli-spinners "^2.5.0" 1236 | is-interactive "^1.0.0" 1237 | is-unicode-supported "^0.1.0" 1238 | log-symbols "^4.1.0" 1239 | strip-ansi "^6.0.0" 1240 | wcwidth "^1.0.1" 1241 | 1242 | os-tmpdir@~1.0.2: 1243 | version "1.0.2" 1244 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 1245 | integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== 1246 | 1247 | outvariant@^1.2.1, outvariant@^1.3.0: 1248 | version "1.3.0" 1249 | resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.3.0.tgz#c39723b1d2cba729c930b74bf962317a81b9b1c9" 1250 | integrity sha512-yeWM9k6UPfG/nzxdaPlJkB2p08hCg4xP6Lx99F+vP8YF7xyZVfTmJjrrNalkmzudD4WFvNLVudQikqUmF8zhVQ== 1251 | 1252 | path-key@^3.1.0: 1253 | version "3.1.1" 1254 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 1255 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1256 | 1257 | path-parse@^1.0.7: 1258 | version "1.0.7" 1259 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 1260 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 1261 | 1262 | path-to-regexp@^6.2.0: 1263 | version "6.2.1" 1264 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" 1265 | integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== 1266 | 1267 | performance-now@^2.1.0: 1268 | version "2.1.0" 1269 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" 1270 | integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== 1271 | 1272 | picocolors@^1.0.0: 1273 | version "1.0.0" 1274 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" 1275 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== 1276 | 1277 | picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2: 1278 | version "2.3.1" 1279 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 1280 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1281 | 1282 | postcss@^8.4.21: 1283 | version "8.4.21" 1284 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" 1285 | integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== 1286 | dependencies: 1287 | nanoid "^3.3.4" 1288 | picocolors "^1.0.0" 1289 | source-map-js "^1.0.2" 1290 | 1291 | promise@^8.1.0: 1292 | version "8.3.0" 1293 | resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" 1294 | integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== 1295 | dependencies: 1296 | asap "~2.0.6" 1297 | 1298 | raf@^3.4.1: 1299 | version "3.4.1" 1300 | resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" 1301 | integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== 1302 | dependencies: 1303 | performance-now "^2.1.0" 1304 | 1305 | react-app-polyfill@^3.0.0: 1306 | version "3.0.0" 1307 | resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz#95221e0a9bd259e5ca6b177c7bb1cb6768f68fd7" 1308 | integrity sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w== 1309 | dependencies: 1310 | core-js "^3.19.2" 1311 | object-assign "^4.1.1" 1312 | promise "^8.1.0" 1313 | raf "^3.4.1" 1314 | regenerator-runtime "^0.13.9" 1315 | whatwg-fetch "^3.6.2" 1316 | 1317 | react-dom@^18.2.0: 1318 | version "18.2.0" 1319 | resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" 1320 | integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== 1321 | dependencies: 1322 | loose-envify "^1.1.0" 1323 | scheduler "^0.23.0" 1324 | 1325 | react-query-auth@2.1.1: 1326 | version "2.1.1" 1327 | resolved "https://registry.yarnpkg.com/react-query-auth/-/react-query-auth-2.1.1.tgz#6faa3ca07e4d40873aa28eb1c747943291e65dc3" 1328 | integrity sha512-KCTqwcRjUlmkBQwgkPHKuHQQnYTXA5ePYB1dbUkN/Qr2JdCo1/7rwmMgtKtaJ/hOfJ3Ax+ZSRz46+sdUvTslIA== 1329 | 1330 | react-refresh@^0.13.0: 1331 | version "0.13.0" 1332 | resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.13.0.tgz#cbd01a4482a177a5da8d44c9755ebb1f26d5a1c1" 1333 | integrity sha512-XP8A9BT0CpRBD+NYLLeIhld/RqG9+gktUjW1FkE+Vm7OCinbG1SshcK5tb9ls4kzvjZr9mOQc7HYgBngEyPAXg== 1334 | 1335 | react@^18.2.0: 1336 | version "18.2.0" 1337 | resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" 1338 | integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== 1339 | dependencies: 1340 | loose-envify "^1.1.0" 1341 | 1342 | readable-stream@^3.4.0: 1343 | version "3.6.0" 1344 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" 1345 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 1346 | dependencies: 1347 | inherits "^2.0.3" 1348 | string_decoder "^1.1.1" 1349 | util-deprecate "^1.0.1" 1350 | 1351 | readdirp@~3.6.0: 1352 | version "3.6.0" 1353 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 1354 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 1355 | dependencies: 1356 | picomatch "^2.2.1" 1357 | 1358 | regenerator-runtime@^0.13.9: 1359 | version "0.13.11" 1360 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" 1361 | integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== 1362 | 1363 | remove-accents@0.4.2: 1364 | version "0.4.2" 1365 | resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5" 1366 | integrity sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA== 1367 | 1368 | require-directory@^2.1.1: 1369 | version "2.1.1" 1370 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 1371 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 1372 | 1373 | resolve@^1.22.0, resolve@^1.22.1: 1374 | version "1.22.1" 1375 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" 1376 | integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== 1377 | dependencies: 1378 | is-core-module "^2.9.0" 1379 | path-parse "^1.0.7" 1380 | supports-preserve-symlinks-flag "^1.0.0" 1381 | 1382 | restore-cursor@^3.1.0: 1383 | version "3.1.0" 1384 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" 1385 | integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== 1386 | dependencies: 1387 | onetime "^5.1.0" 1388 | signal-exit "^3.0.2" 1389 | 1390 | rollup@^3.10.0: 1391 | version "3.17.2" 1392 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.17.2.tgz#a4ecd29c488672a0606e41ef57474fad715750a9" 1393 | integrity sha512-qMNZdlQPCkWodrAZ3qnJtvCAl4vpQ8q77uEujVCCbC/6CLB7Lcmvjq7HyiOSnf4fxTT9XgsE36oLHJBH49xjqA== 1394 | optionalDependencies: 1395 | fsevents "~2.3.2" 1396 | 1397 | run-async@^2.4.0: 1398 | version "2.4.1" 1399 | resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" 1400 | integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== 1401 | 1402 | rxjs@^7.5.5: 1403 | version "7.8.0" 1404 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" 1405 | integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== 1406 | dependencies: 1407 | tslib "^2.1.0" 1408 | 1409 | safe-buffer@~5.2.0: 1410 | version "5.2.1" 1411 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1412 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1413 | 1414 | "safer-buffer@>= 2.1.2 < 3": 1415 | version "2.1.2" 1416 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 1417 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 1418 | 1419 | scheduler@^0.23.0: 1420 | version "0.23.0" 1421 | resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" 1422 | integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== 1423 | dependencies: 1424 | loose-envify "^1.1.0" 1425 | 1426 | semver@^6.3.0: 1427 | version "6.3.0" 1428 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" 1429 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 1430 | 1431 | set-cookie-parser@^2.4.6: 1432 | version "2.5.1" 1433 | resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.5.1.tgz#ddd3e9a566b0e8e0862aca974a6ac0e01349430b" 1434 | integrity sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ== 1435 | 1436 | shebang-command@^2.0.0: 1437 | version "2.0.0" 1438 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1439 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1440 | dependencies: 1441 | shebang-regex "^3.0.0" 1442 | 1443 | shebang-regex@^3.0.0: 1444 | version "3.0.0" 1445 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1446 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1447 | 1448 | signal-exit@^3.0.2: 1449 | version "3.0.7" 1450 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 1451 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 1452 | 1453 | source-map-js@^1.0.2: 1454 | version "1.0.2" 1455 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" 1456 | integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== 1457 | 1458 | strict-event-emitter@^0.2.4: 1459 | version "0.2.8" 1460 | resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.2.8.tgz#b4e768927c67273c14c13d20e19d5e6c934b47ca" 1461 | integrity sha512-KDf/ujU8Zud3YaLtMCcTI4xkZlZVIYxTLr+XIULexP+77EEVWixeXroLUXQXiVtH4XH2W7jr/3PT1v3zBuvc3A== 1462 | dependencies: 1463 | events "^3.3.0" 1464 | 1465 | strict-event-emitter@^0.4.3: 1466 | version "0.4.6" 1467 | resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.4.6.tgz#ff347c8162b3e931e3ff5f02cfce6772c3b07eb3" 1468 | integrity sha512-12KWeb+wixJohmnwNFerbyiBrAlq5qJLwIt38etRtKtmmHyDSoGlIqFE9wx+4IwG0aDjI7GV8tc8ZccjWZZtTg== 1469 | 1470 | string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: 1471 | version "4.2.3" 1472 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1473 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1474 | dependencies: 1475 | emoji-regex "^8.0.0" 1476 | is-fullwidth-code-point "^3.0.0" 1477 | strip-ansi "^6.0.1" 1478 | 1479 | string_decoder@^1.1.1: 1480 | version "1.3.0" 1481 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 1482 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 1483 | dependencies: 1484 | safe-buffer "~5.2.0" 1485 | 1486 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1487 | version "6.0.1" 1488 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1489 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1490 | dependencies: 1491 | ansi-regex "^5.0.1" 1492 | 1493 | superjson@^1.10.0: 1494 | version "1.12.2" 1495 | resolved "https://registry.yarnpkg.com/superjson/-/superjson-1.12.2.tgz#072471f1e6add2d95a38b77fef8c7a199d82103a" 1496 | integrity sha512-ugvUo9/WmvWOjstornQhsN/sR9mnGtWGYeTxFuqLb4AiT4QdUavjGFRALCPKWWnAiUJ4HTpytj5e0t5HoMRkXg== 1497 | dependencies: 1498 | copy-anything "^3.0.2" 1499 | 1500 | supports-color@^5.3.0: 1501 | version "5.5.0" 1502 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1503 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1504 | dependencies: 1505 | has-flag "^3.0.0" 1506 | 1507 | supports-color@^7.1.0: 1508 | version "7.2.0" 1509 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1510 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1511 | dependencies: 1512 | has-flag "^4.0.0" 1513 | 1514 | supports-preserve-symlinks-flag@^1.0.0: 1515 | version "1.0.0" 1516 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" 1517 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 1518 | 1519 | through@^2.3.6: 1520 | version "2.3.8" 1521 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1522 | integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== 1523 | 1524 | tmp@^0.0.33: 1525 | version "0.0.33" 1526 | resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" 1527 | integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== 1528 | dependencies: 1529 | os-tmpdir "~1.0.2" 1530 | 1531 | to-fast-properties@^2.0.0: 1532 | version "2.0.0" 1533 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" 1534 | integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== 1535 | 1536 | to-regex-range@^5.0.1: 1537 | version "5.0.1" 1538 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1539 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1540 | dependencies: 1541 | is-number "^7.0.0" 1542 | 1543 | tr46@~0.0.3: 1544 | version "0.0.3" 1545 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 1546 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 1547 | 1548 | tslib@^2.1.0: 1549 | version "2.5.0" 1550 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" 1551 | integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== 1552 | 1553 | type-fest@^0.21.3: 1554 | version "0.21.3" 1555 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" 1556 | integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== 1557 | 1558 | type-fest@^2.19.0: 1559 | version "2.19.0" 1560 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" 1561 | integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== 1562 | 1563 | typescript@^4: 1564 | version "4.9.5" 1565 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" 1566 | integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== 1567 | 1568 | update-browserslist-db@^1.0.10: 1569 | version "1.0.10" 1570 | resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" 1571 | integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== 1572 | dependencies: 1573 | escalade "^3.1.1" 1574 | picocolors "^1.0.0" 1575 | 1576 | use-sync-external-store@^1.2.0: 1577 | version "1.2.0" 1578 | resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" 1579 | integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== 1580 | 1581 | util-deprecate@^1.0.1: 1582 | version "1.0.2" 1583 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1584 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 1585 | 1586 | util@^0.12.3: 1587 | version "0.12.5" 1588 | resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" 1589 | integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== 1590 | dependencies: 1591 | inherits "^2.0.3" 1592 | is-arguments "^1.0.4" 1593 | is-generator-function "^1.0.7" 1594 | is-typed-array "^1.1.3" 1595 | which-typed-array "^1.1.2" 1596 | 1597 | vite-preset-react@latest: 1598 | version "2.3.0" 1599 | resolved "https://registry.yarnpkg.com/vite-preset-react/-/vite-preset-react-2.3.0.tgz#1433da9ebfe160ffb96e7a2000555c20a3689b61" 1600 | integrity sha512-so8NjBurFEkG1okeB1kuZALhUs5LBRPDqlcf+7Fw/E2Pkz7O3fL7aQKHY0xU0i4wBIW72Yox/d0M0MREzcfuhQ== 1601 | dependencies: 1602 | "@vitejs/plugin-react" "^1.3.2" 1603 | 1604 | vite@latest: 1605 | version "4.1.3" 1606 | resolved "https://registry.yarnpkg.com/vite/-/vite-4.1.3.tgz#001a038c3a7757d532787c0de429b8368136ded5" 1607 | integrity sha512-0Zqo4/Fr/swSOBmbl+HAAhOjrqNwju+yTtoe4hQX9UsARdcuc9njyOdr6xU0DDnV7YP0RT6mgTTOiRtZgxfCxA== 1608 | dependencies: 1609 | esbuild "^0.16.14" 1610 | postcss "^8.4.21" 1611 | resolve "^1.22.1" 1612 | rollup "^3.10.0" 1613 | optionalDependencies: 1614 | fsevents "~2.3.2" 1615 | 1616 | wcwidth@^1.0.1: 1617 | version "1.0.1" 1618 | resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" 1619 | integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== 1620 | dependencies: 1621 | defaults "^1.0.3" 1622 | 1623 | web-encoding@^1.1.5: 1624 | version "1.1.5" 1625 | resolved "https://registry.yarnpkg.com/web-encoding/-/web-encoding-1.1.5.tgz#fc810cf7667364a6335c939913f5051d3e0c4864" 1626 | integrity sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA== 1627 | dependencies: 1628 | util "^0.12.3" 1629 | optionalDependencies: 1630 | "@zxing/text-encoding" "0.9.0" 1631 | 1632 | webidl-conversions@^3.0.0: 1633 | version "3.0.1" 1634 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 1635 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 1636 | 1637 | whatwg-fetch@^3.6.2: 1638 | version "3.6.2" 1639 | resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" 1640 | integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== 1641 | 1642 | whatwg-url@^5.0.0: 1643 | version "5.0.0" 1644 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 1645 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 1646 | dependencies: 1647 | tr46 "~0.0.3" 1648 | webidl-conversions "^3.0.0" 1649 | 1650 | which-typed-array@^1.1.2: 1651 | version "1.1.9" 1652 | resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" 1653 | integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== 1654 | dependencies: 1655 | available-typed-arrays "^1.0.5" 1656 | call-bind "^1.0.2" 1657 | for-each "^0.3.3" 1658 | gopd "^1.0.1" 1659 | has-tostringtag "^1.0.0" 1660 | is-typed-array "^1.1.10" 1661 | 1662 | which@^2.0.1: 1663 | version "2.0.2" 1664 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1665 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1666 | dependencies: 1667 | isexe "^2.0.0" 1668 | 1669 | wrap-ansi@^7.0.0: 1670 | version "7.0.0" 1671 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1672 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1673 | dependencies: 1674 | ansi-styles "^4.0.0" 1675 | string-width "^4.1.0" 1676 | strip-ansi "^6.0.0" 1677 | 1678 | y18n@^5.0.5: 1679 | version "5.0.8" 1680 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1681 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1682 | 1683 | yallist@^3.0.2: 1684 | version "3.1.1" 1685 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" 1686 | integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== 1687 | 1688 | yargs-parser@^21.1.1: 1689 | version "21.1.1" 1690 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" 1691 | integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== 1692 | 1693 | yargs@^17.3.1: 1694 | version "17.7.0" 1695 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.0.tgz#b21e9af1e0a619a2a9c67b1133219b2975a07985" 1696 | integrity sha512-dwqOPg5trmrre9+v8SUo2q/hAwyKoVfu8OC1xPHKJGNdxAvPl4sKxL4vBnh3bQz/ZvvGAFeA5H3ou2kcOY8sQQ== 1697 | dependencies: 1698 | cliui "^8.0.1" 1699 | escalade "^3.1.1" 1700 | get-caller-file "^2.0.5" 1701 | require-directory "^2.1.1" 1702 | string-width "^4.2.3" 1703 | y18n "^5.0.5" 1704 | yargs-parser "^21.1.1" 1705 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'jsdom', 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-query-auth", 3 | "version": "2.2.0", 4 | "author": "alan2207", 5 | "license": "MIT", 6 | "repository": "alan2207/react-query-auth", 7 | "main": "./dist/index.mjs", 8 | "module": "./dist/index.mjs", 9 | "types": "./dist/index.d.ts", 10 | "files": [ 11 | "dist", 12 | "src" 13 | ], 14 | "exports": { 15 | "require": "./dist/index.js", 16 | "import": "./dist/index.mjs" 17 | }, 18 | "engines": { 19 | "node": ">=16" 20 | }, 21 | "scripts": { 22 | "dev": "tsup src/index.tsx --watch", 23 | "build": "tsup src/index.tsx", 24 | "test": "jest", 25 | "lint": "eslint --fix ./src", 26 | "size": "size-limit" 27 | }, 28 | "peerDependencies": { 29 | "@tanstack/react-query": "^4.24.6", 30 | "react": ">=16.8.0" 31 | }, 32 | "husky": { 33 | "hooks": { 34 | "pre-commit": "npm run lint" 35 | } 36 | }, 37 | "size-limit": [ 38 | { 39 | "path": "dist/index.mjs", 40 | "limit": "10 KB" 41 | }, 42 | { 43 | "path": "dist/index.js", 44 | "limit": "10 KB" 45 | } 46 | ], 47 | "devDependencies": { 48 | "@size-limit/preset-small-lib": "^8.2.4", 49 | "@tanstack/react-query": "^4.24.6", 50 | "@testing-library/jest-dom": "^5.16.5", 51 | "@testing-library/react": "^13.4.0", 52 | "@testing-library/react-hooks": "^8.0.1", 53 | "@types/react": "^18.0.28", 54 | "@types/react-dom": "^18.0.11", 55 | "@typescript-eslint/eslint-plugin": "^5.52.0", 56 | "@typescript-eslint/parser": "^5.52.0", 57 | "eslint": "^8.34.0", 58 | "eslint-config-prettier": "^8.6.0", 59 | "eslint-plugin-react": "^7.32.2", 60 | "husky": "^8.0.3", 61 | "jest": "^29.4.3", 62 | "jest-environment-jsdom": "^29.4.3", 63 | "react": "^18.2.0", 64 | "react-dom": "^18.2.0", 65 | "size-limit": "^8.2.4", 66 | "ts-jest": "^29.0.5", 67 | "tsup": "^6.6.3", 68 | "typescript": "^4.9.5" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | useQuery, 4 | useMutation, 5 | useQueryClient, 6 | QueryKey, 7 | UseQueryOptions, 8 | QueryFunction, 9 | MutationFunction, 10 | UseMutationOptions, 11 | } from '@tanstack/react-query'; 12 | 13 | export interface ReactQueryAuthConfig< 14 | User, 15 | LoginCredentials, 16 | RegisterCredentials 17 | > { 18 | userFn: QueryFunction; 19 | loginFn: MutationFunction; 20 | registerFn: MutationFunction; 21 | logoutFn: MutationFunction; 22 | userKey?: QueryKey; 23 | } 24 | 25 | export interface AuthProviderProps { 26 | children: React.ReactNode; 27 | } 28 | 29 | export function configureAuth< 30 | User, 31 | Error, 32 | LoginCredentials, 33 | RegisterCredentials 34 | >(config: ReactQueryAuthConfig) { 35 | const { 36 | userFn, 37 | userKey = ['authenticated-user'], 38 | loginFn, 39 | registerFn, 40 | logoutFn, 41 | } = config; 42 | 43 | const useUser = ( 44 | options?: Omit< 45 | UseQueryOptions, 46 | 'queryKey' | 'queryFn' 47 | > 48 | ) => useQuery(userKey, userFn, options); 49 | 50 | const useLogin = ( 51 | options?: Omit< 52 | UseMutationOptions, 53 | 'mutationFn' 54 | > 55 | ) => { 56 | const queryClient = useQueryClient(); 57 | 58 | const setUser = React.useCallback( 59 | (data: User) => queryClient.setQueryData(userKey, data), 60 | [queryClient] 61 | ); 62 | 63 | return useMutation({ 64 | mutationFn: loginFn, 65 | ...options, 66 | onSuccess: (user, ...rest) => { 67 | setUser(user); 68 | options?.onSuccess?.(user, ...rest); 69 | }, 70 | }); 71 | }; 72 | 73 | const useRegister = ( 74 | options?: Omit< 75 | UseMutationOptions, 76 | 'mutationFn' 77 | > 78 | ) => { 79 | const queryClient = useQueryClient(); 80 | 81 | const setUser = React.useCallback( 82 | (data: User) => queryClient.setQueryData(userKey, data), 83 | [queryClient] 84 | ); 85 | 86 | return useMutation({ 87 | mutationFn: registerFn, 88 | ...options, 89 | onSuccess: (user, ...rest) => { 90 | setUser(user); 91 | options?.onSuccess?.(user, ...rest); 92 | }, 93 | }); 94 | }; 95 | 96 | const useLogout = (options?: UseMutationOptions) => { 97 | const queryClient = useQueryClient(); 98 | 99 | const setUser = React.useCallback( 100 | (data: User | null) => queryClient.setQueryData(userKey, data), 101 | [queryClient] 102 | ); 103 | 104 | return useMutation({ 105 | mutationFn: logoutFn, 106 | ...options, 107 | onSuccess: (...args) => { 108 | setUser(null); 109 | options?.onSuccess?.(...args); 110 | }, 111 | }); 112 | }; 113 | 114 | function AuthLoader({ 115 | children, 116 | renderLoading, 117 | renderUnauthenticated, 118 | renderError = (error: Error) => <>{JSON.stringify(error)}, 119 | }: { 120 | children: React.ReactNode; 121 | renderLoading: () => JSX.Element; 122 | renderUnauthenticated?: () => JSX.Element; 123 | renderError?: (error: Error) => JSX.Element; 124 | }) { 125 | const { isSuccess, isFetched, status, data, error } = useUser(); 126 | 127 | if (isSuccess) { 128 | if (renderUnauthenticated && !data) { 129 | return renderUnauthenticated(); 130 | } 131 | return <>{children}; 132 | } 133 | 134 | if (!isFetched) { 135 | return renderLoading(); 136 | } 137 | 138 | if (status === 'error') { 139 | return renderError(error); 140 | } 141 | 142 | return null; 143 | } 144 | 145 | return { 146 | useUser, 147 | useLogin, 148 | useRegister, 149 | useLogout, 150 | AuthLoader, 151 | }; 152 | } 153 | -------------------------------------------------------------------------------- /test/index.test.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { 3 | act, 4 | render, 5 | renderHook, 6 | screen, 7 | waitFor, 8 | } from '@testing-library/react'; 9 | import { configureAuth } from '../src'; 10 | 11 | import '@testing-library/jest-dom/extend-expect'; 12 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; 13 | 14 | const renderApp = (children: React.ReactNode) => { 15 | const client = new QueryClient(); 16 | return render( 17 | {children} 18 | ); 19 | }; 20 | 21 | const renderAppHook = (hook: () => Result) => { 22 | const client = new QueryClient(); 23 | return renderHook(hook, { 24 | wrapper: ({ children }) => ( 25 | {children} 26 | ), 27 | }); 28 | }; 29 | 30 | beforeEach(() => { 31 | jest.resetAllMocks(); 32 | }); 33 | 34 | const user = { 35 | id: '1', 36 | name: 'Test User', 37 | email: 'user@mail.com', 38 | }; 39 | 40 | const config = { 41 | userFn: jest.fn(), 42 | loginFn: jest.fn(), 43 | logoutFn: jest.fn(), 44 | registerFn: jest.fn(), 45 | }; 46 | 47 | const { AuthLoader, useUser, useLogin, useRegister, useLogout } = 48 | configureAuth(config); 49 | 50 | describe('useUser', () => { 51 | it('returns the authenticated user', async () => { 52 | config.userFn.mockResolvedValue(user); 53 | 54 | const { result } = renderAppHook(() => useUser()); 55 | 56 | await waitFor(() => expect(result.current.data).toEqual(user)); 57 | 58 | expect(config.userFn).toHaveBeenCalled(); 59 | }); 60 | }); 61 | 62 | describe('useRegister', () => { 63 | it('calls the register function and sets the authenticated user on success', async () => { 64 | config.registerFn.mockResolvedValue(user); 65 | 66 | const registerCredentials = { 67 | name: 'Test User 2', 68 | email: 'user2@mail.com', 69 | password: 'password', 70 | }; 71 | 72 | const { result } = renderAppHook(() => useRegister()); 73 | 74 | act(() => { 75 | result.current.mutate(registerCredentials); 76 | }); 77 | 78 | await waitFor(() => 79 | expect(config.registerFn).toHaveBeenCalledWith(registerCredentials) 80 | ); 81 | expect(result.current.data).toEqual(user); 82 | }); 83 | }); 84 | 85 | describe('useLogin', () => { 86 | it('calls the login function and sets the authenticated user on success', async () => { 87 | config.loginFn.mockResolvedValue(user); 88 | 89 | const loginCredentials = { 90 | email: 'user@mail.com', 91 | password: 'password', 92 | }; 93 | 94 | const { result } = renderAppHook(() => useLogin()); 95 | 96 | act(() => { 97 | result.current.mutate(loginCredentials); 98 | }); 99 | 100 | await waitFor(() => 101 | expect(config.loginFn).toHaveBeenCalledWith(loginCredentials) 102 | ); 103 | expect(result.current.data).toEqual(user); 104 | }); 105 | }); 106 | 107 | describe('useLogout', () => { 108 | it('calls the logout function and removes the authenticated user on success', async () => { 109 | config.logoutFn.mockResolvedValue(true); 110 | 111 | const { result } = renderAppHook(() => useLogout()); 112 | 113 | act(() => { 114 | result.current.mutate({}); 115 | }); 116 | 117 | await waitFor(() => expect(config.logoutFn).toHaveBeenCalled()); 118 | expect(result.current.data).toEqual(true); 119 | }); 120 | }); 121 | 122 | describe('AuthLoader', () => { 123 | it('renders loading component when not yet fetched', () => { 124 | config.userFn.mockResolvedValue(null); 125 | renderApp( 126 |
Loading...
} 128 | renderUnauthenticated={() =>
Unauthenticated
} 129 | > 130 | Hello {user.name}! 131 |
132 | ); 133 | 134 | expect(screen.getByText('Loading...')).toBeInTheDocument(); 135 | }); 136 | 137 | it('renders unauthenticated component when authenticated user is null', async () => { 138 | config.userFn.mockResolvedValue(null); 139 | renderApp( 140 |
Loading...
} 142 | renderUnauthenticated={() =>
Unauthenticated
} 143 | > 144 | Hello {user.name}! 145 |
146 | ); 147 | 148 | await waitFor(() => 149 | expect(screen.getByText('Unauthenticated')).toBeInTheDocument() 150 | ); 151 | }); 152 | 153 | it('renders children when authenticated user is not null', async () => { 154 | const TestChild = () =>
Test
; 155 | 156 | config.userFn.mockResolvedValue(user); 157 | 158 | renderApp( 159 |
Loading...
}> 160 | Hello {user.name}! 161 |
162 | ); 163 | 164 | await waitFor(() => 165 | expect(screen.getByText(`Hello ${user.name}!`)).toBeInTheDocument() 166 | ); 167 | }); 168 | }); 169 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "jsx": "react", 5 | "module": "ESNext", 6 | "moduleResolution": "node", 7 | "skipLibCheck": true, 8 | "strict": true, 9 | "noEmit": true 10 | }, 11 | "include": ["src"] 12 | } 13 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { Options } from 'tsup'; 2 | 3 | const config: Options = { 4 | entry: ['src/index.tsx'], 5 | dts: true, 6 | sourcemap: true, 7 | format: ['cjs', 'esm'], 8 | minify: true, 9 | clean: true, 10 | }; 11 | 12 | export default config; 13 | --------------------------------------------------------------------------------