├── .github
└── CONTRIBUTING.md
├── .gitignore
├── .prettierignore
├── .prettierrc
├── LICENSE.md
├── Readme.md
├── docs
├── .nojekyll
├── README.md
├── _404.md
├── _coverpage.md
├── _media
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── apple-touch-icon.png
│ ├── browserconfig.xml
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── logo.png
│ ├── logo.svg
│ ├── mstile-144x144.png
│ ├── mstile-150x150.png
│ ├── mstile-310x150.png
│ ├── mstile-310x310.png
│ ├── mstile-70x70.png
│ ├── safari-pinned-tab.svg
│ └── site.webmanifest
├── favicon.ico
└── index.html
├── examples
├── basic
│ ├── .cargo-ok
│ ├── .prettierrc
│ ├── LICENSE.md
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── webpack.config.js
│ ├── wrangler.toml
│ └── yarn.lock
├── domain-routing
│ ├── .cargo-ok
│ ├── .gitignore
│ ├── .prettierrc
│ ├── LICENSE.md
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── webpack.config.js
│ ├── wrangler.toml
│ └── yarn.lock
└── hello-world
│ ├── .cargo-ok
│ ├── .gitignore
│ ├── .prettierrc
│ ├── LICENSE.md
│ ├── README.md
│ ├── package.json
│ ├── src
│ └── index.ts
│ ├── tsconfig.json
│ ├── webpack.config.js
│ ├── wrangler.toml
│ └── yarn.lock
├── package.json
├── rollup.config.js
├── src
├── context.ts
├── default.ts
├── global.d.ts
├── index.ts
├── middlewares
│ ├── cors.ts
│ └── static.ts
├── request.ts
├── response.ts
├── router.ts
├── types.ts
└── vhost
│ └── index.ts
├── tsconfig.json
├── workers
├── .cargo-ok
├── .gitignore
├── index.js
├── package.json
└── yarn.lock
├── wrangler.toml
└── yarn.lock
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change.
4 |
5 | Please note we have a code of conduct, please follow it in all your interactions with the project.
6 |
7 | ## Pull Request Process
8 |
9 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a build.
10 | 2. Update the README.md with details of changes to the interface, this includes new environment variables, exposed ports, useful file locations and container parameters.
11 | 3. Increase the version numbers in any examples files and the README.md to the new version that this Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
12 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you do not have permission to do that, you may request the second reviewer to merge it for you.
13 |
14 | ## Code of Conduct
15 |
16 | ### Our Pledge
17 |
18 | In the interest of fostering an open and welcoming environment, we as
19 | contributors and maintainers pledge to making participation in our project and
20 | our community a harassment-free experience for everyone, regardless of age, body
21 | size, disability, ethnicity, gender identity and expression, level of experience,
22 | nationality, personal appearance, race, religion, or sexual identity and
23 | orientation.
24 |
25 | ### Our Standards
26 |
27 | Examples of behavior that contributes to creating a positive environment
28 | include:
29 |
30 | - Using welcoming and inclusive language
31 | - Being respectful of differing viewpoints and experiences
32 | - Gracefully accepting constructive criticism
33 | - Focusing on what is best for the community
34 | - Showing empathy towards other community members
35 |
36 | Examples of unacceptable behavior by participants include:
37 |
38 | - The use of sexualized language or imagery and unwelcome sexual attention or
39 | advances
40 | - Trolling, insulting/derogatory comments, and personal or political attacks
41 | - Public or private harassment
42 | - Publishing others' private information, such as a physical or electronic
43 | address, without explicit permission
44 | - Other conduct which could reasonably be considered inappropriate in a
45 | professional setting
46 |
47 | ### Our Responsibilities
48 |
49 | Project maintainers are responsible for clarifying the standards of acceptable
50 | behavior and are expected to take appropriate and fair corrective action in
51 | response to any instances of unacceptable behavior.
52 |
53 | Project maintainers have the right and responsibility to remove, edit, or
54 | reject comments, commits, code, wiki edits, issues, and other contributions
55 | that are not aligned to this Code of Conduct, or to ban temporarily or
56 | permanently any contributor for other behaviors that they deem inappropriate,
57 | threatening, offensive, or harmful.
58 |
59 | ### Scope
60 |
61 | This Code of Conduct applies both within project spaces and in public spaces
62 | when an individual is representing the project or its community. Examples of
63 | representing a project or community include using an official project e-mail
64 | address, posting via an official social media account, or acting as an appointed
65 | representative at an online or offline event. Representation of a project may be
66 | further defined and clarified by project maintainers.
67 |
68 | ### Enforcement
69 |
70 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
71 | reported by contacting the project team at [dev@edgehub.in](mailto:dev@edgehub.in). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is
72 | obligated to maintain confidentiality with regard to the reporter of an incident.
73 | Further details of specific enforcement policies may be posted separately.
74 |
75 | Project maintainers who do not follow or enforce the Code of Conduct in good
76 | faith may face temporary or permanent repercussions as determined by other
77 | members of the project's leadership.
78 |
79 | ### Attribution
80 |
81 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
82 |
83 | [homepage]: http://contributor-covenant.org
84 | [version]: http://contributor-covenant.org/version/1/4/
85 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # Snowpack dependency directory (https://snowpack.dev/)
45 | web_modules/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 | .parcel-cache
78 |
79 | # Next.js build output
80 | .next
81 |
82 | # Nuxt.js build / generate output
83 | .nuxt
84 | dist
85 |
86 | # Gatsby files
87 | .cache/
88 | # Comment in the public line in if your project uses Gatsby and not Next.js
89 | # https://nextjs.org/blog/next-9-1#public-directory-support
90 | # public
91 |
92 | # vuepress build output
93 | .vuepress/dist
94 |
95 | # Serverless directories
96 | .serverless/
97 |
98 | # FuseBox cache
99 | .fusebox/
100 |
101 | # DynamoDB Local files
102 | .dynamodb/
103 |
104 | # TernJS port file
105 | .tern-port
106 |
107 | # Stores VSCode versions used for testing VSCode extensions
108 | .vscode-test
109 |
110 | # yarn v2
111 |
112 | .yarn/cache
113 | .yarn/unplugged
114 | .yarn/build-state.yml
115 | .pnp.*
116 |
117 | # microbundle
118 | .rts*
119 | .DS_Store
120 | docs/_lib/
121 | worker/
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist/
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": true,
6 | "singleQuote": false,
7 | "trailingComma": "es5",
8 | "bracketSpacing": true,
9 | "jsxBracketSameLine": false,
10 | "arrowParens": "always",
11 | "rangeStart": 0
12 | }
13 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright (c) 2020, Vinay Puppal.
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
13 | all 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
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | > Still in development and not production ready
2 |
3 | # EdgeRouter
4 |
5 | A minimal Express.js like router for cloudflare workers.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | ## Documentation
20 |
21 | Visit https://router.edgehub.in to view the documentation.
22 |
23 | ## Todo
24 |
25 | - [ ] Tests
26 | - [ ] Preview examples and library with `https://cloudflareworkers.com/`
27 |
28 | ## Contributing
29 |
30 | Please see our [contributing.md](/.github/CONTRIBUTING.md).
31 |
32 | ## Authors
33 |
34 | - [VinayPuppal](https://vinaypuppal.com)
35 |
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/.nojekyll
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ## ✨ Features
2 |
3 | - Based on [trouter](https://github.com/lukeed/trouter)
4 | - Express style routes.
5 | - Helper functions
6 | - Read requests: Built-in body-parser, cookie-parser, and a query string-parser.
7 | - To modify headers and
8 | - Send a response.
9 | - Middleware support.
10 | - CORS Middleware
11 | - Workers site Middleware
12 | - Domain routing.
13 |
14 | ## 🔋 Install
15 |
16 | With Yarn
17 |
18 | ```bash
19 | yarn add @edgehub/router
20 | ```
21 |
22 | With NPM
23 |
24 | ```bash
25 | npm install @edgehub/router
26 | ```
27 |
28 | ## 💻 Hello world example
29 |
30 | You can try this example with [wrangler](https://github.com/cloudflare/wrangler) by running this command
31 |
32 | ```bash
33 | wrangler generate myapp https://github.com/edge-hub/router/tree/master/examples/hello-world
34 | ```
35 |
36 | ```js
37 | import { EdgeRouter } from "@edgehub/router";
38 |
39 | const worker = new EdgeRouter();
40 |
41 | // Middleware to set a header for all routes
42 | worker.use((req, res) => {
43 | res.setHeader("x-router", "EdgeRouter");
44 | });
45 |
46 | // The worker responds with `Hello World` for requests to root URL(/). For every other path, it will fallback to origin response if its exists or error.
47 | worker.get("/", (req, res) => {
48 | return res.send(`Hello World`);
49 | });
50 |
51 | worker.listen({ passThroughOnException: true });
52 | ```
53 |
54 | > You can find more examples [here](https://github.com/edge-hub/router/tree/master/examples/)
55 |
56 | ## 🥳 Basic Routing
57 |
58 | Routing refers to determining how a worker responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on).
59 |
60 | Each route can have one or more handler functions, which are executed when the route is matched.
61 |
62 | Route definition takes the following structure:
63 |
64 | ```js
65 | worker.METHOD(PATTERN, HANDLER);
66 | ```
67 |
68 | Where:
69 |
70 | - `worker` is an instance of EdgeRouter
71 | - `METHOD` is one of the HTTP methods in lowercase. For a full list of valid METHODs, please see [this list](https://github.com/lukeed/trouter#method)
72 | - `PATTERN` is a routing pattern (pathname) which is `string`. The supported pattern types are:
73 | - static (`/posts`)
74 | - named parameters (`/posts/:id`)
75 | - nested parameters (`/posts/:id/users/:id`)
76 | - optional parameters (`/users/:id?/books/:title?`)
77 | - any match / wildcards (`/users/*`)
78 | - `HANDLER` is the function executed when the route is matched.
79 | - Every route definition must contain a valid handler function, or else an error will be thrown at runtime.
80 | - It accepts a two arguments **[req](#📨-request)** and **[res](#📣-response)**
81 |
82 | ## 👀 API
83 |
84 | EdgeRouter extends [Trouter](https://github.com/lukeed/trouter) which means it inherits its API
85 |
86 | ### ✏️ Options
87 |
88 | ```js
89 | import { EdgeRouter } from "@edgehub/router";
90 |
91 | const worker = new EdgeRouter(options);
92 | ```
93 |
94 | > All options are optional which means you need to specify them if you want to change the default behavior.
95 |
96 | The following table describes the properties of the optional options object.
97 |
98 | | Property | Description | Type | Default |
99 | | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------- |
100 | | onNoMatch | A handler to be executed when no route is matched. | Function | undefined |
101 | | onError | A catch-all error handler; executed whenever a middleware throws an error. | Function | undefined |
102 | | onBeforeResponse | A handler which executes right before sending a response from a route handler.**If this handler returns a Response object then normal route processing will stop and the response will be sent out.** | Function | undefined |
103 |
104 | > The signature of these handlers is same as the route handlers which you saw in [Basic Routing](#🥳-basic-routing)
105 |
106 | ### ☁️ Instance
107 |
108 | The `worker` object conventionally denotes the Cloudflare worker. Create it by calling the `new EdgeRouter()` class exported by the `@edgehub/router` module:
109 |
110 | ```js
111 | import { EdgeRouter } from "@edgehub/router";
112 |
113 | const worker = new EdgeRouter();
114 |
115 | // The worker responds with `Hello World` for requests to root URL(/). For every other path, it will fallback to origin response if its exists or error.
116 | worker.get("/", (req, res) => {
117 | return res.send(`Hello World`);
118 | });
119 |
120 | worker.listen({ passThroughOnException: true });
121 | ```
122 |
123 | The `worker` object has methods for
124 |
125 | - Routing HTTP requests; see for example, [worker.METHOD()](#workermethod)
126 | - Configuring middleware; see [worker.use()](#workeruse)
127 | - Listening for incoming requests; see [worker.listen()](#workerlisten)
128 |
129 | #### worker.METHOD()
130 |
131 | Routes an HTTP request, where METHOD is the HTTP method of the request, such as GET, PUT, POST, and so on, in lowercase.
132 |
133 | See [Basic Routing Section](#🥳-basic-routing) for more info.
134 |
135 | #### worker.use()
136 |
137 | Mounts the specified middleware function or functions at the specified path or for all routes.
138 | _The middleware function is executed when the base of the requested path matches path or for every request in case of global middleware_.
139 |
140 | See [Middlewares Section](#middlewares) for more info.
141 |
142 | #### worker.listen()
143 |
144 | It defines the `fetch` event listener to listen for incoming requests.
145 |
146 | Example:
147 |
148 | ```js
149 | worker.listen({ passThroughOnException: true });
150 | ```
151 |
152 | Options:
153 |
154 | | Property | Description | Type | Default |
155 | | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------- |
156 | | passThroughOnException | Cause the script to "fail open" unhandled exceptions. Instead of returning a runtime error response, the runtime proxies the request to its destination. To prevent JavaScript errors from causing entire requests to fail on uncaught exceptions, passThroughOnException causes the Worker script to act as if the exception wasn’t there. This allows the script to yield control to your origin server. | boolean | false |
157 |
158 | #### Custom listener
159 |
160 | You can set up a custom listener as shown below
161 |
162 | ```js
163 | import { EdgeRouter } from "@edgehub/router";
164 |
165 | const worker = new EdgeRouter();
166 |
167 | worker.get("/", async (req, res) => {
168 | return res.send({ hello: "world" });
169 | });
170 |
171 | addEventListener("fetch", (event) => {
172 | event.respondWith(worker.onRequest(event));
173 | });
174 | ```
175 |
176 | ### 📨 Request
177 |
178 | The req object has properties for the request query string, parameters, body, HTTP headers, original _Fetch Request_, _FetchEvent_ and so on. In this documentation and by convention, the object is always referred to as req (and the response is res) but its actual name is determined by the parameters to the callback function in which you’re working.
179 |
180 | #### req.query
181 |
182 | This property is an object containing a property for each query string parameter in the route.
183 | It can be:
184 |
185 | - This object defaults to {}
186 | - Each property inside the query object can be either `string` or `array` as shown below
187 |
188 | ```js
189 | // GET /posts?limit=10
190 | console.log(req.query.limit);
191 | // => "10"
192 |
193 | // GET /search?tags=javascript&tags=react
194 | console.log(req.query.tags);
195 | // => ["javascript", "react"]
196 | ```
197 |
198 | #### req.params
199 |
200 | This property is an object containing properties mapped to the named route “parameters”. For example, if you have the route `/posts/:id`, then the “name” property is available as `req.params.id`. This object defaults to `{}`.
201 |
202 | ```js
203 | // GET /posts/123456
204 | console.log(req.params.id);
205 | // => "123456"
206 | ```
207 |
208 | #### req.url
209 |
210 | This property contains the original request URL as shown below.
211 |
212 | ```js
213 | // If request comes for https://edgehub.in/posts/123456
214 | worker.get("/posts/:id", (req, res) => {
215 | console.log(req.url);
216 | });
217 | // => https://edgehub.in/posts/123456
218 | ```
219 |
220 | #### req.host
221 |
222 | This property contains `host` parsed from the original request URL as shown below.
223 |
224 | ```js
225 | // If request comes for https://edgehub.in/posts/123456
226 | worker.get("/posts/:id", (req, res) => {
227 | console.log(req.url);
228 | });
229 | // => edgehub.in
230 | ```
231 |
232 | #### req.pathname
233 |
234 | This property contains `path` parsed from the original request URL as shown below.
235 |
236 | ```js
237 | // If request comes for https://edgehub.in/posts/123456
238 | worker.get("/posts/:id", (req, res) => {
239 | console.log(req.url);
240 | });
241 | // => /posts/123456
242 | ```
243 |
244 | #### req.protocol
245 |
246 | This property contains `protocol` parsed from the original request URL as shown below.
247 |
248 | ```js
249 | // If request comes for https://edgehub.in/posts/123456
250 | worker.get("/posts/:id", (req, res) => {
251 | console.log(req.url);
252 | });
253 | // => https:
254 | ```
255 |
256 | #### req.method
257 |
258 | This property contains a string corresponding to the HTTP method of the request: GET, POST, PUT, and so on.
259 |
260 | #### req.search
261 |
262 | This property contains the unparsed query string parameter in the route.
263 |
264 | ```js
265 | // GET /posts?limit=10
266 | console.log(req.query.limit);
267 | // => "?limit=10"
268 | ```
269 |
270 | #### req.querystring
271 |
272 | This property is same as [req.search](#req.search) but without the leading `?`.
273 |
274 | ```js
275 | // GET /posts?limit=10
276 | console.log(req.query.limit);
277 | // => "limit=10"
278 | ```
279 |
280 | #### req.cookies
281 |
282 | EdgeRouter includes built-in cookie parser and this property is an object that contains cookies sent by the request. If the request contains no cookies, it defaults to {}.
283 |
284 | ```js
285 | // Cookie: token=skenfklwnefklwnfkwnefklmwekldm
286 | console.log(req.cookies.token);
287 | // => // "skenfklwnefklwnfkwnefklmwekldm"
288 | ```
289 |
290 | #### req.headers
291 |
292 | This object conatains the request header list. You can use
293 |
294 | - `get()` to get a header by name and
295 | - `has()` to check if a header exists
296 |
297 | ```js
298 | console.log(req.headers.has("content-type"));
299 | // => true
300 |
301 | console.log(req.headers.get("content-type"));
302 | // => "application/json"
303 | ```
304 |
305 | #### req.header()
306 |
307 | Returns the specified HTTP request header field (case-insensitive match).
308 |
309 | ```js
310 | req.header("content-type");
311 | // => "text/plain"
312 |
313 | req.header("Content-Type");
314 | // => "text/plain"
315 | ```
316 |
317 | #### req.body()
318 |
319 | Returns an object which contains key-value pairs of data submitted in the request body.
320 |
321 | > It's a `async` function so you need to use `await` to get the data back when called.
322 |
323 | ```js
324 | // A post request sending this JSON data "{"name": "EdgeRouter"}"
325 | worker.post("/user", async (req, res) => {
326 | const data = await req.body();
327 | console.log(data);
328 | });
329 | // => { name: "EdgeRouter" }
330 | ```
331 |
332 | #### req.\_originalRequest
333 |
334 | This property contains original fetch request recieved by the Coudflare Worker. You can read about available properties and methods on this object [here](https://developers.cloudflare.com/workers/reference/apis/request/)
335 |
336 | #### req.\_event
337 |
338 | This property contains original fetchEvent recieved by the Coudflare Worker. You can read about available properties and methods on this object [here](https://developers.cloudflare.com/workers/reference/apis/fetch-event/)
339 |
340 | ### 📣 Response
341 |
342 | The res object is used to create a response that a worker sends when it gets an HTTP request. In this documentation and by convention, the object is always referred to as res (and the request is req) but its actual name is determined by the parameters to the callback function in which you’re working.
343 |
344 | #### res.setHeader()
345 |
346 | Sets the response’s HTTP header field to value.
347 |
348 | ```js
349 | res.setHeader(field [, value])
350 | ```
351 |
352 | #### res.setCookie()
353 |
354 | Sets cookie name to value. The value parameter may be a string or object converted to JSON.
355 |
356 | ```js
357 | res.cookie(name, value [, options])
358 | ```
359 |
360 | > The options parameter is an object that can have the properties mentioned [here](https://github.com/jshttp/cookie#options-1).
361 |
362 | #### res.status()
363 |
364 | Sets the HTTP status for the response. It is a chainable as shown below
365 |
366 | ```js
367 | res.status(400).send("Bad Request");
368 | ```
369 |
370 | #### res.sendStatus()
371 |
372 | Sets the response HTTP status code to statusCode and creates its string representation as the response body.
373 |
374 | !> `res.sendStatus` only creates the Response and it does not really send it. Inorder to send it you need to return the response generated from your route handler.
375 |
376 | ```js
377 | import { EdgeRouter } from "@edgehub/router";
378 |
379 | const worker = new EdgeRouter();
380 |
381 | worker.get("/", async (req, res) => {
382 | return res.sendStatus(200);
383 | });
384 |
385 | worker.listen({ passThroughOnException: true });
386 | ```
387 |
388 | #### res.send()
389 |
390 | Creates the HTTP response. It takes `body` as argument.
391 |
392 | - The `body` parameter can be a String, a Number, a Boolean, an object, or an Array.
393 | - When the `body` is an object or array the response is sent with content-type `application/json`
394 | - For rest of the types it's sent with content-type `text/html`
395 |
396 | For example:
397 |
398 | ```js
399 | res.send({ some: "json" });
400 | res.send("some html
");
401 | res.status(404).send("Sorry, we cannot find that!");
402 | res.status(500).send({ error: "something blew up" });
403 | ```
404 |
405 | !> `res.send` only creates the Response and it does not really send it. Inorder to send it you need to return the response generated from your route handler.
406 |
407 | ```js
408 | import { EdgeRouter } from "@edgehub/router";
409 |
410 | const worker = new EdgeRouter();
411 |
412 | worker.get("/", async (req, res) => {
413 | return res.send({ hello: "world" });
414 | });
415 |
416 | worker.listen({ passThroughOnException: true });
417 | ```
418 |
419 | #### res.redirect()
420 |
421 | Redirects to the specified URL and status, a positive integer that corresponds to an HTTP status code . If not specified, status defaults to “302 “Found”.
422 |
423 | It takes `url` and `status` as arguments
424 |
425 | ```js
426 | // Default status code 302
427 | res.redirect("http://google.com");
428 |
429 | // With status code 301
430 | res.redirect("http://google.com", 301);
431 | ```
432 |
433 | ### 🧚 Middlewares
434 |
435 | Middleware are functions that run in between (hence "middle") receiving the request & executing your route's handler response.
436 |
437 | #### Middleware Sequence
438 |
439 | ```js
440 | worker.use([path], [function, ...] function)
441 | ```
442 |
443 | - Global middleware are defined via `worker.use('/', ...fn)` or `worker.use(...fn)`, which are synonymous. Because every request's pathname begins with a `/`, this tier is always triggered.
444 | - Sub-group or "filtered" middleware are defined with a base pathname that's more specific than `/`. For example, defining `worker.use('/users', ...fn)` will run on any `/users/**/*` request. These functions will execute after "global" middleware but before the route-specific handler.
445 | - Route handlers match specific paths and execute last in the chain. They must also match the method action.
446 |
447 | !> Most importantly, a middleware must either terminate the response (res.send) by returning it or return **nothing**. When it returns nothing the next route/middleware handler will invoked.
448 |
449 | #### Middleware Example
450 |
451 | ```js
452 | import { EdgeRouter } from "@edgehub/router";
453 |
454 | const worker = new EdgeRouter();
455 |
456 | // simple logger for this router's requests
457 | // all requests to this router will first hit this middleware
458 | worker.use((req, res) => {
459 | console.log(req.method, req.url, req.path);
460 | });
461 |
462 | // Middleware to set a header for all routes
463 | worker.use((req, res) => {
464 | res.setHeader("x-router", "EdgeRouter");
465 | });
466 |
467 | // this will only be invoked if the path starts with /bar from the mount point
468 | worker.use("/bar", (req, res) => {
469 | // ... maybe some additional /bar logging ...
470 | });
471 |
472 | // Authorization middleware
473 | worker.use((req, res) => {
474 | // mutate req; available later
475 | req.token = req.headers.get("authorization");
476 | if (!req.token) {
477 | return res.status(401).send(`No token!`);
478 | }
479 | });
480 |
481 | // The worker responds with `Hello World` for requests to root URL(/). For every other path, it will fallback to origin response if its exists or error.
482 | worker.get("/", (req, res) => {
483 | return res.send(`Hello World`);
484 | });
485 |
486 | worker.listen({ passThroughOnException: true });
487 | ```
488 |
489 | #### Built In Middlewares
490 |
491 | ##### CORS Middleware
492 |
493 | This library comes with a cors middleware, which can be used a shown below
494 |
495 | ```js
496 | import { EdgeRouter } from "@edgehub/router";
497 | import { cors } from "@edgehub/router/middlewares/cors";
498 |
499 | const worker = new EdgeRouter();
500 |
501 | // CORS middleware
502 | worker.use(cors());
503 |
504 | // The worker responds with `Hello World` for requests to root URL(/). For every other path, it will fallback to origin response if its exists or error.
505 | worker.get("/", (req, res) => {
506 | return res.send(`Hello World`);
507 | });
508 |
509 | worker.listen({ passThroughOnException: true });
510 | ```
511 |
512 | Options:
513 |
514 | | Property | Type | Default |
515 | | ---------------- | --------------- | ------------------------------------------------------------------------------------------------------------------- |
516 | | allowMethods | Array | ['POST','GET','PUT','PATCH','DELETE','OPTIONS'] |
517 | | allowHeaders | Array | ['X-Requested-With','Access-Control-Allow-Origin','X-HTTP-Method-Override','Content-Type','Authorization','Accept'] |
518 | | exposeHeaders | Array | [] |
519 | | allowCredentials | Boolean | true |
520 | | origin | String/Function | \* |
521 | | maxAge | Number | 86400 |
522 |
523 | ```js
524 | // CORS middleware with options
525 | worker.use(
526 | cors({
527 | allowMethods: ["PUT", "POST"],
528 | origin: (request) => {
529 | const origin = request.headers.get("Origin");
530 | if (WHITELIST.includes(origin)) {
531 | return true;
532 | }
533 | return false;
534 | },
535 | })
536 | );
537 | ```
538 |
539 | !> Here `request` is original fetch request as mentioned [here](https://developers.cloudflare.com/workers/reference/apis/request/)
540 |
541 | ##### Worker Sites Middleware
542 |
543 | This library also comes with a `workersSite` middleware, which can be used to add support for [workers sites](https://developers.cloudflare.com/workers/sites)
544 |
545 | > Inorder to to use this middleware you need to install this package [@cloudflare/kv-asset-handler](https://github.com/cloudflare/kv-asset-handler) `yarn add @cloudflare/kv-asset-handler`
546 |
547 | ```js
548 | import { EdgeRouter } from "@edgehub/router";
549 | import { workersSite } from "@edgehub/router/middlewares/static";
550 |
551 | const worker = new EdgeRouter();
552 |
553 | // workersSite middleware
554 | worker.use(workersSite());
555 |
556 | // Here you can handle more routes
557 |
558 | worker.listen({ passThroughOnException: true });
559 | ```
560 |
561 | > The options supported by this middleware are same as of [cloudflare/kv-asset-handler](https://github.com/cloudflare/kv-asset-handler). You can find supported **[options here](https://github.com/cloudflare/kv-asset-handler#optional-arguments)**
562 |
563 | ```js
564 | // Example with options
565 | worker.use(
566 | workersSite({
567 | cacheControl: {
568 | browserTTL: null, // do not set cache control ttl on responses
569 | edgeTTL: 2 * 60 * 60 * 24, // 2 days
570 | bypassCache: false, // do not bypass Cloudflare's cache
571 | },
572 | })
573 | );
574 | ```
575 |
576 | ## 🕸️ Domain Routing
577 |
578 | This library exposes `VHostRouter` to support domain routing. CLoudflare workers allows to associate multiple domains/subdomains for a worker script as [mentioned here](https://developers.cloudflare.com/workers/about/routes/)
579 |
580 | So using `VHostRouter` you can define/scope `EdgeRouter` to a particular domain and handler it's requests as shown below.
581 |
582 | ### API
583 |
584 | The `vhost` object conventionally denotes the Virtual Host. Create it by calling the `new VHostRouter()` class exported by the `@edgehub/router` module:
585 |
586 | ```js
587 | import { EdgeRouter } from "@edgehub/router";
588 | import { VHostRouter } from "@edgehub/router/vhost";
589 |
590 | const vhost = new VHostRouter();
591 | const apiRouter = new EdgeRouter();
592 | const cdnRouter = new EdgeRouter();
593 |
594 | // API routes
595 | apiRouter.get("/posts", (req, res) => {
596 | return res.send({ posts: { title: "About EdgeRouter" } });
597 | });
598 |
599 | apiRouter.post("/posts", async (req, res) => {
600 | const data = await req.body();
601 | if (!data) {
602 | return res.send(`Not data from POST req`);
603 | }
604 | // store data in db and send response
605 | return res.send(data);
606 | });
607 |
608 | // CDN routes
609 | cdnRouter.all("*", (req, res) => {
610 | // Fetch image from CDN and modify on the fly to webp or resize ...etc
611 | res.send(`Some image`);
612 | });
613 |
614 | vhost.use("api.example.com", apiRouter);
615 | vhost.use("cdn.example.com", cdnRouter);
616 |
617 | vhost.listen({ passThroughOnException: true });
618 | ```
619 |
620 | The `vhost` object has following methods:
621 |
622 | - Listening for incoming requests `vhost.listen()` and it's simillar to [worker.listen()](#workerlisten)
623 | - Routing requests for a particular domain `vhost.use()`
624 | ```js
625 | vhost.use(DOMAIN_PATTERN, EDGEROUTER_INSTANCE);
626 | ```
627 | - `DOMAIN_PATTERN`: It can be a string or a RegExp object. When `DOMAIN_PATTERN` is a string it can contain `*` to match 1 or more characters in that section of the `DOMAIN_PATTERN`. When `DOMAIN_PATTERN` is a RegExp, it will be forced to case-insensitive (since `DOMAIN_PATTERN`s are) and will be forced to match based on the start and end of the `DOMAIN_PATTERN`.
628 | - `EDGEROUTER_INSTANCE`: This is executed when a `DOMAIN_PATTERN` is matched.
629 | - When `DOMAIN_PATTERN` is matched and the request is sent down to a EDGEROUTER_INSTANCE, the req.vhost property will be populated with an object. This object will have numeric properties corresponding to each wildcard (or capture group if RegExp object provided) and the hostname that was matched.
630 |
631 | ## 👉 Contributing
632 |
633 | Please see our [contributing.md](https://github.com/edge-hub/router/blob/master/.github/CONTRIBUTING.md).
634 |
635 | ## 👨💻 Authors
636 |
637 | - [VinayPuppal](https://vinaypuppal.com)
638 |
639 | See also the list of [contributors](https://github.com/edge-hub/router/graphs/contributors) who participated in this project. Join us 🍻
640 |
--------------------------------------------------------------------------------
/docs/_404.md:
--------------------------------------------------------------------------------
1 | Page Not Found
2 |
3 | [Get Back](https://router.edgehub.in)
4 |
--------------------------------------------------------------------------------
/docs/_coverpage.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # EdgeRouter
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | > A minimal Express.js like router for [Cloudflare Workers](https://workers.cloudflare.com/).
16 |
17 | [Get Started](#🔋-install)
18 | [Features](#✨-features)
19 |
--------------------------------------------------------------------------------
/docs/_media/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/android-chrome-192x192.png
--------------------------------------------------------------------------------
/docs/_media/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/android-chrome-512x512.png
--------------------------------------------------------------------------------
/docs/_media/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/apple-touch-icon.png
--------------------------------------------------------------------------------
/docs/_media/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #00aba9
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/_media/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/favicon-16x16.png
--------------------------------------------------------------------------------
/docs/_media/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/favicon-32x32.png
--------------------------------------------------------------------------------
/docs/_media/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/logo.png
--------------------------------------------------------------------------------
/docs/_media/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/docs/_media/mstile-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/mstile-144x144.png
--------------------------------------------------------------------------------
/docs/_media/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/mstile-150x150.png
--------------------------------------------------------------------------------
/docs/_media/mstile-310x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/mstile-310x150.png
--------------------------------------------------------------------------------
/docs/_media/mstile-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/mstile-310x310.png
--------------------------------------------------------------------------------
/docs/_media/mstile-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/_media/mstile-70x70.png
--------------------------------------------------------------------------------
/docs/_media/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 | Created by potrace 1.11, written by Peter Selinger 2001-2013
9 |
10 |
12 |
16 |
21 |
29 |
36 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/docs/_media/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "EdgeRouter",
3 | "short_name": "EdgeRouter",
4 | "description": "A minimal Express.js like router for cloudflare workers.",
5 | "icons": [
6 | {
7 | "src": "/android-chrome-192x192.png",
8 | "sizes": "192x192",
9 | "type": "image/png"
10 | },
11 | {
12 | "src": "/android-chrome-512x512.png",
13 | "sizes": "512x512",
14 | "type": "image/png"
15 | }
16 | ],
17 | "theme_color": "#000000",
18 | "background_color": "#ffffff",
19 | "display": "standalone"
20 | }
21 |
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EdgeRouter
7 |
8 |
9 |
13 |
14 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
46 |
50 |
54 |
59 |
65 |
71 |
72 |
77 |
78 |
79 |
83 |
126 |
127 |
128 |
129 |
130 |
131 | Loading... Please wait.
132 |
133 |
134 |
135 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/examples/basic/.cargo-ok:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/examples/basic/.cargo-ok
--------------------------------------------------------------------------------
/examples/basic/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": true,
6 | "singleQuote": false,
7 | "trailingComma": "es5",
8 | "bracketSpacing": true,
9 | "jsxBracketSameLine": false,
10 | "arrowParens": "always",
11 | "rangeStart": 0
12 | }
13 |
--------------------------------------------------------------------------------
/examples/basic/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020 Cloudflare, Inc.
2 |
3 | Permission is hereby granted, free of charge, to any
4 | person obtaining a copy of this software and associated
5 | documentation files (the "Software"), to deal in the
6 | Software without restriction, including without
7 | limitation the rights to use, copy, modify, merge,
8 | publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software
10 | is furnished to do so, subject to the following
11 | conditions:
12 |
13 | The above copyright notice and this permission notice
14 | shall be included in all copies or substantial portions
15 | of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | DEALINGS IN THE SOFTWARE.
26 |
--------------------------------------------------------------------------------
/examples/basic/README.md:
--------------------------------------------------------------------------------
1 | # A basic routing example with EdgeHub Router
2 |
3 | To generate using Wrangler, run this command:
4 |
5 | ```bash
6 | wrangler generate myapp https://github.com/edge-hub/router/tree/master/examples/basic
7 | ```
8 |
--------------------------------------------------------------------------------
/examples/basic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "edgerouter",
3 | "version": "1.0.0",
4 | "description": "Cloudflare worker EdgeRouter template",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack",
8 | "dev": "NODE_ENV=development npm run build"
9 | },
10 | "author": "edgehub",
11 | "license": "MIT",
12 | "devDependencies": {
13 | "@cloudflare/workers-types": "^1.0.1",
14 | "prettier": "^1.18.2",
15 | "ts-loader": "^6.0.4",
16 | "typescript": "^3.5.3",
17 | "webpack": "^4.43.0",
18 | "webpack-cli": "^3.3.11"
19 | },
20 | "dependencies": {
21 | "@edgehub/router": "^0.0.28"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/basic/src/index.ts:
--------------------------------------------------------------------------------
1 | import { EdgeRouter } from "@edgehub/router";
2 | import { cors } from "@edgehub/router/middlewares/cors";
3 |
4 | const worker = new EdgeRouter();
5 |
6 | worker.use(cors());
7 |
8 | worker.get("/api/posts", async (req, res) => {
9 | // Get posts from some db or rest API
10 | const posts = await getPosts();
11 |
12 | return res.send(posts);
13 | });
14 |
15 | worker.get("/api/posts/:id", async (req, res) => {
16 | const { id } = req.params;
17 | // Get posts from some db or rest API
18 | const post = await getPost(Number(id));
19 |
20 | return res.send(post);
21 | });
22 |
23 | worker.post("/api/posts", async (req, res) => {
24 | const body = await req.body();
25 |
26 | if (!body) {
27 | throw new Error(`POST body is not present`);
28 | }
29 |
30 | if (!body.title || !body.content) {
31 | throw new Error(
32 | `To add post please provide all these fields i.e title and content`
33 | );
34 | }
35 |
36 | const posts = await addPost(body);
37 |
38 | return res.send(posts);
39 | });
40 |
41 | worker.listen({ passThroughOnException: true });
42 |
43 | // For Demo Purpose
44 | const POSTS = [
45 | {
46 | id: 1,
47 | title: `EdgeRouter basic routing`,
48 | author: `EdgeHub`,
49 | content: `Lorem ipsum dolor sit amet, consectetur adipisicing elit.`,
50 | },
51 | {
52 | id: 2,
53 | title: `EdgeRouter examples`,
54 | author: `EdgeHub`,
55 | content: `Lorem ipsum dolor sit amet, consectetur adipisicing elit.`,
56 | },
57 | ];
58 |
59 | async function getPosts() {
60 | return POSTS;
61 | }
62 |
63 | async function getPost(id: number) {
64 | return POSTS.find((post) => post.id === id);
65 | }
66 |
67 | async function addPost(body: Record) {
68 | return [...POSTS, { ...body, id: Date.now() }];
69 | }
70 |
--------------------------------------------------------------------------------
/examples/basic/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist",
4 | "module": "commonjs",
5 | "target": "esnext",
6 | "lib": ["esnext", "webworker"],
7 | "alwaysStrict": true,
8 | "strict": true,
9 | "preserveConstEnums": true,
10 | "moduleResolution": "node",
11 | "sourceMap": true,
12 | "esModuleInterop": true
13 | },
14 | "include": [
15 | "./src/*.ts",
16 | "./test/*.ts",
17 | "./src/**/*.ts",
18 | "./test/**/*.ts",
19 | "./node_modules/@cloudflare/workers-types/index.d.ts"
20 | ],
21 | "exclude": ["node_modules/", "dist/"]
22 | }
23 |
--------------------------------------------------------------------------------
/examples/basic/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 |
3 | const mode = process.env.NODE_ENV || "production";
4 |
5 | module.exports = {
6 | output: {
7 | filename: `worker.${mode}.js`,
8 | path: path.join(__dirname, "dist"),
9 | },
10 | devtool: "source-map",
11 | mode,
12 | resolve: {
13 | extensions: [".ts", ".tsx", ".js"],
14 | plugins: [],
15 | },
16 | module: {
17 | rules: [
18 | {
19 | test: /\.tsx?$/,
20 | loader: "ts-loader",
21 | options: {
22 | transpileOnly: true,
23 | },
24 | },
25 | ],
26 | },
27 | };
28 |
--------------------------------------------------------------------------------
/examples/basic/wrangler.toml:
--------------------------------------------------------------------------------
1 | name = "basic"
2 | type = "webpack"
3 | workers_dev = true
4 | account_id = ""
5 | route = ""
6 | zone_id = ""
7 | webpack_config = "webpack.config.js"
8 |
--------------------------------------------------------------------------------
/examples/domain-routing/.cargo-ok:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/examples/domain-routing/.cargo-ok
--------------------------------------------------------------------------------
/examples/domain-routing/.gitignore:
--------------------------------------------------------------------------------
1 | worker/
--------------------------------------------------------------------------------
/examples/domain-routing/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": true,
6 | "singleQuote": false,
7 | "trailingComma": "es5",
8 | "bracketSpacing": true,
9 | "jsxBracketSameLine": false,
10 | "arrowParens": "always",
11 | "rangeStart": 0
12 | }
13 |
--------------------------------------------------------------------------------
/examples/domain-routing/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020 Cloudflare, Inc.
2 |
3 | Permission is hereby granted, free of charge, to any
4 | person obtaining a copy of this software and associated
5 | documentation files (the "Software"), to deal in the
6 | Software without restriction, including without
7 | limitation the rights to use, copy, modify, merge,
8 | publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software
10 | is furnished to do so, subject to the following
11 | conditions:
12 |
13 | The above copyright notice and this permission notice
14 | shall be included in all copies or substantial portions
15 | of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | DEALINGS IN THE SOFTWARE.
26 |
--------------------------------------------------------------------------------
/examples/domain-routing/README.md:
--------------------------------------------------------------------------------
1 | # Domain Routing example with EdgeHub Router
2 |
3 | To generate using Wrangler, run this command:
4 |
5 | ```bash
6 | wrangler generate myapp https://github.com/edge-hub/router/tree/master/examples/domain-routing
7 | ```
8 |
--------------------------------------------------------------------------------
/examples/domain-routing/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "edgerouter",
3 | "version": "1.0.0",
4 | "description": "Cloudflare worker EdgeRouter template",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack",
8 | "dev": "NODE_ENV=development npm run build"
9 | },
10 | "author": "edgehub",
11 | "license": "MIT",
12 | "devDependencies": {
13 | "@cloudflare/workers-types": "^1.0.1",
14 | "prettier": "^1.18.2",
15 | "ts-loader": "^6.0.4",
16 | "typescript": "^3.5.3",
17 | "webpack": "^4.35.3",
18 | "webpack-cli": "^3.3.6"
19 | },
20 | "dependencies": {
21 | "@edgehub/router": "latest"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/domain-routing/src/index.ts:
--------------------------------------------------------------------------------
1 | import { EdgeRouter } from "@edgehub/router";
2 | import { VHostRouter } from "@edgehub/router/vhost";
3 |
4 | const vhost = new VHostRouter();
5 | const apiRouter = new EdgeRouter();
6 | const cdnRouter = new EdgeRouter();
7 |
8 | // API routes
9 | apiRouter.get("/posts", (req, res) => {
10 | return res.send({ posts: { title: "About EdgeRouter" } });
11 | });
12 |
13 | apiRouter.post("/posts", async (req, res) => {
14 | const data = await req.body();
15 | if (!data) {
16 | return res.send(`Not data from POST req`);
17 | }
18 | // store data in db and send response
19 | return res.send(data);
20 | });
21 |
22 | // CDN routes
23 | cdnRouter.all("*", (req, res) => {
24 | // Fetch image from CDN and modify on the fly to webp or resize ...etc
25 | res.send(`Some image`);
26 | });
27 |
28 | vhost.use("api.example.com", apiRouter);
29 | vhost.use("cdn.example.com", cdnRouter);
30 |
31 | vhost.listen({ passThroughOnException: true });
32 |
--------------------------------------------------------------------------------
/examples/domain-routing/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist",
4 | "module": "commonjs",
5 | "target": "esnext",
6 | "lib": ["esnext", "webworker"],
7 | "alwaysStrict": true,
8 | "strict": true,
9 | "preserveConstEnums": true,
10 | "moduleResolution": "node",
11 | "sourceMap": true,
12 | "esModuleInterop": true
13 | },
14 | "include": [
15 | "./src/*.ts",
16 | "./test/*.ts",
17 | "./src/**/*.ts",
18 | "./test/**/*.ts",
19 | "./node_modules/@cloudflare/workers-types/index.d.ts"
20 | ],
21 | "exclude": ["node_modules/", "dist/"]
22 | }
23 |
--------------------------------------------------------------------------------
/examples/domain-routing/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 |
3 | const mode = process.env.NODE_ENV || "production";
4 |
5 | module.exports = {
6 | output: {
7 | filename: `worker.js`,
8 | path: path.join(__dirname, "dist"),
9 | },
10 | mode,
11 | resolve: {
12 | extensions: [".ts", ".tsx", ".js"],
13 | plugins: [],
14 | },
15 | module: {
16 | rules: [
17 | {
18 | test: /\.tsx?$/,
19 | loader: "ts-loader",
20 | options: {
21 | transpileOnly: true,
22 | },
23 | },
24 | ],
25 | },
26 | };
27 |
--------------------------------------------------------------------------------
/examples/domain-routing/wrangler.toml:
--------------------------------------------------------------------------------
1 | name = "hello-world"
2 | type = "webpack"
3 | workers_dev = true
4 | account_id = ""
5 | route = ""
6 | zone_id = ""
7 | webpack_config = "webpack.config.js"
8 |
--------------------------------------------------------------------------------
/examples/hello-world/.cargo-ok:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/examples/hello-world/.cargo-ok
--------------------------------------------------------------------------------
/examples/hello-world/.gitignore:
--------------------------------------------------------------------------------
1 | worker/
--------------------------------------------------------------------------------
/examples/hello-world/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": true,
6 | "singleQuote": false,
7 | "trailingComma": "es5",
8 | "bracketSpacing": true,
9 | "jsxBracketSameLine": false,
10 | "arrowParens": "always",
11 | "rangeStart": 0
12 | }
13 |
--------------------------------------------------------------------------------
/examples/hello-world/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2020 Cloudflare, Inc.
2 |
3 | Permission is hereby granted, free of charge, to any
4 | person obtaining a copy of this software and associated
5 | documentation files (the "Software"), to deal in the
6 | Software without restriction, including without
7 | limitation the rights to use, copy, modify, merge,
8 | publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software
10 | is furnished to do so, subject to the following
11 | conditions:
12 |
13 | The above copyright notice and this permission notice
14 | shall be included in all copies or substantial portions
15 | of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | DEALINGS IN THE SOFTWARE.
26 |
--------------------------------------------------------------------------------
/examples/hello-world/README.md:
--------------------------------------------------------------------------------
1 | # A simple helloworld example with EdgeHub Router
2 |
3 | To generate using Wrangler, run this command:
4 |
5 | ```bash
6 | wrangler generate myapp https://github.com/edge-hub/router/tree/master/examples/hello-world
7 | ```
8 |
--------------------------------------------------------------------------------
/examples/hello-world/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "edgerouter",
3 | "version": "1.0.0",
4 | "description": "Cloudflare worker EdgeRouter template",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack",
8 | "dev": "NODE_ENV=development npm run build"
9 | },
10 | "author": "edgehub",
11 | "license": "MIT",
12 | "devDependencies": {
13 | "@cloudflare/workers-types": "^1.0.1",
14 | "prettier": "^1.18.2",
15 | "ts-loader": "^6.0.4",
16 | "typescript": "^3.5.3",
17 | "webpack": "^4.35.3",
18 | "webpack-cli": "^3.3.6"
19 | },
20 | "dependencies": {
21 | "@edgehub/router": "latest"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/hello-world/src/index.ts:
--------------------------------------------------------------------------------
1 | import { EdgeRouter } from "@edgehub/router";
2 |
3 | const worker = new EdgeRouter();
4 |
5 | // Middleware to set a header for all routes
6 | worker.use((req, res) => {
7 | res.setHeader("x-router", "EdgeRouter");
8 | });
9 |
10 | // The worker responds with `Hello World` for requests to root URL(/). For every other path, it will fallback to origin response if its exists or error.
11 | worker.get("/", (req, res) => {
12 | return res.send(`Hello World`);
13 | });
14 |
15 | worker.listen({ passThroughOnException: true });
16 |
--------------------------------------------------------------------------------
/examples/hello-world/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist",
4 | "module": "commonjs",
5 | "target": "esnext",
6 | "lib": ["esnext", "webworker"],
7 | "alwaysStrict": true,
8 | "strict": true,
9 | "preserveConstEnums": true,
10 | "moduleResolution": "node",
11 | "sourceMap": true,
12 | "esModuleInterop": true
13 | },
14 | "include": [
15 | "./src/*.ts",
16 | "./test/*.ts",
17 | "./src/**/*.ts",
18 | "./test/**/*.ts",
19 | "./node_modules/@cloudflare/workers-types/index.d.ts"
20 | ],
21 | "exclude": ["node_modules/", "dist/"]
22 | }
23 |
--------------------------------------------------------------------------------
/examples/hello-world/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 |
3 | const mode = process.env.NODE_ENV || "production";
4 |
5 | module.exports = {
6 | output: {
7 | filename: `worker.js`,
8 | path: path.join(__dirname, "dist"),
9 | },
10 | mode,
11 | resolve: {
12 | extensions: [".ts", ".tsx", ".js"],
13 | plugins: [],
14 | },
15 | module: {
16 | rules: [
17 | {
18 | test: /\.tsx?$/,
19 | loader: "ts-loader",
20 | options: {
21 | transpileOnly: true,
22 | },
23 | },
24 | ],
25 | },
26 | };
27 |
--------------------------------------------------------------------------------
/examples/hello-world/wrangler.toml:
--------------------------------------------------------------------------------
1 | name = "hello-world"
2 | type = "webpack"
3 | workers_dev = true
4 | account_id = ""
5 | route = ""
6 | zone_id = ""
7 | webpack_config = "webpack.config.js"
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@edgehub/router",
3 | "version": "0.0.31",
4 | "description": "A minimal Express.js like router for cloudflare workers.",
5 | "keywords": [
6 | "cloudflare",
7 | "workers",
8 | "router",
9 | "cloudflare-workers"
10 | ],
11 | "homepage": "https://github.com/edge-hub/router#readme",
12 | "bugs": {
13 | "url": "https://github.com/edge-hub/router/issues"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "git+https://github.com/edge-hub/router.git"
18 | },
19 | "engines": {
20 | "node": ">=10"
21 | },
22 | "license": "MIT",
23 | "author": "vinaypuppal",
24 | "main": "index.js",
25 | "module": "index.js",
26 | "types": "index.d.ts",
27 | "sideEffects": false,
28 | "scripts": {
29 | "prebuild": "rimraf dist",
30 | "build": "tsc && yarn rollup -c rollup.config.js",
31 | "copypackage": "cp package.json dist/package.json && cp Readme.md dist/Readme.md",
32 | "dist": "yarn build && yarn copypackage",
33 | "release": "npm publish --access public dist/",
34 | "pre-release": "npm publish --access public --tag next dist/"
35 | },
36 | "husky": {
37 | "hooks": {
38 | "pre-commit": "lint-staged"
39 | }
40 | },
41 | "lint-staged": {
42 | "**/*.md": [
43 | "prettier --write",
44 | "git add"
45 | ],
46 | "*.{js,ts,json}": [
47 | "prettier --write",
48 | "git add"
49 | ]
50 | },
51 | "dependencies": {
52 | "@cloudflare/kv-asset-handler": "^0.0.9",
53 | "@types/cookie": "^0.3.3",
54 | "@types/trouter": "^3.1.0",
55 | "cookie": "^0.4.0",
56 | "trouter": "^3.1.0"
57 | },
58 | "devDependencies": {
59 | "@rollup/plugin-commonjs": "^11.0.2",
60 | "@rollup/plugin-node-resolve": "^7.1.1",
61 | "@types/jest": "^25.2.1",
62 | "husky": "^4.2.3",
63 | "lint-staged": "^10.0.10",
64 | "prettier": "^2.0.2",
65 | "rimraf": "^3.0.2",
66 | "rollup": "^2.6.0",
67 | "rollup-plugin-node-globals": "^1.4.0",
68 | "rollup-plugin-terser": "^5.3.0",
69 | "rollup-plugin-typescript2": "^0.27.0",
70 | "typescript": "^3.8.3"
71 | },
72 | "filesize": {
73 | "track": [
74 | "./dist/index.umd.js"
75 | ]
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | const { terser } = require("rollup-plugin-terser");
2 | const resolve = require("@rollup/plugin-node-resolve");
3 | const commonjs = require("@rollup/plugin-commonjs");
4 | const globals = require("rollup-plugin-node-globals");
5 | const typescript = require("rollup-plugin-typescript2");
6 |
7 | export default [
8 | {
9 | input: "src/index.ts",
10 | output: [
11 | {
12 | file: "docs/_lib/index.umd.js",
13 | format: "umd",
14 | name: "EdgeRouter",
15 | esModule: false,
16 | },
17 | ],
18 | plugins: [
19 | typescript({
20 | tsconfig: "tsconfig.json",
21 | tsconfigOverride: { compilerOptions: { declaration: false } },
22 | }),
23 | commonjs(),
24 | resolve({ preferBuiltins: true, module: false, browser: true }),
25 | globals(),
26 | terser({ output: { comments: false } }),
27 | ],
28 | },
29 | ];
30 |
--------------------------------------------------------------------------------
/src/context.ts:
--------------------------------------------------------------------------------
1 | export class Context {
2 | constructor(event: FetchEvent) {}
3 | protected _instanceToJson(instance: any) {
4 | return [...instance].reduce((obj, item) => {
5 | const key = item[0] as string;
6 | if (obj[key]) {
7 | obj[key] = Array.isArray(obj[key])
8 | ? [...obj[key], item[1]]
9 | : [obj[key], item[1]];
10 | return obj;
11 | }
12 |
13 | const prop: { [key: string]: any } = {};
14 | prop[key] = item[1];
15 | return { ...obj, ...prop };
16 | }, {});
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/default.ts:
--------------------------------------------------------------------------------
1 | import { EdgeRequest } from "./request";
2 | import { EdgeResponse } from "./response";
3 |
4 | export function onNoMatch() {
5 | return new Response(`404 - Resource not found`, { status: 404 });
6 | }
7 |
8 | export function onError(error: Error, req: EdgeRequest, res: EdgeResponse) {
9 | const acceptHeader = req.headers.get("Accept");
10 | if (acceptHeader && acceptHeader.includes("text/html")) {
11 | return res.status(500).send(error.message || error.toString());
12 | }
13 | return res
14 | .status(500)
15 | .raw(
16 | JSON.stringify(error, Object.getOwnPropertyNames(error)),
17 | "application/json"
18 | )
19 | .end();
20 | }
21 |
--------------------------------------------------------------------------------
/src/global.d.ts:
--------------------------------------------------------------------------------
1 | interface FetchEvent {
2 | passThroughOnException: () => void;
3 | }
4 |
5 | declare function addEventListener(
6 | type: "fetch",
7 | handler: (event: FetchEvent) => void
8 | ): undefined | null | Response | Promise;
9 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./router";
2 | export * from "./types";
3 |
--------------------------------------------------------------------------------
/src/middlewares/cors.ts:
--------------------------------------------------------------------------------
1 | import { EdgeRequest } from "../request";
2 | import { EdgeResponse } from "../response";
3 | import { RouteHandler } from "../types";
4 |
5 | const DEFAULT_ALLOW_METHODS = [
6 | "POST",
7 | "GET",
8 | "PUT",
9 | "PATCH",
10 | "DELETE",
11 | "OPTIONS",
12 | ];
13 |
14 | const DEFAULT_ALLOW_HEADERS = [
15 | "X-Requested-With",
16 | "Access-Control-Allow-Origin",
17 | "X-HTTP-Method-Override",
18 | "Content-Type",
19 | "Authorization",
20 | "Accept",
21 | ];
22 |
23 | const DEFAULT_MAX_AGE_SECONDS = 60 * 60 * 24; // 24 hours
24 |
25 | type Origin = ((request: EdgeRequest) => string | boolean) | string | boolean;
26 | interface Options {
27 | origin?: Origin;
28 | maxAge?: number;
29 | allowMethods?: string[];
30 | allowHeaders?: string[];
31 | exposeHeaders?: string[];
32 | allowCredentials?: boolean;
33 | }
34 |
35 | function getOriginValue(origin: Origin, request: EdgeRequest) {
36 | if (typeof origin === "function") {
37 | return origin(request);
38 | }
39 | if (typeof origin === "boolean") {
40 | return origin ? "*" : "";
41 | }
42 | return origin;
43 | }
44 |
45 | export function cors(options: Options = {}): RouteHandler {
46 | return (req: EdgeRequest, res: EdgeResponse) => {
47 | const origin = options.origin || "*";
48 | const maxAge = options.maxAge || DEFAULT_MAX_AGE_SECONDS;
49 | const allowMethods = options.allowMethods || DEFAULT_ALLOW_METHODS;
50 | const allowHeaders = options.allowHeaders || DEFAULT_ALLOW_HEADERS;
51 | const allowCredentials = options.allowCredentials || true;
52 | const exposeHeaders = options.exposeHeaders || [];
53 |
54 | const originValue = getOriginValue(origin, req);
55 |
56 | if (originValue) {
57 | res.setHeader("Access-Control-Allow-Origin", String(originValue));
58 | }
59 |
60 | if (allowCredentials) {
61 | res.setHeader("Access-Control-Allow-Credentials", "true");
62 | }
63 |
64 | if (exposeHeaders.length) {
65 | res.setHeader("Access-Control-Expose-Headers", exposeHeaders.join(","));
66 | }
67 |
68 | const preFlight = req.method === "OPTIONS";
69 | if (preFlight) {
70 | res.setHeader("Access-Control-Allow-Methods", allowMethods.join(","));
71 | res.setHeader("Access-Control-Allow-Headers", allowHeaders.join(","));
72 | res.setHeader("Access-Control-Max-Age", String(maxAge));
73 | }
74 | };
75 | }
76 |
--------------------------------------------------------------------------------
/src/middlewares/static.ts:
--------------------------------------------------------------------------------
1 | import { Options } from "@cloudflare/kv-asset-handler/src/types";
2 | import { getAssetFromKV } from "@cloudflare/kv-asset-handler";
3 |
4 | import { EdgeRequest } from "../request";
5 | import { EdgeResponse } from "../response";
6 | import { RouteHandler } from "../types";
7 |
8 | export function workersSite(options?: Partial): RouteHandler {
9 | return async (req: EdgeRequest, _res: EdgeResponse) => {
10 | try {
11 | const response = await getAssetFromKV(req._event, options);
12 | return response;
13 | } catch (error) {
14 | switch (error.status) {
15 | case 404:
16 | return;
17 | case 405:
18 | return;
19 | default:
20 | throw error;
21 | }
22 | }
23 | };
24 | }
25 |
--------------------------------------------------------------------------------
/src/request.ts:
--------------------------------------------------------------------------------
1 | import cookie from "cookie";
2 |
3 | import { Context } from "./context";
4 | import { VHostData } from "./types";
5 |
6 | export class EdgeRequest extends Context {
7 | public _originalRequest: Request;
8 | public _event: FetchEvent;
9 | public vhost?: VHostData;
10 | public url: string;
11 | public hash: string;
12 | public host: string;
13 | public origin: string;
14 | public hostname: string;
15 | public pathname: string;
16 | public protocol: string;
17 | public subdomains: string[];
18 | public method: string;
19 | public search: string;
20 | public querystring: string;
21 | public query: Record;
22 | public params: Record = {};
23 | public cookies: Record = {};
24 | public headers: Headers;
25 | public header: (name: string) => string | null;
26 | public body: () => Promise | void>;
27 | constructor(event: FetchEvent) {
28 | super(event);
29 | const { request } = event;
30 | const url = new URL(request.url);
31 | this._event = event;
32 | this._originalRequest = request;
33 | this.method = request.method;
34 | this.url = url.href;
35 | this.hostname = url.hostname;
36 | this.host = url.hostname;
37 | this.origin = url.origin;
38 | this.subdomains = url.hostname.split(".").reverse().slice(2);
39 | this.hash = url.hash;
40 | this.pathname = url.pathname;
41 | this.protocol = url.protocol.slice(0, -1);
42 | this.search = url.search;
43 | this.querystring = url.search.slice(1);
44 | this.query = this._instanceToJson(url.searchParams);
45 | this.cookies = cookie.parse(request.headers.get("cookie") || "");
46 | this.headers = request.headers;
47 | this.header = this._header(request.headers);
48 | this.body = this._getBodyParserHelper(request.clone());
49 | }
50 | private _getBodyParserHelper(request: Request) {
51 | return async () => {
52 | const parsableMethods = ["post", "put"];
53 | if (!parsableMethods.includes(request.method.toLowerCase())) {
54 | return;
55 | }
56 | const contentType = request.headers.get("content-type");
57 | if (contentType === "application/json") {
58 | return await request.json();
59 | }
60 | if (contentType === "application/x-www-form-urlencoded") {
61 | const formData = await request.formData();
62 | return this._instanceToJson(formData);
63 | }
64 | };
65 | }
66 | private _header(headers: Headers) {
67 | return (name: string) => {
68 | return headers.get(name);
69 | };
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/response.ts:
--------------------------------------------------------------------------------
1 | import cookie, { CookieSerializeOptions } from "cookie";
2 |
3 | import { Context } from "./context";
4 |
5 | type Body =
6 | | Blob
7 | | BufferSource
8 | | FormData
9 | | URLSearchParams
10 | | ReadableStream
11 | | string;
12 |
13 | export class EdgeResponse extends Context {
14 | private headers: Headers | string[][] | Record = {};
15 | private cookies: Record<
16 | string,
17 | { value: string; options?: CookieSerializeOptions }
18 | > = {};
19 | private statusCode?: number;
20 | private statusText?: string;
21 | private body?: Body | null;
22 | private type?: string;
23 | public _response?: Response;
24 | public raw(data: any, type?: string) {
25 | this.body = data;
26 | if (type) {
27 | this.type = type;
28 | }
29 | return this;
30 | }
31 | public text(data: string) {
32 | this.body = data;
33 | if (!this.type) {
34 | this.type = "text/plain";
35 | }
36 | return this;
37 | }
38 | public html(data: string) {
39 | this.body = data;
40 | if (!this.type) {
41 | this.type = "text/html; charset=utf-8";
42 | }
43 | return this;
44 | }
45 | public status(code: number, statusText?: string) {
46 | this.statusCode = code;
47 | this.statusText = statusText;
48 | return this;
49 | }
50 | public setHeader(key: string, value: string | string[]) {
51 | this.headers = {
52 | ...this.headers,
53 | [key]: Array.isArray(value) ? value.join(",") : value,
54 | };
55 | return this;
56 | }
57 | public setCookie(
58 | key: string,
59 | value: string,
60 | options?: CookieSerializeOptions
61 | ) {
62 | this.cookies = {
63 | ...this.cookies,
64 | [key]: { value, options },
65 | };
66 | return this;
67 | }
68 | public redirect(url: string, status?: number) {
69 | return Response.redirect(url, status);
70 | }
71 | public sendStatus(status: number) {
72 | const headers = this._getheaders();
73 | return new Response(null, { status, headers });
74 | }
75 | public end(
76 | data: {
77 | body?: Body | null;
78 | status?: number;
79 | statusText?: string;
80 | headers?: Headers | string[][] | Record;
81 | } = {}
82 | ) {
83 | const {
84 | headers: endHeaders = {},
85 | status = this.statusCode,
86 | statusText = this.statusText,
87 | body = this.body,
88 | } = data;
89 | this.headers = {
90 | ...this.headers,
91 | ...endHeaders,
92 | };
93 | const headers = this._getheaders();
94 | return new Response(body, { status, headers, statusText });
95 | }
96 | public json(data: object) {
97 | return this._json(data).end();
98 | }
99 | public send(data?: string | number | boolean | object) {
100 | switch (typeof data) {
101 | case "boolean":
102 | case "number": {
103 | return this.text(String(data)).end();
104 | }
105 | case "object": {
106 | return this._json(data).end();
107 | }
108 | case "string": {
109 | return this.html(data).end();
110 | }
111 | default: {
112 | return this.end();
113 | }
114 | }
115 | }
116 | private _json(data: object) {
117 | this.body = JSON.stringify(data);
118 | if (!this.type) {
119 | this.type = "application/json";
120 | }
121 | return this;
122 | }
123 | private _getheaders() {
124 | const cookieHeader = Object.keys(this.cookies).reduce(
125 | (p: string, key: string) => {
126 | const { value, options } = this.cookies[key];
127 | return `${p}${cookie.serialize(key, value, options)}`;
128 | },
129 | ``
130 | );
131 | return {
132 | ...(this.type ? { "Content-Type": this.type } : {}),
133 | ...this.headers,
134 | "Set-Cookie": cookieHeader,
135 | };
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/router.ts:
--------------------------------------------------------------------------------
1 | import Trouter from "trouter";
2 |
3 | import {
4 | RouteHandler,
5 | ErrorHandler,
6 | RouterOptions,
7 | NoMatchHandler,
8 | OnRequestOptions,
9 | BeforeResponseHandler,
10 | } from "./types";
11 | import { EdgeRequest } from "./request";
12 | import { EdgeResponse } from "./response";
13 |
14 | export class EdgeRouter extends Trouter {
15 | private onNoMatch: NoMatchHandler | undefined;
16 | private onError: ErrorHandler | undefined;
17 | private onBeforeResponse: BeforeResponseHandler | undefined;
18 |
19 | constructor(options?: RouterOptions) {
20 | super();
21 | this.onNoMatch = options ? options.onNoMatch : undefined;
22 | this.onError = options ? options.onError : undefined;
23 | this.onBeforeResponse = options ? options.onBeforeResponse : undefined;
24 | }
25 |
26 | public use(
27 | path: string | RegExp | RouteHandler,
28 | ...handlers: RouteHandler[]
29 | ) {
30 | if (typeof path === "function") {
31 | handlers.unshift(path);
32 | super.use("/", ...handlers);
33 | } else {
34 | super.use(path, ...handlers);
35 | }
36 | return this;
37 | }
38 |
39 | public async onRequest(event: FetchEvent, ctx?: OnRequestOptions) {
40 | const { request } = event;
41 | const req = new EdgeRequest(event);
42 | const res = new EdgeResponse(event);
43 |
44 | if (ctx && ctx.vhost) {
45 | req.vhost = ctx.vhost;
46 | }
47 |
48 | try {
49 | const { handlers, params } = this.find(
50 | request.method as Trouter.HTTPMethod,
51 | req.pathname
52 | );
53 | req.params = params;
54 |
55 | for (const handler of handlers) {
56 | const _response = await handler(req, res);
57 | if (_response instanceof Response) {
58 | if (this.onBeforeResponse !== undefined) {
59 | res._response = _response;
60 | const _res = await this.onBeforeResponse(req, res);
61 | if (_res instanceof Response) return _res;
62 | }
63 | return _response;
64 | }
65 | }
66 |
67 | if (this.onNoMatch) {
68 | return this.onNoMatch(req, res);
69 | }
70 | console.warn(
71 | `No response was returned by any router handler. Did you forgot to return "res.send"?`
72 | );
73 | } catch (error) {
74 | if (this.onError) {
75 | return this.onError(error, req, res);
76 | }
77 | }
78 | }
79 |
80 | public listen({
81 | passThroughOnException = false,
82 | }: {
83 | passThroughOnException?: boolean;
84 | } = {}) {
85 | addEventListener("fetch", (event) => {
86 | if (passThroughOnException) {
87 | event.passThroughOnException();
88 | if (this.onError) {
89 | console.warn(
90 | `You enabled passThroughOnException and also have onError handler so onError handler will be used if any of your route handlers throw error instead of fallingback to origin response!`
91 | );
92 | }
93 | } else {
94 | if (!this.onError) {
95 | console.warn(
96 | `You did not passThroughOnException and also did not set onError handler so if any of your route handlers throw error it will be ignored and a generic worker error will be returned!`
97 | );
98 | }
99 | }
100 |
101 | // Why?
102 | // Because when passThroughOnException is set we want to ignore errors and return response from origin.
103 | // Incase of error or no match router does not send any response so worker will send response from origin as it is.
104 | // We can override this by specifying error and nomatch handlers.
105 | // @ts-ignore
106 | event.respondWith(this.onRequest(event));
107 | });
108 | return this;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | import { EdgeRequest } from "./request";
2 | import { EdgeResponse } from "./response";
3 |
4 | export type RouteHandler = (
5 | req: EdgeRequest,
6 | res: EdgeResponse
7 | ) => Response | Promise | void;
8 |
9 | export type ErrorHandler = (
10 | error: Error,
11 | req: EdgeRequest,
12 | res: EdgeResponse
13 | ) => Response | Promise;
14 |
15 | export type NoMatchHandler = (
16 | req: EdgeRequest,
17 | res: EdgeResponse
18 | ) => Response | Promise;
19 |
20 | export type BeforeResponseHandler = (
21 | req: EdgeRequest,
22 | res: EdgeResponse
23 | ) => Response | Promise | void;
24 |
25 | export interface RouterOptions {
26 | onError?: ErrorHandler;
27 | onNoMatch?: NoMatchHandler;
28 | onBeforeResponse?: BeforeResponseHandler;
29 | }
30 |
31 | export interface VHostData {
32 | host: string;
33 | params: string[];
34 | }
35 |
36 | export interface OnRequestOptions {
37 | vhost?: VHostData;
38 | }
39 |
--------------------------------------------------------------------------------
/src/vhost/index.ts:
--------------------------------------------------------------------------------
1 | import { EdgeRouter } from "../router";
2 | import {
3 | VHostData,
4 | NoMatchHandler,
5 | ErrorHandler,
6 | RouterOptions,
7 | } from "../types";
8 | import { EdgeRequest } from "../request";
9 | import { EdgeResponse } from "../response";
10 |
11 | const ASTERISK_REGEXP = /\*/g;
12 | const ASTERISK_REPLACE = "([^.]+)";
13 | const END_ANCHORED_REGEXP = /(?:^|[^\\])(?:\\\\)*\$$/;
14 | const ESCAPE_REGEXP = /([.+?^=!:${}()|[\]/\\])/g;
15 | const ESCAPE_REPLACE = "\\$1";
16 |
17 | interface HostHandler extends VHostData {
18 | router: EdgeRouter;
19 | }
20 |
21 | export class VHostRouter {
22 | private onNoMatch: NoMatchHandler | undefined;
23 | private onError: ErrorHandler | undefined;
24 | private routers: { pattern: RegExp; handler: EdgeRouter }[];
25 |
26 | constructor(options?: Omit) {
27 | this.routers = [];
28 | this.onNoMatch = options ? options.onNoMatch : undefined;
29 | this.onError = options ? options.onError : undefined;
30 | }
31 |
32 | private isregexp(val: string | RegExp) {
33 | return Object.prototype.toString.call(val) === "[object RegExp]";
34 | }
35 |
36 | private parseHost(val: string | RegExp) {
37 | let source = !this.isregexp(val)
38 | ? String(val)
39 | .replace(ESCAPE_REGEXP, ESCAPE_REPLACE)
40 | .replace(ASTERISK_REGEXP, ASTERISK_REPLACE)
41 | : (val as RegExp).source;
42 |
43 | if (source[0] !== "^") {
44 | source = "^" + source;
45 | }
46 |
47 | if (!END_ANCHORED_REGEXP.test(source)) {
48 | source += "$";
49 | }
50 |
51 | return new RegExp(source, "i");
52 | }
53 |
54 | private vhostOf(host: string, pattern: RegExp) {
55 | const match = pattern.exec(host);
56 | if (!match) {
57 | return;
58 | }
59 |
60 | const params: string[] = [];
61 | params.length = match.length - 1;
62 | for (var i = 1; i < match.length; i++) {
63 | params[i - 1] = match[i];
64 | }
65 |
66 | return {
67 | host,
68 | params,
69 | };
70 | }
71 |
72 | private find(host: string) {
73 | const handlers: HostHandler[] = [];
74 | for (const r of this.routers) {
75 | const data = this.vhostOf(host, r.pattern);
76 | if (data) {
77 | handlers.push({
78 | ...data,
79 | router: r.handler,
80 | });
81 | }
82 | }
83 | return handlers;
84 | }
85 |
86 | public use(hostPattern: string | RegExp, router: EdgeRouter) {
87 | const pattern = this.parseHost(hostPattern);
88 | this.routers.push({ pattern, handler: router });
89 | return this;
90 | }
91 |
92 | public async onRequest(event: FetchEvent) {
93 | try {
94 | const { request } = event;
95 | const url = new URL(request.url);
96 | const host = url.host;
97 | const handlers = this.find(host);
98 |
99 | for (const handler of handlers) {
100 | const { router, ...data } = handler;
101 | const _response = await router.onRequest(event, { vhost: data });
102 | if (_response instanceof Response) {
103 | return _response;
104 | }
105 | }
106 |
107 | if (this.onNoMatch) {
108 | const req = new EdgeRequest(event);
109 | const res = new EdgeResponse(event);
110 | return this.onNoMatch(req, res);
111 | }
112 | } catch (error) {
113 | console.log(error.stack);
114 | if (this.onError) {
115 | const req = new EdgeRequest(event);
116 | const res = new EdgeResponse(event);
117 | return this.onError(error, req, res);
118 | }
119 | }
120 | }
121 |
122 | public listen({
123 | passThroughOnException = false,
124 | }: {
125 | passThroughOnException?: boolean;
126 | } = {}) {
127 | addEventListener("fetch", (event) => {
128 | if (passThroughOnException) {
129 | event.passThroughOnException();
130 | if (this.onError) {
131 | console.warn(
132 | `You enabled passThroughOnException and also have onError handler so onError handler will be used if any of your route handlers throw error instead of fallingback to origin response!`
133 | );
134 | }
135 | } else {
136 | if (!this.onError) {
137 | console.warn(
138 | `You did not passThroughOnException and also did not set onError handler so if any of your route handlers throw error it will be ignored and a generic worker error will be returned!`
139 | );
140 | }
141 | }
142 |
143 | // Why?
144 | // Because when passThroughOnException is set we want to ignore errors and return response from origin.
145 | // Incase of error or no match router does not send any response so worker will send response from origin as it is.
146 | // We can override this by specifying error and nomatch handlers.
147 | // @ts-ignore
148 | event.respondWith(this.onRequest(event));
149 | });
150 | return this;
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist",
4 | "module": "ESNext",
5 | "target": "esnext",
6 | "lib": ["esnext", "webworker"],
7 | "declaration": true,
8 | "alwaysStrict": true,
9 | "strict": true,
10 | "preserveConstEnums": true,
11 | "moduleResolution": "node",
12 | "sourceMap": false,
13 | "esModuleInterop": true
14 | },
15 | "include": ["./src/**/*.ts"],
16 | "exclude": ["node_modules", "dist/"]
17 | }
18 |
--------------------------------------------------------------------------------
/workers/.cargo-ok:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edge-hub/router/1b3d3ade7ebab9685da069d1634a8b32346f0bbf/workers/.cargo-ok
--------------------------------------------------------------------------------
/workers/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | worker
3 |
--------------------------------------------------------------------------------
/workers/index.js:
--------------------------------------------------------------------------------
1 | import { EdgeRouter, workersSite } from "@edgehub/router";
2 |
3 | const worker = new EdgeRouter({
4 | onNoMatch: (_req, res) => {
5 | return res.status(404).send(`Resource not found! Go Back `);
6 | },
7 | });
8 |
9 | worker.use(workersSite());
10 |
11 | worker.listen({ passThroughOnException: true });
12 |
--------------------------------------------------------------------------------
/workers/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "worker",
4 | "version": "1.0.0",
5 | "description": "A template for kick starting a Cloudflare Workers project",
6 | "main": "index.js",
7 | "author": "Ashley Lewis ",
8 | "license": "MIT",
9 | "dependencies": {
10 | "@cloudflare/kv-asset-handler": "^0.0.9",
11 | "@edgehub/router": "^0.0.4"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/workers/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@cloudflare/kv-asset-handler@^0.0.9":
6 | version "0.0.9"
7 | resolved "https://registry.yarnpkg.com/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.0.9.tgz#b49247eb49819080ed0db796992e6e5dd7cd81ce"
8 | integrity sha512-OP+uwr+5VShB9ktzJvkwy1AibGaTV7EoHs/YMemUY56fgnqI+IlV++e4T6cTUfHDAfE/pdXMx7q4zMf90dU00Q==
9 | dependencies:
10 | "@types/mime" "^2.0.1"
11 | mime "^2.4.4"
12 |
13 | "@edgehub/router@^0.0.4":
14 | version "0.0.4"
15 | resolved "https://registry.yarnpkg.com/@edgehub/router/-/router-0.0.4.tgz#60c0e062dfa2f11e20c30fdca403d04909658054"
16 | integrity sha512-Q77yF+9NpElIi1emJ39t0AfxxUZagKT5pTvOCDt82qJBA2EPWSeY8LE2AmbHt72rYjuVO7MZGsY1ZsUJQHWTXw==
17 | dependencies:
18 | "@types/cookie" "^0.3.3"
19 | "@types/trouter" "^3.1.0"
20 | cookie "^0.4.0"
21 | trouter "^3.1.0"
22 |
23 | "@types/cookie@^0.3.3":
24 | version "0.3.3"
25 | resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.3.tgz#85bc74ba782fb7aa3a514d11767832b0e3bc6803"
26 | integrity sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==
27 |
28 | "@types/mime@^2.0.1":
29 | version "2.0.1"
30 | resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d"
31 | integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==
32 |
33 | "@types/trouter@^3.1.0":
34 | version "3.1.0"
35 | resolved "https://registry.yarnpkg.com/@types/trouter/-/trouter-3.1.0.tgz#8a3c7b34352b1cb454217a194e8bf03e5cdf7cc4"
36 | integrity sha512-4LPNrqSJknLzILMVXn2P/mh0djNgFvom4T9Y1hmhaB8OBm1cY71bMMSrGRu1q5qF4JZzY6iaGT11BHmCMY/NZg==
37 |
38 | cookie@^0.4.0:
39 | version "0.4.0"
40 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
41 | integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
42 |
43 | mime@^2.4.4:
44 | version "2.4.4"
45 | resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5"
46 | integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==
47 |
48 | regexparam@^1.3.0:
49 | version "1.3.0"
50 | resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f"
51 | integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==
52 |
53 | trouter@^3.1.0:
54 | version "3.1.0"
55 | resolved "https://registry.yarnpkg.com/trouter/-/trouter-3.1.0.tgz#76f4faea81d5ebd11bba4762c664a3b55eda9b23"
56 | integrity sha512-3Swwu638QQWOefHLss9cdyLi5/9BKYmXZEXpH0KOFfB9YZwUAwHbDAcoYxaHfqAeFvbi/LqAK7rGkhCr1v1BJA==
57 | dependencies:
58 | regexparam "^1.3.0"
59 |
--------------------------------------------------------------------------------
/wrangler.toml:
--------------------------------------------------------------------------------
1 | name = "edge-router-docs"
2 | type = "webpack"
3 | account_id = "861533869cd09ff8b4ef02d65205ac54"
4 | workers_dev = false
5 | route = "router.edgehub.in/*"
6 | zone_id = "bd3c7073a97220f7952e86912a574a7c"
7 |
8 | [site]
9 | bucket = "docs"
10 | entry-point = "workers"
11 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5":
6 | version "7.8.3"
7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
8 | integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==
9 | dependencies:
10 | "@babel/highlight" "^7.8.3"
11 |
12 | "@babel/helper-validator-identifier@^7.9.0":
13 | version "7.9.0"
14 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed"
15 | integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==
16 |
17 | "@babel/highlight@^7.8.3":
18 | version "7.9.0"
19 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079"
20 | integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==
21 | dependencies:
22 | "@babel/helper-validator-identifier" "^7.9.0"
23 | chalk "^2.0.0"
24 | js-tokens "^4.0.0"
25 |
26 | "@babel/runtime@^7.8.7":
27 | version "7.9.2"
28 | resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06"
29 | integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==
30 | dependencies:
31 | regenerator-runtime "^0.13.4"
32 |
33 | "@cloudflare/kv-asset-handler@^0.0.9":
34 | version "0.0.9"
35 | resolved "https://registry.yarnpkg.com/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.0.9.tgz#b49247eb49819080ed0db796992e6e5dd7cd81ce"
36 | integrity sha512-OP+uwr+5VShB9ktzJvkwy1AibGaTV7EoHs/YMemUY56fgnqI+IlV++e4T6cTUfHDAfE/pdXMx7q4zMf90dU00Q==
37 | dependencies:
38 | "@types/mime" "^2.0.1"
39 | mime "^2.4.4"
40 |
41 | "@jest/types@^25.3.0":
42 | version "25.3.0"
43 | resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.3.0.tgz#88f94b277a1d028fd7117bc1f74451e0fc2131e7"
44 | integrity sha512-UkaDNewdqXAmCDbN2GlUM6amDKS78eCqiw/UmF5nE0mmLTd6moJkiZJML/X52Ke3LH7Swhw883IRXq8o9nWjVw==
45 | dependencies:
46 | "@types/istanbul-lib-coverage" "^2.0.0"
47 | "@types/istanbul-reports" "^1.1.1"
48 | "@types/yargs" "^15.0.0"
49 | chalk "^3.0.0"
50 |
51 | "@rollup/plugin-commonjs@^11.0.2":
52 | version "11.0.2"
53 | resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-11.0.2.tgz#837cc6950752327cb90177b608f0928a4e60b582"
54 | integrity sha512-MPYGZr0qdbV5zZj8/2AuomVpnRVXRU5XKXb3HVniwRoRCreGlf5kOE081isNWeiLIi6IYkwTX9zE0/c7V8g81g==
55 | dependencies:
56 | "@rollup/pluginutils" "^3.0.0"
57 | estree-walker "^1.0.1"
58 | is-reference "^1.1.2"
59 | magic-string "^0.25.2"
60 | resolve "^1.11.0"
61 |
62 | "@rollup/plugin-node-resolve@^7.1.1":
63 | version "7.1.1"
64 | resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.1.tgz#8c6e59c4b28baf9d223028d0e450e06a485bb2b7"
65 | integrity sha512-14ddhD7TnemeHE97a4rLOhobfYvUVcaYuqTnL8Ti7Jxi9V9Jr5LY7Gko4HZ5k4h4vqQM0gBQt6tsp9xXW94WPA==
66 | dependencies:
67 | "@rollup/pluginutils" "^3.0.6"
68 | "@types/resolve" "0.0.8"
69 | builtin-modules "^3.1.0"
70 | is-module "^1.0.0"
71 | resolve "^1.14.2"
72 |
73 | "@rollup/pluginutils@^3.0.0", "@rollup/pluginutils@^3.0.6", "@rollup/pluginutils@^3.0.8":
74 | version "3.0.8"
75 | resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.0.8.tgz#4e94d128d94b90699e517ef045422960d18c8fde"
76 | integrity sha512-rYGeAc4sxcZ+kPG/Tw4/fwJODC3IXHYDH4qusdN/b6aLw5LPUbzpecYbEJh4sVQGPFJxd2dBU4kc1H3oy9/bnw==
77 | dependencies:
78 | estree-walker "^1.0.1"
79 |
80 | "@samverschueren/stream-to-observable@^0.3.0":
81 | version "0.3.0"
82 | resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
83 | integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==
84 | dependencies:
85 | any-observable "^0.3.0"
86 |
87 | "@types/color-name@^1.1.1":
88 | version "1.1.1"
89 | resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
90 | integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
91 |
92 | "@types/cookie@^0.3.3":
93 | version "0.3.3"
94 | resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.3.tgz#85bc74ba782fb7aa3a514d11767832b0e3bc6803"
95 | integrity sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==
96 |
97 | "@types/estree@0.0.39":
98 | version "0.0.39"
99 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
100 | integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
101 |
102 | "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
103 | version "2.0.1"
104 | resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
105 | integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==
106 |
107 | "@types/istanbul-lib-report@*":
108 | version "3.0.0"
109 | resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686"
110 | integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==
111 | dependencies:
112 | "@types/istanbul-lib-coverage" "*"
113 |
114 | "@types/istanbul-reports@^1.1.1":
115 | version "1.1.1"
116 | resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a"
117 | integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==
118 | dependencies:
119 | "@types/istanbul-lib-coverage" "*"
120 | "@types/istanbul-lib-report" "*"
121 |
122 | "@types/jest@^25.2.1":
123 | version "25.2.1"
124 | resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.2.1.tgz#9544cd438607955381c1bdbdb97767a249297db5"
125 | integrity sha512-msra1bCaAeEdkSyA0CZ6gW1ukMIvZ5YoJkdXw/qhQdsuuDlFTcEUrUw8CLCPt2rVRUfXlClVvK2gvPs9IokZaA==
126 | dependencies:
127 | jest-diff "^25.2.1"
128 | pretty-format "^25.2.1"
129 |
130 | "@types/mime@^2.0.1":
131 | version "2.0.1"
132 | resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d"
133 | integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==
134 |
135 | "@types/node@*":
136 | version "13.11.1"
137 | resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7"
138 | integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==
139 |
140 | "@types/parse-json@^4.0.0":
141 | version "4.0.0"
142 | resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
143 | integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
144 |
145 | "@types/resolve@0.0.8":
146 | version "0.0.8"
147 | resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"
148 | integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==
149 | dependencies:
150 | "@types/node" "*"
151 |
152 | "@types/trouter@^3.1.0":
153 | version "3.1.0"
154 | resolved "https://registry.yarnpkg.com/@types/trouter/-/trouter-3.1.0.tgz#8a3c7b34352b1cb454217a194e8bf03e5cdf7cc4"
155 | integrity sha512-4LPNrqSJknLzILMVXn2P/mh0djNgFvom4T9Y1hmhaB8OBm1cY71bMMSrGRu1q5qF4JZzY6iaGT11BHmCMY/NZg==
156 |
157 | "@types/yargs-parser@*":
158 | version "15.0.0"
159 | resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
160 | integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
161 |
162 | "@types/yargs@^15.0.0":
163 | version "15.0.4"
164 | resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.4.tgz#7e5d0f8ca25e9d5849f2ea443cf7c402decd8299"
165 | integrity sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==
166 | dependencies:
167 | "@types/yargs-parser" "*"
168 |
169 | acorn@^5.7.3:
170 | version "5.7.4"
171 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
172 | integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==
173 |
174 | ansi-escapes@^3.0.0:
175 | version "3.2.0"
176 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
177 | integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==
178 |
179 | ansi-regex@^2.0.0:
180 | version "2.1.1"
181 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
182 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
183 |
184 | ansi-regex@^3.0.0:
185 | version "3.0.0"
186 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
187 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
188 |
189 | ansi-regex@^5.0.0:
190 | version "5.0.0"
191 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
192 | integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
193 |
194 | ansi-styles@^2.2.1:
195 | version "2.2.1"
196 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
197 | integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
198 |
199 | ansi-styles@^3.2.1:
200 | version "3.2.1"
201 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
202 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
203 | dependencies:
204 | color-convert "^1.9.0"
205 |
206 | ansi-styles@^4.0.0, ansi-styles@^4.1.0:
207 | version "4.2.1"
208 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
209 | integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
210 | dependencies:
211 | "@types/color-name" "^1.1.1"
212 | color-convert "^2.0.1"
213 |
214 | any-observable@^0.3.0:
215 | version "0.3.0"
216 | resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b"
217 | integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==
218 |
219 | balanced-match@^1.0.0:
220 | version "1.0.0"
221 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
222 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
223 |
224 | brace-expansion@^1.1.7:
225 | version "1.1.11"
226 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
227 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
228 | dependencies:
229 | balanced-match "^1.0.0"
230 | concat-map "0.0.1"
231 |
232 | braces@^3.0.1:
233 | version "3.0.2"
234 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
235 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
236 | dependencies:
237 | fill-range "^7.0.1"
238 |
239 | buffer-es6@^4.9.3:
240 | version "4.9.3"
241 | resolved "https://registry.yarnpkg.com/buffer-es6/-/buffer-es6-4.9.3.tgz#f26347b82df76fd37e18bcb5288c4970cfd5c404"
242 | integrity sha1-8mNHuC33b9N+GLy1KIxJcM/VxAQ=
243 |
244 | buffer-from@^1.0.0:
245 | version "1.1.1"
246 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
247 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
248 |
249 | builtin-modules@^3.1.0:
250 | version "3.1.0"
251 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.1.0.tgz#aad97c15131eb76b65b50ef208e7584cd76a7484"
252 | integrity sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==
253 |
254 | callsites@^3.0.0:
255 | version "3.1.0"
256 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
257 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
258 |
259 | chalk@^1.0.0, chalk@^1.1.3:
260 | version "1.1.3"
261 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
262 | integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
263 | dependencies:
264 | ansi-styles "^2.2.1"
265 | escape-string-regexp "^1.0.2"
266 | has-ansi "^2.0.0"
267 | strip-ansi "^3.0.0"
268 | supports-color "^2.0.0"
269 |
270 | chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
271 | version "2.4.2"
272 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
273 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
274 | dependencies:
275 | ansi-styles "^3.2.1"
276 | escape-string-regexp "^1.0.5"
277 | supports-color "^5.3.0"
278 |
279 | chalk@^3.0.0:
280 | version "3.0.0"
281 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
282 | integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
283 | dependencies:
284 | ansi-styles "^4.1.0"
285 | supports-color "^7.1.0"
286 |
287 | ci-info@^2.0.0:
288 | version "2.0.0"
289 | resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
290 | integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
291 |
292 | cli-cursor@^2.0.0, cli-cursor@^2.1.0:
293 | version "2.1.0"
294 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
295 | integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=
296 | dependencies:
297 | restore-cursor "^2.0.0"
298 |
299 | cli-truncate@^0.2.1:
300 | version "0.2.1"
301 | resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
302 | integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=
303 | dependencies:
304 | slice-ansi "0.0.4"
305 | string-width "^1.0.1"
306 |
307 | code-point-at@^1.0.0:
308 | version "1.1.0"
309 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
310 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
311 |
312 | color-convert@^1.9.0:
313 | version "1.9.3"
314 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
315 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
316 | dependencies:
317 | color-name "1.1.3"
318 |
319 | color-convert@^2.0.1:
320 | version "2.0.1"
321 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
322 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
323 | dependencies:
324 | color-name "~1.1.4"
325 |
326 | color-name@1.1.3:
327 | version "1.1.3"
328 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
329 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
330 |
331 | color-name@~1.1.4:
332 | version "1.1.4"
333 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
334 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
335 |
336 | commander@^2.20.0:
337 | version "2.20.3"
338 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
339 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
340 |
341 | commander@^4.0.1:
342 | version "4.1.1"
343 | resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
344 | integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
345 |
346 | commondir@^1.0.1:
347 | version "1.0.1"
348 | resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
349 | integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
350 |
351 | compare-versions@^3.5.1:
352 | version "3.6.0"
353 | resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62"
354 | integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==
355 |
356 | concat-map@0.0.1:
357 | version "0.0.1"
358 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
359 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
360 |
361 | cookie@^0.4.0:
362 | version "0.4.0"
363 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
364 | integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
365 |
366 | cosmiconfig@^6.0.0:
367 | version "6.0.0"
368 | resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982"
369 | integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==
370 | dependencies:
371 | "@types/parse-json" "^4.0.0"
372 | import-fresh "^3.1.0"
373 | parse-json "^5.0.0"
374 | path-type "^4.0.0"
375 | yaml "^1.7.2"
376 |
377 | cross-spawn@^7.0.0:
378 | version "7.0.1"
379 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14"
380 | integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==
381 | dependencies:
382 | path-key "^3.1.0"
383 | shebang-command "^2.0.0"
384 | which "^2.0.1"
385 |
386 | date-fns@^1.27.2:
387 | version "1.30.1"
388 | resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
389 | integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
390 |
391 | debug@^4.1.1:
392 | version "4.1.1"
393 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
394 | integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
395 | dependencies:
396 | ms "^2.1.1"
397 |
398 | dedent@^0.7.0:
399 | version "0.7.0"
400 | resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
401 | integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
402 |
403 | diff-sequences@^25.2.6:
404 | version "25.2.6"
405 | resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd"
406 | integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==
407 |
408 | elegant-spinner@^1.0.1:
409 | version "1.0.1"
410 | resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
411 | integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=
412 |
413 | end-of-stream@^1.1.0:
414 | version "1.4.4"
415 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
416 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
417 | dependencies:
418 | once "^1.4.0"
419 |
420 | error-ex@^1.3.1:
421 | version "1.3.2"
422 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
423 | integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
424 | dependencies:
425 | is-arrayish "^0.2.1"
426 |
427 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
428 | version "1.0.5"
429 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
430 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
431 |
432 | estree-walker@^0.5.2:
433 | version "0.5.2"
434 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.2.tgz#d3850be7529c9580d815600b53126515e146dd39"
435 | integrity sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==
436 |
437 | estree-walker@^0.6.1:
438 | version "0.6.1"
439 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362"
440 | integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==
441 |
442 | estree-walker@^1.0.1:
443 | version "1.0.1"
444 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700"
445 | integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==
446 |
447 | execa@^3.4.0:
448 | version "3.4.0"
449 | resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89"
450 | integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==
451 | dependencies:
452 | cross-spawn "^7.0.0"
453 | get-stream "^5.0.0"
454 | human-signals "^1.1.1"
455 | is-stream "^2.0.0"
456 | merge-stream "^2.0.0"
457 | npm-run-path "^4.0.0"
458 | onetime "^5.1.0"
459 | p-finally "^2.0.0"
460 | signal-exit "^3.0.2"
461 | strip-final-newline "^2.0.0"
462 |
463 | figures@^1.7.0:
464 | version "1.7.0"
465 | resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
466 | integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=
467 | dependencies:
468 | escape-string-regexp "^1.0.5"
469 | object-assign "^4.1.0"
470 |
471 | figures@^2.0.0:
472 | version "2.0.0"
473 | resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
474 | integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=
475 | dependencies:
476 | escape-string-regexp "^1.0.5"
477 |
478 | fill-range@^7.0.1:
479 | version "7.0.1"
480 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
481 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
482 | dependencies:
483 | to-regex-range "^5.0.1"
484 |
485 | find-cache-dir@^3.3.1:
486 | version "3.3.1"
487 | resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880"
488 | integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==
489 | dependencies:
490 | commondir "^1.0.1"
491 | make-dir "^3.0.2"
492 | pkg-dir "^4.1.0"
493 |
494 | find-up@^4.0.0:
495 | version "4.1.0"
496 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
497 | integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
498 | dependencies:
499 | locate-path "^5.0.0"
500 | path-exists "^4.0.0"
501 |
502 | find-versions@^3.2.0:
503 | version "3.2.0"
504 | resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e"
505 | integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==
506 | dependencies:
507 | semver-regex "^2.0.0"
508 |
509 | fs-extra@8.1.0:
510 | version "8.1.0"
511 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
512 | integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
513 | dependencies:
514 | graceful-fs "^4.2.0"
515 | jsonfile "^4.0.0"
516 | universalify "^0.1.0"
517 |
518 | fs.realpath@^1.0.0:
519 | version "1.0.0"
520 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
521 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
522 |
523 | fsevents@~2.1.2:
524 | version "2.1.2"
525 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805"
526 | integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==
527 |
528 | get-own-enumerable-property-symbols@^3.0.0:
529 | version "3.0.2"
530 | resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
531 | integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==
532 |
533 | get-stream@^5.0.0:
534 | version "5.1.0"
535 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9"
536 | integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==
537 | dependencies:
538 | pump "^3.0.0"
539 |
540 | glob@^7.1.3:
541 | version "7.1.6"
542 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
543 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
544 | dependencies:
545 | fs.realpath "^1.0.0"
546 | inflight "^1.0.4"
547 | inherits "2"
548 | minimatch "^3.0.4"
549 | once "^1.3.0"
550 | path-is-absolute "^1.0.0"
551 |
552 | graceful-fs@^4.1.6, graceful-fs@^4.2.0:
553 | version "4.2.3"
554 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
555 | integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
556 |
557 | has-ansi@^2.0.0:
558 | version "2.0.0"
559 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
560 | integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
561 | dependencies:
562 | ansi-regex "^2.0.0"
563 |
564 | has-flag@^3.0.0:
565 | version "3.0.0"
566 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
567 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
568 |
569 | has-flag@^4.0.0:
570 | version "4.0.0"
571 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
572 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
573 |
574 | human-signals@^1.1.1:
575 | version "1.1.1"
576 | resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
577 | integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
578 |
579 | husky@^4.2.3:
580 | version "4.2.3"
581 | resolved "https://registry.yarnpkg.com/husky/-/husky-4.2.3.tgz#3b18d2ee5febe99e27f2983500202daffbc3151e"
582 | integrity sha512-VxTsSTRwYveKXN4SaH1/FefRJYCtx+wx04sSVcOpD7N2zjoHxa+cEJ07Qg5NmV3HAK+IRKOyNVpi2YBIVccIfQ==
583 | dependencies:
584 | chalk "^3.0.0"
585 | ci-info "^2.0.0"
586 | compare-versions "^3.5.1"
587 | cosmiconfig "^6.0.0"
588 | find-versions "^3.2.0"
589 | opencollective-postinstall "^2.0.2"
590 | pkg-dir "^4.2.0"
591 | please-upgrade-node "^3.2.0"
592 | slash "^3.0.0"
593 | which-pm-runs "^1.0.0"
594 |
595 | import-fresh@^3.1.0:
596 | version "3.2.1"
597 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
598 | integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==
599 | dependencies:
600 | parent-module "^1.0.0"
601 | resolve-from "^4.0.0"
602 |
603 | indent-string@^3.0.0:
604 | version "3.2.0"
605 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
606 | integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=
607 |
608 | inflight@^1.0.4:
609 | version "1.0.6"
610 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
611 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
612 | dependencies:
613 | once "^1.3.0"
614 | wrappy "1"
615 |
616 | inherits@2:
617 | version "2.0.4"
618 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
619 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
620 |
621 | is-arrayish@^0.2.1:
622 | version "0.2.1"
623 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
624 | integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
625 |
626 | is-fullwidth-code-point@^1.0.0:
627 | version "1.0.0"
628 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
629 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
630 | dependencies:
631 | number-is-nan "^1.0.0"
632 |
633 | is-fullwidth-code-point@^2.0.0:
634 | version "2.0.0"
635 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
636 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
637 |
638 | is-module@^1.0.0:
639 | version "1.0.0"
640 | resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
641 | integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
642 |
643 | is-number@^7.0.0:
644 | version "7.0.0"
645 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
646 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
647 |
648 | is-obj@^1.0.1:
649 | version "1.0.1"
650 | resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
651 | integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
652 |
653 | is-observable@^1.1.0:
654 | version "1.1.0"
655 | resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e"
656 | integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==
657 | dependencies:
658 | symbol-observable "^1.1.0"
659 |
660 | is-promise@^2.1.0:
661 | version "2.1.0"
662 | resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
663 | integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
664 |
665 | is-reference@^1.1.2:
666 | version "1.1.4"
667 | resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.1.4.tgz#3f95849886ddb70256a3e6d062b1a68c13c51427"
668 | integrity sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==
669 | dependencies:
670 | "@types/estree" "0.0.39"
671 |
672 | is-regexp@^1.0.0:
673 | version "1.0.0"
674 | resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
675 | integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk=
676 |
677 | is-stream@^1.1.0:
678 | version "1.1.0"
679 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
680 | integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
681 |
682 | is-stream@^2.0.0:
683 | version "2.0.0"
684 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
685 | integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
686 |
687 | isexe@^2.0.0:
688 | version "2.0.0"
689 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
690 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
691 |
692 | jest-diff@^25.2.1:
693 | version "25.3.0"
694 | resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.3.0.tgz#0d7d6f5d6171e5dacde9e05be47b3615e147c26f"
695 | integrity sha512-vyvs6RPoVdiwARwY4kqFWd4PirPLm2dmmkNzKqo38uZOzJvLee87yzDjIZLmY1SjM3XR5DwsUH+cdQ12vgqi1w==
696 | dependencies:
697 | chalk "^3.0.0"
698 | diff-sequences "^25.2.6"
699 | jest-get-type "^25.2.6"
700 | pretty-format "^25.3.0"
701 |
702 | jest-get-type@^25.2.6:
703 | version "25.2.6"
704 | resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877"
705 | integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==
706 |
707 | jest-worker@^24.9.0:
708 | version "24.9.0"
709 | resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5"
710 | integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==
711 | dependencies:
712 | merge-stream "^2.0.0"
713 | supports-color "^6.1.0"
714 |
715 | js-tokens@^4.0.0:
716 | version "4.0.0"
717 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
718 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
719 |
720 | json-parse-better-errors@^1.0.1:
721 | version "1.0.2"
722 | resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
723 | integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
724 |
725 | jsonfile@^4.0.0:
726 | version "4.0.0"
727 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
728 | integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
729 | optionalDependencies:
730 | graceful-fs "^4.1.6"
731 |
732 | lines-and-columns@^1.1.6:
733 | version "1.1.6"
734 | resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
735 | integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
736 |
737 | lint-staged@^10.0.10:
738 | version "10.0.10"
739 | resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.0.10.tgz#d14d33ee02a31a31ad36cf9aa7973fc156c461b5"
740 | integrity sha512-91vNy3eYStExElLWw1Idva5lghKpFaXh9AJqjcyrJXf7AYZrThi4EhQ+GpmiHdPmJJauKhZMMSzQR1bMB90MtA==
741 | dependencies:
742 | chalk "^3.0.0"
743 | commander "^4.0.1"
744 | cosmiconfig "^6.0.0"
745 | debug "^4.1.1"
746 | dedent "^0.7.0"
747 | execa "^3.4.0"
748 | listr "^0.14.3"
749 | log-symbols "^3.0.0"
750 | micromatch "^4.0.2"
751 | normalize-path "^3.0.0"
752 | please-upgrade-node "^3.2.0"
753 | string-argv "0.3.1"
754 | stringify-object "^3.3.0"
755 |
756 | listr-silent-renderer@^1.1.1:
757 | version "1.1.1"
758 | resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
759 | integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=
760 |
761 | listr-update-renderer@^0.5.0:
762 | version "0.5.0"
763 | resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2"
764 | integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==
765 | dependencies:
766 | chalk "^1.1.3"
767 | cli-truncate "^0.2.1"
768 | elegant-spinner "^1.0.1"
769 | figures "^1.7.0"
770 | indent-string "^3.0.0"
771 | log-symbols "^1.0.2"
772 | log-update "^2.3.0"
773 | strip-ansi "^3.0.1"
774 |
775 | listr-verbose-renderer@^0.5.0:
776 | version "0.5.0"
777 | resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db"
778 | integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==
779 | dependencies:
780 | chalk "^2.4.1"
781 | cli-cursor "^2.1.0"
782 | date-fns "^1.27.2"
783 | figures "^2.0.0"
784 |
785 | listr@^0.14.3:
786 | version "0.14.3"
787 | resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586"
788 | integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==
789 | dependencies:
790 | "@samverschueren/stream-to-observable" "^0.3.0"
791 | is-observable "^1.1.0"
792 | is-promise "^2.1.0"
793 | is-stream "^1.1.0"
794 | listr-silent-renderer "^1.1.1"
795 | listr-update-renderer "^0.5.0"
796 | listr-verbose-renderer "^0.5.0"
797 | p-map "^2.0.0"
798 | rxjs "^6.3.3"
799 |
800 | locate-path@^5.0.0:
801 | version "5.0.0"
802 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
803 | integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
804 | dependencies:
805 | p-locate "^4.1.0"
806 |
807 | log-symbols@^1.0.2:
808 | version "1.0.2"
809 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
810 | integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=
811 | dependencies:
812 | chalk "^1.0.0"
813 |
814 | log-symbols@^3.0.0:
815 | version "3.0.0"
816 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4"
817 | integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==
818 | dependencies:
819 | chalk "^2.4.2"
820 |
821 | log-update@^2.3.0:
822 | version "2.3.0"
823 | resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708"
824 | integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg=
825 | dependencies:
826 | ansi-escapes "^3.0.0"
827 | cli-cursor "^2.0.0"
828 | wrap-ansi "^3.0.1"
829 |
830 | magic-string@^0.22.5:
831 | version "0.22.5"
832 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e"
833 | integrity sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==
834 | dependencies:
835 | vlq "^0.2.2"
836 |
837 | magic-string@^0.25.2:
838 | version "0.25.7"
839 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
840 | integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
841 | dependencies:
842 | sourcemap-codec "^1.4.4"
843 |
844 | make-dir@^3.0.2:
845 | version "3.0.2"
846 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392"
847 | integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==
848 | dependencies:
849 | semver "^6.0.0"
850 |
851 | merge-stream@^2.0.0:
852 | version "2.0.0"
853 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
854 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
855 |
856 | micromatch@^4.0.2:
857 | version "4.0.2"
858 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
859 | integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
860 | dependencies:
861 | braces "^3.0.1"
862 | picomatch "^2.0.5"
863 |
864 | mime@^2.4.4:
865 | version "2.4.4"
866 | resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5"
867 | integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==
868 |
869 | mimic-fn@^1.0.0:
870 | version "1.2.0"
871 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
872 | integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
873 |
874 | mimic-fn@^2.1.0:
875 | version "2.1.0"
876 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
877 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
878 |
879 | minimatch@^3.0.4:
880 | version "3.0.4"
881 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
882 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
883 | dependencies:
884 | brace-expansion "^1.1.7"
885 |
886 | ms@^2.1.1:
887 | version "2.1.2"
888 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
889 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
890 |
891 | normalize-path@^3.0.0:
892 | version "3.0.0"
893 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
894 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
895 |
896 | npm-run-path@^4.0.0:
897 | version "4.0.1"
898 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
899 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
900 | dependencies:
901 | path-key "^3.0.0"
902 |
903 | number-is-nan@^1.0.0:
904 | version "1.0.1"
905 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
906 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
907 |
908 | object-assign@^4.1.0:
909 | version "4.1.1"
910 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
911 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
912 |
913 | once@^1.3.0, once@^1.3.1, once@^1.4.0:
914 | version "1.4.0"
915 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
916 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
917 | dependencies:
918 | wrappy "1"
919 |
920 | onetime@^2.0.0:
921 | version "2.0.1"
922 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
923 | integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=
924 | dependencies:
925 | mimic-fn "^1.0.0"
926 |
927 | onetime@^5.1.0:
928 | version "5.1.0"
929 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5"
930 | integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==
931 | dependencies:
932 | mimic-fn "^2.1.0"
933 |
934 | opencollective-postinstall@^2.0.2:
935 | version "2.0.2"
936 | resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89"
937 | integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==
938 |
939 | p-finally@^2.0.0:
940 | version "2.0.1"
941 | resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561"
942 | integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==
943 |
944 | p-limit@^2.2.0:
945 | version "2.2.2"
946 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e"
947 | integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==
948 | dependencies:
949 | p-try "^2.0.0"
950 |
951 | p-locate@^4.1.0:
952 | version "4.1.0"
953 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
954 | integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
955 | dependencies:
956 | p-limit "^2.2.0"
957 |
958 | p-map@^2.0.0:
959 | version "2.1.0"
960 | resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
961 | integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
962 |
963 | p-try@^2.0.0:
964 | version "2.2.0"
965 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
966 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
967 |
968 | parent-module@^1.0.0:
969 | version "1.0.1"
970 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
971 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
972 | dependencies:
973 | callsites "^3.0.0"
974 |
975 | parse-json@^5.0.0:
976 | version "5.0.0"
977 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f"
978 | integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==
979 | dependencies:
980 | "@babel/code-frame" "^7.0.0"
981 | error-ex "^1.3.1"
982 | json-parse-better-errors "^1.0.1"
983 | lines-and-columns "^1.1.6"
984 |
985 | path-exists@^4.0.0:
986 | version "4.0.0"
987 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
988 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
989 |
990 | path-is-absolute@^1.0.0:
991 | version "1.0.1"
992 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
993 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
994 |
995 | path-key@^3.0.0, path-key@^3.1.0:
996 | version "3.1.1"
997 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
998 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
999 |
1000 | path-parse@^1.0.6:
1001 | version "1.0.6"
1002 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
1003 | integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
1004 |
1005 | path-type@^4.0.0:
1006 | version "4.0.0"
1007 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
1008 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
1009 |
1010 | picomatch@^2.0.5:
1011 | version "2.2.2"
1012 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
1013 | integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
1014 |
1015 | pkg-dir@^4.1.0, pkg-dir@^4.2.0:
1016 | version "4.2.0"
1017 | resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
1018 | integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
1019 | dependencies:
1020 | find-up "^4.0.0"
1021 |
1022 | please-upgrade-node@^3.2.0:
1023 | version "3.2.0"
1024 | resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"
1025 | integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==
1026 | dependencies:
1027 | semver-compare "^1.0.0"
1028 |
1029 | prettier@^2.0.2:
1030 | version "2.0.2"
1031 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08"
1032 | integrity sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg==
1033 |
1034 | pretty-format@^25.2.1, pretty-format@^25.3.0:
1035 | version "25.3.0"
1036 | resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.3.0.tgz#d0a4f988ff4a6cd350342fdabbb809aeb4d49ad5"
1037 | integrity sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA==
1038 | dependencies:
1039 | "@jest/types" "^25.3.0"
1040 | ansi-regex "^5.0.0"
1041 | ansi-styles "^4.0.0"
1042 | react-is "^16.12.0"
1043 |
1044 | process-es6@^0.11.6:
1045 | version "0.11.6"
1046 | resolved "https://registry.yarnpkg.com/process-es6/-/process-es6-0.11.6.tgz#c6bb389f9a951f82bd4eb169600105bd2ff9c778"
1047 | integrity sha1-xrs4n5qVH4K9TrFpYAEFvS/5x3g=
1048 |
1049 | pump@^3.0.0:
1050 | version "3.0.0"
1051 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
1052 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
1053 | dependencies:
1054 | end-of-stream "^1.1.0"
1055 | once "^1.3.1"
1056 |
1057 | react-is@^16.12.0:
1058 | version "16.13.1"
1059 | resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
1060 | integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
1061 |
1062 | regenerator-runtime@^0.13.4:
1063 | version "0.13.5"
1064 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"
1065 | integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
1066 |
1067 | regexparam@^1.3.0:
1068 | version "1.3.0"
1069 | resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f"
1070 | integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==
1071 |
1072 | resolve-from@^4.0.0:
1073 | version "4.0.0"
1074 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
1075 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
1076 |
1077 | resolve@1.15.1, resolve@^1.11.0, resolve@^1.14.2:
1078 | version "1.15.1"
1079 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
1080 | integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==
1081 | dependencies:
1082 | path-parse "^1.0.6"
1083 |
1084 | restore-cursor@^2.0.0:
1085 | version "2.0.0"
1086 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
1087 | integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368=
1088 | dependencies:
1089 | onetime "^2.0.0"
1090 | signal-exit "^3.0.2"
1091 |
1092 | rimraf@^3.0.2:
1093 | version "3.0.2"
1094 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
1095 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
1096 | dependencies:
1097 | glob "^7.1.3"
1098 |
1099 | rollup-plugin-node-globals@^1.4.0:
1100 | version "1.4.0"
1101 | resolved "https://registry.yarnpkg.com/rollup-plugin-node-globals/-/rollup-plugin-node-globals-1.4.0.tgz#5e1f24a9bb97c0ef51249f625e16c7e61b7c020b"
1102 | integrity sha512-xRkB+W/m1KLIzPUmG0ofvR+CPNcvuCuNdjVBVS7ALKSxr3EDhnzNceGkGi1m8MToSli13AzKFYH4ie9w3I5L3g==
1103 | dependencies:
1104 | acorn "^5.7.3"
1105 | buffer-es6 "^4.9.3"
1106 | estree-walker "^0.5.2"
1107 | magic-string "^0.22.5"
1108 | process-es6 "^0.11.6"
1109 | rollup-pluginutils "^2.3.1"
1110 |
1111 | rollup-plugin-terser@^5.3.0:
1112 | version "5.3.0"
1113 | resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-5.3.0.tgz#9c0dd33d5771df9630cd027d6a2559187f65885e"
1114 | integrity sha512-XGMJihTIO3eIBsVGq7jiNYOdDMb3pVxuzY0uhOE/FM4x/u9nQgr3+McsjzqBn3QfHIpNSZmFnpoKAwHBEcsT7g==
1115 | dependencies:
1116 | "@babel/code-frame" "^7.5.5"
1117 | jest-worker "^24.9.0"
1118 | rollup-pluginutils "^2.8.2"
1119 | serialize-javascript "^2.1.2"
1120 | terser "^4.6.2"
1121 |
1122 | rollup-plugin-typescript2@^0.27.0:
1123 | version "0.27.0"
1124 | resolved "https://registry.yarnpkg.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.27.0.tgz#95ff96f9e07d5000a9d2df4d76b548f9a1f83511"
1125 | integrity sha512-SRKG/Canve3cxBsqhY1apIBznqnX9X/WU3Lrq3XSwmTmFqccj3+//logLXFEmp+PYFNllSVng+f4zjqRTPKNkA==
1126 | dependencies:
1127 | "@rollup/pluginutils" "^3.0.8"
1128 | find-cache-dir "^3.3.1"
1129 | fs-extra "8.1.0"
1130 | resolve "1.15.1"
1131 | tslib "1.11.1"
1132 |
1133 | rollup-pluginutils@^2.3.1, rollup-pluginutils@^2.8.2:
1134 | version "2.8.2"
1135 | resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e"
1136 | integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==
1137 | dependencies:
1138 | estree-walker "^0.6.1"
1139 |
1140 | rollup@^2.6.0:
1141 | version "2.6.0"
1142 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.6.0.tgz#e69d50dc2217af23ab5f6df9a48e45df4ab56df1"
1143 | integrity sha512-qbvQ9ZbvbhBdtRBZ/A4g+9z3iJQ1rHAtjinn3FiN+j5tfz8xiNyTE1JEEMcFWqlH7+NHadI9ieeqKdp8HwYLnQ==
1144 | optionalDependencies:
1145 | fsevents "~2.1.2"
1146 |
1147 | rxjs@^6.3.3:
1148 | version "6.5.4"
1149 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c"
1150 | integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==
1151 | dependencies:
1152 | tslib "^1.9.0"
1153 |
1154 | semver-compare@^1.0.0:
1155 | version "1.0.0"
1156 | resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
1157 | integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
1158 |
1159 | semver-regex@^2.0.0:
1160 | version "2.0.0"
1161 | resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338"
1162 | integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==
1163 |
1164 | semver@^6.0.0:
1165 | version "6.3.0"
1166 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
1167 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
1168 |
1169 | serialize-javascript@^2.1.2:
1170 | version "2.1.2"
1171 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
1172 | integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==
1173 |
1174 | shebang-command@^2.0.0:
1175 | version "2.0.0"
1176 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
1177 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
1178 | dependencies:
1179 | shebang-regex "^3.0.0"
1180 |
1181 | shebang-regex@^3.0.0:
1182 | version "3.0.0"
1183 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
1184 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
1185 |
1186 | signal-exit@^3.0.2:
1187 | version "3.0.3"
1188 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
1189 | integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
1190 |
1191 | slash@^3.0.0:
1192 | version "3.0.0"
1193 | resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
1194 | integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
1195 |
1196 | slice-ansi@0.0.4:
1197 | version "0.0.4"
1198 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
1199 | integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=
1200 |
1201 | source-map-support@~0.5.12:
1202 | version "0.5.16"
1203 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
1204 | integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==
1205 | dependencies:
1206 | buffer-from "^1.0.0"
1207 | source-map "^0.6.0"
1208 |
1209 | source-map@^0.6.0, source-map@~0.6.1:
1210 | version "0.6.1"
1211 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
1212 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
1213 |
1214 | sourcemap-codec@^1.4.4:
1215 | version "1.4.8"
1216 | resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
1217 | integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
1218 |
1219 | string-argv@0.3.1:
1220 | version "0.3.1"
1221 | resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da"
1222 | integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==
1223 |
1224 | string-width@^1.0.1:
1225 | version "1.0.2"
1226 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
1227 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
1228 | dependencies:
1229 | code-point-at "^1.0.0"
1230 | is-fullwidth-code-point "^1.0.0"
1231 | strip-ansi "^3.0.0"
1232 |
1233 | string-width@^2.1.1:
1234 | version "2.1.1"
1235 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
1236 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
1237 | dependencies:
1238 | is-fullwidth-code-point "^2.0.0"
1239 | strip-ansi "^4.0.0"
1240 |
1241 | stringify-object@^3.3.0:
1242 | version "3.3.0"
1243 | resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629"
1244 | integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==
1245 | dependencies:
1246 | get-own-enumerable-property-symbols "^3.0.0"
1247 | is-obj "^1.0.1"
1248 | is-regexp "^1.0.0"
1249 |
1250 | strip-ansi@^3.0.0, strip-ansi@^3.0.1:
1251 | version "3.0.1"
1252 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
1253 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
1254 | dependencies:
1255 | ansi-regex "^2.0.0"
1256 |
1257 | strip-ansi@^4.0.0:
1258 | version "4.0.0"
1259 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
1260 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
1261 | dependencies:
1262 | ansi-regex "^3.0.0"
1263 |
1264 | strip-final-newline@^2.0.0:
1265 | version "2.0.0"
1266 | resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
1267 | integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
1268 |
1269 | supports-color@^2.0.0:
1270 | version "2.0.0"
1271 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
1272 | integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
1273 |
1274 | supports-color@^5.3.0:
1275 | version "5.5.0"
1276 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
1277 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
1278 | dependencies:
1279 | has-flag "^3.0.0"
1280 |
1281 | supports-color@^6.1.0:
1282 | version "6.1.0"
1283 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
1284 | integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
1285 | dependencies:
1286 | has-flag "^3.0.0"
1287 |
1288 | supports-color@^7.1.0:
1289 | version "7.1.0"
1290 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
1291 | integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==
1292 | dependencies:
1293 | has-flag "^4.0.0"
1294 |
1295 | symbol-observable@^1.1.0:
1296 | version "1.2.0"
1297 | resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
1298 | integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
1299 |
1300 | terser@^4.6.2:
1301 | version "4.6.11"
1302 | resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.11.tgz#12ff99fdd62a26de2a82f508515407eb6ccd8a9f"
1303 | integrity sha512-76Ynm7OXUG5xhOpblhytE7X58oeNSmC8xnNhjWVo8CksHit0U0kO4hfNbPrrYwowLWFgM2n9L176VNx2QaHmtA==
1304 | dependencies:
1305 | commander "^2.20.0"
1306 | source-map "~0.6.1"
1307 | source-map-support "~0.5.12"
1308 |
1309 | to-regex-range@^5.0.1:
1310 | version "5.0.1"
1311 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
1312 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
1313 | dependencies:
1314 | is-number "^7.0.0"
1315 |
1316 | trouter@^3.1.0:
1317 | version "3.1.0"
1318 | resolved "https://registry.yarnpkg.com/trouter/-/trouter-3.1.0.tgz#76f4faea81d5ebd11bba4762c664a3b55eda9b23"
1319 | integrity sha512-3Swwu638QQWOefHLss9cdyLi5/9BKYmXZEXpH0KOFfB9YZwUAwHbDAcoYxaHfqAeFvbi/LqAK7rGkhCr1v1BJA==
1320 | dependencies:
1321 | regexparam "^1.3.0"
1322 |
1323 | tslib@1.11.1, tslib@^1.9.0:
1324 | version "1.11.1"
1325 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
1326 | integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==
1327 |
1328 | typescript@^3.8.3:
1329 | version "3.8.3"
1330 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061"
1331 | integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==
1332 |
1333 | universalify@^0.1.0:
1334 | version "0.1.2"
1335 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
1336 | integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
1337 |
1338 | vlq@^0.2.2:
1339 | version "0.2.3"
1340 | resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26"
1341 | integrity sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==
1342 |
1343 | which-pm-runs@^1.0.0:
1344 | version "1.0.0"
1345 | resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb"
1346 | integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=
1347 |
1348 | which@^2.0.1:
1349 | version "2.0.2"
1350 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
1351 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
1352 | dependencies:
1353 | isexe "^2.0.0"
1354 |
1355 | wrap-ansi@^3.0.1:
1356 | version "3.0.1"
1357 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba"
1358 | integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=
1359 | dependencies:
1360 | string-width "^2.1.1"
1361 | strip-ansi "^4.0.0"
1362 |
1363 | wrappy@1:
1364 | version "1.0.2"
1365 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
1366 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
1367 |
1368 | yaml@^1.7.2:
1369 | version "1.8.3"
1370 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.8.3.tgz#2f420fca58b68ce3a332d0ca64be1d191dd3f87a"
1371 | integrity sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw==
1372 | dependencies:
1373 | "@babel/runtime" "^7.8.7"
1374 |
--------------------------------------------------------------------------------