├── .husky ├── .gitignore └── pre-commit ├── .gitignore ├── prettier.config.js ├── .npmignore ├── tsconfig.json ├── .github └── workflows │ ├── test.yml │ └── publish.yml ├── package.json ├── index.ts ├── README.md └── yarn.lock /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.log 3 | .DS_Store 4 | node_modules 5 | dist 6 | *.bak 7 | .envrc 8 | .direnv/ 9 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: 'typescript', 3 | singleQuote: true, 4 | trailingComma: 'all', 5 | arrowParens: 'always', 6 | }; 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | prettier.config.js 2 | tsconfig.json 3 | yarn.lock 4 | yarn-error.log 5 | .husky/ 6 | flake.nix 7 | flake.lock 8 | *.test.ts 9 | *.test.js 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["ES2019", "dom"], 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "outDir": "./dist", 8 | "declaration": true, 9 | "strict": true, 10 | "esModuleInterop": true, 11 | "skipLibCheck": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "baseUrl": "." 14 | }, 15 | "include": ["index.ts"], 16 | } 17 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | node-version: [14.x] 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: use node ${{ matrix.node-version }} 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | - run: yarn 24 | - run: yarn test 25 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: publish 2 | on: 3 | release: 4 | types: [published] 5 | jobs: 6 | publish: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - uses: actions/setup-node@v1 11 | with: 12 | node-version: 14 13 | registry-url: https://registry.npmjs.org 14 | - name: install dependencies 15 | run: yarn install --frozen-lockfile 16 | - name: test 17 | run: yarn test 18 | - name: version 19 | run: yarn version --new-version "${GITHUB_REF:10}" --no-git-tag-version 20 | - name: publish 21 | run: yarn publish --access public 22 | env: 23 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remix-middleware", 3 | "version": "0.0.0", 4 | "description": "middleware for your remix loaders and actions", 5 | "main": "./dist/index.js", 6 | "types": "./dist/index.d.ts", 7 | "repository": "https://github.com/neurosnap/remix-middleware.git", 8 | "author": "Eric Bower", 9 | "license": "MIT", 10 | "private": false, 11 | "devDependencies": { 12 | "@remix-run/server-runtime": "^1.1.1", 13 | "@types/node": "^17.0.10", 14 | "husky": ">=6", 15 | "lint-staged": ">=10", 16 | "prettier": "^2.5.1", 17 | "remix-auth": "^3.2.1", 18 | "typescript": "^4.5.4" 19 | }, 20 | "lint-staged": { 21 | "*.{ts}": "prettier --write" 22 | }, 23 | "scripts": { 24 | "prepare": "husky install", 25 | "test": "tsc --noEmit", 26 | "build": "tsc", 27 | "prepublish": "yarn build" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import type { DataFunctionArgs, AppData } from '@remix-run/server-runtime'; 2 | import type { Authenticator } from 'remix-auth'; 3 | 4 | type Next = () => any; 5 | export interface Ctx extends DataFunctionArgs { 6 | response: Promise | Response | Promise | AppData; 7 | } 8 | export interface AuthCtx extends Ctx { 9 | user: U; 10 | } 11 | 12 | type Middleware = (ctx: CurCtx, next: Next) => any; 13 | type MiddlewareCo = 14 | | Middleware 15 | | Middleware[]; 16 | 17 | export function compose( 18 | middleware: Middleware[], 19 | ) { 20 | if (!Array.isArray(middleware)) { 21 | throw new TypeError('Middleware stack must be an array!'); 22 | } 23 | for (const fn of middleware) { 24 | if (typeof fn !== 'function') { 25 | throw new TypeError('Middleware must be composed of functions!'); 26 | } 27 | } 28 | 29 | return async function composer(context: CurCtx, next?: Next) { 30 | // last called middleware # 31 | let index = -1; 32 | await dispatch(0); 33 | 34 | async function dispatch(i: number) { 35 | if (i <= index) { 36 | throw new Error('next() called multiple times'); 37 | } 38 | index = i; 39 | let fn: any = middleware[i]; 40 | if (i === middleware.length) fn = next; 41 | if (!fn) return; 42 | await fn(context, dispatch.bind(null, i + 1)); 43 | } 44 | }; 45 | } 46 | 47 | async function defaultMiddleware( 48 | _: CurCtx, 49 | next: Next, 50 | ) { 51 | await next(); 52 | } 53 | 54 | const compileName = (request: Request): string => 55 | `${request.url} [${request.method}]`; 56 | 57 | export function createMiddleware() { 58 | const middleware: Middleware[] = []; 59 | const middlewareMap: { [key: string]: Middleware[] } = {}; 60 | 61 | async function middlewareFn( 62 | props: DataFunctionArgs, 63 | md: MiddlewareCo, 64 | ) { 65 | const name = compileName(props.request); 66 | if (Array.isArray(md)) { 67 | middlewareMap[name] = md; 68 | } else { 69 | middlewareMap[name] = [md]; 70 | } 71 | 72 | const ctx: Ctx = { ...props, response: {} }; 73 | const fn = compose(middleware); 74 | await fn(ctx as any); 75 | return ctx.response; 76 | } 77 | 78 | return { 79 | use: (md: Middleware) => { 80 | middleware.push(md); 81 | }, 82 | response: (resp: CurCtx['response']) => async (ctx: CurCtx, next: Next) => { 83 | ctx.response = resp; 84 | await next(); 85 | }, 86 | routes: () => async (ctx: CurCtx, next: Next) => { 87 | const name = compileName(ctx.request); 88 | const match = middlewareMap[name]; 89 | if (!match) { 90 | await next(); 91 | return; 92 | } 93 | 94 | const md = compose(match); 95 | await md(ctx, next); 96 | }, 97 | run: ( 98 | props: DataFunctionArgs, 99 | md: MiddlewareCo = defaultMiddleware, 100 | ): Promise | Promise => middlewareFn(props, md), 101 | }; 102 | } 103 | 104 | export function isAuthenticated( 105 | auth: Authenticator, 106 | options?: { successRedirect?: never; failureRedirect?: never }, 107 | ): Middleware>; 108 | export function isAuthenticated( 109 | auth: Authenticator, 110 | options: { successRedirect: string; failureRedirect?: never }, 111 | ): Middleware>; 112 | export function isAuthenticated( 113 | auth: Authenticator, 114 | options: { successRedirect?: never; failureRedirect: string }, 115 | ): Middleware>; 116 | export function isAuthenticated( 117 | auth: Authenticator, 118 | props: 119 | | { successRedirect?: never; failureRedirect?: never } 120 | | { successRedirect: string; failureRedirect?: never } 121 | | { successRedirect?: never; failureRedirect: string } = {}, 122 | ): Middleware> { 123 | async function isAuthMdw(ctx: AuthCtx, next: Next) { 124 | const user = await auth.isAuthenticated(ctx.request, props as any); 125 | ctx.user = user; 126 | await next(); 127 | } 128 | return isAuthMdw; 129 | } 130 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # remix-middleware 2 | 3 | Add an express-like middleware stack to your remix loaders and actions! 4 | 5 | ```bash 6 | yarn add remix-middleware 7 | ``` 8 | 9 | ```ts 10 | // ./app/middleware.server.ts 11 | export const mdw = createMiddleware(); 12 | 13 | mdw.use(async (ctx, next) => { 14 | console.log("middleware activated for", ctx.request.url); 15 | await next(); 16 | console.log("middleware completed for", ctx.request.url); 17 | }); 18 | 19 | mdw.use(mdw.routes()); 20 | ``` 21 | 22 | ```tsx 23 | // ./app/routes/posts/index.tsx 24 | import { ActionFunction, LoaderFunction, Form, useLoaderData } from "remix"; 25 | 26 | import { mdw } from "~/middleware.server"; 27 | 28 | interface Post { 29 | id: string; 30 | title: string; 31 | } 32 | 33 | export const loader: LoaderFunction = (props) => 34 | mdw.run(props, (ctx) => { 35 | // ctx.response is where the response object goes 36 | ctx.response = [ 37 | { 38 | id: "1", 39 | title: "My First Post", 40 | }, 41 | { 42 | id: "2", 43 | title: "A Mixtape I Made Just For You", 44 | }, 45 | ]; 46 | }); 47 | 48 | export const action: ActionFunction = (props) => 49 | mdw.run(props, async (ctx) => { 50 | const body = await ctx.request.formData(); 51 | const post = { id: "3", title: body.get("title") }; 52 | ctx.response = post; 53 | }); 54 | 55 | export default function Posts() { 56 | const posts = useLoaderData(); 57 | return ( 58 |
59 |

Posts

60 |
61 | {posts.map((post) => ( 62 |
{post.title}
63 | ))} 64 |
65 |
66 |
67 |

68 | 71 |

72 |

73 | 74 |

75 |
76 |
77 |
78 | ); 79 | } 80 | ``` 81 | 82 | Just have simple JSON that you are returning in a loader like in the example 83 | above? 84 | 85 | ```tsx 86 | export const loader: LoaderFunction = (props) => 87 | mdw.run( 88 | props, 89 | mdw.response([ 90 | { 91 | id: "1", 92 | title: "My First Post", 93 | }, 94 | { 95 | id: "2", 96 | title: "A Mixtape I Made Just For You", 97 | }, 98 | ]) 99 | ); 100 | ``` 101 | 102 | ## remix-auth 103 | 104 | We built a middleware that will help interacting with [remix-auth](https://github.com/sergiodxa/remix-auth) 105 | more streamlined. 106 | 107 | - isAuthenticated - activates `authenticator.isAuthenticated` 108 | 109 | Setting up `remix-auth` 110 | 111 | ```tsx 112 | // ./app/user.ts 113 | export interface User { 114 | id: string; 115 | email: string; 116 | } 117 | ``` 118 | 119 | ```ts 120 | // ./app/authenticator.ts 121 | import { Authenticator } from 'remix-auth'; 122 | import { sessionStorage } from "./session"; 123 | import type { User } from './user'; 124 | 125 | export const authenticator = new Authenticator(sessionStorage); 126 | ``` 127 | 128 | Create middleware for your needs 129 | 130 | ```ts 131 | // ./app/middleware.server.ts 132 | import { createMiddleware, AuthCtx, isAuthenticated } from 'remix-middleware'; 133 | import { authenticator } from './authenticator'; 134 | import type { User } from './user'; 135 | 136 | // use this middleware for routes that do *not* require authentication 137 | // but you want the user to automatically redirect somewhere 138 | export const unauthed = createMiddleware>(); 139 | unauthed.use(isAuthenticated(authenticator, { successRedirect: '/dashboard' })); 140 | unauthed.use(unauthed.routes()); 141 | 142 | // use this middleware for routes that *require* authentication 143 | export const authed = createMiddleware>(); 144 | authed.use(isAuthenticated(authenticator, { failureRedirect: '/login' })); 145 | authed.use(authed.routes()); 146 | 147 | // use this middleware if the route allows both authenticated and 148 | // non-authenticated users 149 | export const mdw = createMiddleware>(); 150 | mdw.use(isAuthenticated(authenticator)); 151 | mdw.use(async (ctx, next) => { 152 | if (ctx.user) { 153 | // ... do something with the user 154 | } else { 155 | // ... do something with a non-user 156 | } 157 | await next(); 158 | }); 159 | ``` 160 | 161 | Now in your routes that require authentication 162 | 163 | ```ts 164 | // in a route that requires auth 165 | import { authed } from '~/middleware.server'; 166 | 167 | export const loader: LoaderFunction = (props) => 168 | authed.run(props, (ctx) => { 169 | // no user can make it to this point without being authenticated 170 | // and as a result we now have access to ctx.user which is `User` 171 | // in this example 172 | console.log(ctx.user); // { id: '123', email: 'cool@lib.bro' } 173 | 174 | ctx.response = { text: `Hi ${ctx.user.email}!` }; 175 | }); 176 | ``` 177 | 178 | Now in your routes that do *not* require authentication 179 | 180 | ```ts 181 | // in a route that does *not* require auth 182 | import { unauthed } from '~/middleware.server'; 183 | 184 | // `.run()` doesn't need any middleware, it'll run without it 185 | export const loader = (props) => unauthed.run(props); 186 | ``` 187 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/runtime@^7.7.6": 6 | version "7.16.7" 7 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" 8 | integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== 9 | dependencies: 10 | regenerator-runtime "^0.13.4" 11 | 12 | "@remix-run/server-runtime@^1.1.1": 13 | version "1.1.1" 14 | resolved "https://registry.yarnpkg.com/@remix-run/server-runtime/-/server-runtime-1.1.1.tgz#c713bf517a75b49544fc01316775f813ade25af6" 15 | integrity sha512-uTTGSjCn2WTXUShruvTuErpbdbGoLu2dZ/zQ0ZHA0MMgP4VDA8xyuBeRcv/By3xqGcu2zSxcEGv7tRPgzU1AtA== 16 | dependencies: 17 | "@types/cookie" "^0.4.0" 18 | cookie "^0.4.1" 19 | jsesc "^3.0.1" 20 | react-router-dom "^6.2.1" 21 | set-cookie-parser "^2.4.8" 22 | source-map "^0.7.3" 23 | 24 | "@types/cookie@^0.4.0": 25 | version "0.4.1" 26 | resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" 27 | integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== 28 | 29 | "@types/node@^17.0.10": 30 | version "17.0.10" 31 | resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.10.tgz#616f16e9d3a2a3d618136b1be244315d95bd7cab" 32 | integrity sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog== 33 | 34 | aggregate-error@^3.0.0: 35 | version "3.1.0" 36 | resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" 37 | integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== 38 | dependencies: 39 | clean-stack "^2.0.0" 40 | indent-string "^4.0.0" 41 | 42 | ansi-escapes@^4.3.0: 43 | version "4.3.2" 44 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" 45 | integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== 46 | dependencies: 47 | type-fest "^0.21.3" 48 | 49 | ansi-regex@^5.0.1: 50 | version "5.0.1" 51 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 52 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 53 | 54 | ansi-regex@^6.0.1: 55 | version "6.0.1" 56 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" 57 | integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== 58 | 59 | ansi-styles@^4.0.0: 60 | version "4.3.0" 61 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 62 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 63 | dependencies: 64 | color-convert "^2.0.1" 65 | 66 | ansi-styles@^6.0.0: 67 | version "6.1.0" 68 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3" 69 | integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== 70 | 71 | astral-regex@^2.0.0: 72 | version "2.0.0" 73 | resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" 74 | integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== 75 | 76 | braces@^3.0.1: 77 | version "3.0.2" 78 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 79 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 80 | dependencies: 81 | fill-range "^7.0.1" 82 | 83 | clean-stack@^2.0.0: 84 | version "2.2.0" 85 | resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" 86 | integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== 87 | 88 | cli-cursor@^3.1.0: 89 | version "3.1.0" 90 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" 91 | integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== 92 | dependencies: 93 | restore-cursor "^3.1.0" 94 | 95 | cli-truncate@^2.1.0: 96 | version "2.1.0" 97 | resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" 98 | integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== 99 | dependencies: 100 | slice-ansi "^3.0.0" 101 | string-width "^4.2.0" 102 | 103 | cli-truncate@^3.1.0: 104 | version "3.1.0" 105 | resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" 106 | integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== 107 | dependencies: 108 | slice-ansi "^5.0.0" 109 | string-width "^5.0.0" 110 | 111 | color-convert@^2.0.1: 112 | version "2.0.1" 113 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 114 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 115 | dependencies: 116 | color-name "~1.1.4" 117 | 118 | color-name@~1.1.4: 119 | version "1.1.4" 120 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 121 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 122 | 123 | colorette@^2.0.16: 124 | version "2.0.16" 125 | resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" 126 | integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== 127 | 128 | commander@^8.3.0: 129 | version "8.3.0" 130 | resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" 131 | integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== 132 | 133 | cookie@^0.4.1: 134 | version "0.4.1" 135 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" 136 | integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== 137 | 138 | cross-spawn@^7.0.3: 139 | version "7.0.3" 140 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 141 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 142 | dependencies: 143 | path-key "^3.1.0" 144 | shebang-command "^2.0.0" 145 | which "^2.0.1" 146 | 147 | debug@^4.3.3: 148 | version "4.3.3" 149 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" 150 | integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== 151 | dependencies: 152 | ms "2.1.2" 153 | 154 | eastasianwidth@^0.2.0: 155 | version "0.2.0" 156 | resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" 157 | integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== 158 | 159 | emoji-regex@^8.0.0: 160 | version "8.0.0" 161 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 162 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 163 | 164 | emoji-regex@^9.2.2: 165 | version "9.2.2" 166 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" 167 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 168 | 169 | execa@^5.1.1: 170 | version "5.1.1" 171 | resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" 172 | integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== 173 | dependencies: 174 | cross-spawn "^7.0.3" 175 | get-stream "^6.0.0" 176 | human-signals "^2.1.0" 177 | is-stream "^2.0.0" 178 | merge-stream "^2.0.0" 179 | npm-run-path "^4.0.1" 180 | onetime "^5.1.2" 181 | signal-exit "^3.0.3" 182 | strip-final-newline "^2.0.0" 183 | 184 | fill-range@^7.0.1: 185 | version "7.0.1" 186 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 187 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 188 | dependencies: 189 | to-regex-range "^5.0.1" 190 | 191 | get-stream@^6.0.0: 192 | version "6.0.1" 193 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" 194 | integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== 195 | 196 | history@^5.2.0: 197 | version "5.2.0" 198 | resolved "https://registry.yarnpkg.com/history/-/history-5.2.0.tgz#7cdd31cf9bac3c5d31f09c231c9928fad0007b7c" 199 | integrity sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig== 200 | dependencies: 201 | "@babel/runtime" "^7.7.6" 202 | 203 | human-signals@^2.1.0: 204 | version "2.1.0" 205 | resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" 206 | integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== 207 | 208 | husky@>=6: 209 | version "7.0.4" 210 | resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535" 211 | integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ== 212 | 213 | indent-string@^4.0.0: 214 | version "4.0.0" 215 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" 216 | integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== 217 | 218 | is-fullwidth-code-point@^3.0.0: 219 | version "3.0.0" 220 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 221 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 222 | 223 | is-fullwidth-code-point@^4.0.0: 224 | version "4.0.0" 225 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" 226 | integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== 227 | 228 | is-number@^7.0.0: 229 | version "7.0.0" 230 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 231 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 232 | 233 | is-stream@^2.0.0: 234 | version "2.0.1" 235 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" 236 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 237 | 238 | isexe@^2.0.0: 239 | version "2.0.0" 240 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 241 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 242 | 243 | jsesc@^3.0.1: 244 | version "3.0.2" 245 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" 246 | integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== 247 | 248 | lilconfig@2.0.4: 249 | version "2.0.4" 250 | resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.4.tgz#f4507d043d7058b380b6a8f5cb7bcd4b34cee082" 251 | integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA== 252 | 253 | lint-staged@>=10: 254 | version "12.2.1" 255 | resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-12.2.1.tgz#e37b5a81deaabf5823f43b3aa903a70c15c9d0b3" 256 | integrity sha512-VCVcA9C2Vt5HHxSR4EZVZFJcQRJH984CGBeY+cJ/xed4mBd+JidbM/xbKcCq5ASaygAV0iITtdsCTnID7h/1OQ== 257 | dependencies: 258 | cli-truncate "^3.1.0" 259 | colorette "^2.0.16" 260 | commander "^8.3.0" 261 | debug "^4.3.3" 262 | execa "^5.1.1" 263 | lilconfig "2.0.4" 264 | listr2 "^3.13.5" 265 | micromatch "^4.0.4" 266 | normalize-path "^3.0.0" 267 | object-inspect "^1.11.1" 268 | string-argv "^0.3.1" 269 | supports-color "^9.2.1" 270 | yaml "^1.10.2" 271 | 272 | listr2@^3.13.5: 273 | version "3.14.0" 274 | resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" 275 | integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== 276 | dependencies: 277 | cli-truncate "^2.1.0" 278 | colorette "^2.0.16" 279 | log-update "^4.0.0" 280 | p-map "^4.0.0" 281 | rfdc "^1.3.0" 282 | rxjs "^7.5.1" 283 | through "^2.3.8" 284 | wrap-ansi "^7.0.0" 285 | 286 | log-update@^4.0.0: 287 | version "4.0.0" 288 | resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" 289 | integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== 290 | dependencies: 291 | ansi-escapes "^4.3.0" 292 | cli-cursor "^3.1.0" 293 | slice-ansi "^4.0.0" 294 | wrap-ansi "^6.2.0" 295 | 296 | merge-stream@^2.0.0: 297 | version "2.0.0" 298 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" 299 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 300 | 301 | micromatch@^4.0.4: 302 | version "4.0.4" 303 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" 304 | integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== 305 | dependencies: 306 | braces "^3.0.1" 307 | picomatch "^2.2.3" 308 | 309 | mimic-fn@^2.1.0: 310 | version "2.1.0" 311 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" 312 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 313 | 314 | ms@2.1.2: 315 | version "2.1.2" 316 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 317 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 318 | 319 | normalize-path@^3.0.0: 320 | version "3.0.0" 321 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 322 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 323 | 324 | npm-run-path@^4.0.1: 325 | version "4.0.1" 326 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" 327 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== 328 | dependencies: 329 | path-key "^3.0.0" 330 | 331 | object-inspect@^1.11.1: 332 | version "1.12.0" 333 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" 334 | integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== 335 | 336 | onetime@^5.1.0, onetime@^5.1.2: 337 | version "5.1.2" 338 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" 339 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 340 | dependencies: 341 | mimic-fn "^2.1.0" 342 | 343 | p-map@^4.0.0: 344 | version "4.0.0" 345 | resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" 346 | integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== 347 | dependencies: 348 | aggregate-error "^3.0.0" 349 | 350 | path-key@^3.0.0, path-key@^3.1.0: 351 | version "3.1.1" 352 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 353 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 354 | 355 | picomatch@^2.2.3: 356 | version "2.3.1" 357 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 358 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 359 | 360 | prettier@^2.5.1: 361 | version "2.5.1" 362 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" 363 | integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== 364 | 365 | react-router-dom@^6.2.1: 366 | version "6.2.1" 367 | resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.2.1.tgz#32ec81829152fbb8a7b045bf593a22eadf019bec" 368 | integrity sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA== 369 | dependencies: 370 | history "^5.2.0" 371 | react-router "6.2.1" 372 | 373 | react-router@6.2.1: 374 | version "6.2.1" 375 | resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.2.1.tgz#be2a97a6006ce1d9123c28934e604faef51448a3" 376 | integrity sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg== 377 | dependencies: 378 | history "^5.2.0" 379 | 380 | regenerator-runtime@^0.13.4: 381 | version "0.13.9" 382 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" 383 | integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== 384 | 385 | remix-auth@^3.2.1: 386 | version "3.2.1" 387 | resolved "https://registry.yarnpkg.com/remix-auth/-/remix-auth-3.2.1.tgz#6252246eef1016de2c9f426b1fd8c5a2689dfb09" 388 | integrity sha512-5N5ZjKCYGjbRmMi9PQwngKuuGkBEfny0Q4iXyTrDxQhSzAbQ/+wHX+ZKGdneYWHULZJCRZbjSmyrjk/rJxGFlw== 389 | dependencies: 390 | remix-utils "^2.2.0" 391 | uuid "^8.3.2" 392 | 393 | remix-utils@^2.2.0: 394 | version "2.4.0" 395 | resolved "https://registry.yarnpkg.com/remix-utils/-/remix-utils-2.4.0.tgz#a614508369a00fd77a0633fd636d76c1526ea58e" 396 | integrity sha512-qwzlPwjvRHIrPULnl7AFZAbjku6sihid2412QLMc8bPC6mm1XpUKnJtebW30WtO6wgwQu2CAwhIFQ2HsBQLXTw== 397 | dependencies: 398 | type-fest "^2.5.2" 399 | uuid "^8.3.2" 400 | 401 | restore-cursor@^3.1.0: 402 | version "3.1.0" 403 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" 404 | integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== 405 | dependencies: 406 | onetime "^5.1.0" 407 | signal-exit "^3.0.2" 408 | 409 | rfdc@^1.3.0: 410 | version "1.3.0" 411 | resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" 412 | integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== 413 | 414 | rxjs@^7.5.1: 415 | version "7.5.2" 416 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.2.tgz#11e4a3a1dfad85dbf7fb6e33cbba17668497490b" 417 | integrity sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w== 418 | dependencies: 419 | tslib "^2.1.0" 420 | 421 | set-cookie-parser@^2.4.8: 422 | version "2.4.8" 423 | resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz#d0da0ed388bc8f24e706a391f9c9e252a13c58b2" 424 | integrity sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg== 425 | 426 | shebang-command@^2.0.0: 427 | version "2.0.0" 428 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 429 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 430 | dependencies: 431 | shebang-regex "^3.0.0" 432 | 433 | shebang-regex@^3.0.0: 434 | version "3.0.0" 435 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 436 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 437 | 438 | signal-exit@^3.0.2, signal-exit@^3.0.3: 439 | version "3.0.6" 440 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" 441 | integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== 442 | 443 | slice-ansi@^3.0.0: 444 | version "3.0.0" 445 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" 446 | integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== 447 | dependencies: 448 | ansi-styles "^4.0.0" 449 | astral-regex "^2.0.0" 450 | is-fullwidth-code-point "^3.0.0" 451 | 452 | slice-ansi@^4.0.0: 453 | version "4.0.0" 454 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" 455 | integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== 456 | dependencies: 457 | ansi-styles "^4.0.0" 458 | astral-regex "^2.0.0" 459 | is-fullwidth-code-point "^3.0.0" 460 | 461 | slice-ansi@^5.0.0: 462 | version "5.0.0" 463 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" 464 | integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== 465 | dependencies: 466 | ansi-styles "^6.0.0" 467 | is-fullwidth-code-point "^4.0.0" 468 | 469 | source-map@^0.7.3: 470 | version "0.7.3" 471 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" 472 | integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== 473 | 474 | string-argv@^0.3.1: 475 | version "0.3.1" 476 | resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" 477 | integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== 478 | 479 | string-width@^4.1.0, string-width@^4.2.0: 480 | version "4.2.3" 481 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 482 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 483 | dependencies: 484 | emoji-regex "^8.0.0" 485 | is-fullwidth-code-point "^3.0.0" 486 | strip-ansi "^6.0.1" 487 | 488 | string-width@^5.0.0: 489 | version "5.1.0" 490 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.0.tgz#5ab00980cfb29f43e736b113a120a73a0fb569d3" 491 | integrity sha512-7x54QnN21P+XL/v8SuNKvfgsUre6PXpN7mc77N3HlZv+f1SBRGmjxtOud2Z6FZ8DmdkD/IdjCaf9XXbnqmTZGQ== 492 | dependencies: 493 | eastasianwidth "^0.2.0" 494 | emoji-regex "^9.2.2" 495 | strip-ansi "^7.0.1" 496 | 497 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 498 | version "6.0.1" 499 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 500 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 501 | dependencies: 502 | ansi-regex "^5.0.1" 503 | 504 | strip-ansi@^7.0.1: 505 | version "7.0.1" 506 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" 507 | integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== 508 | dependencies: 509 | ansi-regex "^6.0.1" 510 | 511 | strip-final-newline@^2.0.0: 512 | version "2.0.0" 513 | resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" 514 | integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== 515 | 516 | supports-color@^9.2.1: 517 | version "9.2.1" 518 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.2.1.tgz#599dc9d45acf74c6176e0d880bab1d7d718fe891" 519 | integrity sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ== 520 | 521 | through@^2.3.8: 522 | version "2.3.8" 523 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 524 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 525 | 526 | to-regex-range@^5.0.1: 527 | version "5.0.1" 528 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 529 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 530 | dependencies: 531 | is-number "^7.0.0" 532 | 533 | tslib@^2.1.0: 534 | version "2.3.1" 535 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" 536 | integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== 537 | 538 | type-fest@^0.21.3: 539 | version "0.21.3" 540 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" 541 | integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== 542 | 543 | type-fest@^2.5.2: 544 | version "2.10.0" 545 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.10.0.tgz#0ee9c3cd411efb3bba434065d32235592d3644cf" 546 | integrity sha512-u2yreDMllFI3VCpWt0rKrGs/E2LO0YHBwiiOIj+ilQh9+ALMaa4lNBSdoDvuHN3cbKcYk9L1BXP49x9RT+o/SA== 547 | 548 | typescript@^4.5.4: 549 | version "4.5.4" 550 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" 551 | integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== 552 | 553 | uuid@^8.3.2: 554 | version "8.3.2" 555 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" 556 | integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== 557 | 558 | which@^2.0.1: 559 | version "2.0.2" 560 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 561 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 562 | dependencies: 563 | isexe "^2.0.0" 564 | 565 | wrap-ansi@^6.2.0: 566 | version "6.2.0" 567 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" 568 | integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== 569 | dependencies: 570 | ansi-styles "^4.0.0" 571 | string-width "^4.1.0" 572 | strip-ansi "^6.0.0" 573 | 574 | wrap-ansi@^7.0.0: 575 | version "7.0.0" 576 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 577 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 578 | dependencies: 579 | ansi-styles "^4.0.0" 580 | string-width "^4.1.0" 581 | strip-ansi "^6.0.0" 582 | 583 | yaml@^1.10.2: 584 | version "1.10.2" 585 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" 586 | integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== 587 | --------------------------------------------------------------------------------