├── app ├── style.css ├── script.ts └── index.html ├── .devcontainer ├── Dockerfile └── devcontainer.json ├── netlify.toml ├── vite.config.ts ├── tsconfig.json ├── api └── ably-token-request │ ├── package.json │ ├── index.ts │ └── package-lock.json ├── package.json ├── .gitignore └── README.md /app/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: antiquewhite; 3 | } -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # Append -bullseye variants on local arm64/Apple Silicon. 2 | 3 | ARG VARIANT=16 4 | FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:${VARIANT} 5 | 6 | RUN su node -c "npm install -g npm" 7 | RUN su node -c "npm install -g netlify-cli" 8 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "dist" 3 | command = "npm run build" 4 | 5 | [functions] 6 | directory = "api" 7 | 8 | [[redirects]] 9 | from = "/api/*" 10 | to = "/.netlify/functions/:splat" 11 | status = 200 12 | 13 | [template.environment] 14 | ABLY_API_KEY = "change me to your Ably API key" 15 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | // https://vitejs.dev/config/ 4 | export default defineConfig({ 5 | root: "app", 6 | server: { 7 | port: 8080, 8 | strictPort: true, 9 | host: true, 10 | proxy: { 11 | '/.netlify': 'http://localhost:9999/.netlify' 12 | } 13 | }, 14 | build: { 15 | outDir: "../dist", 16 | sourcemap: true, 17 | emptyOutDir: true 18 | }, 19 | plugins: [] 20 | }) 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": [ 6 | "DOM", 7 | "DOM.Iterable", 8 | "ESNext" 9 | ], 10 | "allowJs": true, 11 | "skipLibCheck": false, 12 | "esModuleInterop": false, 13 | "allowSyntheticDefaultImports": true, 14 | "module": "ESNext", 15 | "moduleResolution": "Node", 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "noEmit": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /api/ably-token-request/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ably-token-request", 3 | "version": "1.0.0", 4 | "description": "ably token request", 5 | "main": "index.ts", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "netlify", 11 | "serverless", 12 | "typescript" 13 | ], 14 | "author": "Netlify", 15 | "license": "MIT", 16 | "dependencies": { 17 | "@netlify/functions": "^1.0.0", 18 | "@types/node": "^14.0.0", 19 | "typescript": "^4.7.4", 20 | "ably": "^1.2.29", 21 | "dotenv": "^16.0.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "netlify-and-ably", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "prepare": "cd api/ably-token-request && npm install", 8 | "dev:app": "vite", 9 | "start": "netlify dev -c \"npm run dev:app\" --targetPort 8080", 10 | "test": "npm run test:app", 11 | "test:app": "vitest run", 12 | "build": "npx vite build" 13 | }, 14 | "author": "", 15 | "license": "ISC", 16 | "devDependencies": { 17 | "npm-run-all": "^4.1.5", 18 | "typescript": "^4.7.4", 19 | "vite": "^3.0.0", 20 | "vitest": "^0.19.1" 21 | }, 22 | "dependencies": { 23 | "ably": "^1.2.29", 24 | "dotenv": "^16.0.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/script.ts: -------------------------------------------------------------------------------- 1 | import { Types } from "ably/promises"; 2 | import * as Ably from "ably/promises"; 3 | 4 | (async () => { 5 | 6 | console.log("Oh hai! 🖤"); 7 | 8 | const optionalClientId = "optionalClientId"; // When not provided in authUrl, a default will be used. 9 | const ably = new Ably.Realtime.Promise({ authUrl: `/api/ably-token-request?clientId=${optionalClientId}` }); 10 | const channel = ably.channels.get("some-channel-name"); 11 | 12 | await channel.subscribe((msg: Types.Message) => { 13 | console.log("Ably message received", msg); 14 | document.getElementById("response").innerHTML += "
" + JSON.stringify(msg); 15 | }); 16 | 17 | channel.publish("hello-world-message", { message: "Hello world!" }); 18 | })(); 19 | 20 | export { }; 21 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Netlify and Ably", 3 | "runArgs": [ 4 | "--init" 5 | ], 6 | "build": { 7 | "dockerfile": "Dockerfile", 8 | "args": { 9 | // Update 'VARIANT' to pick a Node version: 16, 14, 12. 10 | // Append -bullseye or -buster to pin to an OS version. 11 | // Use -bullseye variants on local arm64/Apple Silicon. 12 | "VARIANT": "16" 13 | } 14 | }, 15 | "forwardPorts": [ 16 | 8080, 17 | 8888, 18 | 9999 19 | ], 20 | "portsAttributes": { 21 | "8888": { 22 | "label": "Netlify Local", 23 | "onAutoForward": "openBrowserOnce" 24 | }, 25 | "8080": { 26 | "label": "Vite DevServer", 27 | "onAutoForward": "ignore" 28 | }, 29 | "9999": { 30 | "label": "Netlify Functions", 31 | "onAutoForward": "ignore" 32 | } 33 | }, 34 | "settings": {}, 35 | "postCreateCommand": "npm install", 36 | "remoteUser": "node" 37 | } 38 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Ably 💚 Netlify

14 |
15 |

16 | This application uses Netlify serverless functions to host an API, and a plain HTML application to render the response. 17 |

18 |

19 | We're using the Netlify serverless function to manage an Ably API Key - there is a tokenRequest API that serves on /.netlify/functions/ably-tokenRequest that provides 20 | the in-browser SDK with your API key. 21 |

22 |

23 | Once this page loads, it'll connect to an ably channel, and send a message - the raw messages will appear below: 24 |

25 |
26 |
27 |

Ably messages will append here.

28 |
29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /api/ably-token-request/index.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from "dotenv"; 2 | import * as Ably from "ably/promises"; 3 | import { HandlerEvent, HandlerContext } from "@netlify/functions"; 4 | 5 | dotenv.config(); 6 | 7 | export async function handler(event: HandlerEvent, context: HandlerContext) { 8 | 9 | if (!process.env.ABLY_API_KEY) { 10 | return { 11 | statusCode: 500, 12 | headers: { "content-type": "application/json" }, 13 | body: JSON.stringify(`Missing ABLY_API_KEY environment variable. 14 | If you're running locally, please ensure you have a ./.env file with a value for ABLY_API_KEY=your-key. 15 | If you're running in Netlify, make sure you've configured env variable ABLY_API_KEY. 16 | Please see README.md for more details on configuring your Ably API Key.`) 17 | } 18 | } 19 | 20 | const clientId = event.queryStringParameters["clientId"] || process.env.DEFAULT_CLIENT_ID || "NO_CLIENT_ID"; 21 | const client = new Ably.Rest(process.env.ABLY_API_KEY); 22 | const tokenRequestData = await client.auth.createTokenRequest({ clientId: clientId }); 23 | 24 | return { 25 | statusCode: 200, 26 | headers: { "content-type": "application/json" }, 27 | body: JSON.stringify(tokenRequestData) 28 | }; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | api/node_modules 43 | jspm_packages/ 44 | 45 | # TypeScript v1 declaration files 46 | typings/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Microbundle cache 58 | .rpt2_cache/ 59 | .rts2_cache_cjs/ 60 | .rts2_cache_es/ 61 | .rts2_cache_umd/ 62 | 63 | # Optional REPL history 64 | .node_repl_history 65 | 66 | # Output of 'npm pack' 67 | *.tgz 68 | 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | 72 | # dotenv environment variables file 73 | .env 74 | .env.test 75 | 76 | # parcel-bundler cache (https://parceljs.org/) 77 | .cache 78 | 79 | # Next.js build output 80 | .next 81 | 82 | # Nuxt.js build / generate output 83 | .nuxt 84 | dist 85 | 86 | # Gatsby files 87 | .cache/ 88 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 89 | # https://nextjs.org/blog/next-9-1#public-directory-support 90 | # public 91 | 92 | # vuepress build output 93 | .vuepress/dist 94 | 95 | # Serverless directories 96 | .serverless/ 97 | 98 | # FuseBox cache 99 | .fusebox/ 100 | 101 | # DynamoDB Local files 102 | .dynamodb/ 103 | 104 | # TernJS port file 105 | .tern-port 106 | 107 | .netlify 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Netlify and Ably 2 | 3 | A GitHub template to quickly get started with Ably, hosted on Netlify, using TypeScript. 4 | 5 | [![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/ably-labs/netlify-and-ably) 6 | 7 | ## What is this? 8 | 9 | This is a GitHub template repository that will create you a pre-configured, v-latest experience on Netlify, along with a hot-reload enabled, local development experience. We've configured TypeScript, and a bunch of default build jobs so you can create a new repository and just get to work. 10 | 11 | There's a built in hot-reloading dev experience powered by Vite.js. 12 | 13 | It's built out-of-the-box to support Ably realtime, and has pre-build APIs for the Ably JavaScript SDK to handle authentication and messaging. 14 | 15 | Bundled tools: 16 | 17 | - Vite (vite.dev) - hot reload, bundleless dev server 18 | - TypeScript - language, type checking 19 | - Netlify Functions - bundled API / BFF support. 20 | - Ably - realtime, auth, messaging 21 | 22 | ## Usage 23 | 24 | - Create a repository based on this repository. 25 | - Clone your new repository. 26 | - Run `npm install` to install the dependencies. 27 | - Run `npm run start` to start the local development server. 28 | - Browse to `http://localhost:8888` 29 | 30 | You'll see a white page load, which in turn will load the Ably JavaScript SDK, and use the included Netlify functions to handle API key management. When everything is running, you'll see Ably messages written to the page. 31 | 32 | ## Getting and Managing Ably API keys 33 | 34 | In order to run this app, you will need an Ably API key. If you are not already signed up, you can [sign up now for a free Ably account](https://www.ably.com/signup). Once you have an Ably account: 35 | 36 | 1. Log into your app dashboard. 37 | 2. Under **“Your apps”**, click on **“Manage app”** for any app you wish to use for this tutorial, or create a new one with the “Create New App” button. 38 | 3. Click on the **“API Keys”** tab. 39 | 4. Copy the secret **“API Key”** value from your Root key, we will use this to configure our app. 40 | 41 | This app is going to use [Ably Channels](https://www.ably.com/channels) and [Token Authentication](https://www.ably.com/documentation/rest/authentication/#token-authentication). 42 | 43 | ## Configuring your Ably API keys 44 | 45 | ### For local development 46 | 47 | You need to create a `.env` file in the root with a variable defined called `ABLY_API_KEY` to store your secret. 48 | You can do this from the command line if you like: 49 | 50 | ```bash 51 | cd api 52 | echo ABLY_API_KEY=YOUR-API-KEY-HERE > .env 53 | ``` 54 | 55 | **NB. You need to restart the dev server after you create this `.env` file.** 56 | 57 | ### Deploying to Netlify 58 | 59 | [![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/ably-labs/netlify-and-ably) 60 | 61 | We've bundled a `netlify.toml` file in the root of the repository, which will configure your build and deployment settings. 62 | **You will need to add an environment configuration setting** using the netlify UI: 63 | 64 | ```bash 65 | ABLY_API_KEY=your-ably-api-key 66 | ``` 67 | 68 | You can configure your secrets in `netlify` by going to your app dashboard and visiting: 69 | 70 | Site Overview > Site Settings > Build and Deploy > Environment > Environment Variables 71 | 72 | Click on **Edit Variables** to add the values for `ABLY_API_KEY`. 73 | 74 | The rest of the Netlify build is configured via the `netlify.toml` file included in this repository. 75 | 76 | # Dev Containers 77 | 78 | This repository contains pre-configured `.devcontainer` support, so you can use it to spin up either VS Code devcontainers, or a GitHub Codespace for your application. It will just work! 79 | -------------------------------------------------------------------------------- /api/ably-token-request/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ably-token-request", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "ably-token-request", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@netlify/functions": "^1.0.0", 13 | "@types/node": "^14.0.0", 14 | "ably": "^1.2.29", 15 | "dotenv": "^16.0.1", 16 | "typescript": "^4.7.4" 17 | } 18 | }, 19 | "node_modules/@ably/msgpack-js": { 20 | "version": "0.4.0", 21 | "resolved": "https://registry.npmjs.org/@ably/msgpack-js/-/msgpack-js-0.4.0.tgz", 22 | "integrity": "sha512-IPt/BoiQwCWubqoNik1aw/6M/DleMdrxJOUpSja6xmMRbT2p1TA8oqKWgfZabqzrq8emRNeSl/+4XABPNnW5pQ==", 23 | "dependencies": { 24 | "bops": "^1.0.1" 25 | } 26 | }, 27 | "node_modules/@netlify/functions": { 28 | "version": "1.0.0", 29 | "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-1.0.0.tgz", 30 | "integrity": "sha512-7fnJv3vr8uyyyOYPChwoec6MjzsCw1CoRUO2DhQ1BD6bOyJRlD4DUaOOGlMILB2LCT8P24p5LexEGx8AJb7xdA==", 31 | "dependencies": { 32 | "is-promise": "^4.0.0" 33 | }, 34 | "engines": { 35 | "node": ">=8.3.0" 36 | } 37 | }, 38 | "node_modules/@sindresorhus/is": { 39 | "version": "4.6.0", 40 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", 41 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", 42 | "engines": { 43 | "node": ">=10" 44 | }, 45 | "funding": { 46 | "url": "https://github.com/sindresorhus/is?sponsor=1" 47 | } 48 | }, 49 | "node_modules/@szmarczak/http-timer": { 50 | "version": "4.0.6", 51 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", 52 | "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", 53 | "dependencies": { 54 | "defer-to-connect": "^2.0.0" 55 | }, 56 | "engines": { 57 | "node": ">=10" 58 | } 59 | }, 60 | "node_modules/@types/cacheable-request": { 61 | "version": "6.0.2", 62 | "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", 63 | "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", 64 | "dependencies": { 65 | "@types/http-cache-semantics": "*", 66 | "@types/keyv": "*", 67 | "@types/node": "*", 68 | "@types/responselike": "*" 69 | } 70 | }, 71 | "node_modules/@types/http-cache-semantics": { 72 | "version": "4.0.1", 73 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", 74 | "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" 75 | }, 76 | "node_modules/@types/json-buffer": { 77 | "version": "3.0.0", 78 | "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", 79 | "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" 80 | }, 81 | "node_modules/@types/keyv": { 82 | "version": "3.1.4", 83 | "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", 84 | "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", 85 | "dependencies": { 86 | "@types/node": "*" 87 | } 88 | }, 89 | "node_modules/@types/node": { 90 | "version": "14.18.23", 91 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.23.tgz", 92 | "integrity": "sha512-MhbCWN18R4GhO8ewQWAFK4TGQdBpXWByukz7cWyJmXhvRuCIaM/oWytGPqVmDzgEnnaIc9ss6HbU5mUi+vyZPA==" 93 | }, 94 | "node_modules/@types/responselike": { 95 | "version": "1.0.0", 96 | "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", 97 | "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", 98 | "dependencies": { 99 | "@types/node": "*" 100 | } 101 | }, 102 | "node_modules/ably": { 103 | "version": "1.2.29", 104 | "resolved": "https://registry.npmjs.org/ably/-/ably-1.2.29.tgz", 105 | "integrity": "sha512-bgacOwmDBpHACysn1o0ZoScJsaiOeJoZXhIEUw9aMrqd91B3JBrtJwU80XJjPAw02lE7mxeGCWh85SDNNUN+hg==", 106 | "dependencies": { 107 | "@ably/msgpack-js": "^0.4.0", 108 | "got": "^11.8.2", 109 | "ws": "^5.1" 110 | }, 111 | "engines": { 112 | "node": ">=5.10.x" 113 | } 114 | }, 115 | "node_modules/async-limiter": { 116 | "version": "1.0.1", 117 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", 118 | "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" 119 | }, 120 | "node_modules/base64-js": { 121 | "version": "1.0.2", 122 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.2.tgz", 123 | "integrity": "sha512-ZXBDPMt/v/8fsIqn+Z5VwrhdR6jVka0bYobHdGia0Nxi7BJ9i/Uvml3AocHIBtIIBhZjBw5MR0aR4ROs/8+SNg==", 124 | "engines": { 125 | "node": ">= 0.4" 126 | } 127 | }, 128 | "node_modules/bops": { 129 | "version": "1.0.1", 130 | "resolved": "https://registry.npmjs.org/bops/-/bops-1.0.1.tgz", 131 | "integrity": "sha512-qCMBuZKP36tELrrgXpAfM+gHzqa0nLsWZ+L37ncsb8txYlnAoxOPpVp+g7fK0sGkMXfA0wl8uQkESqw3v4HNag==", 132 | "dependencies": { 133 | "base64-js": "1.0.2", 134 | "to-utf8": "0.0.1" 135 | } 136 | }, 137 | "node_modules/cacheable-lookup": { 138 | "version": "5.0.4", 139 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", 140 | "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", 141 | "engines": { 142 | "node": ">=10.6.0" 143 | } 144 | }, 145 | "node_modules/cacheable-request": { 146 | "version": "7.0.2", 147 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", 148 | "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", 149 | "dependencies": { 150 | "clone-response": "^1.0.2", 151 | "get-stream": "^5.1.0", 152 | "http-cache-semantics": "^4.0.0", 153 | "keyv": "^4.0.0", 154 | "lowercase-keys": "^2.0.0", 155 | "normalize-url": "^6.0.1", 156 | "responselike": "^2.0.0" 157 | }, 158 | "engines": { 159 | "node": ">=8" 160 | } 161 | }, 162 | "node_modules/clone-response": { 163 | "version": "1.0.3", 164 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", 165 | "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", 166 | "dependencies": { 167 | "mimic-response": "^1.0.0" 168 | }, 169 | "funding": { 170 | "url": "https://github.com/sponsors/sindresorhus" 171 | } 172 | }, 173 | "node_modules/compress-brotli": { 174 | "version": "1.3.8", 175 | "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz", 176 | "integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==", 177 | "dependencies": { 178 | "@types/json-buffer": "~3.0.0", 179 | "json-buffer": "~3.0.1" 180 | }, 181 | "engines": { 182 | "node": ">= 12" 183 | } 184 | }, 185 | "node_modules/decompress-response": { 186 | "version": "6.0.0", 187 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 188 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 189 | "dependencies": { 190 | "mimic-response": "^3.1.0" 191 | }, 192 | "engines": { 193 | "node": ">=10" 194 | }, 195 | "funding": { 196 | "url": "https://github.com/sponsors/sindresorhus" 197 | } 198 | }, 199 | "node_modules/decompress-response/node_modules/mimic-response": { 200 | "version": "3.1.0", 201 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 202 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", 203 | "engines": { 204 | "node": ">=10" 205 | }, 206 | "funding": { 207 | "url": "https://github.com/sponsors/sindresorhus" 208 | } 209 | }, 210 | "node_modules/defer-to-connect": { 211 | "version": "2.0.1", 212 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", 213 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", 214 | "engines": { 215 | "node": ">=10" 216 | } 217 | }, 218 | "node_modules/dotenv": { 219 | "version": "16.0.1", 220 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", 221 | "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==", 222 | "engines": { 223 | "node": ">=12" 224 | } 225 | }, 226 | "node_modules/end-of-stream": { 227 | "version": "1.4.4", 228 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 229 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 230 | "dependencies": { 231 | "once": "^1.4.0" 232 | } 233 | }, 234 | "node_modules/get-stream": { 235 | "version": "5.2.0", 236 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 237 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 238 | "dependencies": { 239 | "pump": "^3.0.0" 240 | }, 241 | "engines": { 242 | "node": ">=8" 243 | }, 244 | "funding": { 245 | "url": "https://github.com/sponsors/sindresorhus" 246 | } 247 | }, 248 | "node_modules/got": { 249 | "version": "11.8.5", 250 | "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", 251 | "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", 252 | "dependencies": { 253 | "@sindresorhus/is": "^4.0.0", 254 | "@szmarczak/http-timer": "^4.0.5", 255 | "@types/cacheable-request": "^6.0.1", 256 | "@types/responselike": "^1.0.0", 257 | "cacheable-lookup": "^5.0.3", 258 | "cacheable-request": "^7.0.2", 259 | "decompress-response": "^6.0.0", 260 | "http2-wrapper": "^1.0.0-beta.5.2", 261 | "lowercase-keys": "^2.0.0", 262 | "p-cancelable": "^2.0.0", 263 | "responselike": "^2.0.0" 264 | }, 265 | "engines": { 266 | "node": ">=10.19.0" 267 | }, 268 | "funding": { 269 | "url": "https://github.com/sindresorhus/got?sponsor=1" 270 | } 271 | }, 272 | "node_modules/http-cache-semantics": { 273 | "version": "4.1.0", 274 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", 275 | "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" 276 | }, 277 | "node_modules/http2-wrapper": { 278 | "version": "1.0.3", 279 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", 280 | "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", 281 | "dependencies": { 282 | "quick-lru": "^5.1.1", 283 | "resolve-alpn": "^1.0.0" 284 | }, 285 | "engines": { 286 | "node": ">=10.19.0" 287 | } 288 | }, 289 | "node_modules/is-promise": { 290 | "version": "4.0.0", 291 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", 292 | "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" 293 | }, 294 | "node_modules/json-buffer": { 295 | "version": "3.0.1", 296 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 297 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" 298 | }, 299 | "node_modules/keyv": { 300 | "version": "4.3.3", 301 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.3.tgz", 302 | "integrity": "sha512-AcysI17RvakTh8ir03+a3zJr5r0ovnAH/XTXei/4HIv3bL2K/jzvgivLK9UuI/JbU1aJjM3NSAnVvVVd3n+4DQ==", 303 | "dependencies": { 304 | "compress-brotli": "^1.3.8", 305 | "json-buffer": "3.0.1" 306 | } 307 | }, 308 | "node_modules/lowercase-keys": { 309 | "version": "2.0.0", 310 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 311 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", 312 | "engines": { 313 | "node": ">=8" 314 | } 315 | }, 316 | "node_modules/mimic-response": { 317 | "version": "1.0.1", 318 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 319 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", 320 | "engines": { 321 | "node": ">=4" 322 | } 323 | }, 324 | "node_modules/normalize-url": { 325 | "version": "6.1.0", 326 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", 327 | "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", 328 | "engines": { 329 | "node": ">=10" 330 | }, 331 | "funding": { 332 | "url": "https://github.com/sponsors/sindresorhus" 333 | } 334 | }, 335 | "node_modules/once": { 336 | "version": "1.4.0", 337 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 338 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 339 | "dependencies": { 340 | "wrappy": "1" 341 | } 342 | }, 343 | "node_modules/p-cancelable": { 344 | "version": "2.1.1", 345 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", 346 | "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", 347 | "engines": { 348 | "node": ">=8" 349 | } 350 | }, 351 | "node_modules/pump": { 352 | "version": "3.0.0", 353 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 354 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 355 | "dependencies": { 356 | "end-of-stream": "^1.1.0", 357 | "once": "^1.3.1" 358 | } 359 | }, 360 | "node_modules/quick-lru": { 361 | "version": "5.1.1", 362 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 363 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", 364 | "engines": { 365 | "node": ">=10" 366 | }, 367 | "funding": { 368 | "url": "https://github.com/sponsors/sindresorhus" 369 | } 370 | }, 371 | "node_modules/resolve-alpn": { 372 | "version": "1.2.1", 373 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", 374 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" 375 | }, 376 | "node_modules/responselike": { 377 | "version": "2.0.1", 378 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", 379 | "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", 380 | "dependencies": { 381 | "lowercase-keys": "^2.0.0" 382 | }, 383 | "funding": { 384 | "url": "https://github.com/sponsors/sindresorhus" 385 | } 386 | }, 387 | "node_modules/to-utf8": { 388 | "version": "0.0.1", 389 | "resolved": "https://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz", 390 | "integrity": "sha512-zks18/TWT1iHO3v0vFp5qLKOG27m67ycq/Y7a7cTiRuUNlc4gf3HGnkRgMv0NyhnfTamtkYBJl+YeD1/j07gBQ==" 391 | }, 392 | "node_modules/typescript": { 393 | "version": "4.7.4", 394 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", 395 | "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", 396 | "bin": { 397 | "tsc": "bin/tsc", 398 | "tsserver": "bin/tsserver" 399 | }, 400 | "engines": { 401 | "node": ">=4.2.0" 402 | } 403 | }, 404 | "node_modules/wrappy": { 405 | "version": "1.0.2", 406 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 407 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 408 | }, 409 | "node_modules/ws": { 410 | "version": "5.2.3", 411 | "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz", 412 | "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==", 413 | "dependencies": { 414 | "async-limiter": "~1.0.0" 415 | } 416 | } 417 | }, 418 | "dependencies": { 419 | "@ably/msgpack-js": { 420 | "version": "0.4.0", 421 | "resolved": "https://registry.npmjs.org/@ably/msgpack-js/-/msgpack-js-0.4.0.tgz", 422 | "integrity": "sha512-IPt/BoiQwCWubqoNik1aw/6M/DleMdrxJOUpSja6xmMRbT2p1TA8oqKWgfZabqzrq8emRNeSl/+4XABPNnW5pQ==", 423 | "requires": { 424 | "bops": "^1.0.1" 425 | } 426 | }, 427 | "@netlify/functions": { 428 | "version": "1.0.0", 429 | "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-1.0.0.tgz", 430 | "integrity": "sha512-7fnJv3vr8uyyyOYPChwoec6MjzsCw1CoRUO2DhQ1BD6bOyJRlD4DUaOOGlMILB2LCT8P24p5LexEGx8AJb7xdA==", 431 | "requires": { 432 | "is-promise": "^4.0.0" 433 | } 434 | }, 435 | "@sindresorhus/is": { 436 | "version": "4.6.0", 437 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", 438 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" 439 | }, 440 | "@szmarczak/http-timer": { 441 | "version": "4.0.6", 442 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", 443 | "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", 444 | "requires": { 445 | "defer-to-connect": "^2.0.0" 446 | } 447 | }, 448 | "@types/cacheable-request": { 449 | "version": "6.0.2", 450 | "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", 451 | "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", 452 | "requires": { 453 | "@types/http-cache-semantics": "*", 454 | "@types/keyv": "*", 455 | "@types/node": "*", 456 | "@types/responselike": "*" 457 | } 458 | }, 459 | "@types/http-cache-semantics": { 460 | "version": "4.0.1", 461 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", 462 | "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" 463 | }, 464 | "@types/json-buffer": { 465 | "version": "3.0.0", 466 | "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", 467 | "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" 468 | }, 469 | "@types/keyv": { 470 | "version": "3.1.4", 471 | "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", 472 | "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", 473 | "requires": { 474 | "@types/node": "*" 475 | } 476 | }, 477 | "@types/node": { 478 | "version": "14.18.23", 479 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.23.tgz", 480 | "integrity": "sha512-MhbCWN18R4GhO8ewQWAFK4TGQdBpXWByukz7cWyJmXhvRuCIaM/oWytGPqVmDzgEnnaIc9ss6HbU5mUi+vyZPA==" 481 | }, 482 | "@types/responselike": { 483 | "version": "1.0.0", 484 | "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", 485 | "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", 486 | "requires": { 487 | "@types/node": "*" 488 | } 489 | }, 490 | "ably": { 491 | "version": "1.2.29", 492 | "resolved": "https://registry.npmjs.org/ably/-/ably-1.2.29.tgz", 493 | "integrity": "sha512-bgacOwmDBpHACysn1o0ZoScJsaiOeJoZXhIEUw9aMrqd91B3JBrtJwU80XJjPAw02lE7mxeGCWh85SDNNUN+hg==", 494 | "requires": { 495 | "@ably/msgpack-js": "^0.4.0", 496 | "got": "^11.8.2", 497 | "ws": "^5.1" 498 | } 499 | }, 500 | "async-limiter": { 501 | "version": "1.0.1", 502 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", 503 | "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" 504 | }, 505 | "base64-js": { 506 | "version": "1.0.2", 507 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.2.tgz", 508 | "integrity": "sha512-ZXBDPMt/v/8fsIqn+Z5VwrhdR6jVka0bYobHdGia0Nxi7BJ9i/Uvml3AocHIBtIIBhZjBw5MR0aR4ROs/8+SNg==" 509 | }, 510 | "bops": { 511 | "version": "1.0.1", 512 | "resolved": "https://registry.npmjs.org/bops/-/bops-1.0.1.tgz", 513 | "integrity": "sha512-qCMBuZKP36tELrrgXpAfM+gHzqa0nLsWZ+L37ncsb8txYlnAoxOPpVp+g7fK0sGkMXfA0wl8uQkESqw3v4HNag==", 514 | "requires": { 515 | "base64-js": "1.0.2", 516 | "to-utf8": "0.0.1" 517 | } 518 | }, 519 | "cacheable-lookup": { 520 | "version": "5.0.4", 521 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", 522 | "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==" 523 | }, 524 | "cacheable-request": { 525 | "version": "7.0.2", 526 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", 527 | "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", 528 | "requires": { 529 | "clone-response": "^1.0.2", 530 | "get-stream": "^5.1.0", 531 | "http-cache-semantics": "^4.0.0", 532 | "keyv": "^4.0.0", 533 | "lowercase-keys": "^2.0.0", 534 | "normalize-url": "^6.0.1", 535 | "responselike": "^2.0.0" 536 | } 537 | }, 538 | "clone-response": { 539 | "version": "1.0.3", 540 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", 541 | "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", 542 | "requires": { 543 | "mimic-response": "^1.0.0" 544 | } 545 | }, 546 | "compress-brotli": { 547 | "version": "1.3.8", 548 | "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz", 549 | "integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==", 550 | "requires": { 551 | "@types/json-buffer": "~3.0.0", 552 | "json-buffer": "~3.0.1" 553 | } 554 | }, 555 | "decompress-response": { 556 | "version": "6.0.0", 557 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 558 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 559 | "requires": { 560 | "mimic-response": "^3.1.0" 561 | }, 562 | "dependencies": { 563 | "mimic-response": { 564 | "version": "3.1.0", 565 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 566 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" 567 | } 568 | } 569 | }, 570 | "defer-to-connect": { 571 | "version": "2.0.1", 572 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", 573 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" 574 | }, 575 | "dotenv": { 576 | "version": "16.0.1", 577 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", 578 | "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==" 579 | }, 580 | "end-of-stream": { 581 | "version": "1.4.4", 582 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 583 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 584 | "requires": { 585 | "once": "^1.4.0" 586 | } 587 | }, 588 | "get-stream": { 589 | "version": "5.2.0", 590 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 591 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 592 | "requires": { 593 | "pump": "^3.0.0" 594 | } 595 | }, 596 | "got": { 597 | "version": "11.8.5", 598 | "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", 599 | "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", 600 | "requires": { 601 | "@sindresorhus/is": "^4.0.0", 602 | "@szmarczak/http-timer": "^4.0.5", 603 | "@types/cacheable-request": "^6.0.1", 604 | "@types/responselike": "^1.0.0", 605 | "cacheable-lookup": "^5.0.3", 606 | "cacheable-request": "^7.0.2", 607 | "decompress-response": "^6.0.0", 608 | "http2-wrapper": "^1.0.0-beta.5.2", 609 | "lowercase-keys": "^2.0.0", 610 | "p-cancelable": "^2.0.0", 611 | "responselike": "^2.0.0" 612 | } 613 | }, 614 | "http-cache-semantics": { 615 | "version": "4.1.0", 616 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", 617 | "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" 618 | }, 619 | "http2-wrapper": { 620 | "version": "1.0.3", 621 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", 622 | "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", 623 | "requires": { 624 | "quick-lru": "^5.1.1", 625 | "resolve-alpn": "^1.0.0" 626 | } 627 | }, 628 | "is-promise": { 629 | "version": "4.0.0", 630 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", 631 | "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" 632 | }, 633 | "json-buffer": { 634 | "version": "3.0.1", 635 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 636 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" 637 | }, 638 | "keyv": { 639 | "version": "4.3.3", 640 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.3.tgz", 641 | "integrity": "sha512-AcysI17RvakTh8ir03+a3zJr5r0ovnAH/XTXei/4HIv3bL2K/jzvgivLK9UuI/JbU1aJjM3NSAnVvVVd3n+4DQ==", 642 | "requires": { 643 | "compress-brotli": "^1.3.8", 644 | "json-buffer": "3.0.1" 645 | } 646 | }, 647 | "lowercase-keys": { 648 | "version": "2.0.0", 649 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 650 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" 651 | }, 652 | "mimic-response": { 653 | "version": "1.0.1", 654 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 655 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" 656 | }, 657 | "normalize-url": { 658 | "version": "6.1.0", 659 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", 660 | "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" 661 | }, 662 | "once": { 663 | "version": "1.4.0", 664 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 665 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 666 | "requires": { 667 | "wrappy": "1" 668 | } 669 | }, 670 | "p-cancelable": { 671 | "version": "2.1.1", 672 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", 673 | "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" 674 | }, 675 | "pump": { 676 | "version": "3.0.0", 677 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 678 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 679 | "requires": { 680 | "end-of-stream": "^1.1.0", 681 | "once": "^1.3.1" 682 | } 683 | }, 684 | "quick-lru": { 685 | "version": "5.1.1", 686 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 687 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" 688 | }, 689 | "resolve-alpn": { 690 | "version": "1.2.1", 691 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", 692 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" 693 | }, 694 | "responselike": { 695 | "version": "2.0.1", 696 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", 697 | "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", 698 | "requires": { 699 | "lowercase-keys": "^2.0.0" 700 | } 701 | }, 702 | "to-utf8": { 703 | "version": "0.0.1", 704 | "resolved": "https://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz", 705 | "integrity": "sha512-zks18/TWT1iHO3v0vFp5qLKOG27m67ycq/Y7a7cTiRuUNlc4gf3HGnkRgMv0NyhnfTamtkYBJl+YeD1/j07gBQ==" 706 | }, 707 | "typescript": { 708 | "version": "4.7.4", 709 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", 710 | "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" 711 | }, 712 | "wrappy": { 713 | "version": "1.0.2", 714 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 715 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 716 | }, 717 | "ws": { 718 | "version": "5.2.3", 719 | "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz", 720 | "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==", 721 | "requires": { 722 | "async-limiter": "~1.0.0" 723 | } 724 | } 725 | } 726 | } 727 | --------------------------------------------------------------------------------