├── .codeclimate.yml
├── .env
├── .github
└── workflows
│ ├── deploy.yml
│ └── test.yml
├── .gitignore
├── .nvmrc
├── .prettierignore
├── LICENSE
├── README.md
├── codecov.yml
├── index.js
├── lerna.json
├── package-lock.json
├── package.json
├── packages
├── client
│ ├── .env
│ ├── .gitignore
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ ├── src
│ │ ├── App.css
│ │ ├── App.test.tsx
│ │ ├── App.tsx
│ │ ├── index.css
│ │ ├── index.tsx
│ │ ├── logo.svg
│ │ ├── react-app-env.d.ts
│ │ ├── serviceWorker.ts
│ │ └── setupTests.ts
│ └── tsconfig.json
├── e2e
│ ├── README.md
│ ├── __tests__
│ │ └── index.test.ts
│ ├── jest-playwright.config.js
│ ├── jest.config.js
│ ├── package-lock.json
│ ├── package.json
│ └── tsconfig.json
├── server
│ ├── README.md
│ ├── jest.config.js
│ ├── jest.setup.js
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ │ ├── hello.test.ts
│ │ ├── hello.ts
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ └── types.d.ts
│ └── tsconfig.json
└── worker
│ ├── .gitignore
│ ├── README.md
│ ├── null.js
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ ├── handleError.ts
│ ├── index.ts
│ └── pages.ts
│ ├── tsconfig.json
│ └── webpack.config.js
├── updatePackages.js
└── wrangler.toml
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | version: "2"
2 | plugins:
3 | eslint:
4 | enabled: true
5 | fixme:
6 | enabled: true
7 | git-legal:
8 | enabled: true
9 | markdownlint:
10 | enabled: true
11 | checks:
12 | MD033:
13 | enabled: false
14 | MD013:
15 | enabled: false
16 | nodesecurity:
17 | enabled: true
18 | exclude_patterns:
19 | - ""
20 |
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | SKIP_PREFLIGHT_CHECK=true
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy
2 | on:
3 | repository_dispatch:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | deploy:
10 | runs-on: ubuntu-latest
11 | name: Deploy
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v2
15 | - name: Setup Node
16 | uses: actions/setup-node@v1
17 | - name: Install
18 | run: npm ci
19 | - name: Deploy
20 | run: npm run deploy
21 | env:
22 | CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
23 | CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
24 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 | on: [push]
3 |
4 | jobs:
5 | deploy:
6 | runs-on: ubuntu-latest
7 | name: Test
8 | steps:
9 | - name: Checkout
10 | uses: actions/checkout@v2
11 | - name: Setup Node
12 | uses: actions/setup-node@v1
13 | - name: Setup Playwright
14 | uses: microsoft/playwright-github-action@v1
15 | - name: Install
16 | run: npm ci
17 | - name: Lint
18 | run: npm run lint
19 | - name: Test
20 | run: npm run test
21 | env:
22 | CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
23 | CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
24 | - name: Upload Coverage Report
25 | uses: codecov/codecov-action@v1.0.6
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/git,node,react,visualstudiocode
3 | # Edit at https://www.gitignore.io/?templates=git,node,react,visualstudiocode
4 |
5 | ### Git ###
6 | # Created by git for backups. To disable backups in Git:
7 | # $ git config --global mergetool.keepBackup false
8 | *.orig
9 |
10 | # Created by git when using merge tools for conflicts
11 | *.BACKUP.*
12 | *.BASE.*
13 | *.LOCAL.*
14 | *.REMOTE.*
15 | *_BACKUP_*.txt
16 | *_BASE_*.txt
17 | *_LOCAL_*.txt
18 | *_REMOTE_*.txt
19 |
20 | ### Node ###
21 | # Logs
22 | logs
23 | *.log
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 | lerna-debug.log*
28 |
29 | # Diagnostic reports (https://nodejs.org/api/report.html)
30 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
31 |
32 | # Runtime data
33 | pids
34 | *.pid
35 | *.seed
36 | *.pid.lock
37 |
38 | # Directory for instrumented libs generated by jscoverage/JSCover
39 | lib-cov
40 |
41 | # Coverage directory used by tools like istanbul
42 | coverage
43 | *.lcov
44 |
45 | # nyc test coverage
46 | .nyc_output
47 |
48 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
49 | .grunt
50 |
51 | # Bower dependency directory (https://bower.io/)
52 | bower_components
53 |
54 | # node-waf configuration
55 | .lock-wscript
56 |
57 | # Compiled binary addons (https://nodejs.org/api/addons.html)
58 | build/Release
59 |
60 | # Dependency directories
61 | node_modules/
62 | jspm_packages/
63 |
64 | # TypeScript v1 declaration files
65 | typings/
66 |
67 | # TypeScript cache
68 | *.tsbuildinfo
69 |
70 | # Optional npm cache directory
71 | .npm
72 |
73 | # Optional eslint cache
74 | .eslintcache
75 |
76 | # Optional REPL history
77 | .node_repl_history
78 |
79 | # Output of 'npm pack'
80 | *.tgz
81 |
82 | # Yarn Integrity file
83 | .yarn-integrity
84 |
85 | # dotenv environment variables file
86 | # .env
87 | .env.test
88 |
89 | # parcel-bundler cache (https://parceljs.org/)
90 | .cache
91 |
92 | # next.js build output
93 | .next
94 |
95 | # nuxt.js build output
96 | .nuxt
97 |
98 | # rollup.js default build output
99 | dist/
100 |
101 | # Uncomment the public line if your project uses Gatsby
102 | # https://nextjs.org/blog/next-9-1#public-directory-support
103 | # https://create-react-app.dev/docs/using-the-public-folder/#docsNav
104 | # public
105 |
106 | # Storybook build outputs
107 | .out
108 | .storybook-out
109 |
110 | # vuepress build output
111 | .vuepress/dist
112 |
113 | # Serverless directories
114 | .serverless/
115 |
116 | # FuseBox cache
117 | .fusebox/
118 |
119 | # DynamoDB Local files
120 | .dynamodb/
121 |
122 | # Temporary folders
123 | tmp/
124 | temp/
125 |
126 | ### react ###
127 | .DS_*
128 | **/*.backup.*
129 | **/*.back.*
130 |
131 | node_modules
132 |
133 | *.sublime*
134 |
135 | psd
136 | thumb
137 | sketch
138 |
139 | ### VisualStudioCode ###
140 | .vscode/*
141 | !.vscode/settings.json
142 | !.vscode/tasks.json
143 | !.vscode/launch.json
144 | !.vscode/extensions.json
145 |
146 | ### VisualStudioCode Patch ###
147 | # Ignore all local history of files
148 | .history
149 |
150 | # End of https://www.gitignore.io/api/git,node,react,visualstudiocode
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v13.14.0
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | /packages/client/coverage
2 | /packages/client/build
3 | /packages/server/coverage
4 | /packages/worker/build
5 | /packages/worker/worker
6 | /**/package-lock.json
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Greg Brimble
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cloudflare Workers Typescript Server & Client Template
2 |
3 | [](https://github.com/GregBrimble/cf-workers-typescript-template/actions?query=workflow%3ATest)
4 | [](https://github.com/GregBrimble/cf-workers-typescript-template/actions?query=workflow%3ADeploy)
5 | [](https://lgtm.com/projects/g/GregBrimble/cf-workers-typescript-template/alerts/)
6 | [](https://lgtm.com/projects/g/GregBrimble/cf-workers-typescript-template/context:javascript)
7 | [](https://codeclimate.com/github/GregBrimble/cf-workers-typescript-template/maintainability)
8 | [](https://codecov.io/gh/GregBrimble/cf-workers-typescript-template)
9 | [](https://github.com/GregBrimble/cf-workers-typescript-template/blob/master/LICENSE)
10 | [](https://github.com/GregBrimble/cf-workers-typescript-template)
11 | [](https://lerna.js.org/)
12 |
13 | A perfect\* template for a [Cloudflare Workers](https://workers.cloudflare.com/) project, using [Workers Sites](https://workers.cloudflare.com/sites) ([React](https://reactjs.org/) although can be easily swapped for [Gatsby](https://www.gatsbyjs.org/) or another static builder), [TypeScript](https://www.typescriptlang.org/), [Jest](https://jestjs.io/) and [Prettier](https://prettier.io/).
14 |
15 | **And now, with end-to-end tests thanks to the new [`wrangler dev`](https://github.com/cloudflare/wrangler#-dev) command and [Playwright](https://playwright.dev/)! ✨**
16 |
17 | ## Prerequisites
18 |
19 | - [Node.js](https://nodejs.org/en/)
20 |
21 | - [`cloudflared`](https://developers.cloudflare.com/argo-tunnel/downloads/)
22 |
23 | (On MacOS with Homebrew: `brew install cloudflare/cloudflare/cloudflared`)
24 |
25 | ## Getting Started
26 |
27 | ### Automatic
28 |
29 | Click [the button below](<(https://deploy.workers.cloudflare.com/?url=https://github.com/GregBrimble/cf-workers-typescript-template&paid=true)>) and follow the setup instructions.
30 |
31 | [](https://deploy.workers.cloudflare.com/?url=https://github.com/GregBrimble/cf-workers-typescript-template&paid=true)
32 |
33 | ### Manual
34 |
35 | 1. Fork repository:
36 |
37 | 1. Click the [`Use this template`](https://github.com/GregBrimble/cf-workers-typescript-template/generate) button.
38 |
39 | 1. Add GitHub Actions secret for [`CF_ACCOUNT_ID`](https://dash.cloudflare.com/?to=/:account/workers) and [`CF_API_TOKEN`](https://dash.cloudflare.com/profile/api-tokens) using `Edit Cloudflare Workers` template permissions.
40 |
41 | 1. Enable the [CodeClimate](https://github.com/settings/installations/205740), [Codecov](https://github.com/settings/installations/655980), [LGTM](https://github.com/settings/installations/2030503), and [Synk](https://snyk.io/) apps.
42 |
43 | 1. (Optionally) Update `.nvmrc`:
44 |
45 | - Find available versions with `nvm ls-remote`
46 | - Use the current Node.js version with `node -v > .nvmrc`
47 |
48 | 1. Update `wrangler.toml`:
49 |
50 | 1. Replace `script-name` and `script-name-dev` with `new-script-name` and `new-script-name-dev` respectively.
51 |
52 | 1. Add KV Namespaces. For example:
53 |
54 | ```toml
55 | kv-namespaces = [
56 | { binding = "NAMESPACENAME", id = "86bbce2f10524d33a5f26517e8dee123" }
57 | ]
58 | ```
59 |
60 | - Find existing namespaces with `wrangler kv:namespace list`
61 | - Create a new namespace with `wrangler kv:namespace create NAMESPACENAME`
62 |
63 | 1. Update `account_id`.
64 |
65 | 1. Update `package.json`:
66 |
67 | 1. Replace `script-name` with `new-script-name`.
68 |
69 | 1. Replace `repositoryname` with `newrepositoryname`.
70 |
71 | 1. Update GitHub account name in the following locations:
72 |
73 | 1. `repository.url`
74 |
75 | 1. `bugs.url`
76 |
77 | 1. `homepage`
78 |
79 | 1. Update `homepage` and `author`.
80 |
81 | 1. `npm i`
82 |
83 | 1. (Optionally) Update npm packages: `npm run updatePackages`
84 |
85 | 1. Update `README.md`, (don't forget the badges!).
86 |
87 | 1. Follow additional instructions in `/packages/*/README.md`
88 |
89 | ## Scripts
90 |
91 | These should all be self-explanatory:
92 |
93 | - `npm run lint`
94 |
95 | - `npm run lint:fix`
96 |
97 | - `npm run test`
98 |
99 | - `npm run test:client`
100 | - `npm run test:server`
101 | - `npm run test:e2e`
102 |
103 | - `npm run deploy`
104 |
105 | To start a local version:
106 |
107 | 1. In one terminal window, run `npm run start:client`.
108 |
109 | 1. In another, run `npm run start` and navigate to [http://localhost:8787](http://localhost:8787).
110 |
111 | ## About
112 |
113 | - `/packages/client` is simply a CRA created with `npx create-react-app . --template typescript --use-npm`.
114 |
115 | - `/packages/server` an function which intercepts a request to the client. If it returns a 404, the request is passed through to the client.
116 |
117 | - `/packages/worker` attempts to fetch from the server first, falling back on the client.
118 |
119 | - `/packages/e2e` runs end-to-end tests on the full-stack Worker.
120 |
121 | ---
122 |
123 | \* May not be perfect
124 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | coverage:
2 | status:
3 | project:
4 | default: off
5 | client:
6 | flags: client
7 | server:
8 | flags: server
9 |
10 | flags:
11 | client:
12 | paths:
13 | - packages/client/
14 | server:
15 | paths:
16 | - packages/server/
17 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | require("cross-fetch/polyfill");
2 | const { spawn } = require("child_process");
3 | const cwd = process.cwd();
4 |
5 | const SLEEP_DURATION = 2000;
6 | const hostNameRegex = /userHostname=\"(.*)\"/g;
7 |
8 | const startServer = (hostName) => {
9 | process.env.CLOUDFLARED_TUNNEL = "true";
10 | spawn("npm", ["run", "start:worker", "--", "--host", hostName], {
11 | cwd,
12 | stdio: "inherit",
13 | });
14 | };
15 |
16 | const findTunnelHostname = async () => {
17 | console.log("Waiting for tunnel to initiate...");
18 | try {
19 | const resp = await fetch("http://localhost:8081/metrics");
20 | const data = await resp.text();
21 | const matches = Array.from(data.matchAll(hostNameRegex));
22 | const hostName = matches[0][1];
23 | console.log(`Tunnel initiated: ${hostName}`);
24 | startServer(hostName);
25 | } catch {
26 | setTimeout(findTunnelHostname, SLEEP_DURATION);
27 | }
28 | };
29 |
30 | const startTunnel = () => {
31 | console.log("Starting tunnel...");
32 | spawn("npm", ["run", "start:tunnel"], {
33 | cwd,
34 | });
35 | };
36 |
37 | startTunnel();
38 | findTunnelHostname();
39 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": ["packages/*"],
3 | "version": "1.0.0"
4 | }
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "script-name",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "lerna bootstrap",
7 | "prebuild": "lerna run --scope client build",
8 | "build": "wrangler build",
9 | "clean:node": "rimraf node_modules package-lock.json",
10 | "test:client": "CI=true lerna run --scope client test",
11 | "test:server": "CI=true lerna run --scope server test",
12 | "test:e2e": "CI=true lerna run --scope e2e test:ci",
13 | "test": "CI=true lerna run test:ci",
14 | "lint": "prettier -c .",
15 | "lint:fix": "npm run lint -- --write",
16 | "start": "node index.js",
17 | "start:client": "CI=true lerna run --scope client --stream start",
18 | "start:worker": "wrangler dev",
19 | "start:tunnel": "cloudflared tunnel --url localhost:3000 --metrics localhost:8081",
20 | "predeploy": "npm run prebuild",
21 | "deploy": "wrangler publish --env production",
22 | "updatePackages": "node updatePackages.js && npm i"
23 | },
24 | "repository": {
25 | "type": "git",
26 | "url": "git@github.com:GregBrimble/repositoryname.git"
27 | },
28 | "author": {
29 | "name": "Greg Brimble",
30 | "email": "developer@gregbrimble.com",
31 | "url": "https://gregbrimble.com"
32 | },
33 | "license": "MIT",
34 | "bugs": {
35 | "url": "https://github.com/GregBrimble/repositoryname/issues"
36 | },
37 | "homepage": "https://github.com/GregBrimble/repositoryname#readme",
38 | "devDependencies": {
39 | "@cloudflare/wrangler": "1.12.3",
40 | "cross-fetch": "3.0.6",
41 | "husky": "4.3.7",
42 | "lerna": "3.22.1",
43 | "npm-check-updates": "10.2.5",
44 | "prettier": "2.2.1",
45 | "rimraf": "3.0.2",
46 | "ts-loader": "8.0.14",
47 | "typescript": "4.1.3",
48 | "webpack": "5.12.2"
49 | },
50 | "husky": {
51 | "hooks": {
52 | "pre-commit": "npm run lint || (npm run lint:fix && npm run lint)",
53 | "pre-push": "npm test"
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/client/.env:
--------------------------------------------------------------------------------
1 | SKIP_PREFLIGHT_CHECK=true
--------------------------------------------------------------------------------
/packages/client/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/packages/client/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2 |
3 | ## Available Scripts
4 |
5 | In the project directory, you can run:
6 |
7 | ### `npm start`
8 |
9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
11 |
12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console.
14 |
15 | ### `npm test`
16 |
17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
19 |
20 | ### `npm run build`
21 |
22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance.
24 |
25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed!
27 |
28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
29 |
30 | ### `npm run eject`
31 |
32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
33 |
34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
35 |
36 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
37 |
38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
39 |
40 | ## Learn More
41 |
42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
43 |
44 | To learn React, check out the [React documentation](https://reactjs.org/).
45 |
--------------------------------------------------------------------------------
/packages/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "5.11.8",
7 | "@testing-library/react": "11.2.3",
8 | "@testing-library/user-event": "12.6.0",
9 | "@types/jest": "26.0.20",
10 | "@types/node": "14.14.20",
11 | "@types/react": "17.0.0",
12 | "@types/react-dom": "17.0.0",
13 | "react": "17.0.1",
14 | "react-dom": "17.0.1",
15 | "react-scripts": "4.0.1",
16 | "typescript": "4.1.3"
17 | },
18 | "scripts": {
19 | "start": "react-scripts start",
20 | "build": "react-scripts build",
21 | "test": "react-scripts test",
22 | "test:ci": "npm run test -- --coverage",
23 | "eject": "react-scripts eject",
24 | "lint": "prettier -c .",
25 | "lint:fix": "npm run lint -- --write"
26 | },
27 | "eslintConfig": {
28 | "extends": "react-app"
29 | },
30 | "browserslist": {
31 | "production": [
32 | ">0.2%",
33 | "not dead",
34 | "not op_mini all"
35 | ],
36 | "development": [
37 | "last 1 chrome version",
38 | "last 1 firefox version",
39 | "last 1 safari version"
40 | ]
41 | },
42 | "devDependencies": {
43 | "prettier": "2.2.1"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/packages/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregBrimble/cf-workers-typescript-template/d8d102e5bb158e72da17316d4be9f5f5443c468d/packages/client/public/favicon.ico
--------------------------------------------------------------------------------
/packages/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/packages/client/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregBrimble/cf-workers-typescript-template/d8d102e5bb158e72da17316d4be9f5f5443c468d/packages/client/public/logo192.png
--------------------------------------------------------------------------------
/packages/client/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GregBrimble/cf-workers-typescript-template/d8d102e5bb158e72da17316d4be9f5f5443c468d/packages/client/public/logo512.png
--------------------------------------------------------------------------------
/packages/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/packages/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/packages/client/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/client/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { render } from "@testing-library/react";
3 | import App from "./App";
4 |
5 | test("renders learn react link", () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/packages/client/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import logo from "./logo.svg";
3 | import "./App.css";
4 |
5 | function App() {
6 | return (
7 |
23 | );
24 | }
25 |
26 | export default App;
27 |
--------------------------------------------------------------------------------
/packages/client/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/client/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import "./index.css";
4 | import App from "./App";
5 | import * as serviceWorker from "./serviceWorker";
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById("root")
12 | );
13 |
14 | // If you want your app to work offline and load faster, you can change
15 | // unregister() to register() below. Note this comes with some pitfalls.
16 | // Learn more about service workers: https://bit.ly/CRA-PWA
17 | serviceWorker.unregister();
18 |
--------------------------------------------------------------------------------
/packages/client/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/packages/client/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/packages/client/src/serviceWorker.ts:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === "localhost" ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === "[::1]" ||
17 | // 127.0.0.0/8 are considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | type Config = {
24 | onSuccess?: (registration: ServiceWorkerRegistration) => void;
25 | onUpdate?: (registration: ServiceWorkerRegistration) => void;
26 | };
27 |
28 | export function register(config?: Config) {
29 | if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
30 | // The URL constructor is available in all browsers that support SW.
31 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
32 | if (publicUrl.origin !== window.location.origin) {
33 | // Our service worker won't work if PUBLIC_URL is on a different origin
34 | // from what our page is served on. This might happen if a CDN is used to
35 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
36 | return;
37 | }
38 |
39 | window.addEventListener("load", () => {
40 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
41 |
42 | if (isLocalhost) {
43 | // This is running on localhost. Let's check if a service worker still exists or not.
44 | checkValidServiceWorker(swUrl, config);
45 |
46 | // Add some additional logging to localhost, pointing developers to the
47 | // service worker/PWA documentation.
48 | navigator.serviceWorker.ready.then(() => {
49 | console.log(
50 | "This web app is being served cache-first by a service " +
51 | "worker. To learn more, visit https://bit.ly/CRA-PWA"
52 | );
53 | });
54 | } else {
55 | // Is not localhost. Just register service worker
56 | registerValidSW(swUrl, config);
57 | }
58 | });
59 | }
60 | }
61 |
62 | function registerValidSW(swUrl: string, config?: Config) {
63 | navigator.serviceWorker
64 | .register(swUrl)
65 | .then((registration) => {
66 | registration.onupdatefound = () => {
67 | const installingWorker = registration.installing;
68 | if (installingWorker == null) {
69 | return;
70 | }
71 | installingWorker.onstatechange = () => {
72 | if (installingWorker.state === "installed") {
73 | if (navigator.serviceWorker.controller) {
74 | // At this point, the updated precached content has been fetched,
75 | // but the previous service worker will still serve the older
76 | // content until all client tabs are closed.
77 | console.log(
78 | "New content is available and will be used when all " +
79 | "tabs for this page are closed. See https://bit.ly/CRA-PWA."
80 | );
81 |
82 | // Execute callback
83 | if (config && config.onUpdate) {
84 | config.onUpdate(registration);
85 | }
86 | } else {
87 | // At this point, everything has been precached.
88 | // It's the perfect time to display a
89 | // "Content is cached for offline use." message.
90 | console.log("Content is cached for offline use.");
91 |
92 | // Execute callback
93 | if (config && config.onSuccess) {
94 | config.onSuccess(registration);
95 | }
96 | }
97 | }
98 | };
99 | };
100 | })
101 | .catch((error) => {
102 | console.error("Error during service worker registration:", error);
103 | });
104 | }
105 |
106 | function checkValidServiceWorker(swUrl: string, config?: Config) {
107 | // Check if the service worker can be found. If it can't reload the page.
108 | fetch(swUrl, {
109 | headers: { "Service-Worker": "script" },
110 | })
111 | .then((response) => {
112 | // Ensure service worker exists, and that we really are getting a JS file.
113 | const contentType = response.headers.get("content-type");
114 | if (
115 | response.status === 404 ||
116 | (contentType != null && contentType.indexOf("javascript") === -1)
117 | ) {
118 | // No service worker found. Probably a different app. Reload the page.
119 | navigator.serviceWorker.ready.then((registration) => {
120 | registration.unregister().then(() => {
121 | window.location.reload();
122 | });
123 | });
124 | } else {
125 | // Service worker found. Proceed as normal.
126 | registerValidSW(swUrl, config);
127 | }
128 | })
129 | .catch(() => {
130 | console.log(
131 | "No internet connection found. App is running in offline mode."
132 | );
133 | });
134 | }
135 |
136 | export function unregister() {
137 | if ("serviceWorker" in navigator) {
138 | navigator.serviceWorker.ready
139 | .then((registration) => {
140 | registration.unregister();
141 | })
142 | .catch((error) => {
143 | console.error(error.message);
144 | });
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/packages/client/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import "@testing-library/jest-dom/extend-expect";
6 |
--------------------------------------------------------------------------------
/packages/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "noEmit": true,
16 | "jsx": "react-jsx",
17 | "noFallthroughCasesInSwitch": false
18 | },
19 | "include": ["src"]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/e2e/README.md:
--------------------------------------------------------------------------------
1 | # `e2e`
2 |
3 | Runs end-to-end tests on the full-stack Worker with [Jest](https://jestjs.io/) and [Playwright](https://playwright.dev/).
4 |
5 | ## Getting Started
6 |
7 | 1. `npm t` or `npm run test:ci`
8 |
--------------------------------------------------------------------------------
/packages/e2e/__tests__/index.test.ts:
--------------------------------------------------------------------------------
1 | describe("the universe", () => {
2 | it("can do math", () => {
3 | expect(2 + 2).toBe(4);
4 | });
5 | });
6 |
7 | describe("the front-end", () => {
8 | beforeAll(async () => {
9 | await page.goto("http://localhost:8787/");
10 | });
11 |
12 | test("should load", async () => {
13 | await expect(page).toHaveText("Learn React");
14 | });
15 | });
16 |
17 | describe("the back-end", () => {
18 | beforeAll(async () => {
19 | await page.goto("http://localhost:8787/hello");
20 | });
21 |
22 | test("should load", async () => {
23 | await expect(page).toEqualText("Hello, world!");
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/packages/e2e/jest-playwright.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | serverOptions: {
3 | command: "cd ../.. && npx wrangler dev --port 8787",
4 | port: 8787,
5 | launchTimeout: 30000,
6 | },
7 | };
8 |
--------------------------------------------------------------------------------
/packages/e2e/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: "jest-playwright-preset",
3 | transform: {
4 | "^.+\\.ts$": "ts-jest",
5 | },
6 | setupFilesAfterEnv: ["expect-playwright"],
7 | // testEnvironment: "node",
8 | // collectCoverage: true,
9 | // collectCoverageFrom: [
10 | // "src/**/*.{js,jsx,ts,tsx}",
11 | // "!**/coverage/**",
12 | // "!**/node_modules/**",
13 | // "!**/babel.config.js",
14 | // "!**/jest.setup.js",
15 | // ],
16 | };
17 |
--------------------------------------------------------------------------------
/packages/e2e/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "e2e",
3 | "private": true,
4 | "scripts": {
5 | "clean:node": "rimraf node_modules package-lock.json",
6 | "pretest": "cd ../.. && npm run prebuild",
7 | "test": "jest --watch --coverage=false",
8 | "pretest:ci": "npm run pretest",
9 | "test:ci": "jest --ci"
10 | },
11 | "devDependencies": {
12 | "@cloudflare/workers-types": "2.1.0",
13 | "@types/jest": "26.0.20",
14 | "expect-playwright": "0.3.0",
15 | "jest": "26.6.3",
16 | "jest-playwright-preset": "1.4.3",
17 | "playwright": "1.7.1",
18 | "rimraf": "3.0.2",
19 | "ts-jest": "26.4.4"
20 | },
21 | "dependencies": {}
22 | }
23 |
--------------------------------------------------------------------------------
/packages/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "module": "commonjs",
5 | "experimentalDecorators": true,
6 | "lib": ["esnext", "webworker"],
7 | "types": ["jest", "jest-playwright-preset", "expect-playwright"]
8 | },
9 | "include": ["./__tests__/**/*.ts"],
10 | "exclude": ["node_modules/"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/server/README.md:
--------------------------------------------------------------------------------
1 | # `server`
2 |
3 | ## Getting Started
4 |
5 |
8 |
9 | 1. Update `/src/types.d.ts`:
10 |
11 | 1. Add KV Namespaces. For example:
12 |
13 | ```typescript
14 | declare global {
15 | const NAMESPACENAME: KVNamespace;
16 | }
17 | ```
18 |
--------------------------------------------------------------------------------
/packages/server/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: "ts-jest",
3 | testEnvironment: "node",
4 | setupFiles: ["./jest.setup.js"],
5 | collectCoverage: true,
6 | collectCoverageFrom: [
7 | "src/**/*.{js,jsx,ts,tsx}",
8 | "!**/coverage/**",
9 | "!**/node_modules/**",
10 | "!**/babel.config.js",
11 | "!**/jest.setup.js",
12 | ],
13 | };
14 |
--------------------------------------------------------------------------------
/packages/server/jest.setup.js:
--------------------------------------------------------------------------------
1 | require("cross-fetch/polyfill");
2 |
--------------------------------------------------------------------------------
/packages/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "private": true,
4 | "main": "src/index.ts",
5 | "scripts": {
6 | "clean:node": "rimraf node_modules package-lock.json",
7 | "test": "jest --watch --coverage=false --changedSince=origin/master",
8 | "test:ci": "jest --ci"
9 | },
10 | "devDependencies": {
11 | "@cloudflare/workers-types": "2.1.0",
12 | "@types/jest": "26.0.20",
13 | "jest": "26.6.3",
14 | "rimraf": "3.0.2",
15 | "ts-jest": "26.4.4"
16 | },
17 | "dependencies": {
18 | "@glenstack/cf-workers-router": "1.0.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/server/src/hello.test.ts:
--------------------------------------------------------------------------------
1 | import { handleHello } from "./hello";
2 |
3 | describe("hello", () => {
4 | it("returns a response", async () => {
5 | const response = await handleHello(undefined);
6 | const text = await response.text();
7 | expect(text).toEqual("Hello, world!");
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/packages/server/src/hello.ts:
--------------------------------------------------------------------------------
1 | export const handleHello = async (request: Request): Promise =>
2 | new Response("Hello, world!", { headers: { "Content-Type": "text/plain" } });
3 |
--------------------------------------------------------------------------------
/packages/server/src/index.test.ts:
--------------------------------------------------------------------------------
1 | describe("the universe", () => {
2 | it("can do math", () => {
3 | expect(2 + 2).toBe(4);
4 | });
5 | });
6 |
--------------------------------------------------------------------------------
/packages/server/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Router } from "@glenstack/cf-workers-router";
2 | import { handleHello } from "./hello";
3 |
4 | const router = new Router();
5 |
6 | router.get("/hello", (request) => handleHello(request));
7 |
8 | export const handleRequest = async (request: Request): Promise => {
9 | console.log("Hello from a worker!");
10 | return router.route(request);
11 | };
12 |
--------------------------------------------------------------------------------
/packages/server/src/types.d.ts:
--------------------------------------------------------------------------------
1 | import { KVNamespace } from "@cloudflare/workers-types";
2 |
3 | declare global {}
4 |
--------------------------------------------------------------------------------
/packages/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "module": "commonjs",
5 | "experimentalDecorators": true,
6 | "lib": ["esnext", "webworker"]
7 | },
8 | "include": [
9 | "./src/**/*.ts",
10 | "./node_modules/@cloudflare/workers-types/index.d.ts"
11 | ],
12 | "typeAcquisition": {
13 | "include": ["jest"]
14 | },
15 | "exclude": ["node_modules/"]
16 | }
17 |
--------------------------------------------------------------------------------
/packages/worker/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /worker
--------------------------------------------------------------------------------
/packages/worker/README.md:
--------------------------------------------------------------------------------
1 | # `worker`
2 |
3 | ## Getting Started
4 |
5 | 1. Update `src/handleError.ts` to log to error reporting service or similar.
6 |
7 | 1. Update `src/pages.ts` with pretty pages.
8 |
--------------------------------------------------------------------------------
/packages/worker/null.js:
--------------------------------------------------------------------------------
1 | module.exports = {};
2 |
--------------------------------------------------------------------------------
/packages/worker/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "worker",
3 | "requires": true,
4 | "lockfileVersion": 1,
5 | "dependencies": {
6 | "@cloudflare/kv-asset-handler": {
7 | "version": "0.1.0",
8 | "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.1.0.tgz",
9 | "integrity": "sha512-sXZRw/Z5JJfi/nGh66SECSm5L2zomyf6f9O3nc5QOI11/R3W/4N+BPOecp/Dc8eL/q/Rwgb7lwhhjnqy8O5CYA==",
10 | "requires": {
11 | "@cloudflare/workers-types": "^2.0.0",
12 | "@types/mime": "^2.0.2",
13 | "mime": "^2.4.6"
14 | }
15 | },
16 | "@cloudflare/workers-types": {
17 | "version": "2.1.0",
18 | "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-2.1.0.tgz",
19 | "integrity": "sha512-VmXaHTq0lt6Xre4aK1hUK25hjZjuEUkHtdUEt0FJamv+NzQO54Gwp6Zr5Cfu6SP5EQ/tTmTMP/tK9npA8zhcCg=="
20 | },
21 | "@discoveryjs/json-ext": {
22 | "version": "0.5.2",
23 | "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz",
24 | "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==",
25 | "dev": true
26 | },
27 | "@types/eslint": {
28 | "version": "7.2.6",
29 | "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz",
30 | "integrity": "sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw==",
31 | "dev": true,
32 | "requires": {
33 | "@types/estree": "*",
34 | "@types/json-schema": "*"
35 | }
36 | },
37 | "@types/eslint-scope": {
38 | "version": "3.7.0",
39 | "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz",
40 | "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==",
41 | "dev": true,
42 | "requires": {
43 | "@types/eslint": "*",
44 | "@types/estree": "*"
45 | }
46 | },
47 | "@types/estree": {
48 | "version": "0.0.45",
49 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz",
50 | "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==",
51 | "dev": true
52 | },
53 | "@types/json-schema": {
54 | "version": "7.0.6",
55 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz",
56 | "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
57 | "dev": true
58 | },
59 | "@types/mime": {
60 | "version": "2.0.3",
61 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz",
62 | "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q=="
63 | },
64 | "@types/node": {
65 | "version": "14.14.20",
66 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz",
67 | "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==",
68 | "dev": true
69 | },
70 | "@webassemblyjs/ast": {
71 | "version": "1.9.1",
72 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.1.tgz",
73 | "integrity": "sha512-uMu1nCWn2Wxyy126LlGqRVlhdTOsO/bsBRI4dNq3+6SiSuRKRQX6ejjKgh82LoGAPSq72lDUiQ4FWVaf0PecYw==",
74 | "dev": true,
75 | "requires": {
76 | "@webassemblyjs/helper-module-context": "1.9.1",
77 | "@webassemblyjs/helper-wasm-bytecode": "1.9.1",
78 | "@webassemblyjs/wast-parser": "1.9.1"
79 | }
80 | },
81 | "@webassemblyjs/floating-point-hex-parser": {
82 | "version": "1.9.1",
83 | "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.1.tgz",
84 | "integrity": "sha512-5VEKu024RySmLKTTBl9q1eO/2K5jk9ZS+2HXDBLA9s9p5IjkaXxWiDb/+b7wSQp6FRdLaH1IVGIfOex58Na2pg==",
85 | "dev": true
86 | },
87 | "@webassemblyjs/helper-api-error": {
88 | "version": "1.9.1",
89 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.1.tgz",
90 | "integrity": "sha512-y1lGmfm38djrScwpeL37rRR9f1D6sM8RhMpvM7CYLzOlHVboouZokXK/G88BpzW0NQBSvCCOnW5BFhten4FPfA==",
91 | "dev": true
92 | },
93 | "@webassemblyjs/helper-buffer": {
94 | "version": "1.9.1",
95 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.1.tgz",
96 | "integrity": "sha512-uS6VSgieHbk/m4GSkMU5cqe/5TekdCzQso4revCIEQ3vpGZgqSSExi4jWpTWwDpAHOIAb1Jfrs0gUB9AA4n71w==",
97 | "dev": true
98 | },
99 | "@webassemblyjs/helper-code-frame": {
100 | "version": "1.9.1",
101 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.1.tgz",
102 | "integrity": "sha512-ZQ2ZT6Evk4DPIfD+92AraGYaFIqGm4U20e7FpXwl7WUo2Pn1mZ1v8VGH8i+Y++IQpxPbQo/UyG0Khs7eInskzA==",
103 | "dev": true,
104 | "requires": {
105 | "@webassemblyjs/wast-printer": "1.9.1"
106 | }
107 | },
108 | "@webassemblyjs/helper-fsm": {
109 | "version": "1.9.1",
110 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.1.tgz",
111 | "integrity": "sha512-J32HGpveEqqcKFS0YbgicB0zAlpfIxJa5MjxDxhu3i5ltPcVfY5EPvKQ1suRguFPehxiUs+/hfkwPEXom/l0lw==",
112 | "dev": true
113 | },
114 | "@webassemblyjs/helper-module-context": {
115 | "version": "1.9.1",
116 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.1.tgz",
117 | "integrity": "sha512-IEH2cMmEQKt7fqelLWB5e/cMdZXf2rST1JIrzWmf4XBt3QTxGdnnLvV4DYoN8pJjOx0VYXsWg+yF16MmJtolZg==",
118 | "dev": true,
119 | "requires": {
120 | "@webassemblyjs/ast": "1.9.1"
121 | }
122 | },
123 | "@webassemblyjs/helper-wasm-bytecode": {
124 | "version": "1.9.1",
125 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.1.tgz",
126 | "integrity": "sha512-i2rGTBqFUcSXxyjt2K4vm/3kkHwyzG6o427iCjcIKjOqpWH8SEem+xe82jUk1iydJO250/CvE5o7hzNAMZf0dQ==",
127 | "dev": true
128 | },
129 | "@webassemblyjs/helper-wasm-section": {
130 | "version": "1.9.1",
131 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.1.tgz",
132 | "integrity": "sha512-FetqzjtXZr2d57IECK+aId3D0IcGweeM0CbAnJHkYJkcRTHP+YcMb7Wmc0j21h5UWBpwYGb9dSkK/93SRCTrGg==",
133 | "dev": true,
134 | "requires": {
135 | "@webassemblyjs/ast": "1.9.1",
136 | "@webassemblyjs/helper-buffer": "1.9.1",
137 | "@webassemblyjs/helper-wasm-bytecode": "1.9.1",
138 | "@webassemblyjs/wasm-gen": "1.9.1"
139 | }
140 | },
141 | "@webassemblyjs/ieee754": {
142 | "version": "1.9.1",
143 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.1.tgz",
144 | "integrity": "sha512-EvTG9M78zP1MmkBpUjGQHZc26DzPGZSLIPxYHCjQsBMo60Qy2W34qf8z0exRDtxBbRIoiKa5dFyWer/7r1aaSQ==",
145 | "dev": true,
146 | "requires": {
147 | "@xtuc/ieee754": "^1.2.0"
148 | }
149 | },
150 | "@webassemblyjs/leb128": {
151 | "version": "1.9.1",
152 | "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.1.tgz",
153 | "integrity": "sha512-Oc04ub0vFfLnF+2/+ki3AE+anmW4sv9uNBqb+79fgTaPv6xJsOT0dhphNfL3FrME84CbX/D1T9XT8tjFo0IIiw==",
154 | "dev": true,
155 | "requires": {
156 | "@xtuc/long": "4.2.2"
157 | }
158 | },
159 | "@webassemblyjs/utf8": {
160 | "version": "1.9.1",
161 | "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.1.tgz",
162 | "integrity": "sha512-llkYtppagjCodFjo0alWOUhAkfOiQPQDIc5oA6C9sFAXz7vC9QhZf/f8ijQIX+A9ToM3c9Pq85X0EX7nx9gVhg==",
163 | "dev": true
164 | },
165 | "@webassemblyjs/wasm-edit": {
166 | "version": "1.9.1",
167 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.1.tgz",
168 | "integrity": "sha512-S2IaD6+x9B2Xi8BCT0eGsrXXd8UxAh2LVJpg1ZMtHXnrDcsTtIX2bDjHi40Hio6Lc62dWHmKdvksI+MClCYbbw==",
169 | "dev": true,
170 | "requires": {
171 | "@webassemblyjs/ast": "1.9.1",
172 | "@webassemblyjs/helper-buffer": "1.9.1",
173 | "@webassemblyjs/helper-wasm-bytecode": "1.9.1",
174 | "@webassemblyjs/helper-wasm-section": "1.9.1",
175 | "@webassemblyjs/wasm-gen": "1.9.1",
176 | "@webassemblyjs/wasm-opt": "1.9.1",
177 | "@webassemblyjs/wasm-parser": "1.9.1",
178 | "@webassemblyjs/wast-printer": "1.9.1"
179 | }
180 | },
181 | "@webassemblyjs/wasm-gen": {
182 | "version": "1.9.1",
183 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.1.tgz",
184 | "integrity": "sha512-bqWI0S4lBQsEN5FTZ35vYzfKUJvtjNnBobB1agCALH30xNk1LToZ7Z8eiaR/Z5iVECTlBndoRQV3F6mbEqE/fg==",
185 | "dev": true,
186 | "requires": {
187 | "@webassemblyjs/ast": "1.9.1",
188 | "@webassemblyjs/helper-wasm-bytecode": "1.9.1",
189 | "@webassemblyjs/ieee754": "1.9.1",
190 | "@webassemblyjs/leb128": "1.9.1",
191 | "@webassemblyjs/utf8": "1.9.1"
192 | }
193 | },
194 | "@webassemblyjs/wasm-opt": {
195 | "version": "1.9.1",
196 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.1.tgz",
197 | "integrity": "sha512-gSf7I7YWVXZ5c6XqTEqkZjVs8K1kc1k57vsB6KBQscSagDNbAdxt6MwuJoMjsE1yWY1tsuL+pga268A6u+Fdkg==",
198 | "dev": true,
199 | "requires": {
200 | "@webassemblyjs/ast": "1.9.1",
201 | "@webassemblyjs/helper-buffer": "1.9.1",
202 | "@webassemblyjs/wasm-gen": "1.9.1",
203 | "@webassemblyjs/wasm-parser": "1.9.1"
204 | }
205 | },
206 | "@webassemblyjs/wasm-parser": {
207 | "version": "1.9.1",
208 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.1.tgz",
209 | "integrity": "sha512-ImM4N2T1MEIond0MyE3rXvStVxEmivQrDKf/ggfh5pP6EHu3lL/YTAoSrR7shrbKNPpeKpGesW1LIK/L4kqduw==",
210 | "dev": true,
211 | "requires": {
212 | "@webassemblyjs/ast": "1.9.1",
213 | "@webassemblyjs/helper-api-error": "1.9.1",
214 | "@webassemblyjs/helper-wasm-bytecode": "1.9.1",
215 | "@webassemblyjs/ieee754": "1.9.1",
216 | "@webassemblyjs/leb128": "1.9.1",
217 | "@webassemblyjs/utf8": "1.9.1"
218 | }
219 | },
220 | "@webassemblyjs/wast-parser": {
221 | "version": "1.9.1",
222 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.1.tgz",
223 | "integrity": "sha512-2xVxejXSvj3ls/o2TR/zI6p28qsGupjHhnHL6URULQRcXmryn3w7G83jQMcT7PHqUfyle65fZtWLukfdLdE7qw==",
224 | "dev": true,
225 | "requires": {
226 | "@webassemblyjs/ast": "1.9.1",
227 | "@webassemblyjs/floating-point-hex-parser": "1.9.1",
228 | "@webassemblyjs/helper-api-error": "1.9.1",
229 | "@webassemblyjs/helper-code-frame": "1.9.1",
230 | "@webassemblyjs/helper-fsm": "1.9.1",
231 | "@xtuc/long": "4.2.2"
232 | }
233 | },
234 | "@webassemblyjs/wast-printer": {
235 | "version": "1.9.1",
236 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.1.tgz",
237 | "integrity": "sha512-tDV8V15wm7mmbAH6XvQRU1X+oPGmeOzYsd6h7hlRLz6QpV4Ec/KKxM8OpLtFmQPLCreGxTp+HuxtH4pRIZyL9w==",
238 | "dev": true,
239 | "requires": {
240 | "@webassemblyjs/ast": "1.9.1",
241 | "@webassemblyjs/wast-parser": "1.9.1",
242 | "@xtuc/long": "4.2.2"
243 | }
244 | },
245 | "@webpack-cli/info": {
246 | "version": "1.2.1",
247 | "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.1.tgz",
248 | "integrity": "sha512-fLnDML5HZ5AEKzHul8xLAksoKN2cibu6MgonkUj8R9V7bbeVRkd1XbGEGWrAUNYHbX1jcqCsDEpBviE5StPMzQ==",
249 | "dev": true,
250 | "requires": {
251 | "envinfo": "^7.7.3"
252 | }
253 | },
254 | "@webpack-cli/serve": {
255 | "version": "1.2.1",
256 | "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.2.1.tgz",
257 | "integrity": "sha512-Zj1z6AyS+vqV6Hfi7ngCjFGdHV5EwZNIHo6QfFTNe9PyW+zBU1zJ9BiOW1pmUEq950RC4+Dym6flyA/61/vhyw==",
258 | "dev": true
259 | },
260 | "@xtuc/ieee754": {
261 | "version": "1.2.0",
262 | "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
263 | "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
264 | "dev": true
265 | },
266 | "@xtuc/long": {
267 | "version": "4.2.2",
268 | "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
269 | "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
270 | "dev": true
271 | },
272 | "acorn": {
273 | "version": "8.0.4",
274 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz",
275 | "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==",
276 | "dev": true
277 | },
278 | "ajv": {
279 | "version": "6.12.6",
280 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
281 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
282 | "dev": true,
283 | "requires": {
284 | "fast-deep-equal": "^3.1.1",
285 | "fast-json-stable-stringify": "^2.0.0",
286 | "json-schema-traverse": "^0.4.1",
287 | "uri-js": "^4.2.2"
288 | }
289 | },
290 | "ajv-keywords": {
291 | "version": "3.5.2",
292 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
293 | "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
294 | "dev": true
295 | },
296 | "ansi-colors": {
297 | "version": "4.1.1",
298 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
299 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
300 | "dev": true
301 | },
302 | "balanced-match": {
303 | "version": "1.0.0",
304 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
305 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
306 | "dev": true
307 | },
308 | "brace-expansion": {
309 | "version": "1.1.11",
310 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
311 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
312 | "dev": true,
313 | "requires": {
314 | "balanced-match": "^1.0.0",
315 | "concat-map": "0.0.1"
316 | }
317 | },
318 | "browserslist": {
319 | "version": "4.16.1",
320 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz",
321 | "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==",
322 | "dev": true,
323 | "requires": {
324 | "caniuse-lite": "^1.0.30001173",
325 | "colorette": "^1.2.1",
326 | "electron-to-chromium": "^1.3.634",
327 | "escalade": "^3.1.1",
328 | "node-releases": "^1.1.69"
329 | }
330 | },
331 | "buffer-from": {
332 | "version": "1.1.1",
333 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
334 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
335 | "dev": true
336 | },
337 | "caniuse-lite": {
338 | "version": "1.0.30001173",
339 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001173.tgz",
340 | "integrity": "sha512-R3aqmjrICdGCTAnSXtNyvWYMK3YtV5jwudbq0T7nN9k4kmE4CBuwPqyJ+KBzepSTh0huivV2gLbSMEzTTmfeYw==",
341 | "dev": true
342 | },
343 | "chrome-trace-event": {
344 | "version": "1.0.2",
345 | "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
346 | "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
347 | "dev": true,
348 | "requires": {
349 | "tslib": "^1.9.0"
350 | }
351 | },
352 | "colorette": {
353 | "version": "1.2.1",
354 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz",
355 | "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==",
356 | "dev": true
357 | },
358 | "commander": {
359 | "version": "2.20.3",
360 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
361 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
362 | "dev": true
363 | },
364 | "concat-map": {
365 | "version": "0.0.1",
366 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
367 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
368 | "dev": true
369 | },
370 | "cross-spawn": {
371 | "version": "7.0.3",
372 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
373 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
374 | "dev": true,
375 | "requires": {
376 | "path-key": "^3.1.0",
377 | "shebang-command": "^2.0.0",
378 | "which": "^2.0.1"
379 | }
380 | },
381 | "electron-to-chromium": {
382 | "version": "1.3.635",
383 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.635.tgz",
384 | "integrity": "sha512-RRriZOLs9CpW6KTLmgBqyUdnY0QNqqWs0HOtuQGGEMizOTNNn1P7sGRBxARnUeLejOsgwjDyRqT3E/CSst02ZQ==",
385 | "dev": true
386 | },
387 | "enhanced-resolve": {
388 | "version": "5.4.1",
389 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.4.1.tgz",
390 | "integrity": "sha512-4GbyIMzYktTFoRSmkbgZ1LU+RXwf4AQ8Z+rSuuh1dC8plp0PPeaWvx6+G4hh4KnUJ48VoxKbNyA1QQQIUpXjYA==",
391 | "dev": true,
392 | "requires": {
393 | "graceful-fs": "^4.2.4",
394 | "tapable": "^2.2.0"
395 | }
396 | },
397 | "enquirer": {
398 | "version": "2.3.6",
399 | "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
400 | "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
401 | "dev": true,
402 | "requires": {
403 | "ansi-colors": "^4.1.1"
404 | }
405 | },
406 | "envinfo": {
407 | "version": "7.7.3",
408 | "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.3.tgz",
409 | "integrity": "sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA==",
410 | "dev": true
411 | },
412 | "escalade": {
413 | "version": "3.1.1",
414 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
415 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
416 | "dev": true
417 | },
418 | "eslint-scope": {
419 | "version": "5.1.1",
420 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
421 | "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
422 | "dev": true,
423 | "requires": {
424 | "esrecurse": "^4.3.0",
425 | "estraverse": "^4.1.1"
426 | }
427 | },
428 | "esrecurse": {
429 | "version": "4.3.0",
430 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
431 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
432 | "dev": true,
433 | "requires": {
434 | "estraverse": "^5.2.0"
435 | },
436 | "dependencies": {
437 | "estraverse": {
438 | "version": "5.2.0",
439 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
440 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
441 | "dev": true
442 | }
443 | }
444 | },
445 | "estraverse": {
446 | "version": "4.3.0",
447 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
448 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
449 | "dev": true
450 | },
451 | "events": {
452 | "version": "3.2.0",
453 | "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
454 | "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==",
455 | "dev": true
456 | },
457 | "execa": {
458 | "version": "5.0.0",
459 | "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz",
460 | "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==",
461 | "dev": true,
462 | "requires": {
463 | "cross-spawn": "^7.0.3",
464 | "get-stream": "^6.0.0",
465 | "human-signals": "^2.1.0",
466 | "is-stream": "^2.0.0",
467 | "merge-stream": "^2.0.0",
468 | "npm-run-path": "^4.0.1",
469 | "onetime": "^5.1.2",
470 | "signal-exit": "^3.0.3",
471 | "strip-final-newline": "^2.0.0"
472 | }
473 | },
474 | "fast-deep-equal": {
475 | "version": "3.1.3",
476 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
477 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
478 | "dev": true
479 | },
480 | "fast-json-stable-stringify": {
481 | "version": "2.1.0",
482 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
483 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
484 | "dev": true
485 | },
486 | "fastest-levenshtein": {
487 | "version": "1.0.12",
488 | "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
489 | "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==",
490 | "dev": true
491 | },
492 | "find-up": {
493 | "version": "5.0.0",
494 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
495 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
496 | "dev": true,
497 | "requires": {
498 | "locate-path": "^6.0.0",
499 | "path-exists": "^4.0.0"
500 | }
501 | },
502 | "fs.realpath": {
503 | "version": "1.0.0",
504 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
505 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
506 | "dev": true
507 | },
508 | "function-bind": {
509 | "version": "1.1.1",
510 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
511 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
512 | "dev": true
513 | },
514 | "get-stream": {
515 | "version": "6.0.0",
516 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz",
517 | "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==",
518 | "dev": true
519 | },
520 | "glob": {
521 | "version": "7.1.6",
522 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
523 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
524 | "dev": true,
525 | "requires": {
526 | "fs.realpath": "^1.0.0",
527 | "inflight": "^1.0.4",
528 | "inherits": "2",
529 | "minimatch": "^3.0.4",
530 | "once": "^1.3.0",
531 | "path-is-absolute": "^1.0.0"
532 | }
533 | },
534 | "glob-to-regexp": {
535 | "version": "0.4.1",
536 | "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
537 | "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
538 | "dev": true
539 | },
540 | "graceful-fs": {
541 | "version": "4.2.4",
542 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
543 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
544 | "dev": true
545 | },
546 | "has": {
547 | "version": "1.0.3",
548 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
549 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
550 | "dev": true,
551 | "requires": {
552 | "function-bind": "^1.1.1"
553 | }
554 | },
555 | "has-flag": {
556 | "version": "4.0.0",
557 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
558 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
559 | "dev": true
560 | },
561 | "human-signals": {
562 | "version": "2.1.0",
563 | "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
564 | "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
565 | "dev": true
566 | },
567 | "import-local": {
568 | "version": "3.0.2",
569 | "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz",
570 | "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==",
571 | "dev": true,
572 | "requires": {
573 | "pkg-dir": "^4.2.0",
574 | "resolve-cwd": "^3.0.0"
575 | },
576 | "dependencies": {
577 | "find-up": {
578 | "version": "4.1.0",
579 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
580 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
581 | "dev": true,
582 | "requires": {
583 | "locate-path": "^5.0.0",
584 | "path-exists": "^4.0.0"
585 | }
586 | },
587 | "locate-path": {
588 | "version": "5.0.0",
589 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
590 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
591 | "dev": true,
592 | "requires": {
593 | "p-locate": "^4.1.0"
594 | }
595 | },
596 | "p-limit": {
597 | "version": "2.3.0",
598 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
599 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
600 | "dev": true,
601 | "requires": {
602 | "p-try": "^2.0.0"
603 | }
604 | },
605 | "p-locate": {
606 | "version": "4.1.0",
607 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
608 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
609 | "dev": true,
610 | "requires": {
611 | "p-limit": "^2.2.0"
612 | }
613 | },
614 | "pkg-dir": {
615 | "version": "4.2.0",
616 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
617 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
618 | "dev": true,
619 | "requires": {
620 | "find-up": "^4.0.0"
621 | }
622 | }
623 | }
624 | },
625 | "inflight": {
626 | "version": "1.0.6",
627 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
628 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
629 | "dev": true,
630 | "requires": {
631 | "once": "^1.3.0",
632 | "wrappy": "1"
633 | }
634 | },
635 | "inherits": {
636 | "version": "2.0.4",
637 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
638 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
639 | "dev": true
640 | },
641 | "interpret": {
642 | "version": "2.2.0",
643 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
644 | "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
645 | "dev": true
646 | },
647 | "is-core-module": {
648 | "version": "2.2.0",
649 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
650 | "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
651 | "dev": true,
652 | "requires": {
653 | "has": "^1.0.3"
654 | }
655 | },
656 | "is-stream": {
657 | "version": "2.0.0",
658 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
659 | "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
660 | "dev": true
661 | },
662 | "isexe": {
663 | "version": "2.0.0",
664 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
665 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
666 | "dev": true
667 | },
668 | "jest-worker": {
669 | "version": "26.6.2",
670 | "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
671 | "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
672 | "dev": true,
673 | "requires": {
674 | "@types/node": "*",
675 | "merge-stream": "^2.0.0",
676 | "supports-color": "^7.0.0"
677 | }
678 | },
679 | "json-parse-better-errors": {
680 | "version": "1.0.2",
681 | "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
682 | "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
683 | "dev": true
684 | },
685 | "json-schema-traverse": {
686 | "version": "0.4.1",
687 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
688 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
689 | "dev": true
690 | },
691 | "loader-runner": {
692 | "version": "4.2.0",
693 | "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
694 | "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
695 | "dev": true
696 | },
697 | "locate-path": {
698 | "version": "6.0.0",
699 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
700 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
701 | "dev": true,
702 | "requires": {
703 | "p-locate": "^5.0.0"
704 | }
705 | },
706 | "lodash": {
707 | "version": "4.17.20",
708 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
709 | "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
710 | "dev": true
711 | },
712 | "merge-stream": {
713 | "version": "2.0.0",
714 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
715 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
716 | "dev": true
717 | },
718 | "mime": {
719 | "version": "2.4.7",
720 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.7.tgz",
721 | "integrity": "sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA=="
722 | },
723 | "mime-db": {
724 | "version": "1.45.0",
725 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
726 | "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
727 | "dev": true
728 | },
729 | "mime-types": {
730 | "version": "2.1.28",
731 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
732 | "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
733 | "dev": true,
734 | "requires": {
735 | "mime-db": "1.45.0"
736 | }
737 | },
738 | "mimic-fn": {
739 | "version": "2.1.0",
740 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
741 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
742 | "dev": true
743 | },
744 | "minimatch": {
745 | "version": "3.0.4",
746 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
747 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
748 | "dev": true,
749 | "requires": {
750 | "brace-expansion": "^1.1.7"
751 | }
752 | },
753 | "neo-async": {
754 | "version": "2.6.2",
755 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
756 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
757 | "dev": true
758 | },
759 | "node-releases": {
760 | "version": "1.1.69",
761 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.69.tgz",
762 | "integrity": "sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA==",
763 | "dev": true
764 | },
765 | "npm-run-path": {
766 | "version": "4.0.1",
767 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
768 | "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
769 | "dev": true,
770 | "requires": {
771 | "path-key": "^3.0.0"
772 | }
773 | },
774 | "once": {
775 | "version": "1.4.0",
776 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
777 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
778 | "dev": true,
779 | "requires": {
780 | "wrappy": "1"
781 | }
782 | },
783 | "onetime": {
784 | "version": "5.1.2",
785 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
786 | "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
787 | "dev": true,
788 | "requires": {
789 | "mimic-fn": "^2.1.0"
790 | }
791 | },
792 | "p-limit": {
793 | "version": "3.1.0",
794 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
795 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
796 | "dev": true,
797 | "requires": {
798 | "yocto-queue": "^0.1.0"
799 | }
800 | },
801 | "p-locate": {
802 | "version": "5.0.0",
803 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
804 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
805 | "dev": true,
806 | "requires": {
807 | "p-limit": "^3.0.2"
808 | }
809 | },
810 | "p-try": {
811 | "version": "2.2.0",
812 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
813 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
814 | "dev": true
815 | },
816 | "path-exists": {
817 | "version": "4.0.0",
818 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
819 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
820 | "dev": true
821 | },
822 | "path-is-absolute": {
823 | "version": "1.0.1",
824 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
825 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
826 | "dev": true
827 | },
828 | "path-key": {
829 | "version": "3.1.1",
830 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
831 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
832 | "dev": true
833 | },
834 | "path-parse": {
835 | "version": "1.0.6",
836 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
837 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
838 | "dev": true
839 | },
840 | "pkg-dir": {
841 | "version": "5.0.0",
842 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz",
843 | "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==",
844 | "dev": true,
845 | "requires": {
846 | "find-up": "^5.0.0"
847 | }
848 | },
849 | "punycode": {
850 | "version": "2.1.1",
851 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
852 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
853 | "dev": true
854 | },
855 | "randombytes": {
856 | "version": "2.1.0",
857 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
858 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
859 | "dev": true,
860 | "requires": {
861 | "safe-buffer": "^5.1.0"
862 | }
863 | },
864 | "rechoir": {
865 | "version": "0.7.0",
866 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz",
867 | "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==",
868 | "dev": true,
869 | "requires": {
870 | "resolve": "^1.9.0"
871 | }
872 | },
873 | "resolve": {
874 | "version": "1.19.0",
875 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
876 | "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
877 | "dev": true,
878 | "requires": {
879 | "is-core-module": "^2.1.0",
880 | "path-parse": "^1.0.6"
881 | }
882 | },
883 | "resolve-cwd": {
884 | "version": "3.0.0",
885 | "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
886 | "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
887 | "dev": true,
888 | "requires": {
889 | "resolve-from": "^5.0.0"
890 | }
891 | },
892 | "resolve-from": {
893 | "version": "5.0.0",
894 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
895 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
896 | "dev": true
897 | },
898 | "rimraf": {
899 | "version": "3.0.2",
900 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
901 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
902 | "dev": true,
903 | "requires": {
904 | "glob": "^7.1.3"
905 | }
906 | },
907 | "safe-buffer": {
908 | "version": "5.2.1",
909 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
910 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
911 | "dev": true
912 | },
913 | "schema-utils": {
914 | "version": "3.0.0",
915 | "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
916 | "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
917 | "dev": true,
918 | "requires": {
919 | "@types/json-schema": "^7.0.6",
920 | "ajv": "^6.12.5",
921 | "ajv-keywords": "^3.5.2"
922 | }
923 | },
924 | "serialize-javascript": {
925 | "version": "5.0.1",
926 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
927 | "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
928 | "dev": true,
929 | "requires": {
930 | "randombytes": "^2.1.0"
931 | }
932 | },
933 | "shebang-command": {
934 | "version": "2.0.0",
935 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
936 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
937 | "dev": true,
938 | "requires": {
939 | "shebang-regex": "^3.0.0"
940 | }
941 | },
942 | "shebang-regex": {
943 | "version": "3.0.0",
944 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
945 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
946 | "dev": true
947 | },
948 | "signal-exit": {
949 | "version": "3.0.3",
950 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
951 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
952 | "dev": true
953 | },
954 | "source-list-map": {
955 | "version": "2.0.1",
956 | "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
957 | "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
958 | "dev": true
959 | },
960 | "source-map": {
961 | "version": "0.6.1",
962 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
963 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
964 | "dev": true
965 | },
966 | "source-map-support": {
967 | "version": "0.5.19",
968 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
969 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
970 | "dev": true,
971 | "requires": {
972 | "buffer-from": "^1.0.0",
973 | "source-map": "^0.6.0"
974 | }
975 | },
976 | "strip-final-newline": {
977 | "version": "2.0.0",
978 | "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
979 | "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
980 | "dev": true
981 | },
982 | "supports-color": {
983 | "version": "7.2.0",
984 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
985 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
986 | "dev": true,
987 | "requires": {
988 | "has-flag": "^4.0.0"
989 | }
990 | },
991 | "tapable": {
992 | "version": "2.2.0",
993 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz",
994 | "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==",
995 | "dev": true
996 | },
997 | "terser": {
998 | "version": "5.5.1",
999 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz",
1000 | "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==",
1001 | "dev": true,
1002 | "requires": {
1003 | "commander": "^2.20.0",
1004 | "source-map": "~0.7.2",
1005 | "source-map-support": "~0.5.19"
1006 | },
1007 | "dependencies": {
1008 | "source-map": {
1009 | "version": "0.7.3",
1010 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
1011 | "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
1012 | "dev": true
1013 | }
1014 | }
1015 | },
1016 | "terser-webpack-plugin": {
1017 | "version": "5.1.1",
1018 | "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz",
1019 | "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==",
1020 | "dev": true,
1021 | "requires": {
1022 | "jest-worker": "^26.6.2",
1023 | "p-limit": "^3.1.0",
1024 | "schema-utils": "^3.0.0",
1025 | "serialize-javascript": "^5.0.1",
1026 | "source-map": "^0.6.1",
1027 | "terser": "^5.5.1"
1028 | }
1029 | },
1030 | "tslib": {
1031 | "version": "1.14.1",
1032 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
1033 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
1034 | "dev": true
1035 | },
1036 | "typescript": {
1037 | "version": "4.1.3",
1038 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz",
1039 | "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==",
1040 | "dev": true
1041 | },
1042 | "uri-js": {
1043 | "version": "4.4.0",
1044 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
1045 | "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
1046 | "dev": true,
1047 | "requires": {
1048 | "punycode": "^2.1.0"
1049 | }
1050 | },
1051 | "v8-compile-cache": {
1052 | "version": "2.2.0",
1053 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz",
1054 | "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==",
1055 | "dev": true
1056 | },
1057 | "watchpack": {
1058 | "version": "2.1.0",
1059 | "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.0.tgz",
1060 | "integrity": "sha512-UjgD1mqjkG99+3lgG36at4wPnUXNvis2v1utwTgQ43C22c4LD71LsYMExdWXh4HZ+RmW+B0t1Vrg2GpXAkTOQw==",
1061 | "dev": true,
1062 | "requires": {
1063 | "glob-to-regexp": "^0.4.1",
1064 | "graceful-fs": "^4.1.2"
1065 | }
1066 | },
1067 | "webpack": {
1068 | "version": "5.12.2",
1069 | "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.12.2.tgz",
1070 | "integrity": "sha512-HiTXBGLFQiRecP5Fwrh21aaxlEUqQdDeUaninKVKX0Dtqaf+WjKCsNcv+UVftfYXrY0bnRQHnouw1x+CPqQKFQ==",
1071 | "dev": true,
1072 | "requires": {
1073 | "@types/eslint-scope": "^3.7.0",
1074 | "@types/estree": "^0.0.45",
1075 | "@webassemblyjs/ast": "1.9.1",
1076 | "@webassemblyjs/helper-module-context": "1.9.1",
1077 | "@webassemblyjs/wasm-edit": "1.9.1",
1078 | "@webassemblyjs/wasm-parser": "1.9.1",
1079 | "acorn": "^8.0.4",
1080 | "browserslist": "^4.14.5",
1081 | "chrome-trace-event": "^1.0.2",
1082 | "enhanced-resolve": "^5.3.1",
1083 | "eslint-scope": "^5.1.1",
1084 | "events": "^3.2.0",
1085 | "glob-to-regexp": "^0.4.1",
1086 | "graceful-fs": "^4.2.4",
1087 | "json-parse-better-errors": "^1.0.2",
1088 | "loader-runner": "^4.2.0",
1089 | "mime-types": "^2.1.27",
1090 | "neo-async": "^2.6.2",
1091 | "pkg-dir": "^5.0.0",
1092 | "schema-utils": "^3.0.0",
1093 | "tapable": "^2.1.1",
1094 | "terser-webpack-plugin": "^5.0.3",
1095 | "watchpack": "^2.0.0",
1096 | "webpack-sources": "^2.1.1"
1097 | }
1098 | },
1099 | "webpack-cli": {
1100 | "version": "4.3.1",
1101 | "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.3.1.tgz",
1102 | "integrity": "sha512-/F4+9QNZM/qKzzL9/06Am8NXIkGV+/NqQ62Dx7DSqudxxpAgBqYn6V7+zp+0Y7JuWksKUbczRY3wMTd+7Uj6OA==",
1103 | "dev": true,
1104 | "requires": {
1105 | "@discoveryjs/json-ext": "^0.5.0",
1106 | "@webpack-cli/info": "^1.2.1",
1107 | "@webpack-cli/serve": "^1.2.1",
1108 | "colorette": "^1.2.1",
1109 | "commander": "^6.2.0",
1110 | "enquirer": "^2.3.6",
1111 | "execa": "^5.0.0",
1112 | "fastest-levenshtein": "^1.0.12",
1113 | "import-local": "^3.0.2",
1114 | "interpret": "^2.2.0",
1115 | "rechoir": "^0.7.0",
1116 | "v8-compile-cache": "^2.2.0",
1117 | "webpack-merge": "^4.2.2"
1118 | },
1119 | "dependencies": {
1120 | "commander": {
1121 | "version": "6.2.1",
1122 | "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
1123 | "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
1124 | "dev": true
1125 | }
1126 | }
1127 | },
1128 | "webpack-merge": {
1129 | "version": "4.2.2",
1130 | "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz",
1131 | "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==",
1132 | "dev": true,
1133 | "requires": {
1134 | "lodash": "^4.17.15"
1135 | }
1136 | },
1137 | "webpack-sources": {
1138 | "version": "2.2.0",
1139 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz",
1140 | "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==",
1141 | "dev": true,
1142 | "requires": {
1143 | "source-list-map": "^2.0.1",
1144 | "source-map": "^0.6.1"
1145 | }
1146 | },
1147 | "which": {
1148 | "version": "2.0.2",
1149 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1150 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1151 | "dev": true,
1152 | "requires": {
1153 | "isexe": "^2.0.0"
1154 | }
1155 | },
1156 | "wrappy": {
1157 | "version": "1.0.2",
1158 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1159 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1160 | "dev": true
1161 | },
1162 | "yocto-queue": {
1163 | "version": "0.1.0",
1164 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
1165 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
1166 | "dev": true
1167 | }
1168 | }
1169 | }
1170 |
--------------------------------------------------------------------------------
/packages/worker/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "worker",
3 | "private": true,
4 | "main": "src/index.ts",
5 | "scripts": {
6 | "clean": "rimraf build",
7 | "clean:node": "rimraf node_modules package-lock.json",
8 | "build": "webpack"
9 | },
10 | "devDependencies": {
11 | "@cloudflare/workers-types": "2.1.0",
12 | "rimraf": "3.0.2",
13 | "typescript": "4.1.3",
14 | "webpack": "5.12.2",
15 | "webpack-cli": "4.3.1"
16 | },
17 | "dependencies": {
18 | "@cloudflare/kv-asset-handler": "0.1.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/worker/src/handleError.ts:
--------------------------------------------------------------------------------
1 | export const handleError = async (
2 | event: FetchEvent,
3 | error: Error
4 | ): Promise => {
5 | console.info(event.request);
6 | console.error(error);
7 | };
8 |
--------------------------------------------------------------------------------
/packages/worker/src/index.ts:
--------------------------------------------------------------------------------
1 | import {} from "@cloudflare/workers-types";
2 | import {
3 | getAssetFromKV,
4 | serveSinglePageApp,
5 | } from "@cloudflare/kv-asset-handler";
6 | import { handleRequest as server } from "../../server/src";
7 | import { handleError } from "./handleError";
8 | import { internalServerError, notFound } from "./pages";
9 |
10 | const assetOptions = {
11 | mapRequestToAsset: serveSinglePageApp,
12 | };
13 |
14 | const handleProductionAssetRequest = async (
15 | event: FetchEvent
16 | ): Promise => {
17 | try {
18 | return await getAssetFromKV(event, assetOptions);
19 | } catch (e) {
20 | // TODO: Could also be an error thrown by the getAssetFromKV function: https://github.com/cloudflare/kv-asset-handler#return
21 | return notFound(event);
22 | }
23 | };
24 |
25 | const handleAssetRequest = async (event: any): Promise => {
26 | if (process.env.CLOUDFLARED_TUNNEL) return await fetch(event.request);
27 |
28 | return await handleProductionAssetRequest(event);
29 | };
30 |
31 | const handleRequest = async (event: any): Promise => {
32 | try {
33 | const { request } = event;
34 | const response = await server(request);
35 | if (response.status !== 404) return response;
36 |
37 | return handleAssetRequest(event);
38 | } catch (error) {
39 | event.waitUntil(handleError(event, error));
40 |
41 | return internalServerError(event, error);
42 | }
43 | };
44 |
45 | addEventListener(`fetch`, (event: any) => {
46 | event.respondWith(handleRequest(event));
47 | });
48 |
--------------------------------------------------------------------------------
/packages/worker/src/pages.ts:
--------------------------------------------------------------------------------
1 | export const notFound = (event: any) =>
2 | // TODO: Pretty 404 page
3 | new Response(`Not Found`, {
4 | status: 404,
5 | headers: { "Content-Type": `text/plain` },
6 | });
7 |
8 | export const internalServerError = (event: any, error: Error) =>
9 | // TODO: Pretty 500 page
10 | new Response(`Internal Server Error`, {
11 | status: 500,
12 | headers: { "Content-Type": `text/plain` },
13 | });
14 |
--------------------------------------------------------------------------------
/packages/worker/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./build",
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 | "./node_modules/@cloudflare/workers-types/index.d.ts",
17 | "src/index.ts"
18 | ],
19 | "exclude": ["build/"]
20 | }
21 |
--------------------------------------------------------------------------------
/packages/worker/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const webpack = require("webpack");
3 |
4 | module.exports = {
5 | entry: path.join(__dirname, "src", "index.ts"),
6 | output: {
7 | filename: `worker.js`,
8 | path: path.join(__dirname, "build"),
9 | },
10 | target: "webworker",
11 | resolve: {
12 | extensions: [".ts", ".tsx", ".js"],
13 | alias: {
14 | fs: path.resolve(__dirname, "./null.js"),
15 | },
16 | },
17 | mode: "production",
18 | optimization: {
19 | usedExports: true,
20 | },
21 | module: {
22 | rules: [
23 | {
24 | test: /\.tsx?$/,
25 | loader: "ts-loader",
26 | options: {
27 | transpileOnly: true,
28 | },
29 | },
30 | ],
31 | },
32 | plugins: [new webpack.EnvironmentPlugin({ CLOUDFLARED_TUNNEL: "" })],
33 | };
34 |
--------------------------------------------------------------------------------
/updatePackages.js:
--------------------------------------------------------------------------------
1 | const ncu = require("npm-check-updates");
2 |
3 | const packageFiles = [
4 | "package.json",
5 | "packages/client/package.json",
6 | "packages/server/package.json",
7 | "packages/worker/package.json",
8 | ];
9 |
10 | packageFiles.map((packageFile) => {
11 | ncu
12 | .run({ upgrade: true, packageFile })
13 | .then(() => console.log(`Updated ${packageFile}`));
14 | });
15 |
--------------------------------------------------------------------------------
/wrangler.toml:
--------------------------------------------------------------------------------
1 | name = "script-name-dev"
2 | type = "webpack"
3 | webpack_config = "./packages/worker/webpack.config.js"
4 | account_id = "5a883b414d4090a1442b20361f3c43a9"
5 | workers_dev = true
6 |
7 | kv-namespaces = []
8 |
9 | [site]
10 | bucket = "./packages/client/build"
11 | entry-point = "./packages/worker"
12 |
13 | [env.production]
14 | name = "script-name"
--------------------------------------------------------------------------------