├── .editorconfig ├── .github ├── CODEOWNERS └── workflows │ └── npm-publish.yml ├── .gitignore ├── .husky ├── .gitignore └── pre-commit ├── .lintstagedrc ├── .prettierignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── bun.lockb ├── dev ├── base.md ├── config.md ├── extras.md └── plugins.md ├── examples ├── eviate.config.ts ├── main.html └── main.ts ├── package-lock.json ├── package.json ├── src ├── core │ ├── app.ts │ ├── context.ts │ ├── error.ts │ ├── index.ts │ ├── middlewares.ts │ ├── plugin │ │ ├── index.ts │ │ └── plugin.ts │ ├── router │ │ ├── base.ts │ │ ├── index.ts │ │ ├── internal-router.ts │ │ └── router.ts │ ├── state.ts │ └── tree │ │ ├── index.ts │ │ ├── node.ts │ │ └── tree.ts ├── index.ts ├── interfaces │ ├── config.ts │ ├── data.ts │ ├── handler.ts │ ├── index.ts │ ├── match.ts │ ├── middlewareHandler.ts │ ├── response.ts │ ├── route.ts │ └── state.ts ├── mappings │ ├── EventHandlerType.ts │ ├── MiddlewarePosition.ts │ ├── RouterEvent.ts │ └── index.ts ├── runtime │ └── server.ts ├── schema │ ├── AppListenParams.ts │ ├── AppParams.ts │ └── OpenAPI.ts └── utils │ ├── index.ts │ ├── load-config.ts │ ├── router-logger.ts │ └── startup-banner.ts ├── tsconfig.json ├── tsup.config.ts └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @janaSunrise @apoorvcodes 2 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish npm package 2 | 3 | # Trigger on release 4 | on: 5 | release: 6 | types: [created] 7 | 8 | jobs: 9 | publish: 10 | name: Publish npm package 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v2 16 | 17 | - name: Setup node 18 | uses: actions/setup-node@v2 19 | with: 20 | node-version: '16.x' 21 | registry-url: 'https://registry.npmjs.org/' 22 | 23 | - name: Install dependencies 24 | run: yarn 25 | 26 | - name: Build the library 27 | run: yarn run build 28 | 29 | - name: Publish package 30 | run: yarn publish --access public 31 | env: 32 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor files 2 | .idea/ 3 | .vscode/ 4 | 5 | # dependencies 6 | node_modules/ 7 | .pnp/ 8 | .pnp.js 9 | 10 | # testing 11 | coverage/ 12 | 13 | # Misc folders 14 | dist/ 15 | testing/ 16 | 17 | # Misc files 18 | .DS_Store 19 | *.pem 20 | 21 | # Debug 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | # Environmental variables 27 | .env 28 | .env.local 29 | .env.development 30 | 31 | # Coverage 32 | coverage/ 33 | coverage.json 34 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | . "$(dirname "$0")/_/husky.sh" 4 | 5 | npx lint-staged --concurrent false 6 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.{ts,tsx,json,md}": ["prettier --write"] 3 | } 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Editor files 2 | .idea/ 3 | .vscode/ 4 | 5 | # dependencies 6 | node_modules/ 7 | .pnp/ 8 | .pnp.js 9 | 10 | # testing 11 | coverage/ 12 | 13 | # Misc folders 14 | dist/ 15 | testing/ 16 | 17 | # Misc files 18 | .DS_Store 19 | *.pem 20 | 21 | # Debug 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | # Environmental variables 27 | .env 28 | .env.local 29 | .env.development 30 | 31 | # Coverage 32 | coverage/ 33 | coverage.json 34 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "arrowParens": "avoid", 4 | "singleQuote": true, 5 | "printWidth": 80, 6 | "useTabs": false, 7 | "tabWidth": 2, 8 | "semi": true 9 | } 10 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | . 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-present EviateJS 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 | Footer 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |

Eviate JS (WIP)

3 |

Next-generation web framework to build powerful apps

4 |

5 | 6 | ## Features 7 | 8 | - **Simple**: No more `req` or `res`. It's all `ctx` (context) and plain objects! 9 | - **Fast**: Built from the ground up with performance in mind. Zero, Zilch, Nada dependencies. 10 | - **Typescript-first**: Built with type-safety in mind, first-class support. 11 | - **Flexible**: Completely flexible with access to the all events, and data. 12 | - **Simple error handling**: No more try-catch all around. It's just eviate, you and a `onError` function here. 13 | - **Middleware**: Powerful middleware support. Route-specific, Route-independent, aswell pre-request and post-request middlewares. 14 | - **Plugins**: Built with user in mind, the best plugin support to make it super easy to ship anything. 15 | 16 | ## Getting started 17 | 18 | ### Installation and setup 19 | 20 | One of the _quickest_ ways to get started is to use `create-eviate-app`. 21 | 22 | Get started by scaffolding the app real quick using: 23 | 24 | ```ts 25 | npx create-eviate-app 26 | ``` 27 | 28 | ### Manual setup 29 | 30 | If you want to setup the app manually, you can do so. 31 | 32 | **NOTE**: Ensure you have bun installed (node is not yet supported). 33 | 34 | Get started by quickly installing the dependencies. 35 | 36 | ```ts 37 | bun install eviate 38 | ``` 39 | 40 | Now, create a file called `app.ts` and add the following code: 41 | 42 | ```ts 43 | import { Engine } from 'eviate'; 44 | 45 | const app = new Engine(); 46 | 47 | app.get('/', ctx => { 48 | return { 49 | text: 'Hello world!' 50 | }; 51 | }); 52 | 53 | app.listen(); 54 | ``` 55 | 56 | ## Documentation 57 | 58 | **Documentation WIP** 59 | 60 | ## 🤝 Contributing 61 | 62 | Contributions, issues and feature requests are welcome. After cloning & setting up project locally, you can 63 | just submit a PR to this repo, and it will be deployed once it's accepted. 64 | 65 | ⚠ It’s good to have descriptive commit messages, or PR titles so that other contributors can understand about your 66 | commit or the PR Created. Read [conventional commits](https://www.conventionalcommits.org/en/v1.0.0-beta.3/) before 67 | making the commit message. 68 | 69 | ## Show your support 70 | 71 | We love people's support in growing and improving. Be sure to drop a 🌟 if you like the project and 72 | also be sure to contribute, if you're interested! 73 | 74 | ## License 75 | 76 | Distributed under the MIT License. See [LICENSE](LICENSE) for more information. 77 | 78 |
Made by EviateJS team with ❤
79 | -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eviatejs/eviate/68e19be15fc41e071a6018dd6a87231330299b79/bun.lockb -------------------------------------------------------------------------------- /dev/base.md: -------------------------------------------------------------------------------- 1 | ## Basic App 2 | 3 | ### Initializing the App 4 | 5 | ```ts 6 | import { Eviate } from 'eviate'; 7 | 8 | const app = new Eviate(); 9 | ``` 10 | 11 | ### Kitchen sink configuration 12 | 13 | ```ts 14 | import type { App } from 'eviate'; 15 | 16 | const db = new Database(); 17 | 18 | const app = new Eviate({ 19 | // The types in the state are preserved. Figure out a way to achieve so 20 | state: { 21 | name: 'John Doe', 22 | db: db 23 | }, 24 | // Autogenerated redoc/swagger docs - decide which, or allow both? 25 | docs: { 26 | redoc: '/redoc', 27 | swagger: '/swagger' 28 | }, 29 | // For autodocs, use OpenAPI schema, 30 | openapi: (app: App) => { 31 | return { 32 | title: 'Eviate', 33 | version: '1.0.0', 34 | description: 'A web framework for Bun', 35 | routes: app.routes 36 | }; 37 | } 38 | }); 39 | ``` 40 | 41 | ### Run the app 42 | 43 | ```ts 44 | app.listen({ 45 | host: '127.0.0.1', 46 | port: 3000, 47 | debug: true 48 | }); 49 | ``` 50 | 51 | ## App event handlers 52 | 53 | ```ts 54 | app.on_event('startup', async ({ port }) => { 55 | app.state.client = new Client(); 56 | 57 | console.log(`Listening on port ${port}`); 58 | }); 59 | 60 | app.on_event('shutdown', async () => { 61 | app.state.client.stop(); 62 | }); 63 | 64 | app.on_event('before-request', async (req: Request) => { 65 | // Do something before the request is sent 66 | }); 67 | ``` 68 | 69 | ### Global error handler 70 | 71 | ```ts 72 | import type { Context, EviateError } from 'eviate'; 73 | 74 | app.on_error((ctx: Context, error: EviateError) => { 75 | // Each error will have the route, the actual error 76 | // and the stack trace. 77 | console.log(error.route, error.message, error.stack); 78 | }); 79 | ``` 80 | 81 | ## Routes 82 | 83 | The routes are completely free of `res`, and lets you have optional request aswell! 84 | 85 | The routes remove `req`, `res` and replaces with a simple `ctx` object to make working easy. 86 | 87 | ```ts 88 | import type { Context } from 'eviate'; 89 | 90 | app.get('/health', async _ => { 91 | return { 92 | json: { 93 | status: 'ok' 94 | } 95 | }; 96 | }); 97 | 98 | app.get('/test', async (ctx: Context) => { 99 | // Maybe have type-safe access to the request? 100 | const { name } = ctx.params; 101 | 102 | return { 103 | json: { 104 | name 105 | } 106 | }; 107 | }); 108 | 109 | app.get('/test-500', async (ctx: Context) => { 110 | return { 111 | response: { 112 | status: 500, 113 | json: { 114 | error: 'Internal server error' 115 | } 116 | } 117 | }; 118 | 119 | // OR send text 120 | return { 121 | response: { 122 | status: 500, 123 | text: 'Internal server error' 124 | } 125 | }; 126 | }); 127 | 128 | app.get('/text-resp', async (ctx: Context) => { 129 | return { 130 | text: 'Hello world' 131 | }; 132 | }); 133 | ``` 134 | 135 | Dynamic route parameters: 136 | 137 | ```ts 138 | app.get( 139 | '/test/:name', 140 | async (ctx: Context) => { 141 | const { name } = ctx.params; 142 | 143 | return { 144 | json: { 145 | name 146 | } 147 | }; 148 | }, 149 | // The parameter config section is completely OPTIONAL 150 | { 151 | params: { 152 | name: { 153 | // Type is optional 154 | /* 155 | Types possible: 156 | - string/str 157 | - int 158 | - float 159 | - slug 160 | - path 161 | - date 162 | - uuid 163 | - custom regex 164 | */ 165 | type: 'string', 166 | // Default value is false 167 | required: true 168 | }, 169 | // Shorthand for this 170 | name: 'string' 171 | } 172 | } 173 | ); 174 | 175 | app.post( 176 | '/test', 177 | async (ctx: Context) => { 178 | const { name } = ctx.params; 179 | 180 | return { 181 | json: { 182 | name 183 | } 184 | }; 185 | }, 186 | // This is the schema now for the body 187 | { 188 | /* 189 | Types possible: 190 | - string/str 191 | - int 192 | - float 193 | - slug 194 | - path 195 | - date 196 | - uuid 197 | - object 198 | - custom regex 199 | - objects with nested typing 200 | */ 201 | schema: { 202 | type: 'object', 203 | fields: { 204 | name: 'string' 205 | } 206 | } 207 | } 208 | ); 209 | ``` 210 | 211 | ## URL redirection 212 | 213 | ```ts 214 | app.get( 215 | '/health', 216 | async _ => { 217 | return { 218 | json: { 219 | status: 'ok' 220 | } 221 | }; 222 | }, 223 | { 224 | // Extra config for each route. Each can have an unique name 225 | config: { 226 | name: 'health' 227 | } 228 | } 229 | ); 230 | 231 | app.get('/redirect', async _ => { 232 | return { 233 | redirect: app.url_for('health', { 234 | // Extra params? 235 | name: 'John Doe' 236 | }) 237 | }; 238 | }); 239 | ``` 240 | 241 | ## Routers/Blueprints to organize the filesystem 242 | 243 | ```ts 244 | import { Router } from 'eviate'; 245 | 246 | const router = new Router({ 247 | name: 'health-router', 248 | urlPrefix: '/health' 249 | }); 250 | 251 | router.get('/', async _ => { 252 | return { 253 | json: { 254 | status: 'ok' 255 | } 256 | }; 257 | }); 258 | 259 | // Load the router in the main app 260 | app.register(router); 261 | ``` 262 | 263 | The root router created when making a Eviate app is as so - `new Router('root')`. 264 | 265 | No URL prefixes or colliding names. Also, note that, router is going to be used for routing, the root router URLs can be accessed by `app.url_for('my-route')`, and others as, `app.url_for('router-name.my-route')`. 266 | 267 | There can be a nested way to generate the URLs aswell, `v1-router.health.ping` 268 | 269 | ## Websocket routes 270 | 271 | ## Middlewares 272 | 273 | ## Templating & static files 274 | -------------------------------------------------------------------------------- /dev/config.md: -------------------------------------------------------------------------------- 1 | The configuration for an eviate app can be stored in `eviate.config.js` or `eviate.config.ts` in the root of the project. The config file should export a function that returns the config object. 2 | 3 | ```ts 4 | import { NamePlugin } from 'eviate-plugin'; 5 | 6 | import type { EviateConfig } from 'eviate'; 7 | 8 | const config: EviateConfig = { 9 | port: 4000, 10 | hostname: 'localhost', 11 | development: true, 12 | state: { 13 | name: 'John Doe' 14 | }, 15 | // Register plugins directly here 16 | plugins: [new NamePlugin('test')] 17 | }; 18 | 19 | export default config; 20 | ``` 21 | -------------------------------------------------------------------------------- /dev/extras.md: -------------------------------------------------------------------------------- 1 | ## Background tasks 2 | 3 | ## Versioning 4 | 5 | ## Dependency injection 6 | 7 | ## GraphQL 8 | 9 | ## Type-safe endpoints 10 | -------------------------------------------------------------------------------- /dev/plugins.md: -------------------------------------------------------------------------------- 1 | The plugin would be based off a class for maximising the functionality. 2 | 3 | ```ts 4 | import { Plugin, route } from 'eviate-plugin'; 5 | 6 | import type { PluginSettings, PluginError, PluginEvent } from 'eviate-plugin'; 7 | 8 | class MyPlugin extends Plugin { 9 | constructor() { 10 | super({ 11 | name: 'my-plugin', 12 | version: '1.0.0', 13 | description: 'My plugin' 14 | }); 15 | } 16 | 17 | // Property for plugin settings 18 | public get settings(): PluginSettings { 19 | return { 20 | loadOnce: true 21 | }; 22 | } 23 | 24 | // Plugin events 25 | public async on(event: PluginEvent) { 26 | switch (event) { 27 | case 'startup': 28 | // Do something on startup 29 | this.emit('startup', 'My plugin started'); 30 | break; 31 | case 'shutdown': 32 | // Do something on shutdown 33 | break; 34 | } 35 | } 36 | 37 | // Error streaming 38 | public async onError(err: PluginError) { 39 | // Do something with the error 40 | this.logger.error(err); 41 | } 42 | 43 | // Middlewares or routes that the plugin can create goes below. 44 | public async middleware(ctx: Context) { 45 | // Do something with the context 46 | } 47 | 48 | @route({ 49 | method: 'GET', 50 | path: '/my-plugin' 51 | }) 52 | public async route(ctx: Context) { 53 | // Do something with the context 54 | } 55 | } 56 | ``` 57 | 58 | Once plugin is ready, it can be loaded using: 59 | 60 | ```ts 61 | import { Eviate } from 'eviate'; 62 | 63 | import { MyPlugin } from './my-plugin'; 64 | 65 | const app = new Eviate(); 66 | 67 | app.plugins.load(new MyPlugin()); 68 | ``` 69 | -------------------------------------------------------------------------------- /examples/eviate.config.ts: -------------------------------------------------------------------------------- 1 | import { config } from '../src/interfaces/config'; 2 | 3 | const config: config = { 4 | port: 3000, 5 | hostname: 'localhost', 6 | debug: true, 7 | startMiddlewares: [], 8 | endMiddlewares: [] 9 | }; 10 | 11 | export default config; 12 | -------------------------------------------------------------------------------- /examples/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | Yo 10 | 11 | -------------------------------------------------------------------------------- /examples/main.ts: -------------------------------------------------------------------------------- 1 | import { Engine, Router } from '../src/core'; 2 | import { Context } from '../src/core/context'; 3 | import { 4 | MiddlewareValue, 5 | Plugin, 6 | PluginSettings, 7 | ReturnValue, 8 | RouteValue 9 | } from '@eviatejs/plugin'; 10 | 11 | import type { EviateResponse } from '../src/interfaces'; 12 | 13 | const app = new Engine(); 14 | const router = new Router(); 15 | 16 | class ABCPlugin extends Plugin { 17 | routes: RouteValue[]; 18 | middleware: MiddlewareValue[]; 19 | 20 | constructor() { 21 | super({ 22 | title: 'abc', 23 | description: '', 24 | version: '1.0' 25 | }); 26 | 27 | this.routes = []; 28 | this.middleware = []; 29 | } 30 | 31 | handler(): ReturnValue { 32 | this.routes.push({ 33 | method: 'GET', 34 | path: '/routes/oof', 35 | handler: (ctx: Context): EviateResponse => { 36 | return { 37 | text: 'Helo' 38 | }; 39 | } 40 | }); 41 | 42 | const returnValue: ReturnValue = { 43 | routes: this.routes, 44 | middlewares: this.middleware 45 | }; 46 | 47 | return returnValue; 48 | } 49 | 50 | get settings(): PluginSettings { 51 | return {}; 52 | } 53 | } 54 | 55 | app.plugin.load(new ABCPlugin()); 56 | app.plugin.run(); 57 | 58 | // Event Handlers 59 | app.on('startup', () => { 60 | console.log('Startup working'); 61 | }); 62 | 63 | app.on('before-request', () => { 64 | console.log('Running pre request function'); 65 | }); 66 | 67 | // Error handler 68 | app.error((err, ctx) => { 69 | console.log(err.message); 70 | console.log(ctx?.path); 71 | }); 72 | 73 | // App routes 74 | app.get('/', ctx => { 75 | console.log(ctx.method); 76 | return { 77 | interface: ctx.file('./main.html'), 78 | headers: { 'Content-Type': 'text/html' } 79 | }; 80 | }); 81 | app.get('/json', _ => { 82 | return { 83 | headers: { 'Content-Type': 'appliation/json' }, 84 | json: { 85 | name: 'Hello', 86 | why: 'hi' 87 | } 88 | }; 89 | }); 90 | app.get('/html', _ => { 91 | return { 92 | interface: '

Hi

', 93 | headers: { 'Content-Type': 'text/html' } 94 | }; 95 | }); 96 | 97 | // Router routes 98 | router.post('/hello', ctx => { 99 | console.log(ctx.host); 100 | 101 | return { text: 'Router Works' }; 102 | }); 103 | 104 | app.put('/put', _ => { 105 | return {}; 106 | }); 107 | 108 | app.delete('/delete', _ => { 109 | return {}; 110 | }); 111 | 112 | app.head('/head', _ => { 113 | return {}; 114 | }); 115 | 116 | app.options('/options', _ => { 117 | return {}; 118 | }); 119 | 120 | app.patch('/patch', _ => { 121 | return {}; 122 | }); 123 | 124 | // Implement the router 125 | app.mount(router); 126 | 127 | app.use((ctx: Context): any => { 128 | console.log(ctx.path, ctx.method); 129 | 130 | return { 131 | ctx: ctx, 132 | header: { b: 'def' } 133 | }; 134 | }, 'before'); 135 | 136 | app.use((ctx: Context): any => { 137 | console.log(ctx.path, ctx.method); 138 | 139 | return { 140 | ctx: ctx, 141 | header: { c: 'no' } 142 | }; 143 | }, 'before'); 144 | 145 | app.listen(); 146 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eviate", 3 | "version": "0.1.6", 4 | "description": "Next-gen web framework for bun.js and node.js", 5 | "main": "dist/index.js", 6 | "module": "dist/index.mjs", 7 | "types": "dist/index.d.ts", 8 | "exports": { 9 | ".": { 10 | "require": "./dist/index.js", 11 | "import": "./dist/index.mjs", 12 | "types": "./dist/index.d.ts" 13 | } 14 | }, 15 | "files": [ 16 | "dist" 17 | ], 18 | "scripts": { 19 | "build": "tsup", 20 | "typecheck": "tsc --noEmit", 21 | "format": "prettier --write ./**/*.{ts,json,md}", 22 | "test": "vitest --run", 23 | "prepare": "husky install", 24 | "prepublishOnly": "bun run build" 25 | }, 26 | "dependencies": { 27 | "@eviatejs/plugin": "^0.1.3", 28 | "picocolors": "^1.0.0", 29 | "sweet-event-emitter": "^0.1.0" 30 | }, 31 | "devDependencies": { 32 | "@types/node": "^18.8.2", 33 | "bun-types": "^0.1.11", 34 | "husky": "^8.0.1", 35 | "lint-staged": "^13.0.3", 36 | "prettier": "^2.7.1", 37 | "ts-node": "^10.9.1", 38 | "tsup": "^6.2.3", 39 | "typescript": "^4.8.4" 40 | }, 41 | "keywords": [], 42 | "author": "EviateJS team", 43 | "license": "MIT", 44 | "homepage": "https://github.com/eviatejs/eviate", 45 | "bugs": { 46 | "url": "https://github.com/eviatejs/eviate/issues" 47 | }, 48 | "repository": { 49 | "type": "git", 50 | "url": "git+https://github.com/eviatejs/eviate.git" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/core/app.ts: -------------------------------------------------------------------------------- 1 | import { Server } from '../runtime/server'; 2 | import { Router } from './router/router'; 3 | import { InternalRouter } from './router/internal-router'; 4 | import { Context } from './context'; 5 | import { EngineError } from './error'; 6 | import { AppState } from './state'; 7 | import { startupBanner } from '../utils/startup-banner'; 8 | import { Middleware } from './middlewares'; 9 | import { loadConfig } from '../utils/load-config'; 10 | import { UserMiddlewarePosition } from '../mappings/MiddlewarePosition'; 11 | import { 12 | defaultAppMetadataParams, 13 | defaultAppStateParams 14 | } from '../schema/AppParams'; 15 | import { EviatePlugin } from './plugin'; 16 | 17 | import type { EventEmitter } from 'sweet-event-emitter'; 18 | import type { config, MiddlewareHandler } from '../interfaces'; 19 | import type { handler } from '../interfaces/handler'; 20 | import type { AppParams, AppMetadata } from '../schema/AppParams'; 21 | import type { AppListenParams } from '../schema/AppListenParams'; 22 | import type { Route } from '../interfaces/route'; 23 | import type { EviateMiddlewareResponse } from '../interfaces/response'; 24 | 25 | export class Engine { 26 | public metadata: AppMetadata; 27 | public config?: config; 28 | 29 | private server: Server; 30 | private plugins: EviatePlugin; 31 | private appState: AppState; 32 | private router: InternalRouter; 33 | private eventEmitter: EventEmitter; 34 | private middleware: Middleware; 35 | 36 | constructor(params?: AppParams) { 37 | const { state, metadata } = { 38 | metadata: { ...defaultAppMetadataParams, ...params?.metadata }, 39 | state: { ...defaultAppStateParams, ...params?.state } 40 | }; 41 | 42 | loadConfig(this); 43 | 44 | this.metadata = metadata; 45 | 46 | this.appState = new AppState({ ...state, ...this.config?.state }); 47 | this.plugins = new EviatePlugin(this); 48 | this.middleware = new Middleware(); 49 | this.router = new InternalRouter(this); 50 | this.eventEmitter = this.router.event; 51 | 52 | this.server = new Server( 53 | this.router, 54 | this.middleware, 55 | this.eventEmitter, 56 | this.config 57 | ); 58 | 59 | startupBanner(this.server.getRuntime()); 60 | } 61 | 62 | // Region: Getters and setters (properties) 63 | public get plugin(): EviatePlugin { 64 | return this.plugins; 65 | } 66 | // Endregion 67 | 68 | // Region: Route methods and registering 69 | public register(method: string, path: string, handler: handler) { 70 | this.router.register(method, path, handler); 71 | } 72 | 73 | public get(path: string, handler: handler) { 74 | this.router.get(path, handler); 75 | } 76 | 77 | public put(path: string, handler: handler) { 78 | this.router.put(path, handler); 79 | } 80 | 81 | public patch(path: string, handler: handler) { 82 | this.router.patch(path, handler); 83 | } 84 | 85 | public delete(path: string, handler: handler) { 86 | this.router.delete(path, handler); 87 | } 88 | 89 | public head(path: string, handler: handler) { 90 | this.router.head(path, handler); 91 | } 92 | 93 | public options(path: string, handler: handler) { 94 | this.router.options(path, handler); 95 | } 96 | 97 | public post(path: string, handler: handler) { 98 | this.router.post(path, handler); 99 | } 100 | // Endregion 101 | 102 | // Region: Route and middleware mounting 103 | public mount(router: Router, prefix?: string) { 104 | this.router.event.emit('router-mount'); 105 | 106 | router.routes.map((value: Route) => { 107 | if (!prefix) { 108 | this.router.register(value.method, value.path, value.handler); 109 | } else { 110 | this.router.register(value.method, prefix + value.path, value.handler); 111 | } 112 | }); 113 | } 114 | 115 | public use( 116 | context: MiddlewareHandler, 117 | pos: string = UserMiddlewarePosition.Before 118 | ) { 119 | switch (pos) { 120 | case UserMiddlewarePosition.Before: 121 | this.middleware.register(0, context); 122 | return; 123 | 124 | case UserMiddlewarePosition.After: 125 | this.middleware.register(1, context); 126 | return; 127 | 128 | default: 129 | throw new Error('Invalid middleware position.'); 130 | } 131 | } 132 | // Endregion 133 | 134 | // Region: Events and error handler 135 | public on(name: string, callback: (...args: any[]) => void) { 136 | this.router.on(name, callback); 137 | } 138 | 139 | public error(callback: (err: EngineError, ctx?: Context) => void) { 140 | this.router.error(callback); 141 | } 142 | // Endregion 143 | 144 | // Region: Running the app 145 | public async listen(params?: AppListenParams) { 146 | this.server.listen(params); 147 | } 148 | 149 | public shutdown() { 150 | this.eventEmitter.emit('shutdown'); 151 | process.exit(0); 152 | } 153 | // Endregion 154 | } 155 | -------------------------------------------------------------------------------- /src/core/context.ts: -------------------------------------------------------------------------------- 1 | import { throws } from 'node:assert'; 2 | import { readFileSync } from 'node:fs'; 3 | 4 | class BaseContext { 5 | req: Request; 6 | res?: Response; 7 | 8 | public params: any; // TODO: Add correct type here. 9 | readonly body: {}; 10 | readonly method: string; 11 | readonly path: string; 12 | readonly host: string; 13 | readonly headers: Request['headers']; 14 | readonly url: URL; 15 | 16 | constructor(req: Request) { 17 | this.req = req; 18 | this.method = req.method; 19 | this.headers = req.headers; 20 | this.body = req.json(); 21 | const url = new URL(req.url || ''); 22 | this.path = url.pathname; 23 | this.host = url.host; 24 | this.url = url; 25 | 26 | this.res = undefined; 27 | this.req.blob(); 28 | } 29 | } 30 | 31 | export class Context extends BaseContext { 32 | constructor(req: Request) { 33 | super(req); 34 | } 35 | 36 | public get secure(): boolean { 37 | return this.url.protocol === 'https' || this.url.protocol === 'wss'; 38 | } 39 | 40 | public file(path: string): Buffer { 41 | const file = readFileSync(path); 42 | return file; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/core/error.ts: -------------------------------------------------------------------------------- 1 | export class EviateError extends Error { 2 | public route: string; 3 | public method: string; 4 | public originalError: Error; 5 | 6 | constructor( 7 | message: string, 8 | route: string, 9 | method: string, 10 | originalError: Error 11 | ) { 12 | super(message); 13 | 14 | this.name = 'EviateError'; 15 | 16 | this.route = route; 17 | this.method = method; 18 | this.originalError = originalError; 19 | } 20 | } 21 | 22 | export class EngineError { 23 | public message: string; 24 | 25 | constructor(message: string) { 26 | this.message = message; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/core/index.ts: -------------------------------------------------------------------------------- 1 | export { Engine } from './app'; 2 | export { Router } from './router/router'; 3 | export { Context } from './context'; 4 | export { EviateError } from './error'; 5 | -------------------------------------------------------------------------------- /src/core/middlewares.ts: -------------------------------------------------------------------------------- 1 | import { MiddlewarePosition } from '../mappings/MiddlewarePosition'; 2 | 3 | import type { Context } from '../core/context'; 4 | import type { EviateMiddlewareResponse } from '../interfaces/response'; 5 | import type { MiddlewareHandler } from '../interfaces'; 6 | 7 | type MiddlewarePositionKeys = keyof typeof MiddlewarePosition; 8 | type MiddlewarePositionValues = 9 | typeof MiddlewarePosition[MiddlewarePositionKeys]; 10 | 11 | type StringObject = { [key: string]: string }; 12 | 13 | export class Middleware { 14 | private before: MiddlewareHandler[] = []; 15 | private after: MiddlewareHandler[] = []; 16 | 17 | public register( 18 | position: MiddlewarePositionValues, 19 | handler: MiddlewareHandler 20 | ) { 21 | switch (position) { 22 | case MiddlewarePosition.Before: 23 | this.before.push(handler); 24 | break; 25 | 26 | case MiddlewarePosition.After: 27 | this.after.push(handler); 28 | break; 29 | } 30 | } 31 | 32 | public async runBefore(ctx: Context): Promise { 33 | let resp: EviateMiddlewareResponse = { ctx: ctx, header: {} }; 34 | 35 | this.before.forEach(async (handler: MiddlewareHandler) => { 36 | const mutate: EviateMiddlewareResponse = await handler(ctx); 37 | 38 | mutate.header = this.appendHeaders( 39 | resp.header || {}, 40 | mutate.header || undefined 41 | ); 42 | resp = mutate; 43 | 44 | return resp; 45 | }); 46 | 47 | return resp; 48 | } 49 | 50 | public async runAfter(ctx: Context): Promise { 51 | let resp: EviateMiddlewareResponse = { ctx: ctx }; 52 | 53 | for (const handler of this.before) { 54 | resp = await handler(ctx); 55 | } 56 | 57 | return resp; 58 | } 59 | 60 | private appendHeaders( 61 | orignal: StringObject, 62 | mutate?: StringObject 63 | ): StringObject { 64 | if (!mutate) { 65 | return orignal; 66 | } 67 | for (const header in mutate) { 68 | orignal[header] = mutate[header]; 69 | } 70 | return orignal; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/core/plugin/index.ts: -------------------------------------------------------------------------------- 1 | export * from './plugin'; 2 | -------------------------------------------------------------------------------- /src/core/plugin/plugin.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Plugin, 3 | PluginSettings, 4 | RouteValue, 5 | MiddlewareValue 6 | } from '@eviatejs/plugin'; 7 | 8 | import { Engine } from '../app'; 9 | 10 | export class EviatePlugin { 11 | private app: Engine; 12 | private plugins: Map; 13 | private pluginSettings: PluginSettings[]; 14 | 15 | constructor(app: Engine) { 16 | this.app = app; 17 | this.plugins = new Map(); 18 | this.pluginSettings = []; 19 | } 20 | 21 | public load(plugin: Plugin) { 22 | this.plugins.set(plugin.metadata.title, plugin); 23 | } 24 | 25 | public get(title: string): Plugin | undefined { 26 | return this.plugins.get(title); 27 | } 28 | 29 | public getAll(): Map { 30 | return this.plugins; 31 | } 32 | 33 | public settings(settings: PluginSettings) { 34 | this.pluginSettings.push(settings); 35 | } 36 | 37 | private saveRoutes(routes: RouteValue[]) { 38 | routes.forEach((val: RouteValue) => { 39 | this.app.register(val.method, val.path, val.handler); 40 | }); 41 | } 42 | 43 | private saveMiddleware(middle: MiddlewareValue[]) { 44 | middle.forEach((val: MiddlewareValue) => { 45 | this.app.use(val.handler, val.position); 46 | }); 47 | } 48 | 49 | public run() { 50 | const plugins = this.getAll(); 51 | 52 | plugins.forEach((plugin: Plugin) => { 53 | const handler = plugin.handler(); 54 | 55 | if (handler.routes.length != 0) this.saveRoutes(handler.routes); 56 | if (handler.middlewares.length != 0) 57 | this.saveMiddleware(handler.middlewares); 58 | }); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/core/router/base.ts: -------------------------------------------------------------------------------- 1 | import type { handler } from '../../interfaces/handler'; 2 | 3 | export abstract class BaseRouter { 4 | abstract register(method: string, path: string, handler: handler): void; 5 | 6 | public get(path: string, handler: handler) { 7 | this.register('GET', path, handler); 8 | } 9 | 10 | public post(path: string, handler: handler) { 11 | this.register('POST', path, handler); 12 | } 13 | 14 | public patch(path: string, handler: handler) { 15 | this.register('PATCH', path, handler); 16 | } 17 | 18 | public delete(path: string, handler: handler) { 19 | this.register('DELETE', path, handler); 20 | } 21 | 22 | public options(path: string, handler: handler) { 23 | this.register('OPTIONS', path, handler); 24 | } 25 | 26 | public head(path: string, handler: handler) { 27 | this.register('HEAD', path, handler); 28 | } 29 | 30 | public put(path: string, handler: handler) { 31 | this.register('PUT', path, handler); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/core/router/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eviatejs/eviate/68e19be15fc41e071a6018dd6a87231330299b79/src/core/router/index.ts -------------------------------------------------------------------------------- /src/core/router/internal-router.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from 'sweet-event-emitter'; 2 | import { BaseRouter } from './base'; 3 | import { Context } from '../context'; 4 | import { Tree } from '../tree/tree'; 5 | import { EngineError } from '../error'; 6 | import { routeMount } from '../../utils/router-logger'; 7 | import { RouterEvent } from '../../mappings/RouterEvent'; 8 | import { EviatePlugin } from '../plugin/plugin'; 9 | import { Engine } from '../app'; 10 | import type { ServerResponse, IncomingMessage } from 'node:http'; 11 | import type { handler } from '../../interfaces/handler'; 12 | import type { EviateResponse } from '../../interfaces/response'; 13 | 14 | const allRouterEvents = '- ' + Object.values(RouterEvent).join('\n- '); 15 | 16 | export class InternalRouter extends BaseRouter { 17 | public event: EventEmitter; 18 | public routes: Map; 19 | public isRan: boolean; 20 | public pluginsRan: boolean; 21 | public notFound: handler | undefined; 22 | 23 | private state: Engine; 24 | 25 | constructor(state: Engine) { 26 | super(); 27 | 28 | this.routes = new Map([ 29 | ['GET', new Tree()], 30 | ['POST', new Tree()], 31 | ['OPTIONS', new Tree()], 32 | ['HEAD', new Tree()], 33 | ['PUT', new Tree()], 34 | ['DELETE', new Tree()], 35 | ['PATCH', new Tree()] 36 | ]); 37 | 38 | this.isRan = false; 39 | this.pluginsRan = false; 40 | this.state = state; 41 | 42 | this.event = new EventEmitter(); 43 | } 44 | 45 | public get plugin(): EviatePlugin { 46 | return this.plugin; 47 | } 48 | 49 | public register(method: string, path: string, handler: handler) { 50 | const tree: Tree | undefined = this.routes.get(method); 51 | tree?.add(path, { handler: handler }); 52 | 53 | routeMount(method, path); 54 | } 55 | 56 | public setNotFoundHandler(handler: handler) { 57 | this.notFound = handler; 58 | } 59 | 60 | // Region: Event and Error handlers 61 | public on(name: string, callback: (...args: any[]) => void) { 62 | switch (name) { 63 | case RouterEvent.Startup: 64 | this.event.on(name, callback); 65 | return; 66 | 67 | case RouterEvent.Shutdown: 68 | this.event.on(name, callback); 69 | return; 70 | 71 | case RouterEvent.BeforeRequest: 72 | this.event.on(name, callback); 73 | return; 74 | 75 | case RouterEvent.Mount: 76 | this.event.on(name, callback); 77 | return; 78 | 79 | case RouterEvent.PluginLoad: 80 | this.event.on(name, callback); 81 | return; 82 | 83 | default: 84 | throw new Error(`Event handler supports only:\n${allRouterEvents}`); 85 | } 86 | } 87 | 88 | public error(callback: (err: EngineError, ctx?: Context) => void) { 89 | this.event.on('err', callback); 90 | } 91 | 92 | // Region: Handling each runtime (bun/node) separately 93 | public serveBunHandler( 94 | ctx: Context, 95 | headers: { [key: string]: string } 96 | ): Response | undefined { 97 | const data = this.routes.get(ctx.method)?.find(ctx.path); 98 | 99 | if (!data) return undefined; 100 | 101 | ctx.params = data.params; 102 | 103 | const returnValue: EviateResponse = data.data.handler(ctx); 104 | if (!returnValue.headers) returnValue.headers = {}; 105 | 106 | for (const header in headers) { 107 | returnValue.headers[header] = headers[header]; 108 | } 109 | 110 | if (returnValue.text !== undefined && returnValue.json !== undefined) { 111 | throw new Error("You can't send both text and json object as response"); 112 | } 113 | 114 | if (returnValue.error) { 115 | return new Response(JSON.stringify(returnValue.error) || '', { 116 | headers: returnValue.headers, 117 | status: returnValue.status || 404 118 | }); 119 | } 120 | 121 | if (returnValue.headers) { 122 | switch (returnValue.headers['Content-type']) { 123 | case 'application/json': 124 | ctx.res = new Response(JSON.stringify(returnValue.json) || '', { 125 | headers: returnValue.headers, 126 | status: returnValue.status || 200 127 | }); 128 | 129 | return ctx.res; 130 | 131 | case 'text/plain': 132 | ctx.res = new Response(returnValue.text || '', { 133 | headers: returnValue.headers, 134 | status: returnValue.status || 200 135 | }); 136 | 137 | return ctx.res; 138 | 139 | case 'application/octet-stream': 140 | ctx.res = new Response(returnValue.Blob || '', { 141 | headers: returnValue.headers, 142 | status: returnValue.status || 200 143 | }); 144 | 145 | return ctx.res; 146 | 147 | default: 148 | ctx.res = new Response( 149 | returnValue.interface || 150 | returnValue.json || 151 | returnValue.Blob || 152 | returnValue.text, 153 | { headers: returnValue.headers, status: returnValue.status || 200 } 154 | ); 155 | 156 | return ctx.res; 157 | } 158 | } 159 | 160 | return ctx.res; 161 | } 162 | 163 | public serveNodeHandler( 164 | ctx: Context, 165 | headers: { [key: string]: string }, 166 | res: ServerResponse 167 | ): boolean { 168 | const data = this.routes.get(ctx.method)?.find(ctx.path); 169 | 170 | if (!data) return false; 171 | 172 | ctx.params = data.params; 173 | 174 | const returnValue: EviateResponse = data.data.handler(ctx); 175 | if (!returnValue.headers) returnValue.headers = {}; 176 | 177 | for (const header in headers) { 178 | returnValue.headers[header] = headers[header]; 179 | } 180 | 181 | if (returnValue.text !== undefined && returnValue.json !== undefined) { 182 | throw new Error("You can't send both text and json object as response"); 183 | } 184 | 185 | for (const headers in returnValue.headers) { 186 | res.setHeader(headers, returnValue.headers[headers]); 187 | } 188 | 189 | if (returnValue.error) { 190 | res.statusCode = returnValue.status || 404; 191 | res.end(JSON.stringify(returnValue.error)); 192 | return true; 193 | } 194 | if (returnValue.headers) { 195 | switch (returnValue.headers['Content-type']) { 196 | case 'application/json': 197 | res.statusCode = returnValue.status || 200; 198 | res.end(JSON.stringify(returnValue.json)); 199 | return true; 200 | 201 | case 'text/plain': 202 | res.statusCode = returnValue.status || 200; 203 | res.end(returnValue.text); 204 | 205 | return true; 206 | 207 | case 'application/octet-stream': 208 | res.statusCode = returnValue.status || 200; 209 | res.end(returnValue.Blob); 210 | return true; 211 | 212 | default: 213 | res.statusCode = returnValue.status || 200; 214 | res.end( 215 | returnValue.interface || 216 | JSON.stringify(returnValue.json) || 217 | returnValue.Blob || 218 | returnValue.text 219 | ); 220 | return true; 221 | } 222 | } 223 | return true; 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /src/core/router/router.ts: -------------------------------------------------------------------------------- 1 | import { BaseRouter } from './base'; 2 | 3 | import type { Route } from '../../interfaces/route'; 4 | import type { handler } from '../../interfaces/handler'; 5 | 6 | export class Router extends BaseRouter { 7 | public routes: Route[]; 8 | constructor() { 9 | super(); 10 | this.routes = []; 11 | } 12 | 13 | public register(method: string, path: string, handler: handler) { 14 | this.routes.push({ method: method, path: path, handler: handler }); 15 | } 16 | 17 | public getAllRoutes(): Route[] | undefined { 18 | return this.routes; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/core/state.ts: -------------------------------------------------------------------------------- 1 | import type { State } from '../interfaces/state'; 2 | 3 | export class AppState { 4 | private state: State; 5 | 6 | constructor(state: State) { 7 | this.state = { ...state }; 8 | } 9 | 10 | public getKey(key: string): T { 11 | return this.state[key]; 12 | } 13 | 14 | public setKey(key: string, value: T): void { 15 | this.state[key] = value; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/core/tree/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eviatejs/eviate/68e19be15fc41e071a6018dd6a87231330299b79/src/core/tree/index.ts -------------------------------------------------------------------------------- /src/core/tree/node.ts: -------------------------------------------------------------------------------- 1 | import type { Data } from '../../interfaces/data'; 2 | 3 | export class Node { 4 | public path: string; 5 | public fullPath: string; 6 | public data: Data; 7 | public priority: number; 8 | public type: number; 9 | public children: any; 10 | 11 | public static DEFAULT: number; 12 | public static CATCHALL: number; 13 | public static PARAM: number; 14 | 15 | constructor(path: string, fullPath: string, data: any) { 16 | this.path = path; 17 | this.fullPath = fullPath; 18 | this.data = data; 19 | this.priority = 1; 20 | this.type = Node.DEFAULT; 21 | 22 | this.children = []; 23 | } 24 | 25 | append(node: any) { 26 | this.children.push(node); 27 | this.sort(); 28 | } 29 | 30 | remove(node: any) { 31 | let position = this.children.indexOf(node); 32 | 33 | if (position === -1) { 34 | return; 35 | } 36 | 37 | this.children.splice(position, 1); 38 | } 39 | 40 | sort() { 41 | this.children.sort( 42 | (a: { priority: number }, b: { priority: number }) => 43 | b.priority - a.priority 44 | ); 45 | } 46 | } 47 | 48 | Node.DEFAULT = 0; 49 | Node.PARAM = 1; 50 | Node.CATCHALL = 2; 51 | -------------------------------------------------------------------------------- /src/core/tree/tree.ts: -------------------------------------------------------------------------------- 1 | import { Node } from './node'; 2 | 3 | import type { Data } from '../../interfaces/data'; 4 | 5 | export class Tree { 6 | root: null | Node; 7 | 8 | constructor() { 9 | this.root = null; 10 | } 11 | 12 | public add(path: string, data: Data) { 13 | if (this.isEmpty()) { 14 | this.root = new Node('', '', null); 15 | } 16 | 17 | const fullPath = path; 18 | 19 | let node = this.root!; 20 | node.priority++; 21 | 22 | node_loop: while (node) { 23 | path = path.slice(node.path.length); 24 | 25 | if (path.length === 0) { 26 | if (node.data) { 27 | throw new Error('Node already defined'); 28 | } 29 | 30 | node.data = data; 31 | 32 | return this; 33 | } 34 | 35 | if (node.children.length) { 36 | for (let nodeIndex = 0; nodeIndex < node.children.length; nodeIndex++) { 37 | if (node.children[nodeIndex].path[0] === path[0]) { 38 | let selectedNode = node.children[nodeIndex]; 39 | 40 | let pathCompareIndex; 41 | for ( 42 | pathCompareIndex = 0; 43 | pathCompareIndex < 44 | Math.min(selectedNode.path.length, path.length); 45 | pathCompareIndex++ 46 | ) { 47 | if ( 48 | path[pathCompareIndex] !== selectedNode.path[pathCompareIndex] 49 | ) { 50 | break; 51 | } 52 | } 53 | 54 | // go further down the tree 55 | if (pathCompareIndex >= selectedNode.path.length) { 56 | node.children[nodeIndex].priority++; 57 | node.sort(); 58 | 59 | node = selectedNode; 60 | 61 | continue node_loop; 62 | // we inject a new node, cause the new path is part of this one 63 | } else if (pathCompareIndex >= path.length) { 64 | let newChild = new Node(path, fullPath, data); 65 | 66 | selectedNode.path = selectedNode.path.replace(path, ''); 67 | 68 | node.remove(selectedNode); 69 | 70 | newChild.priority = selectedNode.priority + 1; 71 | newChild.append(selectedNode); 72 | 73 | node.append(newChild); 74 | 75 | return this; 76 | // we match partly, generate a new edge 77 | } else if (pathCompareIndex > 0) { 78 | let newEdge = new Node( 79 | path.substr(0, pathCompareIndex), 80 | '', 81 | null 82 | ); 83 | 84 | selectedNode.path = selectedNode.path.substr(pathCompareIndex); 85 | 86 | newEdge.priority = selectedNode.priority + 1; 87 | 88 | node.remove(selectedNode); 89 | node.append(newEdge); 90 | 91 | newEdge.append(selectedNode); 92 | 93 | node = newEdge; 94 | 95 | continue node_loop; 96 | } 97 | } 98 | } 99 | } 100 | 101 | this.appendNode(node, path, fullPath, data); 102 | 103 | return this; 104 | } 105 | 106 | return this; 107 | } 108 | 109 | public appendNode(node: Node, path: string, fullPath: string, data: Data) { 110 | let offset = 0; 111 | 112 | let child: Node = new Node('', '', {}); 113 | 114 | for (let index = 0; index < path.length; index++) { 115 | let character = path[index]; 116 | 117 | if (character !== ':' && character !== '*') { 118 | continue; 119 | } 120 | 121 | if (character === ':') { 122 | if (node.children.length !== 0 && index === 0) { 123 | throw new Error( 124 | 'Param node can not be appended to an already existing path' 125 | ); 126 | } 127 | 128 | if (offset < index - offset) { 129 | child.path = path.substr(offset, index - offset); 130 | 131 | offset = index; 132 | node.append(child); 133 | node = child; 134 | } 135 | 136 | child = new Node('', '', {}); 137 | child.type = Node.PARAM; 138 | } else if (character === '*') { 139 | if (node.children.length !== 0 && index === 0) { 140 | throw new Error( 141 | 'Param node can not be appended to an already existing path' 142 | ); 143 | } 144 | 145 | if (offset < index - offset) { 146 | child.path = path.substr(offset, index - offset); 147 | 148 | offset = index; 149 | node.append(child); 150 | node = child; 151 | } 152 | 153 | child = new Node('', '', {}); 154 | child.type = Node.CATCHALL; 155 | } 156 | } 157 | 158 | child.path = path.slice(offset); 159 | child.fullPath = fullPath; 160 | child.data = data; 161 | 162 | node.append(child); 163 | 164 | return this; 165 | } 166 | 167 | public remove(path: string) { 168 | if (this.isEmpty()) { 169 | return this; 170 | } 171 | 172 | let node = this.root; 173 | let offset = node?.path.length || 1; 174 | 175 | let pathLength = path.length; 176 | 177 | let passedNodes = []; 178 | 179 | node_loop: while (node) { 180 | passedNodes.push(node); 181 | 182 | if (pathLength === offset) { 183 | break; 184 | } 185 | 186 | if (!node.children.length) { 187 | return this; 188 | } 189 | 190 | for (let index = 0; index < node.children.length; index++) { 191 | let child = node.children[index]; 192 | 193 | if (child.type === Node.DEFAULT) { 194 | if ( 195 | path[offset] === child.path[0] && 196 | path.indexOf(child.path, offset) === offset 197 | ) { 198 | node = child; 199 | offset += node?.path.length || 0; 200 | 201 | continue node_loop; 202 | } 203 | } else if (child.type === Node.PARAM) { 204 | // break if no parameter 205 | if (path[offset] !== ':') { 206 | return this; 207 | } 208 | 209 | let paramEnd = path.indexOf('/', offset); 210 | paramEnd = paramEnd !== -1 ? paramEnd : pathLength; 211 | 212 | // are the names not matching, abort 213 | if (child.path !== path.substr(offset, paramEnd - offset)) { 214 | return this; 215 | } 216 | 217 | offset = paramEnd; 218 | node = child; 219 | 220 | continue node_loop; 221 | } else if (child.type === Node.CATCHALL) { 222 | // break if no catchall 223 | if (path[offset] !== '*') { 224 | return this; 225 | } 226 | 227 | // are the names not matching, abort 228 | if (child.path !== path.substr(offset)) { 229 | return this; 230 | } 231 | 232 | offset = path.length; 233 | node = child; 234 | 235 | continue node_loop; 236 | } 237 | } 238 | 239 | break; 240 | } 241 | 242 | passedNodes.reverse(); 243 | 244 | node = passedNodes[0]; 245 | let parentNode = passedNodes[1]; 246 | 247 | switch (node.children.length) { 248 | case 0: 249 | parentNode.remove(node); 250 | break; 251 | 252 | case 1: 253 | let childNode = node.children[0]; 254 | childNode.path = node.path + childNode.path; 255 | 256 | parentNode.remove(node); 257 | parentNode.append(childNode); 258 | break; 259 | 260 | default: 261 | break; 262 | } 263 | 264 | return this; 265 | } 266 | 267 | public removeAll() { 268 | this.root = null; 269 | 270 | return this; 271 | } 272 | 273 | public countParams(path: string) { 274 | let matches = path.match(/:|\*/g); 275 | 276 | return matches ? matches.length : 0; 277 | } 278 | 279 | public find(path: string) { 280 | if (this.isEmpty()) { 281 | return undefined; 282 | } 283 | 284 | let node = this.root; 285 | let offset = node?.path.length || 0; 286 | let params = null; 287 | 288 | let pathLength = path.length; 289 | 290 | node_loop: while (node) { 291 | if (pathLength === offset) { 292 | let result = { 293 | path: node.fullPath, 294 | data: node.data, 295 | params: params 296 | }; 297 | 298 | if (node.data) { 299 | result.data = node.data; 300 | } 301 | 302 | if (params) { 303 | result.params = params; 304 | } 305 | 306 | return result; 307 | } 308 | 309 | if (!node.children.length) { 310 | break; 311 | } 312 | 313 | for (let index = 0; index < node.children.length; index++) { 314 | let child = node.children[index]; 315 | 316 | if (child.type === Node.DEFAULT) { 317 | if ( 318 | path[offset] === child.path[0] && 319 | path.indexOf(child.path, offset) === offset 320 | ) { 321 | node = child; 322 | offset += node?.path.length || 0; 323 | 324 | continue node_loop; 325 | } 326 | } else if (child.type === Node.PARAM) { 327 | let paramEnd = path.indexOf('/', offset); 328 | 329 | paramEnd = paramEnd !== -1 ? paramEnd : pathLength; 330 | 331 | if (!params) { 332 | params = {}; 333 | } 334 | //@ts-ignore 335 | params[child.path.substr(1)] = path.substr(offset, paramEnd - offset); 336 | 337 | offset = paramEnd; 338 | node = child; 339 | 340 | continue node_loop; 341 | } else if (child.type === Node.CATCHALL) { 342 | if (!params) { 343 | params = {}; 344 | } 345 | //@ts-ignore 346 | params[child.path.substr(1)] = path.substr(offset); 347 | 348 | offset = path.length; 349 | node = child; 350 | 351 | continue node_loop; 352 | } 353 | } 354 | 355 | break; 356 | } 357 | 358 | return undefined; 359 | } 360 | 361 | public isEmpty() { 362 | return this.root === null; 363 | } 364 | } 365 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './core'; 2 | export * from './mappings'; 3 | export * from './interfaces'; 4 | -------------------------------------------------------------------------------- /src/interfaces/config.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from '@eviatejs/plugin'; 2 | import { Router } from '../core'; 3 | import { MiddlewareHandler } from './middlewareHandler'; 4 | 5 | export interface config { 6 | port: number; 7 | hostname: string; 8 | debug: boolean; 9 | state?: Record; 10 | startMiddlewares?: MiddlewareHandler[]; 11 | endMiddlewares?: MiddlewareHandler[]; 12 | routers?: Router[]; 13 | plugins?: Plugin[]; 14 | } 15 | -------------------------------------------------------------------------------- /src/interfaces/data.ts: -------------------------------------------------------------------------------- 1 | import { handler } from './handler'; 2 | 3 | export interface Data { 4 | handler: handler; 5 | } 6 | -------------------------------------------------------------------------------- /src/interfaces/handler.ts: -------------------------------------------------------------------------------- 1 | import type { Context } from '../core/context'; 2 | import type { EviateResponse } from './response'; 3 | 4 | export type handler = (ctx: Context) => EviateResponse; 5 | -------------------------------------------------------------------------------- /src/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export { config } from './config'; 2 | export { Data } from './data'; 3 | export { handler } from './handler'; 4 | export { EviateResponse, EviateMiddlewareResponse } from './response'; 5 | export { MiddlewareHandler } from './middlewareHandler'; 6 | -------------------------------------------------------------------------------- /src/interfaces/match.ts: -------------------------------------------------------------------------------- 1 | import type { handler } from './handler'; 2 | 3 | export interface MatchedData { 4 | params: any; // TODO: Add proper typing. 5 | handler: handler; 6 | } 7 | -------------------------------------------------------------------------------- /src/interfaces/middlewareHandler.ts: -------------------------------------------------------------------------------- 1 | import { Context } from '../core'; 2 | import { EviateMiddlewareResponse } from './response'; 3 | 4 | export interface MiddlewareHandler { 5 | (ctx: Context): EviateMiddlewareResponse | Promise; 6 | } 7 | -------------------------------------------------------------------------------- /src/interfaces/response.ts: -------------------------------------------------------------------------------- 1 | import type { Context } from '../core/context'; 2 | 3 | export interface EviateResponse { 4 | status?: number; 5 | text?: string; 6 | json?: { [key: string]: any }; 7 | error?: Error | string | { [key: string]: any }; 8 | headers?: { [key: string]: string }; 9 | interface?: any; 10 | Blob?: Blob; 11 | } 12 | 13 | export interface EviateMiddlewareResponse { 14 | status?: number; 15 | header?: { [key: string]: string }; 16 | ctx: Context; 17 | } 18 | -------------------------------------------------------------------------------- /src/interfaces/route.ts: -------------------------------------------------------------------------------- 1 | import { handler } from './handler'; 2 | 3 | export interface Route { 4 | method: string; 5 | path: string; 6 | handler: handler; 7 | } 8 | -------------------------------------------------------------------------------- /src/interfaces/state.ts: -------------------------------------------------------------------------------- 1 | export interface State { 2 | [key: string]: any; 3 | } 4 | -------------------------------------------------------------------------------- /src/mappings/EventHandlerType.ts: -------------------------------------------------------------------------------- 1 | export const EventHandlerType = Object.freeze({ 2 | startup: 'startup', 3 | shutdown: 'shutdown' 4 | }); 5 | 6 | export const EventHandlerTypeList = [ 7 | EventHandlerType.startup, 8 | EventHandlerType.shutdown 9 | ]; 10 | -------------------------------------------------------------------------------- /src/mappings/MiddlewarePosition.ts: -------------------------------------------------------------------------------- 1 | export const MiddlewarePosition = Object.freeze({ 2 | Before: 0, 3 | After: 1 4 | }); 5 | 6 | export const UserMiddlewarePosition = Object.freeze({ 7 | Before: 'before', 8 | After: 'after' 9 | }); 10 | -------------------------------------------------------------------------------- /src/mappings/RouterEvent.ts: -------------------------------------------------------------------------------- 1 | export const RouterEvent = Object.freeze({ 2 | Startup: 'startup', 3 | Shutdown: 'shutdown', 4 | BeforeRequest: 'before-request', 5 | Mount: 'router-mount', 6 | PluginLoad: 'plugin-load' 7 | }); 8 | -------------------------------------------------------------------------------- /src/mappings/index.ts: -------------------------------------------------------------------------------- 1 | export { EventHandlerType, EventHandlerTypeList } from './EventHandlerType'; 2 | export { MiddlewarePosition } from './MiddlewarePosition'; 3 | -------------------------------------------------------------------------------- /src/runtime/server.ts: -------------------------------------------------------------------------------- 1 | import { Context } from '../core'; 2 | import { defaultAppListenParams } from '../schema/AppListenParams'; 3 | 4 | import type { Serve } from 'bun'; 5 | import type { EventEmitter } from 'sweet-event-emitter'; 6 | import type { Middleware } from '../core/middlewares'; 7 | import type { config, EviateMiddlewareResponse } from '../interfaces'; 8 | import type { InternalRouter } from '../core/router/internal-router'; 9 | import type { AppListenParams } from '../schema/AppListenParams'; 10 | 11 | // Server that runs on bun/node runtime independently. 12 | export class Server { 13 | public config?: config; 14 | public router: InternalRouter; 15 | public middleware: Middleware; 16 | public eventEmitter: EventEmitter; 17 | 18 | constructor( 19 | router: InternalRouter, 20 | middleware: Middleware, 21 | eventEmitter: EventEmitter, 22 | config?: config 23 | ) { 24 | this.router = router; 25 | this.middleware = middleware; 26 | this.eventEmitter = eventEmitter; 27 | this.config = config; 28 | } 29 | 30 | public getRuntime(): 'bun' | 'node' { 31 | // If `Bun` is defined on global scope, then we are running on bun runtime. 32 | // Else, we are running on node runtime. 33 | return typeof Bun !== 'undefined' ? 'bun' : 'node'; 34 | } 35 | 36 | private serveBun(host: string, port: number, debug: boolean): Serve { 37 | const router: InternalRouter = this.router; 38 | const middleware: Middleware = this.middleware; 39 | 40 | return { 41 | port: port, 42 | hostname: host, 43 | debug: debug, 44 | 45 | // @ts-ignore 46 | async fetch(req: Request) { 47 | router.event.emit('before-request'); 48 | 49 | let ctx: Context = new Context(req); 50 | 51 | const resp: EviateMiddlewareResponse = await middleware.runBefore(ctx); 52 | const res = router.serveBunHandler(resp.ctx, resp.header || {}); 53 | 54 | middleware.runAfter(ctx); 55 | 56 | return res; 57 | }, 58 | 59 | // @ts-ignore 60 | error(error: Error) { 61 | console.log(error); 62 | } 63 | }; 64 | } 65 | 66 | private serveNode( 67 | http: typeof import('node:http'), 68 | hostname: string, 69 | port: number 70 | ) { 71 | const server = http.createServer(async (req, res) => { 72 | const standardRequest = new Request(`http://${hostname}${req.url}`); 73 | const ctx: Context = new Context(standardRequest); 74 | const resp: EviateMiddlewareResponse = await this.middleware.runBefore( 75 | ctx 76 | ); 77 | 78 | const bool: boolean = this.router.serveNodeHandler( 79 | resp.ctx, 80 | resp.header || {}, 81 | res 82 | ); 83 | 84 | if (bool) { 85 | this.middleware.runAfter(resp.ctx); 86 | } 87 | }); 88 | 89 | return server; 90 | } 91 | 92 | public async listen(params?: AppListenParams) { 93 | const runtime = this.getRuntime(); 94 | 95 | const { port, hostname, debug } = { 96 | ...defaultAppListenParams, 97 | ...this.config, 98 | ...params 99 | }; 100 | 101 | this.eventEmitter.emit('startup', { port, hostname, debug }); 102 | 103 | if (runtime === 'bun') { 104 | Bun.serve(this.serveBun(hostname, port, debug)); 105 | } else { 106 | const http = await import('node:http'); 107 | 108 | this.serveNode(http, hostname, port).listen(port, hostname); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/schema/AppListenParams.ts: -------------------------------------------------------------------------------- 1 | export interface AppListenParams { 2 | hostname: string; 3 | port: number; 4 | debug: boolean; 5 | } 6 | 7 | export const defaultAppListenParams: AppListenParams = { 8 | hostname: '127.0.0.1', 9 | port: 4000, 10 | debug: false 11 | }; 12 | -------------------------------------------------------------------------------- /src/schema/AppParams.ts: -------------------------------------------------------------------------------- 1 | import type { OpenAPISchema } from './OpenAPI'; 2 | import type { Engine } from '../core'; 3 | 4 | export interface AppMetadata { 5 | title: string; 6 | description: string; 7 | version: string; 8 | } 9 | 10 | export const defaultAppMetadataParams = { 11 | title: 'Eviate', 12 | description: '', 13 | version: '1.0.0' 14 | }; 15 | 16 | export interface AppParams { 17 | metadata: AppMetadata; 18 | state: Record; 19 | openapi?: (app: Engine) => OpenAPISchema; 20 | } 21 | 22 | export const defaultAppStateParams = {}; 23 | -------------------------------------------------------------------------------- /src/schema/OpenAPI.ts: -------------------------------------------------------------------------------- 1 | interface Server { 2 | url: string; 3 | description: string; 4 | } 5 | 6 | export interface OpenAPISchema { 7 | termsOfService?: string; 8 | contact?: { 9 | name: string; 10 | url: string; 11 | email: string; 12 | }; 13 | license?: { 14 | name: string; 15 | url: string; 16 | }; 17 | servers?: Server[]; 18 | } 19 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eviatejs/eviate/68e19be15fc41e071a6018dd6a87231330299b79/src/utils/index.ts -------------------------------------------------------------------------------- /src/utils/load-config.ts: -------------------------------------------------------------------------------- 1 | import { existsSync } from 'fs'; 2 | 3 | import type { Engine } from '../core'; 4 | 5 | export async function loadConfig(app: Engine) { 6 | let loadedData; 7 | if (existsSync(`${process.cwd()}/eviate.config.ts`)) 8 | loadedData = await import(`${process.cwd()}/eviate.config.ts`); 9 | if (existsSync(`${process.cwd()}/eviate.config.js`)) 10 | loadedData = await import(`${process.cwd()}/eviate.config.js`); 11 | 12 | if (!loadedData) { 13 | app.config = undefined; 14 | return; 15 | } 16 | 17 | app.config = loadedData.default; 18 | 19 | // Load the middlewares (if any) 20 | app.config?.startMiddlewares?.forEach(handler => { 21 | app.use(handler, 'before'); 22 | }); 23 | app.config?.endMiddlewares?.forEach(handler => { 24 | app.use(handler, 'after'); 25 | }); 26 | 27 | // Load plugins (if any) 28 | app.config?.plugins?.forEach(plugin => { 29 | app.plugin.load(plugin); 30 | }); 31 | 32 | // Load the routes (if any) 33 | app.config?.routers?.forEach(route => { 34 | app.mount(route); 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /src/utils/router-logger.ts: -------------------------------------------------------------------------------- 1 | import pc from 'picocolors'; 2 | 3 | export function routeMount(method: string, path: string) { 4 | console.log( 5 | pc.blue( 6 | `[${new Date().toLocaleTimeString()}]: Mounted ${method} request on path ${path}` 7 | ) 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /src/utils/startup-banner.ts: -------------------------------------------------------------------------------- 1 | import os from 'os'; 2 | 3 | import pc from 'picocolors'; 4 | 5 | import packageJson from '../../package.json'; 6 | 7 | const osTypeMap: Record = { 8 | Darwin: 'macOS', 9 | Linux: 'linux', 10 | Windows_NT: 'windows' 11 | }; 12 | 13 | export const startupBanner = (runtime: string) => { 14 | const banner = 15 | pc.cyan(` 16 | ____ _ __ 17 | / __/ __(_)__ _/ /____ 18 | / _/| |/ / / _ / __/ -_) 19 | /___/|___/_/\_,_/\__/\__/ 20 | 21 | `) + 22 | pc.yellow( 23 | pc.bold( 24 | `v${packageJson.version} | Running on ${runtime} (${ 25 | osTypeMap[os.type()] 26 | })` 27 | ) 28 | ); 29 | 30 | console.log(banner); 31 | }; 32 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // Included directories. 3 | "include": ["src"], 4 | "exclude": ["node_modules"], 5 | "compilerOptions": { 6 | "target": "es2015", 7 | "lib": ["es5", "es6", "dom", "es2015"], 8 | // Module 9 | "module": "esnext", 10 | 11 | // Output JS type 12 | 13 | // Directories 14 | "rootDir": ".", 15 | "outDir": "./dist", 16 | 17 | // stricter type-checking for stronger correctness. Recommended by TS 18 | "strict": true, 19 | 20 | // linter checks for common issues 21 | "noImplicitReturns": true, 22 | "noFallthroughCasesInSwitch": true, 23 | 24 | // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative 25 | "noUnusedLocals": false, 26 | "noUnusedParameters": false, 27 | 28 | // use Node's module resolution algorithm, instead of the legacy TS one 29 | "moduleResolution": "node", 30 | "resolveJsonModule": true, 31 | 32 | // interop between ESM and CJS modules. Recommended by TS 33 | "esModuleInterop": true, 34 | 35 | // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS 36 | "skipLibCheck": true, 37 | 38 | // error out if import and file system have a casing mismatch. Recommended by TS 39 | "forceConsistentCasingInFileNames": true, 40 | 41 | // enable output emitting 42 | "noEmit": false, 43 | 44 | // enable default imports 45 | "allowSyntheticDefaultImports": true, 46 | 47 | // "bun-types" is the important part 48 | "types": ["@types/node", "bun-types"] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | entry: ['src/index.ts'], 5 | clean: true, 6 | splitting: true, 7 | treeshake: true, 8 | minify: true, 9 | format: ['cjs', 'esm'], 10 | external: ['bun'], 11 | dts: true 12 | }); 13 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@cspotcode/source-map-support@^0.8.0": 6 | version "0.8.1" 7 | resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" 8 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== 9 | dependencies: 10 | "@jridgewell/trace-mapping" "0.3.9" 11 | 12 | "@esbuild/android-arm@0.15.9": 13 | version "0.15.9" 14 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.9.tgz#7e1221604ab88ed5021ead74fa8cca4405e1e431" 15 | integrity sha512-VZPy/ETF3fBG5PiinIkA0W/tlsvlEgJccyN2DzWZEl0DlVKRbu91PvY2D6Lxgluj4w9QtYHjOWjAT44C+oQ+EQ== 16 | 17 | "@esbuild/linux-loong64@0.15.9": 18 | version "0.15.9" 19 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.9.tgz#b658a97babf1f40783354af7039b84c3fdfc3fc3" 20 | integrity sha512-O+NfmkfRrb3uSsTa4jE3WApidSe3N5++fyOVGP1SmMZi4A3BZELkhUUvj5hwmMuNdlpzAZ8iAPz2vmcR7DCFQA== 21 | 22 | "@eviatejs/plugin@^0.1.3": 23 | version "0.1.3" 24 | resolved "https://registry.yarnpkg.com/@eviatejs/plugin/-/plugin-0.1.3.tgz#9c6434ab6c6b899116d3a1f1e842249b7c3dc0d8" 25 | integrity sha512-Q6kVxPbsoVC6B26Oz6LXAq6ump8ZeH9BVjC6FBySp03vQzlMhP+6X2MNN8Kr7POKuku4LQOBddmpjQPv/YsS/g== 26 | dependencies: 27 | sweet-event-emitter "^0.1.0" 28 | 29 | "@jridgewell/resolve-uri@^3.0.3": 30 | version "3.1.0" 31 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" 32 | integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== 33 | 34 | "@jridgewell/sourcemap-codec@^1.4.10": 35 | version "1.4.14" 36 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" 37 | integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== 38 | 39 | "@jridgewell/trace-mapping@0.3.9": 40 | version "0.3.9" 41 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" 42 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== 43 | dependencies: 44 | "@jridgewell/resolve-uri" "^3.0.3" 45 | "@jridgewell/sourcemap-codec" "^1.4.10" 46 | 47 | "@nodelib/fs.scandir@2.1.5": 48 | version "2.1.5" 49 | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" 50 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 51 | dependencies: 52 | "@nodelib/fs.stat" "2.0.5" 53 | run-parallel "^1.1.9" 54 | 55 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": 56 | version "2.0.5" 57 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" 58 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 59 | 60 | "@nodelib/fs.walk@^1.2.3": 61 | version "1.2.8" 62 | resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" 63 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 64 | dependencies: 65 | "@nodelib/fs.scandir" "2.1.5" 66 | fastq "^1.6.0" 67 | 68 | "@tsconfig/node10@^1.0.7": 69 | version "1.0.9" 70 | resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" 71 | integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== 72 | 73 | "@tsconfig/node12@^1.0.7": 74 | version "1.0.11" 75 | resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" 76 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== 77 | 78 | "@tsconfig/node14@^1.0.0": 79 | version "1.0.3" 80 | resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" 81 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== 82 | 83 | "@tsconfig/node16@^1.0.2": 84 | version "1.0.3" 85 | resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" 86 | integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== 87 | 88 | "@types/node@^18.8.2": 89 | version "18.11.0" 90 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.0.tgz#f38c7139247a1d619f6cc6f27b072606af7c289d" 91 | integrity sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w== 92 | 93 | acorn-walk@^8.1.1: 94 | version "8.2.0" 95 | resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" 96 | integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== 97 | 98 | acorn@^8.4.1: 99 | version "8.8.0" 100 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" 101 | integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== 102 | 103 | aggregate-error@^3.0.0: 104 | version "3.1.0" 105 | resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" 106 | integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== 107 | dependencies: 108 | clean-stack "^2.0.0" 109 | indent-string "^4.0.0" 110 | 111 | ansi-escapes@^4.3.0: 112 | version "4.3.2" 113 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" 114 | integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== 115 | dependencies: 116 | type-fest "^0.21.3" 117 | 118 | ansi-regex@^5.0.1: 119 | version "5.0.1" 120 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 121 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 122 | 123 | ansi-regex@^6.0.1: 124 | version "6.0.1" 125 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" 126 | integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== 127 | 128 | ansi-styles@^4.0.0: 129 | version "4.3.0" 130 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 131 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 132 | dependencies: 133 | color-convert "^2.0.1" 134 | 135 | ansi-styles@^6.0.0: 136 | version "6.1.1" 137 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.1.tgz#63cd61c72283a71cb30bd881dbb60adada74bc70" 138 | integrity sha512-qDOv24WjnYuL+wbwHdlsYZFy+cgPtrYw0Tn7GLORicQp9BkQLzrgI3Pm4VyR9ERZ41YTn7KlMPuL1n05WdZvmg== 139 | 140 | any-promise@^1.0.0: 141 | version "1.3.0" 142 | resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" 143 | integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== 144 | 145 | anymatch@~3.1.2: 146 | version "3.1.2" 147 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" 148 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 149 | dependencies: 150 | normalize-path "^3.0.0" 151 | picomatch "^2.0.4" 152 | 153 | arg@^4.1.0: 154 | version "4.1.3" 155 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" 156 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 157 | 158 | array-union@^2.1.0: 159 | version "2.1.0" 160 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" 161 | integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== 162 | 163 | astral-regex@^2.0.0: 164 | version "2.0.0" 165 | resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" 166 | integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== 167 | 168 | balanced-match@^1.0.0: 169 | version "1.0.2" 170 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 171 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 172 | 173 | binary-extensions@^2.0.0: 174 | version "2.2.0" 175 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 176 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 177 | 178 | brace-expansion@^1.1.7: 179 | version "1.1.11" 180 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 181 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 182 | dependencies: 183 | balanced-match "^1.0.0" 184 | concat-map "0.0.1" 185 | 186 | braces@^3.0.2, braces@~3.0.2: 187 | version "3.0.2" 188 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 189 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 190 | dependencies: 191 | fill-range "^7.0.1" 192 | 193 | bun-types@^0.1.11: 194 | version "0.1.11" 195 | resolved "https://registry.yarnpkg.com/bun-types/-/bun-types-0.1.11.tgz#cc34bf6c9fe3ade6569a18fdc2e442e80ad912e7" 196 | integrity sha512-a5G9LZtF5qBsDMjGnS5FfTvIeg1bS0PzI3Q2LqShEjJWdhZTB56xO8ewqZ83J+3my5rW/PPPWT/udAofRQ3zdg== 197 | 198 | bundle-require@^3.1.0: 199 | version "3.1.0" 200 | resolved "https://registry.yarnpkg.com/bundle-require/-/bundle-require-3.1.0.tgz#e07256ff02c72cd3a665afa84ce930d111ae4252" 201 | integrity sha512-IIXtAO7fKcwPHNPt9kY/WNVJqy7NDy6YqJvv6ENH0TOZoJ+yjpEsn1w40WKZbR2ibfu5g1rfgJTvmFHpm5aOMA== 202 | dependencies: 203 | load-tsconfig "^0.2.0" 204 | 205 | cac@^6.7.12: 206 | version "6.7.14" 207 | resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" 208 | integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== 209 | 210 | chokidar@^3.5.1: 211 | version "3.5.3" 212 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 213 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 214 | dependencies: 215 | anymatch "~3.1.2" 216 | braces "~3.0.2" 217 | glob-parent "~5.1.2" 218 | is-binary-path "~2.1.0" 219 | is-glob "~4.0.1" 220 | normalize-path "~3.0.0" 221 | readdirp "~3.6.0" 222 | optionalDependencies: 223 | fsevents "~2.3.2" 224 | 225 | clean-stack@^2.0.0: 226 | version "2.2.0" 227 | resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" 228 | integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== 229 | 230 | cli-cursor@^3.1.0: 231 | version "3.1.0" 232 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" 233 | integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== 234 | dependencies: 235 | restore-cursor "^3.1.0" 236 | 237 | cli-truncate@^2.1.0: 238 | version "2.1.0" 239 | resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" 240 | integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== 241 | dependencies: 242 | slice-ansi "^3.0.0" 243 | string-width "^4.2.0" 244 | 245 | cli-truncate@^3.1.0: 246 | version "3.1.0" 247 | resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" 248 | integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== 249 | dependencies: 250 | slice-ansi "^5.0.0" 251 | string-width "^5.0.0" 252 | 253 | color-convert@^2.0.1: 254 | version "2.0.1" 255 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 256 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 257 | dependencies: 258 | color-name "~1.1.4" 259 | 260 | color-name@~1.1.4: 261 | version "1.1.4" 262 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 263 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 264 | 265 | colorette@^2.0.16, colorette@^2.0.17: 266 | version "2.0.19" 267 | resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" 268 | integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== 269 | 270 | commander@^4.0.0: 271 | version "4.1.1" 272 | resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" 273 | integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== 274 | 275 | commander@^9.3.0: 276 | version "9.4.0" 277 | resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c" 278 | integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw== 279 | 280 | concat-map@0.0.1: 281 | version "0.0.1" 282 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 283 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 284 | 285 | create-require@^1.1.0: 286 | version "1.1.1" 287 | resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" 288 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== 289 | 290 | cross-spawn@^7.0.3: 291 | version "7.0.3" 292 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 293 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 294 | dependencies: 295 | path-key "^3.1.0" 296 | shebang-command "^2.0.0" 297 | which "^2.0.1" 298 | 299 | debug@^4.3.1, debug@^4.3.4: 300 | version "4.3.4" 301 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 302 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 303 | dependencies: 304 | ms "2.1.2" 305 | 306 | diff@^4.0.1: 307 | version "4.0.2" 308 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 309 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 310 | 311 | dir-glob@^3.0.1: 312 | version "3.0.1" 313 | resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" 314 | integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== 315 | dependencies: 316 | path-type "^4.0.0" 317 | 318 | eastasianwidth@^0.2.0: 319 | version "0.2.0" 320 | resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" 321 | integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== 322 | 323 | emoji-regex@^8.0.0: 324 | version "8.0.0" 325 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 326 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 327 | 328 | emoji-regex@^9.2.2: 329 | version "9.2.2" 330 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" 331 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 332 | 333 | esbuild-android-64@0.15.9: 334 | version "0.15.9" 335 | resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.15.9.tgz#4a7eb320ca8d3a305f14792061fd9614ccebb7c0" 336 | integrity sha512-HQCX7FJn9T4kxZQkhPjNZC7tBWZqJvhlLHPU2SFzrQB/7nDXjmTIFpFTjt7Bd1uFpeXmuwf5h5fZm+x/hLnhbw== 337 | 338 | esbuild-android-arm64@0.15.9: 339 | version "0.15.9" 340 | resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.9.tgz#c948e5686df20857ad361ec67e070d40d7cab985" 341 | integrity sha512-E6zbLfqbFVCNEKircSHnPiSTsm3fCRxeIMPfrkS33tFjIAoXtwegQfVZqMGR0FlsvVxp2NEDOUz+WW48COCjSg== 342 | 343 | esbuild-darwin-64@0.15.9: 344 | version "0.15.9" 345 | resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.9.tgz#25f564fa4b39c1cec84dc46bce5634fdbce1d5e4" 346 | integrity sha512-gI7dClcDN/HHVacZhTmGjl0/TWZcGuKJ0I7/xDGJwRQQn7aafZGtvagOFNmuOq+OBFPhlPv1T6JElOXb0unkSQ== 347 | 348 | esbuild-darwin-arm64@0.15.9: 349 | version "0.15.9" 350 | resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.9.tgz#60faea3ed95d15239536aa88d06bb82b29278a86" 351 | integrity sha512-VZIMlcRN29yg/sv7DsDwN+OeufCcoTNaTl3Vnav7dL/nvsApD7uvhVRbgyMzv0zU/PP0xRhhIpTyc7lxEzHGSw== 352 | 353 | esbuild-freebsd-64@0.15.9: 354 | version "0.15.9" 355 | resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.9.tgz#0339ef1c90a919175e7816788224517896657a0e" 356 | integrity sha512-uM4z5bTvuAXqPxrI204txhlsPIolQPWRMLenvGuCPZTnnGlCMF2QLs0Plcm26gcskhxewYo9LkkmYSS5Czrb5A== 357 | 358 | esbuild-freebsd-arm64@0.15.9: 359 | version "0.15.9" 360 | resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.9.tgz#32abfc0be3ae3dd38e5a86a9beadbbcf592f1b57" 361 | integrity sha512-HHDjT3O5gWzicGdgJ5yokZVN9K9KG05SnERwl9nBYZaCjcCgj/sX8Ps1jvoFSfNCO04JSsHSOWo4qvxFuj8FoA== 362 | 363 | esbuild-linux-32@0.15.9: 364 | version "0.15.9" 365 | resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.15.9.tgz#93581348a4da7ed2b29bc5539f2605ad7fcee77b" 366 | integrity sha512-AQIdE8FugGt1DkcekKi5ycI46QZpGJ/wqcMr7w6YUmOmp2ohQ8eO4sKUsOxNOvYL7hGEVwkndSyszR6HpVHLFg== 367 | 368 | esbuild-linux-64@0.15.9: 369 | version "0.15.9" 370 | resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.15.9.tgz#0d171e7946c95d0d3ed4826026af2c5632d7dcc4" 371 | integrity sha512-4RXjae7g6Qs7StZyiYyXTZXBlfODhb1aBVAjd+ANuPmMhWthQilWo7rFHwJwL7DQu1Fjej2sODAVwLbcIVsAYQ== 372 | 373 | esbuild-linux-arm64@0.15.9: 374 | version "0.15.9" 375 | resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.9.tgz#9838795a3720cbe736d3bc20621bd366eac22f24" 376 | integrity sha512-a+bTtxJmYmk9d+s2W4/R1SYKDDAldOKmWjWP0BnrWtDbvUBNOm++du0ysPju4mZVoEFgS1yLNW+VXnG/4FNwdQ== 377 | 378 | esbuild-linux-arm@0.15.9: 379 | version "0.15.9" 380 | resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.9.tgz#dce96cd817bc7376f6af3967649c4ab1f2f79506" 381 | integrity sha512-3Zf2GVGUOI7XwChH3qrnTOSqfV1V4CAc/7zLVm4lO6JT6wbJrTgEYCCiNSzziSju+J9Jhf9YGWk/26quWPC6yQ== 382 | 383 | esbuild-linux-mips64le@0.15.9: 384 | version "0.15.9" 385 | resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.9.tgz#0335a0739e61aa97cb9b4a018e3facfcca9cdcfd" 386 | integrity sha512-Zn9HSylDp89y+TRREMDoGrc3Z4Hs5u56ozZLQCiZAUx2+HdbbXbWdjmw3FdTJ/i7t5Cew6/Q+6kfO3KCcFGlyw== 387 | 388 | esbuild-linux-ppc64le@0.15.9: 389 | version "0.15.9" 390 | resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.9.tgz#18482afb95b8a705e2da0a59d7131bff221281f9" 391 | integrity sha512-OEiOxNAMH9ENFYqRsWUj3CWyN3V8P3ZXyfNAtX5rlCEC/ERXrCEFCJji/1F6POzsXAzxvUJrTSTCy7G6BhA6Fw== 392 | 393 | esbuild-linux-riscv64@0.15.9: 394 | version "0.15.9" 395 | resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.9.tgz#03b6f9708272c117006b9ce1c9ae8aab91b5a5b6" 396 | integrity sha512-ukm4KsC3QRausEFjzTsOZ/qqazw0YvJsKmfoZZm9QW27OHjk2XKSQGGvx8gIEswft/Sadp03/VZvAaqv5AIwNA== 397 | 398 | esbuild-linux-s390x@0.15.9: 399 | version "0.15.9" 400 | resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.9.tgz#65fb645623d575780f155f0ee52935e62f9cca4f" 401 | integrity sha512-uDOQEH55wQ6ahcIKzQr3VyjGc6Po/xblLGLoUk3fVL1qjlZAibtQr6XRfy5wPJLu/M2o0vQKLq4lyJ2r1tWKcw== 402 | 403 | esbuild-netbsd-64@0.15.9: 404 | version "0.15.9" 405 | resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.9.tgz#7894297bb9e11f3d2f6f31efecd1be4e181f0d54" 406 | integrity sha512-yWgxaYTQz+TqX80wXRq6xAtb7GSBAp6gqLKfOdANg9qEmAI1Bxn04IrQr0Mzm4AhxvGKoHzjHjMgXbCCSSDxcw== 407 | 408 | esbuild-openbsd-64@0.15.9: 409 | version "0.15.9" 410 | resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.9.tgz#0f9d4c6b6772ae50d491d68ad4cc028300dda7c0" 411 | integrity sha512-JmS18acQl4iSAjrEha1MfEmUMN4FcnnrtTaJ7Qg0tDCOcgpPPQRLGsZqhes0vmx8VA6IqRyScqXvaL7+Q0Uf3A== 412 | 413 | esbuild-sunos-64@0.15.9: 414 | version "0.15.9" 415 | resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.9.tgz#c32b7ce574b08f814de810ce7c1e34b843768126" 416 | integrity sha512-UKynGSWpzkPmXW3D2UMOD9BZPIuRaSqphxSCwScfEE05Be3KAmvjsBhht1fLzKpiFVJb0BYMd4jEbWMyJ/z1hQ== 417 | 418 | esbuild-windows-32@0.15.9: 419 | version "0.15.9" 420 | resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.15.9.tgz#37a8f7cfccdb2177cd46613a1a1e1fcb419d36df" 421 | integrity sha512-aqXvu4/W9XyTVqO/hw3rNxKE1TcZiEYHPsXM9LwYmKSX9/hjvfIJzXwQBlPcJ/QOxedfoMVH0YnhhQ9Ffb0RGA== 422 | 423 | esbuild-windows-64@0.15.9: 424 | version "0.15.9" 425 | resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.15.9.tgz#5fe1e76fc13dd7f520febecaea110b6f1649c7b2" 426 | integrity sha512-zm7h91WUmlS4idMtjvCrEeNhlH7+TNOmqw5dJPJZrgFaxoFyqYG6CKDpdFCQXdyKpD5yvzaQBOMVTCBVKGZDEg== 427 | 428 | esbuild-windows-arm64@0.15.9: 429 | version "0.15.9" 430 | resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.9.tgz#98504428f7ba7d2cfc11940be68ee1139173fdce" 431 | integrity sha512-yQEVIv27oauAtvtuhJVfSNMztJJX47ismRS6Sv2QMVV9RM+6xjbMWuuwM2nxr5A2/gj/mu2z9YlQxiwoFRCfZA== 432 | 433 | esbuild@^0.15.1: 434 | version "0.15.9" 435 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.15.9.tgz#33fb18b67b85004b6f7616bec955ca4b3e58935d" 436 | integrity sha512-OnYr1rkMVxtmMHIAKZLMcEUlJmqcbxBz9QoBU8G9v455na0fuzlT/GLu6l+SRghrk0Mm2fSSciMmzV43Q8e0Gg== 437 | optionalDependencies: 438 | "@esbuild/android-arm" "0.15.9" 439 | "@esbuild/linux-loong64" "0.15.9" 440 | esbuild-android-64 "0.15.9" 441 | esbuild-android-arm64 "0.15.9" 442 | esbuild-darwin-64 "0.15.9" 443 | esbuild-darwin-arm64 "0.15.9" 444 | esbuild-freebsd-64 "0.15.9" 445 | esbuild-freebsd-arm64 "0.15.9" 446 | esbuild-linux-32 "0.15.9" 447 | esbuild-linux-64 "0.15.9" 448 | esbuild-linux-arm "0.15.9" 449 | esbuild-linux-arm64 "0.15.9" 450 | esbuild-linux-mips64le "0.15.9" 451 | esbuild-linux-ppc64le "0.15.9" 452 | esbuild-linux-riscv64 "0.15.9" 453 | esbuild-linux-s390x "0.15.9" 454 | esbuild-netbsd-64 "0.15.9" 455 | esbuild-openbsd-64 "0.15.9" 456 | esbuild-sunos-64 "0.15.9" 457 | esbuild-windows-32 "0.15.9" 458 | esbuild-windows-64 "0.15.9" 459 | esbuild-windows-arm64 "0.15.9" 460 | 461 | execa@^5.0.0: 462 | version "5.1.1" 463 | resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" 464 | integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== 465 | dependencies: 466 | cross-spawn "^7.0.3" 467 | get-stream "^6.0.0" 468 | human-signals "^2.1.0" 469 | is-stream "^2.0.0" 470 | merge-stream "^2.0.0" 471 | npm-run-path "^4.0.1" 472 | onetime "^5.1.2" 473 | signal-exit "^3.0.3" 474 | strip-final-newline "^2.0.0" 475 | 476 | execa@^6.1.0: 477 | version "6.1.0" 478 | resolved "https://registry.yarnpkg.com/execa/-/execa-6.1.0.tgz#cea16dee211ff011246556388effa0818394fb20" 479 | integrity sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA== 480 | dependencies: 481 | cross-spawn "^7.0.3" 482 | get-stream "^6.0.1" 483 | human-signals "^3.0.1" 484 | is-stream "^3.0.0" 485 | merge-stream "^2.0.0" 486 | npm-run-path "^5.1.0" 487 | onetime "^6.0.0" 488 | signal-exit "^3.0.7" 489 | strip-final-newline "^3.0.0" 490 | 491 | fast-glob@^3.2.9: 492 | version "3.2.12" 493 | resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" 494 | integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== 495 | dependencies: 496 | "@nodelib/fs.stat" "^2.0.2" 497 | "@nodelib/fs.walk" "^1.2.3" 498 | glob-parent "^5.1.2" 499 | merge2 "^1.3.0" 500 | micromatch "^4.0.4" 501 | 502 | fastq@^1.6.0: 503 | version "1.13.0" 504 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" 505 | integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== 506 | dependencies: 507 | reusify "^1.0.4" 508 | 509 | fill-range@^7.0.1: 510 | version "7.0.1" 511 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 512 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 513 | dependencies: 514 | to-regex-range "^5.0.1" 515 | 516 | fs.realpath@^1.0.0: 517 | version "1.0.0" 518 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 519 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 520 | 521 | fsevents@~2.3.2: 522 | version "2.3.2" 523 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" 524 | integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== 525 | 526 | get-stream@^6.0.0, get-stream@^6.0.1: 527 | version "6.0.1" 528 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" 529 | integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== 530 | 531 | glob-parent@^5.1.2, glob-parent@~5.1.2: 532 | version "5.1.2" 533 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 534 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 535 | dependencies: 536 | is-glob "^4.0.1" 537 | 538 | glob@7.1.6: 539 | version "7.1.6" 540 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 541 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 542 | dependencies: 543 | fs.realpath "^1.0.0" 544 | inflight "^1.0.4" 545 | inherits "2" 546 | minimatch "^3.0.4" 547 | once "^1.3.0" 548 | path-is-absolute "^1.0.0" 549 | 550 | globby@^11.0.3: 551 | version "11.1.0" 552 | resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" 553 | integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== 554 | dependencies: 555 | array-union "^2.1.0" 556 | dir-glob "^3.0.1" 557 | fast-glob "^3.2.9" 558 | ignore "^5.2.0" 559 | merge2 "^1.4.1" 560 | slash "^3.0.0" 561 | 562 | human-signals@^2.1.0: 563 | version "2.1.0" 564 | resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" 565 | integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== 566 | 567 | human-signals@^3.0.1: 568 | version "3.0.1" 569 | resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5" 570 | integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ== 571 | 572 | husky@^8.0.1: 573 | version "8.0.1" 574 | resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.1.tgz#511cb3e57de3e3190514ae49ed50f6bc3f50b3e9" 575 | integrity sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw== 576 | 577 | ignore@^5.2.0: 578 | version "5.2.0" 579 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" 580 | integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== 581 | 582 | indent-string@^4.0.0: 583 | version "4.0.0" 584 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" 585 | integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== 586 | 587 | inflight@^1.0.4: 588 | version "1.0.6" 589 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 590 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 591 | dependencies: 592 | once "^1.3.0" 593 | wrappy "1" 594 | 595 | inherits@2: 596 | version "2.0.4" 597 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 598 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 599 | 600 | is-binary-path@~2.1.0: 601 | version "2.1.0" 602 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 603 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 604 | dependencies: 605 | binary-extensions "^2.0.0" 606 | 607 | is-extglob@^2.1.1: 608 | version "2.1.1" 609 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 610 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 611 | 612 | is-fullwidth-code-point@^3.0.0: 613 | version "3.0.0" 614 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 615 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 616 | 617 | is-fullwidth-code-point@^4.0.0: 618 | version "4.0.0" 619 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" 620 | integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== 621 | 622 | is-glob@^4.0.1, is-glob@~4.0.1: 623 | version "4.0.3" 624 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 625 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 626 | dependencies: 627 | is-extglob "^2.1.1" 628 | 629 | is-number@^7.0.0: 630 | version "7.0.0" 631 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 632 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 633 | 634 | is-stream@^2.0.0: 635 | version "2.0.1" 636 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" 637 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 638 | 639 | is-stream@^3.0.0: 640 | version "3.0.0" 641 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" 642 | integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== 643 | 644 | isexe@^2.0.0: 645 | version "2.0.0" 646 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 647 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 648 | 649 | joycon@^3.0.1: 650 | version "3.1.1" 651 | resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" 652 | integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== 653 | 654 | lilconfig@2.0.5: 655 | version "2.0.5" 656 | resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.5.tgz#19e57fd06ccc3848fd1891655b5a447092225b25" 657 | integrity sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg== 658 | 659 | lilconfig@^2.0.5: 660 | version "2.0.6" 661 | resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" 662 | integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== 663 | 664 | lines-and-columns@^1.1.6: 665 | version "1.2.4" 666 | resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" 667 | integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== 668 | 669 | lint-staged@^13.0.3: 670 | version "13.0.3" 671 | resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.0.3.tgz#d7cdf03a3830b327a2b63c6aec953d71d9dc48c6" 672 | integrity sha512-9hmrwSCFroTSYLjflGI8Uk+GWAwMB4OlpU4bMJEAT5d/llQwtYKoim4bLOyLCuWFAhWEupE0vkIFqtw/WIsPug== 673 | dependencies: 674 | cli-truncate "^3.1.0" 675 | colorette "^2.0.17" 676 | commander "^9.3.0" 677 | debug "^4.3.4" 678 | execa "^6.1.0" 679 | lilconfig "2.0.5" 680 | listr2 "^4.0.5" 681 | micromatch "^4.0.5" 682 | normalize-path "^3.0.0" 683 | object-inspect "^1.12.2" 684 | pidtree "^0.6.0" 685 | string-argv "^0.3.1" 686 | yaml "^2.1.1" 687 | 688 | listr2@^4.0.5: 689 | version "4.0.5" 690 | resolved "https://registry.yarnpkg.com/listr2/-/listr2-4.0.5.tgz#9dcc50221583e8b4c71c43f9c7dfd0ef546b75d5" 691 | integrity sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA== 692 | dependencies: 693 | cli-truncate "^2.1.0" 694 | colorette "^2.0.16" 695 | log-update "^4.0.0" 696 | p-map "^4.0.0" 697 | rfdc "^1.3.0" 698 | rxjs "^7.5.5" 699 | through "^2.3.8" 700 | wrap-ansi "^7.0.0" 701 | 702 | load-tsconfig@^0.2.0: 703 | version "0.2.3" 704 | resolved "https://registry.yarnpkg.com/load-tsconfig/-/load-tsconfig-0.2.3.tgz#08af3e7744943caab0c75f8af7f1703639c3ef1f" 705 | integrity sha512-iyT2MXws+dc2Wi6o3grCFtGXpeMvHmJqS27sMPGtV2eUu4PeFnG+33I8BlFK1t1NWMjOpcx9bridn5yxLDX2gQ== 706 | 707 | lodash.sortby@^4.7.0: 708 | version "4.7.0" 709 | resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" 710 | integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== 711 | 712 | log-update@^4.0.0: 713 | version "4.0.0" 714 | resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" 715 | integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== 716 | dependencies: 717 | ansi-escapes "^4.3.0" 718 | cli-cursor "^3.1.0" 719 | slice-ansi "^4.0.0" 720 | wrap-ansi "^6.2.0" 721 | 722 | make-error@^1.1.1: 723 | version "1.3.6" 724 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" 725 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 726 | 727 | merge-stream@^2.0.0: 728 | version "2.0.0" 729 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" 730 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 731 | 732 | merge2@^1.3.0, merge2@^1.4.1: 733 | version "1.4.1" 734 | resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" 735 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 736 | 737 | micromatch@^4.0.4, micromatch@^4.0.5: 738 | version "4.0.5" 739 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" 740 | integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== 741 | dependencies: 742 | braces "^3.0.2" 743 | picomatch "^2.3.1" 744 | 745 | mimic-fn@^2.1.0: 746 | version "2.1.0" 747 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" 748 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 749 | 750 | mimic-fn@^4.0.0: 751 | version "4.0.0" 752 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" 753 | integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== 754 | 755 | minimatch@^3.0.4: 756 | version "3.1.2" 757 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 758 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 759 | dependencies: 760 | brace-expansion "^1.1.7" 761 | 762 | ms@2.1.2: 763 | version "2.1.2" 764 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 765 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 766 | 767 | mz@^2.7.0: 768 | version "2.7.0" 769 | resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" 770 | integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== 771 | dependencies: 772 | any-promise "^1.0.0" 773 | object-assign "^4.0.1" 774 | thenify-all "^1.0.0" 775 | 776 | normalize-path@^3.0.0, normalize-path@~3.0.0: 777 | version "3.0.0" 778 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 779 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 780 | 781 | npm-run-path@^4.0.1: 782 | version "4.0.1" 783 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" 784 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== 785 | dependencies: 786 | path-key "^3.0.0" 787 | 788 | npm-run-path@^5.1.0: 789 | version "5.1.0" 790 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" 791 | integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== 792 | dependencies: 793 | path-key "^4.0.0" 794 | 795 | object-assign@^4.0.1: 796 | version "4.1.1" 797 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 798 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 799 | 800 | object-inspect@^1.12.2: 801 | version "1.12.2" 802 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" 803 | integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== 804 | 805 | once@^1.3.0: 806 | version "1.4.0" 807 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 808 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 809 | dependencies: 810 | wrappy "1" 811 | 812 | onetime@^5.1.0, onetime@^5.1.2: 813 | version "5.1.2" 814 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" 815 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 816 | dependencies: 817 | mimic-fn "^2.1.0" 818 | 819 | onetime@^6.0.0: 820 | version "6.0.0" 821 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" 822 | integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== 823 | dependencies: 824 | mimic-fn "^4.0.0" 825 | 826 | p-map@^4.0.0: 827 | version "4.0.0" 828 | resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" 829 | integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== 830 | dependencies: 831 | aggregate-error "^3.0.0" 832 | 833 | path-is-absolute@^1.0.0: 834 | version "1.0.1" 835 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 836 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 837 | 838 | path-key@^3.0.0, path-key@^3.1.0: 839 | version "3.1.1" 840 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 841 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 842 | 843 | path-key@^4.0.0: 844 | version "4.0.0" 845 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" 846 | integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== 847 | 848 | path-type@^4.0.0: 849 | version "4.0.0" 850 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" 851 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 852 | 853 | picocolors@^1.0.0: 854 | version "1.0.0" 855 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" 856 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== 857 | 858 | picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: 859 | version "2.3.1" 860 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 861 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 862 | 863 | pidtree@^0.6.0: 864 | version "0.6.0" 865 | resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" 866 | integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== 867 | 868 | pirates@^4.0.1: 869 | version "4.0.5" 870 | resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" 871 | integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== 872 | 873 | postcss-load-config@^3.0.1: 874 | version "3.1.4" 875 | resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855" 876 | integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== 877 | dependencies: 878 | lilconfig "^2.0.5" 879 | yaml "^1.10.2" 880 | 881 | prettier@^2.7.1: 882 | version "2.7.1" 883 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" 884 | integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== 885 | 886 | punycode@^2.1.0: 887 | version "2.1.1" 888 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 889 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 890 | 891 | queue-microtask@^1.2.2: 892 | version "1.2.3" 893 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" 894 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 895 | 896 | readdirp@~3.6.0: 897 | version "3.6.0" 898 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 899 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 900 | dependencies: 901 | picomatch "^2.2.1" 902 | 903 | resolve-from@^5.0.0: 904 | version "5.0.0" 905 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" 906 | integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== 907 | 908 | restore-cursor@^3.1.0: 909 | version "3.1.0" 910 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" 911 | integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== 912 | dependencies: 913 | onetime "^5.1.0" 914 | signal-exit "^3.0.2" 915 | 916 | reusify@^1.0.4: 917 | version "1.0.4" 918 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 919 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 920 | 921 | rfdc@^1.3.0: 922 | version "1.3.0" 923 | resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" 924 | integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== 925 | 926 | rollup@^2.74.1: 927 | version "2.79.1" 928 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" 929 | integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== 930 | optionalDependencies: 931 | fsevents "~2.3.2" 932 | 933 | run-parallel@^1.1.9: 934 | version "1.2.0" 935 | resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" 936 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 937 | dependencies: 938 | queue-microtask "^1.2.2" 939 | 940 | rxjs@^7.5.5: 941 | version "7.5.7" 942 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39" 943 | integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA== 944 | dependencies: 945 | tslib "^2.1.0" 946 | 947 | shebang-command@^2.0.0: 948 | version "2.0.0" 949 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 950 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 951 | dependencies: 952 | shebang-regex "^3.0.0" 953 | 954 | shebang-regex@^3.0.0: 955 | version "3.0.0" 956 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 957 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 958 | 959 | signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: 960 | version "3.0.7" 961 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 962 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 963 | 964 | slash@^3.0.0: 965 | version "3.0.0" 966 | resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" 967 | integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== 968 | 969 | slice-ansi@^3.0.0: 970 | version "3.0.0" 971 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" 972 | integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== 973 | dependencies: 974 | ansi-styles "^4.0.0" 975 | astral-regex "^2.0.0" 976 | is-fullwidth-code-point "^3.0.0" 977 | 978 | slice-ansi@^4.0.0: 979 | version "4.0.0" 980 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" 981 | integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== 982 | dependencies: 983 | ansi-styles "^4.0.0" 984 | astral-regex "^2.0.0" 985 | is-fullwidth-code-point "^3.0.0" 986 | 987 | slice-ansi@^5.0.0: 988 | version "5.0.0" 989 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" 990 | integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== 991 | dependencies: 992 | ansi-styles "^6.0.0" 993 | is-fullwidth-code-point "^4.0.0" 994 | 995 | source-map@0.8.0-beta.0: 996 | version "0.8.0-beta.0" 997 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" 998 | integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== 999 | dependencies: 1000 | whatwg-url "^7.0.0" 1001 | 1002 | string-argv@^0.3.1: 1003 | version "0.3.1" 1004 | resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" 1005 | integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== 1006 | 1007 | string-width@^4.1.0, string-width@^4.2.0: 1008 | version "4.2.3" 1009 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1010 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1011 | dependencies: 1012 | emoji-regex "^8.0.0" 1013 | is-fullwidth-code-point "^3.0.0" 1014 | strip-ansi "^6.0.1" 1015 | 1016 | string-width@^5.0.0: 1017 | version "5.1.2" 1018 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" 1019 | integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== 1020 | dependencies: 1021 | eastasianwidth "^0.2.0" 1022 | emoji-regex "^9.2.2" 1023 | strip-ansi "^7.0.1" 1024 | 1025 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1026 | version "6.0.1" 1027 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1028 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1029 | dependencies: 1030 | ansi-regex "^5.0.1" 1031 | 1032 | strip-ansi@^7.0.1: 1033 | version "7.0.1" 1034 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" 1035 | integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== 1036 | dependencies: 1037 | ansi-regex "^6.0.1" 1038 | 1039 | strip-final-newline@^2.0.0: 1040 | version "2.0.0" 1041 | resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" 1042 | integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== 1043 | 1044 | strip-final-newline@^3.0.0: 1045 | version "3.0.0" 1046 | resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" 1047 | integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== 1048 | 1049 | sucrase@^3.20.3: 1050 | version "3.27.0" 1051 | resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.27.0.tgz#32b8e8735ae0e78c6e1e917d2dd61ecad69e5604" 1052 | integrity sha512-IjpEeFzOWCGrB/e2DnPawkFajW6ONFFgs+lQT1+Ts5Z5ZM9gPnxpDh0q8tu7HVLt6IfRiUTbSsjfhqjHOP/cwQ== 1053 | dependencies: 1054 | commander "^4.0.0" 1055 | glob "7.1.6" 1056 | lines-and-columns "^1.1.6" 1057 | mz "^2.7.0" 1058 | pirates "^4.0.1" 1059 | ts-interface-checker "^0.1.9" 1060 | 1061 | sweet-event-emitter@^0.1.0: 1062 | version "0.1.0" 1063 | resolved "https://registry.yarnpkg.com/sweet-event-emitter/-/sweet-event-emitter-0.1.0.tgz#a9f1a192907961a1077c8f9eb045b43d7b28f981" 1064 | integrity sha512-NroPqoihsibcIGPnOlVFdda14F+CFxA1SoC67RvGBhpx915srdyJpsTT8dQP7rqqkjm7SlRs5uvWIiLZx397cA== 1065 | 1066 | thenify-all@^1.0.0: 1067 | version "1.6.0" 1068 | resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" 1069 | integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== 1070 | dependencies: 1071 | thenify ">= 3.1.0 < 4" 1072 | 1073 | "thenify@>= 3.1.0 < 4": 1074 | version "3.3.1" 1075 | resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" 1076 | integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== 1077 | dependencies: 1078 | any-promise "^1.0.0" 1079 | 1080 | through@^2.3.8: 1081 | version "2.3.8" 1082 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1083 | integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== 1084 | 1085 | to-regex-range@^5.0.1: 1086 | version "5.0.1" 1087 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1088 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1089 | dependencies: 1090 | is-number "^7.0.0" 1091 | 1092 | tr46@^1.0.1: 1093 | version "1.0.1" 1094 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" 1095 | integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== 1096 | dependencies: 1097 | punycode "^2.1.0" 1098 | 1099 | tree-kill@^1.2.2: 1100 | version "1.2.2" 1101 | resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" 1102 | integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== 1103 | 1104 | ts-interface-checker@^0.1.9: 1105 | version "0.1.13" 1106 | resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" 1107 | integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== 1108 | 1109 | ts-node@^10.9.1: 1110 | version "10.9.1" 1111 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" 1112 | integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== 1113 | dependencies: 1114 | "@cspotcode/source-map-support" "^0.8.0" 1115 | "@tsconfig/node10" "^1.0.7" 1116 | "@tsconfig/node12" "^1.0.7" 1117 | "@tsconfig/node14" "^1.0.0" 1118 | "@tsconfig/node16" "^1.0.2" 1119 | acorn "^8.4.1" 1120 | acorn-walk "^8.1.1" 1121 | arg "^4.1.0" 1122 | create-require "^1.1.0" 1123 | diff "^4.0.1" 1124 | make-error "^1.1.1" 1125 | v8-compile-cache-lib "^3.0.1" 1126 | yn "3.1.1" 1127 | 1128 | tslib@^2.1.0: 1129 | version "2.4.0" 1130 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" 1131 | integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== 1132 | 1133 | tsup@^6.2.3: 1134 | version "6.2.3" 1135 | resolved "https://registry.yarnpkg.com/tsup/-/tsup-6.2.3.tgz#87f57b2e53d49f1c1ab89aba21fed96aaab0ec9f" 1136 | integrity sha512-J5Pu2Dx0E1wlpIEsVFv9ryzP1pZ1OYsJ2cBHZ7GrKteytNdzaSz5hmLX7/nAxtypq+jVkVvA79d7S83ETgHQ5w== 1137 | dependencies: 1138 | bundle-require "^3.1.0" 1139 | cac "^6.7.12" 1140 | chokidar "^3.5.1" 1141 | debug "^4.3.1" 1142 | esbuild "^0.15.1" 1143 | execa "^5.0.0" 1144 | globby "^11.0.3" 1145 | joycon "^3.0.1" 1146 | postcss-load-config "^3.0.1" 1147 | resolve-from "^5.0.0" 1148 | rollup "^2.74.1" 1149 | source-map "0.8.0-beta.0" 1150 | sucrase "^3.20.3" 1151 | tree-kill "^1.2.2" 1152 | 1153 | type-fest@^0.21.3: 1154 | version "0.21.3" 1155 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" 1156 | integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== 1157 | 1158 | typescript@^4.8.4: 1159 | version "4.8.4" 1160 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" 1161 | integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== 1162 | 1163 | v8-compile-cache-lib@^3.0.1: 1164 | version "3.0.1" 1165 | resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" 1166 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== 1167 | 1168 | webidl-conversions@^4.0.2: 1169 | version "4.0.2" 1170 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" 1171 | integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== 1172 | 1173 | whatwg-url@^7.0.0: 1174 | version "7.1.0" 1175 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" 1176 | integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== 1177 | dependencies: 1178 | lodash.sortby "^4.7.0" 1179 | tr46 "^1.0.1" 1180 | webidl-conversions "^4.0.2" 1181 | 1182 | which@^2.0.1: 1183 | version "2.0.2" 1184 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1185 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1186 | dependencies: 1187 | isexe "^2.0.0" 1188 | 1189 | wrap-ansi@^6.2.0: 1190 | version "6.2.0" 1191 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" 1192 | integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== 1193 | dependencies: 1194 | ansi-styles "^4.0.0" 1195 | string-width "^4.1.0" 1196 | strip-ansi "^6.0.0" 1197 | 1198 | wrap-ansi@^7.0.0: 1199 | version "7.0.0" 1200 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1201 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1202 | dependencies: 1203 | ansi-styles "^4.0.0" 1204 | string-width "^4.1.0" 1205 | strip-ansi "^6.0.0" 1206 | 1207 | wrappy@1: 1208 | version "1.0.2" 1209 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1210 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1211 | 1212 | yaml@^1.10.2: 1213 | version "1.10.2" 1214 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" 1215 | integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== 1216 | 1217 | yaml@^2.1.1: 1218 | version "2.1.1" 1219 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.1.tgz#1e06fb4ca46e60d9da07e4f786ea370ed3c3cfec" 1220 | integrity sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw== 1221 | 1222 | yn@3.1.1: 1223 | version "3.1.1" 1224 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" 1225 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 1226 | --------------------------------------------------------------------------------