├── .gitignore ├── LICENSE.md ├── README.md ├── packages ├── worker │ ├── README.md │ ├── package.json │ ├── pnpm-lock.yaml │ ├── src │ │ ├── bucket.ts │ │ ├── cors.ts │ │ ├── index.ts │ │ ├── template.tsx │ │ └── utils.ts │ ├── tsconfig.json │ └── wrangler.toml └── workers-og │ ├── .gitignore │ ├── README.md │ ├── bin │ └── esbuild.js │ ├── package.json │ ├── src │ ├── font.ts │ ├── index.ts │ ├── og.ts │ ├── parseHtml.ts │ ├── parseUtils.ts │ └── types.ts │ ├── tsconfig.json │ └── vendors │ ├── resvg.wasm │ └── yoga.wasm ├── pnpm-lock.yaml └── pnpm-workspace.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | #Misc 2 | .DS_Store 3 | 4 | # Logs 5 | 6 | logs 7 | _.log 8 | npm-debug.log_ 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | .pnpm-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | 16 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 17 | 18 | # Runtime data 19 | 20 | pids 21 | _.pid 22 | _.seed 23 | \*.pid.lock 24 | 25 | # Directory for instrumented libs generated by jscoverage/JSCover 26 | 27 | lib-cov 28 | 29 | # Coverage directory used by tools like istanbul 30 | 31 | coverage 32 | \*.lcov 33 | 34 | # nyc test coverage 35 | 36 | .nyc_output 37 | 38 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 39 | 40 | .grunt 41 | 42 | # Bower dependency directory (https://bower.io/) 43 | 44 | bower_components 45 | 46 | # node-waf configuration 47 | 48 | .lock-wscript 49 | 50 | # Compiled binary addons (https://nodejs.org/api/addons.html) 51 | 52 | build/Release 53 | 54 | # Dependency directories 55 | 56 | node_modules/ 57 | jspm_packages/ 58 | 59 | # Snowpack dependency directory (https://snowpack.dev/) 60 | 61 | web_modules/ 62 | 63 | # TypeScript cache 64 | 65 | \*.tsbuildinfo 66 | 67 | # Optional npm cache directory 68 | 69 | .npm 70 | 71 | # Optional eslint cache 72 | 73 | .eslintcache 74 | 75 | # Optional stylelint cache 76 | 77 | .stylelintcache 78 | 79 | # Microbundle cache 80 | 81 | .rpt2_cache/ 82 | .rts2_cache_cjs/ 83 | .rts2_cache_es/ 84 | .rts2_cache_umd/ 85 | 86 | # Optional REPL history 87 | 88 | .node_repl_history 89 | 90 | # Output of 'npm pack' 91 | 92 | \*.tgz 93 | 94 | # Yarn Integrity file 95 | 96 | .yarn-integrity 97 | 98 | # dotenv environment variable files 99 | 100 | .env 101 | .env.development.local 102 | .env.test.local 103 | .env.production.local 104 | .env.local 105 | 106 | # parcel-bundler cache (https://parceljs.org/) 107 | 108 | .cache 109 | .parcel-cache 110 | 111 | # Next.js build output 112 | 113 | .next 114 | out 115 | 116 | # Nuxt.js build / generate output 117 | 118 | .nuxt 119 | dist/ 120 | 121 | # Gatsby files 122 | 123 | .cache/ 124 | 125 | # Comment in the public line in if your project uses Gatsby and not Next.js 126 | 127 | # https://nextjs.org/blog/next-9-1#public-directory-support 128 | 129 | # public 130 | 131 | # vuepress build output 132 | 133 | .vuepress/dist 134 | 135 | # vuepress v2.x temp and cache directory 136 | 137 | .temp 138 | .cache 139 | 140 | # Docusaurus cache and generated files 141 | 142 | .docusaurus 143 | 144 | # Serverless directories 145 | 146 | .serverless/ 147 | 148 | # FuseBox cache 149 | 150 | .fusebox/ 151 | 152 | # DynamoDB Local files 153 | 154 | .dynamodb/ 155 | 156 | # TernJS port file 157 | 158 | .tern-port 159 | 160 | # Stores VSCode versions used for testing VSCode extensions 161 | 162 | .vscode-test 163 | 164 | # yarn v2 165 | 166 | .yarn/cache 167 | .yarn/unplugged 168 | .yarn/build-state.yml 169 | .yarn/install-state.gz 170 | .pnp.\* 171 | 172 | # wrangler project 173 | 174 | .dev.vars 175 | .wrangler -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Kevin Ang 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cloudflare Workers OG Image Generator 2 | 3 | > Using Vercel's [Satori](https://github.com/vercel/satori) engine, and many credits to [`@vercel/og`](https://vercel.com/docs/concepts/functions/edge-functions/og-image-generation) for the inspiration. 4 | 5 | An `og:image` (social card) generator that is fast, browser-less (no Puppeteer), and capable of running on the edge. 6 | 7 | This package is designed to be used with Cloudflare Workers (but may be used elsewhere), with the simple API inspired by `@vercel/og`. 8 | 9 | ## Difference from `@vercel/og` 10 | 11 | `@vercel/og` is designed to run on Vercel’s edge runtime, and `workers-og` on Cloudflare Workers. 12 | 13 | Although Vercel’s edge runtime runs on Cloudflare Workers, the way WASM is bundled is different and causes an error when using `@vercel/og` on a Worker. 14 | 15 | **Another unique feature**: while `satori` (used in both `@vercel/og` and `workers-og`) accepts React element as the input, `workers-og` adds a feature which allows you to write a simple HTML, which will here be parsed into React element-like object. The parsing is handled by `HTMLRewriter`, which is part of Cloudflare Worker’s runtime API. 16 | 17 | ## Getting started 18 | 19 | Install the package on your Worker project: 20 | 21 | ```bash 22 | npm i workers-og 23 | ``` 24 | 25 | Then, import it to your project. The API mimics `@vercel/og` closely. 26 | 27 | ```typescript 28 | import { ImageResponse } from "workers-og"; 29 | ``` 30 | 31 | ## Example Usage on a Worker: 32 | 33 | ```typescript 34 | import { ImageResponse } from "workers-og"; 35 | 36 | export default { 37 | async fetch( 38 | request: Request, 39 | env: Env, 40 | ctx: ExecutionContext 41 | ): Promise { 42 | const params = new URLSearchParams(new URL(request.url).search); 43 | const title = params.get("title") || "Lorem ipsum"; 44 | 45 | const html = ` 46 |
47 |
48 |

${title}

49 |
50 |
51 | `; 52 | 53 | return new ImageResponse(html, { 54 | width: 1200, 55 | height: 630, 56 | }); 57 | }, 58 | }; 59 | ``` 60 | -------------------------------------------------------------------------------- /packages/worker/README.md: -------------------------------------------------------------------------------- 1 | # Cloudflare Workers using `workers-og` 2 | 3 | A working example of a Cloudflare Workers using `workers-og` to generate social cards on the edge, on the fly. 4 | -------------------------------------------------------------------------------- /packages/worker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "workers-og-cloudflare-worker", 3 | "version": "0.0.12", 4 | "devDependencies": { 5 | "@cloudflare/workers-types": "^4.20231218.0", 6 | "@types/react": "^18.2.47", 7 | "react": "^18.2.0", 8 | "wrangler": "^3.22.4" 9 | }, 10 | "private": false, 11 | "scripts": { 12 | "start": "wrangler dev", 13 | "build": "wrangler build --env production", 14 | "deploy": "wrangler publish" 15 | }, 16 | "dependencies": { 17 | "workers-og": "workspace:^" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/worker/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | '@cloudflare/workers-types': ^3.16.0 5 | workers-og: ^0.0.8 6 | wrangler: ^2.1.11 7 | 8 | dependencies: 9 | workers-og: 0.0.8 10 | 11 | devDependencies: 12 | '@cloudflare/workers-types': 3.17.0 13 | wrangler: 2.1.11 14 | 15 | packages: 16 | 17 | /@cloudflare/kv-asset-handler/0.2.0: 18 | resolution: {integrity: sha512-MVbXLbTcAotOPUj0pAMhVtJ+3/kFkwJqc5qNOleOZTv6QkZZABDMS21dSrSlVswEHwrpWC03e4fWytjqKvuE2A==} 19 | dependencies: 20 | mime: 3.0.0 21 | dev: true 22 | 23 | /@cloudflare/workers-types/3.17.0: 24 | resolution: {integrity: sha512-u0cUQ4ntWFFwn5jx0ETa2ItvwvfOMjyaKF2fX2vFVujrSgNES/PnvRzPAhdt9CMYAMidInm0MGkIjxHRsFBaeg==} 25 | dev: true 26 | 27 | /@esbuild-plugins/node-globals-polyfill/0.1.1_esbuild@0.14.51: 28 | resolution: {integrity: sha512-MR0oAA+mlnJWrt1RQVQ+4VYuRJW/P2YmRTv1AsplObyvuBMnPHiizUF95HHYiSsMGLhyGtWufaq2XQg6+iurBg==} 29 | peerDependencies: 30 | esbuild: '*' 31 | dependencies: 32 | esbuild: 0.14.51 33 | dev: true 34 | 35 | /@esbuild-plugins/node-modules-polyfill/0.1.4_esbuild@0.14.51: 36 | resolution: {integrity: sha512-uZbcXi0zbmKC/050p3gJnne5Qdzw8vkXIv+c2BW0Lsc1ji1SkrxbKPUy5Efr0blbTu1SL8w4eyfpnSdPg3G0Qg==} 37 | peerDependencies: 38 | esbuild: '*' 39 | dependencies: 40 | esbuild: 0.14.51 41 | escape-string-regexp: 4.0.0 42 | rollup-plugin-node-polyfills: 0.2.1 43 | dev: true 44 | 45 | /@iarna/toml/2.2.5: 46 | resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} 47 | dev: true 48 | 49 | /@miniflare/cache/2.9.0: 50 | resolution: {integrity: sha512-lriPxUEva9TJ01vU9P7pI60s3SsFnb4apWkNwZ+D7CRqyXPipSbapY8BWI2FUIwkEG7xap6UhzeTS76NettCXQ==} 51 | engines: {node: '>=16.13'} 52 | dependencies: 53 | '@miniflare/core': 2.9.0 54 | '@miniflare/shared': 2.9.0 55 | http-cache-semantics: 4.1.0 56 | undici: 5.9.1 57 | dev: true 58 | 59 | /@miniflare/cli-parser/2.9.0: 60 | resolution: {integrity: sha512-gu8Z7NWNcYw6514/yOvajaj3GmebRucx+EEt3p1vKirO+gvFgKAt/puyUN3p7u8ZZmLuLF/B+wVnH3lj8BWKlg==} 61 | engines: {node: '>=16.13'} 62 | dependencies: 63 | '@miniflare/shared': 2.9.0 64 | kleur: 4.1.5 65 | dev: true 66 | 67 | /@miniflare/core/2.9.0: 68 | resolution: {integrity: sha512-QqSwF6oHvgrFvN5lnrLc6EEagFlZWW+UMU8QdrE8305cNGHrIOxKCA2nte4PVFZUVw/Ts13a0tVhUk3a2fAyxQ==} 69 | engines: {node: '>=16.13'} 70 | dependencies: 71 | '@iarna/toml': 2.2.5 72 | '@miniflare/queues': 2.9.0 73 | '@miniflare/shared': 2.9.0 74 | '@miniflare/watcher': 2.9.0 75 | busboy: 1.6.0 76 | dotenv: 10.0.0 77 | kleur: 4.1.5 78 | set-cookie-parser: 2.5.1 79 | undici: 5.9.1 80 | urlpattern-polyfill: 4.0.3 81 | dev: true 82 | 83 | /@miniflare/d1/2.9.0: 84 | resolution: {integrity: sha512-swK9nzxw1SvVh/4cH3bRR1SBuHQU/YsB8WvuHojxufmgviAD1xhms3XO3rkpAzfKoGM5Oy6DovMe0xUXV/GS0w==} 85 | engines: {node: '>=16.7'} 86 | dependencies: 87 | '@miniflare/core': 2.9.0 88 | '@miniflare/shared': 2.9.0 89 | dev: true 90 | 91 | /@miniflare/durable-objects/2.9.0: 92 | resolution: {integrity: sha512-7uTvfEUXS7xqwrsWOwWrFUuKc4EiMpVkAWPeYGLB/0TJaJ6N+sZMpYYymdW79TQwPIDfgtpfkIy93MRydqpnrw==} 93 | engines: {node: '>=16.13'} 94 | dependencies: 95 | '@miniflare/core': 2.9.0 96 | '@miniflare/shared': 2.9.0 97 | '@miniflare/storage-memory': 2.9.0 98 | undici: 5.9.1 99 | dev: true 100 | 101 | /@miniflare/html-rewriter/2.9.0: 102 | resolution: {integrity: sha512-K5OB70PtkMo7M+tU46s/cX/j/qtjD9AlJ0hecYswrxVsfrT/YWyrCQJevmShFfJ92h7jPNigbeC3Od3JiVb6QA==} 103 | engines: {node: '>=16.13'} 104 | dependencies: 105 | '@miniflare/core': 2.9.0 106 | '@miniflare/shared': 2.9.0 107 | html-rewriter-wasm: 0.4.1 108 | undici: 5.9.1 109 | dev: true 110 | 111 | /@miniflare/http-server/2.9.0: 112 | resolution: {integrity: sha512-IVJMkFfMpecq9WiCTvATEKhMuKPK9fMs2E6zmgexaefr3u1VlNtj2QxBxoPUXkT9xMJQlT5sSKstlRR1XKDz9Q==} 113 | engines: {node: '>=16.13'} 114 | dependencies: 115 | '@miniflare/core': 2.9.0 116 | '@miniflare/shared': 2.9.0 117 | '@miniflare/web-sockets': 2.9.0 118 | kleur: 4.1.5 119 | selfsigned: 2.1.1 120 | undici: 5.9.1 121 | ws: 8.9.0 122 | youch: 2.2.2 123 | transitivePeerDependencies: 124 | - bufferutil 125 | - utf-8-validate 126 | dev: true 127 | 128 | /@miniflare/kv/2.9.0: 129 | resolution: {integrity: sha512-EqG51okY5rDtgjYs2Ny6j6IUVdTlJzDjwBKBIuW+wOV9NsAAzEchKVdYAXc8CyxvkggpYX481HydTD2OzK3INQ==} 130 | engines: {node: '>=16.13'} 131 | dependencies: 132 | '@miniflare/shared': 2.9.0 133 | dev: true 134 | 135 | /@miniflare/queues/2.9.0: 136 | resolution: {integrity: sha512-cAHWIlLF57rxQaJl19AzXw1k0SOM/uLTlx8r2PylHajZ/RRSs7CkCox3oKA6E5zKyfyxk2M64bmsAFZ9RCA0gw==} 137 | engines: {node: '>=16.7'} 138 | dependencies: 139 | '@miniflare/shared': 2.9.0 140 | dev: true 141 | 142 | /@miniflare/r2/2.9.0: 143 | resolution: {integrity: sha512-aMFWxxciAE3YsVok2OLy3A7hP5+2j/NaK7txmadgoe1CA8HYZyNuvv7v6bn8HKM5gWnJdT8sk4yEbMbBQ7Jv/A==} 144 | engines: {node: '>=16.13'} 145 | dependencies: 146 | '@miniflare/shared': 2.9.0 147 | undici: 5.9.1 148 | dev: true 149 | 150 | /@miniflare/runner-vm/2.9.0: 151 | resolution: {integrity: sha512-vewP+Fy7Czb261GmB9x/YtQkoDs/QP9B5LbP0YfJ35bI2C2j940eJLm8JP72IHV7ILtWNOqMc3Ure8uAbpf9NQ==} 152 | engines: {node: '>=16.13'} 153 | dependencies: 154 | '@miniflare/shared': 2.9.0 155 | dev: true 156 | 157 | /@miniflare/scheduler/2.9.0: 158 | resolution: {integrity: sha512-eodSCGkJYi4Z+Imbx/bNScDfDSt5HOypVSYjbFHj+hA2aNOdkGw6a1b6mzwx49jJD3GadIkonZAKD0S114yWMA==} 159 | engines: {node: '>=16.13'} 160 | dependencies: 161 | '@miniflare/core': 2.9.0 162 | '@miniflare/shared': 2.9.0 163 | cron-schedule: 3.0.6 164 | dev: true 165 | 166 | /@miniflare/shared/2.9.0: 167 | resolution: {integrity: sha512-5Ew/Ph0cHDQqKvOlmN70kz+qZW0hdgE9fQBStKLY3vDYhnBEhopbCUChSS+FCcL7WtxVJJVE7iB6J09NQTnQ/A==} 168 | engines: {node: '>=16.13'} 169 | dependencies: 170 | '@types/better-sqlite3': 7.6.2 171 | kleur: 4.1.5 172 | npx-import: 1.1.4 173 | picomatch: 2.3.1 174 | dev: true 175 | 176 | /@miniflare/sites/2.9.0: 177 | resolution: {integrity: sha512-+tWf7znxSQqXWGzPup8Xqkl8EmLmx+HaLC+UBtWPNnaJZrsjbbVxKwHpmGIdm+wZasEGfQk/82R21gUs9wdZnw==} 178 | engines: {node: '>=16.13'} 179 | dependencies: 180 | '@miniflare/kv': 2.9.0 181 | '@miniflare/shared': 2.9.0 182 | '@miniflare/storage-file': 2.9.0 183 | dev: true 184 | 185 | /@miniflare/storage-file/2.9.0: 186 | resolution: {integrity: sha512-HZHtHfJaLoDzQFddoIMcDGgAJ3/Nee98gwUYusQam7rj9pbEXnWmk54dzjzsDlkQpB/3MBFQNbtN5Bj1NIt0pg==} 187 | engines: {node: '>=16.13'} 188 | dependencies: 189 | '@miniflare/shared': 2.9.0 190 | '@miniflare/storage-memory': 2.9.0 191 | dev: true 192 | 193 | /@miniflare/storage-memory/2.9.0: 194 | resolution: {integrity: sha512-p2yrr0omQhv6teDbdzhdBKzoQAFmUBMLEx+PtrO7CJHX15ICD08/pFAFAp96IcljNwZZDchU20Z3AcbldMj6Tw==} 195 | engines: {node: '>=16.13'} 196 | dependencies: 197 | '@miniflare/shared': 2.9.0 198 | dev: true 199 | 200 | /@miniflare/watcher/2.9.0: 201 | resolution: {integrity: sha512-Yqz8Q1He/2chebXvmCft8sMamuUiDQ4FIn0bwiF0+GBP2vvGCmy6SejXZY4ZD4REluPqQSis3CLKcIOWlHnIsw==} 202 | engines: {node: '>=16.13'} 203 | dependencies: 204 | '@miniflare/shared': 2.9.0 205 | dev: true 206 | 207 | /@miniflare/web-sockets/2.9.0: 208 | resolution: {integrity: sha512-Nob9e84m78qeQCka6OQf/JdNOmMkKCkX+i3rg+TYKSSITiMVuyzWp3vz3Ma184lAZiLg44lxBF4ZzENEdi99Kg==} 209 | engines: {node: '>=16.13'} 210 | dependencies: 211 | '@miniflare/core': 2.9.0 212 | '@miniflare/shared': 2.9.0 213 | undici: 5.9.1 214 | ws: 8.9.0 215 | transitivePeerDependencies: 216 | - bufferutil 217 | - utf-8-validate 218 | dev: true 219 | 220 | /@resvg/resvg-wasm/2.1.0: 221 | resolution: {integrity: sha512-ov/c2NfqhCreBc9ieuELMgHfOrkCzaymvgGeBDkir0GxINs8CLVbDVqtBWfhgcI3558t1j8WeFDAEtsmI/UDyA==} 222 | engines: {node: '>= 10'} 223 | dev: false 224 | 225 | /@shuding/opentype.js/1.4.0-beta.0: 226 | resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==} 227 | engines: {node: '>= 8.0.0'} 228 | hasBin: true 229 | dependencies: 230 | fflate: 0.7.4 231 | string.prototype.codepointat: 0.2.1 232 | dev: false 233 | 234 | /@types/better-sqlite3/7.6.2: 235 | resolution: {integrity: sha512-RgmaapusqTq6IMAr4McMyAsC6RshYTCjXCnzwVV59WctUxC8bNPyUfT9t5F81lKcU41lLurhjqjoMHfauzfqGg==} 236 | dependencies: 237 | '@types/node': 18.11.0 238 | dev: true 239 | 240 | /@types/node/18.11.0: 241 | resolution: {integrity: sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==} 242 | dev: true 243 | 244 | /@types/stack-trace/0.0.29: 245 | resolution: {integrity: sha512-TgfOX+mGY/NyNxJLIbDWrO9DjGoVSW9+aB8H2yy1fy32jsvxijhmyJI9fDFgvz3YP4lvJaq9DzdR/M1bOgVc9g==} 246 | dev: true 247 | 248 | /@types/yoga-layout/1.9.2: 249 | resolution: {integrity: sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==} 250 | dev: false 251 | 252 | /anymatch/3.1.2: 253 | resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} 254 | engines: {node: '>= 8'} 255 | dependencies: 256 | normalize-path: 3.0.0 257 | picomatch: 2.3.1 258 | dev: true 259 | 260 | /binary-extensions/2.2.0: 261 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 262 | engines: {node: '>=8'} 263 | dev: true 264 | 265 | /blake3-wasm/2.1.5: 266 | resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} 267 | dev: true 268 | 269 | /braces/3.0.2: 270 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 271 | engines: {node: '>=8'} 272 | dependencies: 273 | fill-range: 7.0.1 274 | dev: true 275 | 276 | /buffer-from/1.1.2: 277 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 278 | dev: true 279 | 280 | /builtins/5.0.1: 281 | resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} 282 | dependencies: 283 | semver: 7.3.8 284 | dev: true 285 | 286 | /busboy/1.6.0: 287 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} 288 | engines: {node: '>=10.16.0'} 289 | dependencies: 290 | streamsearch: 1.1.0 291 | dev: true 292 | 293 | /camelize/1.0.1: 294 | resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} 295 | dev: false 296 | 297 | /chokidar/3.5.3: 298 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 299 | engines: {node: '>= 8.10.0'} 300 | dependencies: 301 | anymatch: 3.1.2 302 | braces: 3.0.2 303 | glob-parent: 5.1.2 304 | is-binary-path: 2.1.0 305 | is-glob: 4.0.3 306 | normalize-path: 3.0.0 307 | readdirp: 3.6.0 308 | optionalDependencies: 309 | fsevents: 2.3.2 310 | dev: true 311 | 312 | /cookie/0.4.2: 313 | resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} 314 | engines: {node: '>= 0.6'} 315 | dev: true 316 | 317 | /cron-schedule/3.0.6: 318 | resolution: {integrity: sha512-izfGgKyzzIyLaeb1EtZ3KbglkS6AKp9cv7LxmiyoOu+fXfol1tQDC0Cof0enVZGNtudTHW+3lfuW9ZkLQss4Wg==} 319 | dev: true 320 | 321 | /cross-spawn/7.0.3: 322 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 323 | engines: {node: '>= 8'} 324 | dependencies: 325 | path-key: 3.1.1 326 | shebang-command: 2.0.0 327 | which: 2.0.2 328 | dev: true 329 | 330 | /css-background-parser/0.1.0: 331 | resolution: {integrity: sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==} 332 | dev: false 333 | 334 | /css-box-shadow/1.0.0-3: 335 | resolution: {integrity: sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==} 336 | dev: false 337 | 338 | /css-color-keywords/1.0.0: 339 | resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} 340 | engines: {node: '>=4'} 341 | dev: false 342 | 343 | /css-to-react-native/3.0.0: 344 | resolution: {integrity: sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==} 345 | dependencies: 346 | camelize: 1.0.1 347 | css-color-keywords: 1.0.0 348 | postcss-value-parser: 4.2.0 349 | dev: false 350 | 351 | /dom-serializer/2.0.0: 352 | resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} 353 | dependencies: 354 | domelementtype: 2.3.0 355 | domhandler: 5.0.3 356 | entities: 4.4.0 357 | dev: false 358 | 359 | /domelementtype/2.3.0: 360 | resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} 361 | dev: false 362 | 363 | /domhandler/5.0.3: 364 | resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} 365 | engines: {node: '>= 4'} 366 | dependencies: 367 | domelementtype: 2.3.0 368 | dev: false 369 | 370 | /domutils/3.0.1: 371 | resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==} 372 | dependencies: 373 | dom-serializer: 2.0.0 374 | domelementtype: 2.3.0 375 | domhandler: 5.0.3 376 | dev: false 377 | 378 | /dotenv/10.0.0: 379 | resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} 380 | engines: {node: '>=10'} 381 | dev: true 382 | 383 | /entities/4.4.0: 384 | resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} 385 | engines: {node: '>=0.12'} 386 | dev: false 387 | 388 | /esbuild-android-64/0.14.51: 389 | resolution: {integrity: sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==} 390 | engines: {node: '>=12'} 391 | cpu: [x64] 392 | os: [android] 393 | requiresBuild: true 394 | dev: true 395 | optional: true 396 | 397 | /esbuild-android-arm64/0.14.51: 398 | resolution: {integrity: sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==} 399 | engines: {node: '>=12'} 400 | cpu: [arm64] 401 | os: [android] 402 | requiresBuild: true 403 | dev: true 404 | optional: true 405 | 406 | /esbuild-darwin-64/0.14.51: 407 | resolution: {integrity: sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==} 408 | engines: {node: '>=12'} 409 | cpu: [x64] 410 | os: [darwin] 411 | requiresBuild: true 412 | dev: true 413 | optional: true 414 | 415 | /esbuild-darwin-arm64/0.14.51: 416 | resolution: {integrity: sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==} 417 | engines: {node: '>=12'} 418 | cpu: [arm64] 419 | os: [darwin] 420 | requiresBuild: true 421 | dev: true 422 | optional: true 423 | 424 | /esbuild-freebsd-64/0.14.51: 425 | resolution: {integrity: sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==} 426 | engines: {node: '>=12'} 427 | cpu: [x64] 428 | os: [freebsd] 429 | requiresBuild: true 430 | dev: true 431 | optional: true 432 | 433 | /esbuild-freebsd-arm64/0.14.51: 434 | resolution: {integrity: sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==} 435 | engines: {node: '>=12'} 436 | cpu: [arm64] 437 | os: [freebsd] 438 | requiresBuild: true 439 | dev: true 440 | optional: true 441 | 442 | /esbuild-linux-32/0.14.51: 443 | resolution: {integrity: sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==} 444 | engines: {node: '>=12'} 445 | cpu: [ia32] 446 | os: [linux] 447 | requiresBuild: true 448 | dev: true 449 | optional: true 450 | 451 | /esbuild-linux-64/0.14.51: 452 | resolution: {integrity: sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==} 453 | engines: {node: '>=12'} 454 | cpu: [x64] 455 | os: [linux] 456 | requiresBuild: true 457 | dev: true 458 | optional: true 459 | 460 | /esbuild-linux-arm/0.14.51: 461 | resolution: {integrity: sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==} 462 | engines: {node: '>=12'} 463 | cpu: [arm] 464 | os: [linux] 465 | requiresBuild: true 466 | dev: true 467 | optional: true 468 | 469 | /esbuild-linux-arm64/0.14.51: 470 | resolution: {integrity: sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==} 471 | engines: {node: '>=12'} 472 | cpu: [arm64] 473 | os: [linux] 474 | requiresBuild: true 475 | dev: true 476 | optional: true 477 | 478 | /esbuild-linux-mips64le/0.14.51: 479 | resolution: {integrity: sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==} 480 | engines: {node: '>=12'} 481 | cpu: [mips64el] 482 | os: [linux] 483 | requiresBuild: true 484 | dev: true 485 | optional: true 486 | 487 | /esbuild-linux-ppc64le/0.14.51: 488 | resolution: {integrity: sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==} 489 | engines: {node: '>=12'} 490 | cpu: [ppc64] 491 | os: [linux] 492 | requiresBuild: true 493 | dev: true 494 | optional: true 495 | 496 | /esbuild-linux-riscv64/0.14.51: 497 | resolution: {integrity: sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==} 498 | engines: {node: '>=12'} 499 | cpu: [riscv64] 500 | os: [linux] 501 | requiresBuild: true 502 | dev: true 503 | optional: true 504 | 505 | /esbuild-linux-s390x/0.14.51: 506 | resolution: {integrity: sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==} 507 | engines: {node: '>=12'} 508 | cpu: [s390x] 509 | os: [linux] 510 | requiresBuild: true 511 | dev: true 512 | optional: true 513 | 514 | /esbuild-netbsd-64/0.14.51: 515 | resolution: {integrity: sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==} 516 | engines: {node: '>=12'} 517 | cpu: [x64] 518 | os: [netbsd] 519 | requiresBuild: true 520 | dev: true 521 | optional: true 522 | 523 | /esbuild-openbsd-64/0.14.51: 524 | resolution: {integrity: sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==} 525 | engines: {node: '>=12'} 526 | cpu: [x64] 527 | os: [openbsd] 528 | requiresBuild: true 529 | dev: true 530 | optional: true 531 | 532 | /esbuild-sunos-64/0.14.51: 533 | resolution: {integrity: sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==} 534 | engines: {node: '>=12'} 535 | cpu: [x64] 536 | os: [sunos] 537 | requiresBuild: true 538 | dev: true 539 | optional: true 540 | 541 | /esbuild-windows-32/0.14.51: 542 | resolution: {integrity: sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==} 543 | engines: {node: '>=12'} 544 | cpu: [ia32] 545 | os: [win32] 546 | requiresBuild: true 547 | dev: true 548 | optional: true 549 | 550 | /esbuild-windows-64/0.14.51: 551 | resolution: {integrity: sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==} 552 | engines: {node: '>=12'} 553 | cpu: [x64] 554 | os: [win32] 555 | requiresBuild: true 556 | dev: true 557 | optional: true 558 | 559 | /esbuild-windows-arm64/0.14.51: 560 | resolution: {integrity: sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==} 561 | engines: {node: '>=12'} 562 | cpu: [arm64] 563 | os: [win32] 564 | requiresBuild: true 565 | dev: true 566 | optional: true 567 | 568 | /esbuild/0.14.51: 569 | resolution: {integrity: sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==} 570 | engines: {node: '>=12'} 571 | hasBin: true 572 | requiresBuild: true 573 | optionalDependencies: 574 | esbuild-android-64: 0.14.51 575 | esbuild-android-arm64: 0.14.51 576 | esbuild-darwin-64: 0.14.51 577 | esbuild-darwin-arm64: 0.14.51 578 | esbuild-freebsd-64: 0.14.51 579 | esbuild-freebsd-arm64: 0.14.51 580 | esbuild-linux-32: 0.14.51 581 | esbuild-linux-64: 0.14.51 582 | esbuild-linux-arm: 0.14.51 583 | esbuild-linux-arm64: 0.14.51 584 | esbuild-linux-mips64le: 0.14.51 585 | esbuild-linux-ppc64le: 0.14.51 586 | esbuild-linux-riscv64: 0.14.51 587 | esbuild-linux-s390x: 0.14.51 588 | esbuild-netbsd-64: 0.14.51 589 | esbuild-openbsd-64: 0.14.51 590 | esbuild-sunos-64: 0.14.51 591 | esbuild-windows-32: 0.14.51 592 | esbuild-windows-64: 0.14.51 593 | esbuild-windows-arm64: 0.14.51 594 | dev: true 595 | 596 | /escape-string-regexp/4.0.0: 597 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 598 | engines: {node: '>=10'} 599 | dev: true 600 | 601 | /estree-walker/0.6.1: 602 | resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} 603 | dev: true 604 | 605 | /execa/6.1.0: 606 | resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==} 607 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 608 | dependencies: 609 | cross-spawn: 7.0.3 610 | get-stream: 6.0.1 611 | human-signals: 3.0.1 612 | is-stream: 3.0.0 613 | merge-stream: 2.0.0 614 | npm-run-path: 5.1.0 615 | onetime: 6.0.0 616 | signal-exit: 3.0.7 617 | strip-final-newline: 3.0.0 618 | dev: true 619 | 620 | /fflate/0.7.4: 621 | resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} 622 | dev: false 623 | 624 | /fill-range/7.0.1: 625 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 626 | engines: {node: '>=8'} 627 | dependencies: 628 | to-regex-range: 5.0.1 629 | dev: true 630 | 631 | /fsevents/2.3.2: 632 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 633 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 634 | os: [darwin] 635 | requiresBuild: true 636 | dev: true 637 | optional: true 638 | 639 | /get-stream/6.0.1: 640 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} 641 | engines: {node: '>=10'} 642 | dev: true 643 | 644 | /glob-parent/5.1.2: 645 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 646 | engines: {node: '>= 6'} 647 | dependencies: 648 | is-glob: 4.0.3 649 | dev: true 650 | 651 | /html-rewriter-wasm/0.4.1: 652 | resolution: {integrity: sha512-lNovG8CMCCmcVB1Q7xggMSf7tqPCijZXaH4gL6iE8BFghdQCbaY5Met9i1x2Ex8m/cZHDUtXK9H6/znKamRP8Q==} 653 | dev: true 654 | 655 | /htmlparser2/8.0.1: 656 | resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==} 657 | dependencies: 658 | domelementtype: 2.3.0 659 | domhandler: 5.0.3 660 | domutils: 3.0.1 661 | entities: 4.4.0 662 | dev: false 663 | 664 | /http-cache-semantics/4.1.0: 665 | resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} 666 | dev: true 667 | 668 | /human-signals/3.0.1: 669 | resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==} 670 | engines: {node: '>=12.20.0'} 671 | dev: true 672 | 673 | /is-binary-path/2.1.0: 674 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 675 | engines: {node: '>=8'} 676 | dependencies: 677 | binary-extensions: 2.2.0 678 | dev: true 679 | 680 | /is-extglob/2.1.1: 681 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 682 | engines: {node: '>=0.10.0'} 683 | dev: true 684 | 685 | /is-glob/4.0.3: 686 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 687 | engines: {node: '>=0.10.0'} 688 | dependencies: 689 | is-extglob: 2.1.1 690 | dev: true 691 | 692 | /is-number/7.0.0: 693 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 694 | engines: {node: '>=0.12.0'} 695 | dev: true 696 | 697 | /is-stream/3.0.0: 698 | resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} 699 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 700 | dev: true 701 | 702 | /isexe/2.0.0: 703 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 704 | dev: true 705 | 706 | /just-camel-case/6.1.1: 707 | resolution: {integrity: sha512-tDZNyw8wBZM9vdUfAtG9HmKonj5NzP1pKN52IabSNbMR/SXNf67FAW1QAdx2dC1ZSxubQyr/1fiYVpr5ebN8lQ==} 708 | dev: false 709 | 710 | /kleur/4.1.5: 711 | resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} 712 | engines: {node: '>=6'} 713 | dev: true 714 | 715 | /lru-cache/6.0.0: 716 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 717 | engines: {node: '>=10'} 718 | dependencies: 719 | yallist: 4.0.0 720 | dev: true 721 | 722 | /magic-string/0.25.9: 723 | resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} 724 | dependencies: 725 | sourcemap-codec: 1.4.8 726 | dev: true 727 | 728 | /merge-stream/2.0.0: 729 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 730 | dev: true 731 | 732 | /mime/3.0.0: 733 | resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} 734 | engines: {node: '>=10.0.0'} 735 | hasBin: true 736 | dev: true 737 | 738 | /mimic-fn/4.0.0: 739 | resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} 740 | engines: {node: '>=12'} 741 | dev: true 742 | 743 | /miniflare/2.9.0: 744 | resolution: {integrity: sha512-HBGQ5Jj6sMU1B1hX6G3ML46ThtUvu1nvxgXjDDmhp2RhWKYj0XvcohW/nPPL/MTP1gpvfT880De9EHmobVsDsw==} 745 | engines: {node: '>=16.13'} 746 | hasBin: true 747 | peerDependencies: 748 | '@miniflare/storage-redis': 2.9.0 749 | cron-schedule: ^3.0.4 750 | ioredis: ^4.27.9 751 | peerDependenciesMeta: 752 | '@miniflare/storage-redis': 753 | optional: true 754 | cron-schedule: 755 | optional: true 756 | ioredis: 757 | optional: true 758 | dependencies: 759 | '@miniflare/cache': 2.9.0 760 | '@miniflare/cli-parser': 2.9.0 761 | '@miniflare/core': 2.9.0 762 | '@miniflare/d1': 2.9.0 763 | '@miniflare/durable-objects': 2.9.0 764 | '@miniflare/html-rewriter': 2.9.0 765 | '@miniflare/http-server': 2.9.0 766 | '@miniflare/kv': 2.9.0 767 | '@miniflare/queues': 2.9.0 768 | '@miniflare/r2': 2.9.0 769 | '@miniflare/runner-vm': 2.9.0 770 | '@miniflare/scheduler': 2.9.0 771 | '@miniflare/shared': 2.9.0 772 | '@miniflare/sites': 2.9.0 773 | '@miniflare/storage-file': 2.9.0 774 | '@miniflare/storage-memory': 2.9.0 775 | '@miniflare/web-sockets': 2.9.0 776 | kleur: 4.1.5 777 | semiver: 1.1.0 778 | source-map-support: 0.5.21 779 | undici: 5.9.1 780 | transitivePeerDependencies: 781 | - bufferutil 782 | - utf-8-validate 783 | dev: true 784 | 785 | /mustache/4.2.0: 786 | resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} 787 | hasBin: true 788 | dev: true 789 | 790 | /nanoid/3.3.4: 791 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 792 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 793 | hasBin: true 794 | dev: true 795 | 796 | /node-forge/1.3.1: 797 | resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} 798 | engines: {node: '>= 6.13.0'} 799 | dev: true 800 | 801 | /normalize-path/3.0.0: 802 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 803 | engines: {node: '>=0.10.0'} 804 | dev: true 805 | 806 | /npm-run-path/5.1.0: 807 | resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} 808 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 809 | dependencies: 810 | path-key: 4.0.0 811 | dev: true 812 | 813 | /npx-import/1.1.4: 814 | resolution: {integrity: sha512-3ShymTWOgqGyNlh5lMJAejLuIv3W1K3fbI5Ewc6YErZU3Sp0PqsNs8UIU1O8z5+KVl/Du5ag56Gza9vdorGEoA==} 815 | dependencies: 816 | execa: 6.1.0 817 | parse-package-name: 1.0.0 818 | semver: 7.3.8 819 | validate-npm-package-name: 4.0.0 820 | dev: true 821 | 822 | /onetime/6.0.0: 823 | resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} 824 | engines: {node: '>=12'} 825 | dependencies: 826 | mimic-fn: 4.0.0 827 | dev: true 828 | 829 | /parse-package-name/1.0.0: 830 | resolution: {integrity: sha512-kBeTUtcj+SkyfaW4+KBe0HtsloBJ/mKTPoxpVdA57GZiPerREsUWJOhVj9anXweFiJkm5y8FG1sxFZkZ0SN6wg==} 831 | dev: true 832 | 833 | /path-key/3.1.1: 834 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 835 | engines: {node: '>=8'} 836 | dev: true 837 | 838 | /path-key/4.0.0: 839 | resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} 840 | engines: {node: '>=12'} 841 | dev: true 842 | 843 | /path-to-regexp/6.2.1: 844 | resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} 845 | dev: true 846 | 847 | /picomatch/2.3.1: 848 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 849 | engines: {node: '>=8.6'} 850 | dev: true 851 | 852 | /postcss-value-parser/4.2.0: 853 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} 854 | dev: false 855 | 856 | /readdirp/3.6.0: 857 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 858 | engines: {node: '>=8.10.0'} 859 | dependencies: 860 | picomatch: 2.3.1 861 | dev: true 862 | 863 | /rollup-plugin-inject/3.0.2: 864 | resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} 865 | deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. 866 | dependencies: 867 | estree-walker: 0.6.1 868 | magic-string: 0.25.9 869 | rollup-pluginutils: 2.8.2 870 | dev: true 871 | 872 | /rollup-plugin-node-polyfills/0.2.1: 873 | resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} 874 | dependencies: 875 | rollup-plugin-inject: 3.0.2 876 | dev: true 877 | 878 | /rollup-pluginutils/2.8.2: 879 | resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} 880 | dependencies: 881 | estree-walker: 0.6.1 882 | dev: true 883 | 884 | /satori/0.0.38: 885 | resolution: {integrity: sha512-o8nMTp5IiLKi3oOw80Y3LdDAReGS+UfC1StQBAwlnFNzHmY1A3JGFT+9gam6x8I6uMDFrs82FnG9R/kI9iONdg==} 886 | engines: {node: '>=16'} 887 | dependencies: 888 | '@shuding/opentype.js': 1.4.0-beta.0 889 | css-background-parser: 0.1.0 890 | css-box-shadow: 1.0.0-3 891 | css-to-react-native: 3.0.0 892 | postcss-value-parser: 4.2.0 893 | yoga-layout-prebuilt: 1.10.0 894 | dev: false 895 | 896 | /selfsigned/2.1.1: 897 | resolution: {integrity: sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==} 898 | engines: {node: '>=10'} 899 | dependencies: 900 | node-forge: 1.3.1 901 | dev: true 902 | 903 | /semiver/1.1.0: 904 | resolution: {integrity: sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==} 905 | engines: {node: '>=6'} 906 | dev: true 907 | 908 | /semver/7.3.8: 909 | resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} 910 | engines: {node: '>=10'} 911 | hasBin: true 912 | dependencies: 913 | lru-cache: 6.0.0 914 | dev: true 915 | 916 | /set-cookie-parser/2.5.1: 917 | resolution: {integrity: sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ==} 918 | dev: true 919 | 920 | /shebang-command/2.0.0: 921 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 922 | engines: {node: '>=8'} 923 | dependencies: 924 | shebang-regex: 3.0.0 925 | dev: true 926 | 927 | /shebang-regex/3.0.0: 928 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 929 | engines: {node: '>=8'} 930 | dev: true 931 | 932 | /signal-exit/3.0.7: 933 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} 934 | dev: true 935 | 936 | /source-map-support/0.5.21: 937 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 938 | dependencies: 939 | buffer-from: 1.1.2 940 | source-map: 0.6.1 941 | dev: true 942 | 943 | /source-map/0.6.1: 944 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 945 | engines: {node: '>=0.10.0'} 946 | dev: true 947 | 948 | /source-map/0.7.4: 949 | resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} 950 | engines: {node: '>= 8'} 951 | dev: true 952 | 953 | /sourcemap-codec/1.4.8: 954 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} 955 | dev: true 956 | 957 | /stack-trace/0.0.10: 958 | resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} 959 | dev: true 960 | 961 | /streamsearch/1.1.0: 962 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} 963 | engines: {node: '>=10.0.0'} 964 | dev: true 965 | 966 | /string.prototype.codepointat/0.2.1: 967 | resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==} 968 | dev: false 969 | 970 | /strip-final-newline/3.0.0: 971 | resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} 972 | engines: {node: '>=12'} 973 | dev: true 974 | 975 | /to-regex-range/5.0.1: 976 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 977 | engines: {node: '>=8.0'} 978 | dependencies: 979 | is-number: 7.0.0 980 | dev: true 981 | 982 | /undici/5.9.1: 983 | resolution: {integrity: sha512-6fB3a+SNnWEm4CJbgo0/CWR8RGcOCQP68SF4X0mxtYTq2VNN8T88NYrWVBAeSX+zb7bny2dx2iYhP3XHi00omg==} 984 | engines: {node: '>=12.18'} 985 | dev: true 986 | 987 | /urlpattern-polyfill/4.0.3: 988 | resolution: {integrity: sha512-DOE84vZT2fEcl9gqCUTcnAw5ZY5Id55ikUcziSUntuEFL3pRvavg5kwDmTEUJkeCHInTlV/HexFomgYnzO5kdQ==} 989 | dev: true 990 | 991 | /validate-npm-package-name/4.0.0: 992 | resolution: {integrity: sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==} 993 | engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} 994 | dependencies: 995 | builtins: 5.0.1 996 | dev: true 997 | 998 | /which/2.0.2: 999 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1000 | engines: {node: '>= 8'} 1001 | hasBin: true 1002 | dependencies: 1003 | isexe: 2.0.0 1004 | dev: true 1005 | 1006 | /workers-og/0.0.8: 1007 | resolution: {integrity: sha512-kslzHoOKrsbaQP4XPzMhqdh4e3Yt1jY50MQCtQHwqPdg7l6LPhkXTZo0i80wO0b32ujryREzgG9nTYp69Vua7Q==} 1008 | dependencies: 1009 | '@resvg/resvg-wasm': 2.1.0 1010 | domhandler: 5.0.3 1011 | htmlparser2: 8.0.1 1012 | just-camel-case: 6.1.1 1013 | satori: 0.0.38 1014 | dev: false 1015 | 1016 | /wrangler/2.1.11: 1017 | resolution: {integrity: sha512-zXydDzU+KKOwYDD9IX+XdSZMFEPWTghzTN/CiZc+pxHGIjTuQBtbk97trY3i9YKeih/QOSlo+H7Clfoq+6rZLw==} 1018 | engines: {node: '>=16.13.0'} 1019 | hasBin: true 1020 | dependencies: 1021 | '@cloudflare/kv-asset-handler': 0.2.0 1022 | '@esbuild-plugins/node-globals-polyfill': 0.1.1_esbuild@0.14.51 1023 | '@esbuild-plugins/node-modules-polyfill': 0.1.4_esbuild@0.14.51 1024 | '@miniflare/core': 2.9.0 1025 | '@miniflare/d1': 2.9.0 1026 | '@miniflare/durable-objects': 2.9.0 1027 | blake3-wasm: 2.1.5 1028 | chokidar: 3.5.3 1029 | esbuild: 0.14.51 1030 | miniflare: 2.9.0 1031 | nanoid: 3.3.4 1032 | path-to-regexp: 6.2.1 1033 | selfsigned: 2.1.1 1034 | source-map: 0.7.4 1035 | xxhash-wasm: 1.0.1 1036 | optionalDependencies: 1037 | fsevents: 2.3.2 1038 | transitivePeerDependencies: 1039 | - '@miniflare/storage-redis' 1040 | - bufferutil 1041 | - cron-schedule 1042 | - ioredis 1043 | - utf-8-validate 1044 | dev: true 1045 | 1046 | /ws/8.9.0: 1047 | resolution: {integrity: sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==} 1048 | engines: {node: '>=10.0.0'} 1049 | peerDependencies: 1050 | bufferutil: ^4.0.1 1051 | utf-8-validate: ^5.0.2 1052 | peerDependenciesMeta: 1053 | bufferutil: 1054 | optional: true 1055 | utf-8-validate: 1056 | optional: true 1057 | dev: true 1058 | 1059 | /xxhash-wasm/1.0.1: 1060 | resolution: {integrity: sha512-Lc9CTvDrH2vRoiaUzz25q7lRaviMhz90pkx6YxR9EPYtF99yOJnv2cB+CQ0hp/TLoqrUsk8z/W2EN31T568Azw==} 1061 | dev: true 1062 | 1063 | /yallist/4.0.0: 1064 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 1065 | dev: true 1066 | 1067 | /yoga-layout-prebuilt/1.10.0: 1068 | resolution: {integrity: sha512-YnOmtSbv4MTf7RGJMK0FvZ+KD8OEe/J5BNnR0GHhD8J/XcG/Qvxgszm0Un6FTHWW4uHlTgP0IztiXQnGyIR45g==} 1069 | engines: {node: '>=8'} 1070 | dependencies: 1071 | '@types/yoga-layout': 1.9.2 1072 | dev: false 1073 | 1074 | /youch/2.2.2: 1075 | resolution: {integrity: sha512-/FaCeG3GkuJwaMR34GHVg0l8jCbafZLHiFowSjqLlqhC6OMyf2tPJBu8UirF7/NI9X/R5ai4QfEKUCOxMAGxZQ==} 1076 | dependencies: 1077 | '@types/stack-trace': 0.0.29 1078 | cookie: 0.4.2 1079 | mustache: 4.2.0 1080 | stack-trace: 0.0.10 1081 | dev: true 1082 | -------------------------------------------------------------------------------- /packages/worker/src/bucket.ts: -------------------------------------------------------------------------------- 1 | import { Env, PATTERNS } from "."; 2 | 3 | const hasValidHeader = (request: Request, env: Env) => { 4 | return ( 5 | request.headers.get("X-Custom-Auth-Key") === env.BUCKET_AUTH_KEY_SECRET 6 | ); 7 | }; 8 | 9 | export async function handleBucketRequest( 10 | request: Request, 11 | env: Env, 12 | ctx: ExecutionContext 13 | ): Promise { 14 | const key = PATTERNS.bucket.exec(request.url)?.pathname?.groups?.key; 15 | 16 | if (!key) { 17 | return new Response("Key not provided", { status: 404 }); 18 | } 19 | 20 | switch (request.method) { 21 | case "GET": 22 | const object = await env.OG_BUCKET.get(key); 23 | 24 | if (object === null) { 25 | return new Response("Object Not Found", { status: 404 }); 26 | } 27 | 28 | const headers = new Headers(); 29 | object.writeHttpMetadata(headers); 30 | headers.set("etag", object.httpEtag); 31 | 32 | return new Response(object.body, { 33 | headers, 34 | }); 35 | case "PUT": 36 | if (!hasValidHeader(request, env)) { 37 | return new Response("Invalid Request", { status: 403 }); 38 | } 39 | await env.OG_BUCKET.put(key, request.body); 40 | return new Response(`Put ${key} successfully!`); 41 | case "DELETE": 42 | if (!hasValidHeader(request, env)) { 43 | return new Response("Invalid Request", { status: 403 }); 44 | } 45 | await env.OG_BUCKET.delete(key); 46 | return new Response("Deleted!"); 47 | default: 48 | return new Response("Method Not Allowed", { 49 | status: 405, 50 | headers: { 51 | Allow: "PUT, GET, DELETE", 52 | // Allow: "GET", 53 | }, 54 | }); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/worker/src/cors.ts: -------------------------------------------------------------------------------- 1 | export const corsHeaders = { 2 | "Access-Control-Allow-Origin": "*", 3 | "Access-Control-Allow-Methods": "GET,HEAD,POST,OPTIONS", 4 | "Access-Control-Max-Age": "86400", 5 | }; 6 | -------------------------------------------------------------------------------- /packages/worker/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to Cloudflare Workers! This is your first worker. 3 | * 4 | * - Run `wrangler dev src/index.ts` in your terminal to start a development server 5 | * - Open a browser tab at http://localhost:8787/ to see your worker in action 6 | * - Run `wrangler publish src/index.ts --name my-worker` to publish your worker 7 | * 8 | * Learn more at https://developers.cloudflare.com/workers/ 9 | */ 10 | 11 | import { ImageResponse } from "workers-og"; 12 | import { handleBucketRequest } from "./bucket"; 13 | import { corsHeaders } from "./cors"; 14 | import { template } from "./template"; 15 | 16 | export interface Env { 17 | OG_BUCKET: R2Bucket; 18 | BUCKET_AUTH_KEY_SECRET: string; 19 | } 20 | 21 | export const PATTERNS = { 22 | bucket: new URLPattern({ pathname: "/bucket/:key" }), 23 | }; 24 | 25 | export default { 26 | async fetch( 27 | request: Request, 28 | env: Env, 29 | ctx: ExecutionContext 30 | ): Promise { 31 | if (PATTERNS.bucket.test(request.url)) { 32 | return await handleBucketRequest(request, env, ctx); 33 | } 34 | 35 | const params = new URL(request.url).searchParams; 36 | 37 | const format = params.get("format"); 38 | const debug = params.get("debug"); 39 | 40 | const title = 41 | params.get("title") || 42 | "Lorem ipsum dolor sit amet consectetur adipiscing"; 43 | const logoSrc = 44 | params.get("logoSrc") || 45 | `data:image/svg+xml,%3Csvg width='256' height='256' viewBox='0 0 256 256' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M101.702 91.5053L145.181 39.8831C148.253 36.4719 152.008 33.7475 156.202 31.8874C160.395 30.0273 164.933 29.0732 169.518 29.0873H170.493V27H119.32V28.9976H121.47C127.642 28.9976 130.542 34.6087 126.779 39.625L66.624 114.533V43.1376C66.7321 39.4054 68.2919 35.8635 70.9703 33.2678C73.6488 30.6721 77.2338 29.2282 80.96 29.2444H83.7712V27H16V29.2444H18.8784C22.6014 29.2433 26.1775 30.7002 28.8433 33.3042C31.5092 35.9083 33.0537 39.4532 33.1472 43.1824V167.065C33.0739 170.813 31.5359 174.384 28.8637 177.009C26.1915 179.634 22.5982 181.104 18.856 181.104H16V183.348H27.0432L101.702 91.5053Z' fill='%23FFBC42'/%3E%3Cpath d='M239.742 218.9C212.213 217.497 191.806 203.189 166.562 169.937L109.71 99.2374L89.5504 123.814L118.032 158.794H60.8L56.4656 164.068H122.322L138.55 184.021C173.181 227.328 205.75 238.64 240 221.055L239.742 218.9Z' fill='%23FFD890'/%3E%3C/svg%3E`; 46 | const authorSrc = 47 | params.get("authorSrc") || 48 | `data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAgICAgJCAkKCgkNDgwODRMREBARExwUFhQWFBwrGx8bGx8bKyYuJSMlLiZENS8vNUROQj5CTl9VVV93cXecnNEBCAgICAkICQoKCQ0ODA4NExEQEBETHBQWFBYUHCsbHxsbHxsrJi4lIyUuJkQ1Ly81RE5CPkJOX1VVX3dxd5yc0f/CABEIACgAKAMBIgACEQEDEQH/xAAxAAADAQADAQAAAAAAAAAAAAAABgcFAQIEAwEBAQADAAAAAAAAAAAAAAAABQQAAgP/2gAMAwEAAhADEAAAAH/pqxMRLeq0396HOunBVCsSyrJILGIwK1RvxpPmWk4MnCVHyMwaU0oC4r//xAAtEAACAQIFAwIEBwAAAAAAAAABAgMABAUGERIhIjFBIzIHFFFhEBMkUnHBwv/aAAgBAQABPwB4FaTqT28D7isfzvY5btYbcoZ7xgSkXYKnhnNL8UMfaUS/JIIv2iIlay3mWzx613x9E6D1I/7H4InqCswfqM6YnJOCUhKQxDTX2oD/AKqyxDDUQI0wV9vKMnVp9QKwaaCDM2FSW4UC5Z4pNvAPFHtUSjcTrV1hxhxrEDexkfmytIrsAwdfqKs4oJAy/LkEyEiTQBdmm3b0ngVgtgExvD5YxuCSanUlgAAeQTz5pm6TzSgbiO1Z2lEEmGSeCJVJqC4wwQjZtLj2qB5rLoCYdHJtAkZmLGg+8a6VNNDbgvKdABWaMQS9voG3aEKUSHudnctVjsSPUAbv45rLeZ7WKeaxmZlnml3w7h6Z4ACbvBOlW15FKh6iDr2P2r//xAAfEQACAgIBBQAAAAAAAAAAAAABAgARAwQhEhNRYZH/2gAIAQIBAT8A0LVnbwIMzdS2KuGa5IupjvJkVb9/Ix5mvgx9hnrkkiaoAyMY6gGf/8QAHxEAAgICAgMBAAAAAAAAAAAAAQIAEQMEEiIQEzFh/9oACAEDAQE/AMw9hRf2PrqEYhrrxjPfjX0TZ4YsRbjd9YsxkhwZsgMlGFQpoT//2Q==`; 49 | const author = params.get("author") || "Kevin Ang"; 50 | const backgroundImage = 51 | params.get("backgroundImage") || 52 | "linear-gradient(135deg, #281c4a, #160f29)"; 53 | 54 | let imageSrc = params.get("imageSrc"); 55 | 56 | /** 57 | * For loading a remote image, you can use the following example: 58 | */ 59 | // const sampleImage = await env.OG_BUCKET.get("og-sample-image-1.png"); 60 | 61 | // if (sampleImage) { 62 | // const sampleImageBuffer = await sampleImage.arrayBuffer(); 63 | // const sampleImageBase64 = base64ArrayBuffer(sampleImageBuffer); 64 | // imageSrc = `data:image/png;base64,${sampleImageBase64}`; 65 | // } 66 | 67 | const element = template({ 68 | title, 69 | logoSrc, 70 | authorSrc, 71 | author, 72 | backgroundImage, 73 | imageSrc, 74 | }); 75 | 76 | return new ImageResponse(element, { 77 | format: format as "svg" | "png", 78 | debug: debug === "true", 79 | headers: { 80 | ...corsHeaders, 81 | }, 82 | }); 83 | }, 84 | }; 85 | -------------------------------------------------------------------------------- /packages/worker/src/template.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const template = ({ 4 | title, 5 | logoSrc, 6 | authorSrc, 7 | author, 8 | backgroundImage, 9 | imageSrc, 10 | }: { 11 | title: string; 12 | logoSrc: string; 13 | authorSrc: string; 14 | author: string; 15 | backgroundImage: string; 16 | imageSrc?: string | null; 17 | }) => ( 18 |
27 |
35 |
42 | 43 |
44 |
53 |
60 |

69 | {title} 70 |

71 |
78 |
87 | 88 |
89 | 98 | {author} 99 | 100 |
101 |
102 |
103 |
104 | {imageSrc && ( 105 |
106 | 107 |
108 | )} 109 |
110 | ); 111 | -------------------------------------------------------------------------------- /packages/worker/src/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The fastests way to turn arrayBuffer to base64 3 | * benchmark: https://jsben.ch/wnaZC 4 | * 5 | * @see https://gist.github.com/jonleighton/958841 6 | */ 7 | export function base64ArrayBuffer(arrayBuffer: ArrayBuffer): string { 8 | var base64 = ""; 9 | var encodings = 10 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 11 | 12 | var bytes = new Uint8Array(arrayBuffer); 13 | var byteLength = bytes.byteLength; 14 | var byteRemainder = byteLength % 3; 15 | var mainLength = byteLength - byteRemainder; 16 | 17 | var a, b, c, d; 18 | var chunk; 19 | 20 | // Main loop deals with bytes in chunks of 3 21 | for (var i = 0; i < mainLength; i = i + 3) { 22 | // Combine the three bytes into a single integer 23 | chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; 24 | 25 | // Use bitmasks to extract 6-bit segments from the triplet 26 | a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18 27 | b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12 28 | c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6 29 | d = chunk & 63; // 63 = 2^6 - 1 30 | 31 | // Convert the raw binary segments to the appropriate ASCII encoding 32 | base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]; 33 | } 34 | 35 | // Deal with the remaining bytes and padding 36 | if (byteRemainder == 1) { 37 | chunk = bytes[mainLength]; 38 | 39 | a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2 40 | 41 | // Set the 4 least significant bits to zero 42 | b = (chunk & 3) << 4; // 3 = 2^2 - 1 43 | 44 | base64 += encodings[a] + encodings[b] + "=="; 45 | } else if (byteRemainder == 2) { 46 | chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]; 47 | 48 | a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10 49 | b = (chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4 50 | 51 | // Set the 2 least significant bits to zero 52 | c = (chunk & 15) << 2; // 15 = 2^4 - 1 53 | 54 | base64 += encodings[a] + encodings[b] + encodings[c] + "="; 55 | } 56 | 57 | return base64; 58 | } 59 | -------------------------------------------------------------------------------- /packages/worker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 | "lib": [ 16 | "es2021" 17 | ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, 18 | "jsx": "react" /* Specify what JSX code is generated. */, 19 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 20 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 21 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 22 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 23 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 24 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 25 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 26 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 27 | 28 | /* Modules */ 29 | "module": "es2022" /* Specify what module code is generated. */, 30 | // "rootDir": "./", /* Specify the root folder within your source files. */ 31 | "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, 32 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 33 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 34 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 35 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 36 | "types": [ 37 | "@cloudflare/workers-types" 38 | ] /* Specify type package names to be included without being referenced in a source file. */, 39 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 40 | "resolveJsonModule": true /* Enable importing .json files */, 41 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 42 | 43 | /* JavaScript Support */ 44 | "allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */, 45 | "checkJs": false /* Enable error reporting in type-checked JavaScript files. */, 46 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 47 | 48 | /* Emit */ 49 | // "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, 50 | // "declarationMap": true /* Create sourcemaps for d.ts files. */, 51 | // "emitDeclarationOnly": true /* Only output d.ts files and not JavaScript files. */, 52 | // "sourceMap": true /* Create source map files for emitted JavaScript files. */, 53 | // "outFile": "./dist/index.js" /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */, 54 | // "outDir": "./dist" /* Specify an output folder for all emitted files. */, 55 | // "removeComments": true, /* Disable emitting comments. */ 56 | // "noEmit": true /* Disable emitting files from a compilation. */, 57 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 58 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 59 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 60 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 61 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 62 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 63 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 64 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 65 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 66 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 67 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 68 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 69 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 70 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 71 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 72 | 73 | /* Interop Constraints */ 74 | // "isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */, 75 | "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, 76 | // "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, 77 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 78 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 79 | 80 | /* Type Checking */ 81 | "strict": true /* Enable all strict type-checking options. */, 82 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 83 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 84 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 85 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 86 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 87 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 88 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 89 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 90 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 91 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 92 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 93 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 94 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 95 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 96 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 97 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 98 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 99 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 100 | 101 | /* Completeness */ 102 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 103 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /packages/worker/wrangler.toml: -------------------------------------------------------------------------------- 1 | name = "og" 2 | main = "src/index.ts" 3 | compatibility_date = "2022-10-11" 4 | compatibility_flags = ["streams_enable_constructors"] 5 | 6 | [[r2_buckets]] 7 | binding = "OG_BUCKET" # <~ valid JavaScript variable name 8 | bucket_name = 'opengraph' 9 | preview_bucket_name = 'opengraphpreview' -------------------------------------------------------------------------------- /packages/workers-og/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ -------------------------------------------------------------------------------- /packages/workers-og/README.md: -------------------------------------------------------------------------------- 1 | # Cloudflare Workers OG Image Generator 2 | 3 | > Using Vercel's [Satori](https://github.com/vercel/satori) engine, and many credits to [`@vercel/og`](https://vercel.com/docs/concepts/functions/edge-functions/og-image-generation) for the inspiration. 4 | 5 | An `og:image` (social card) generator that is fast, browser-less (no Puppeteer), and capable of running on the edge. 6 | 7 | This package is designed to be used with Cloudflare Workers (but may be used elsewhere), with the simple API inspired by `@vercel/og`. 8 | 9 | ## Difference from `@vercel/og` 10 | 11 | `@vercel/og` is designed to run on Vercel’s edge runtime, and `workers-og` on Cloudflare Workers. 12 | 13 | Although Vercel’s edge runtime runs on Cloudflare Workers, the way WASM is bundled is different and causes an error when using `@vercel/og` on a Worker. 14 | 15 | **Another unique feature**: while `satori` (used in both `@vercel/og` and `workers-og`) accepts React element as the input, `workers-og` adds a feature which allows you to write a simple HTML, which will here be parsed into React element-like object. The parsing is handled by `HTMLRewriter`, which is part of Cloudflare Worker’s runtime API. 16 | 17 | ## Getting started 18 | 19 | Install the package on your Worker project: 20 | 21 | ```bash 22 | npm i workers-og 23 | ``` 24 | 25 | Then, import it to your project. The API mimics `@vercel/og` closely. 26 | 27 | ```typescript 28 | import { ImageResponse } from "workers-og"; 29 | ``` 30 | 31 | ## Example Usage on a Worker: 32 | 33 | ```typescript 34 | import { ImageResponse } from "workers-og"; 35 | 36 | export default { 37 | async fetch( 38 | request: Request, 39 | env: Env, 40 | ctx: ExecutionContext 41 | ): Promise { 42 | const params = new URLSearchParams(new URL(request.url).search); 43 | const title = params.get("title") || "Lorem ipsum"; 44 | 45 | const html = ` 46 |
47 |
48 |

${title}

49 |
50 |
51 | `; 52 | 53 | return new ImageResponse(html, { 54 | width: 1200, 55 | height: 630, 56 | }); 57 | }, 58 | }; 59 | ``` 60 | -------------------------------------------------------------------------------- /packages/workers-og/bin/esbuild.js: -------------------------------------------------------------------------------- 1 | import { build } from "esbuild"; 2 | import { dtsPlugin } from "esbuild-plugin-d.ts"; 3 | 4 | build({ 5 | entryPoints: ["src/index.ts"], 6 | bundle: true, 7 | outdir: "dist", 8 | format: "esm", 9 | loader: { 10 | ".wasm": "copy", 11 | }, 12 | minify: true, 13 | plugins: [dtsPlugin()], 14 | }).catch(() => process.exit(1)); 15 | -------------------------------------------------------------------------------- /packages/workers-og/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "workers-og", 3 | "type": "module", 4 | "files": [ 5 | "dist" 6 | ], 7 | "main": "./dist/index.js", 8 | "module": "./dist/index.js", 9 | "exports": { 10 | ".": { 11 | "import": "./dist/index.js", 12 | "require": "./dist/index.js" 13 | } 14 | }, 15 | "types": "./dist/index.d.ts", 16 | "version": "0.0.24", 17 | "devDependencies": { 18 | "@cloudflare/workers-types": "^4.20231218.0", 19 | "@types/node": "^20.11.0", 20 | "@vercel/og": "^0.6.2", 21 | "esbuild": "^0.19.11", 22 | "esbuild-plugin-d.ts": "^1.2.2", 23 | "typescript": "^5.3.3" 24 | }, 25 | "private": false, 26 | "scripts": { 27 | "build": "node bin/esbuild.js", 28 | "ts": "tsc --noEmit" 29 | }, 30 | "dependencies": { 31 | "@resvg/resvg-wasm": "^2.4.0", 32 | "just-camel-case": "^6.2.0", 33 | "satori": "^0.10.11", 34 | "yoga-wasm-web": "^0.3.3" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/workers-og/src/font.ts: -------------------------------------------------------------------------------- 1 | export async function loadGoogleFont({ 2 | family, 3 | weight, 4 | text, 5 | }: { 6 | family: string; 7 | weight?: number; 8 | text?: string; 9 | }) { 10 | const params: Record = { 11 | family: `${encodeURIComponent(family)}${weight ? `:wght@${weight}` : ""}`, 12 | }; 13 | 14 | if (text) { 15 | params.text = text; 16 | } else { 17 | params.subset = "latin"; 18 | } 19 | 20 | const url = `https://fonts.googleapis.com/css2?${Object.keys(params) 21 | .map((key) => `${key}=${params[key]}`) 22 | .join("&")}`; 23 | 24 | // @ts-expect-error - CacheStorage would use dom lib, but we're referring to CF worker's lib 25 | const cache = caches.default; 26 | const cacheKey = url; 27 | let res = await cache.match(cacheKey); 28 | 29 | if (!res) { 30 | res = await fetch(`${url}`, { 31 | headers: { 32 | // construct user agent to get TTF font 33 | "User-Agent": 34 | "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1", 35 | }, 36 | }); 37 | 38 | res = new Response(res.body, res); 39 | res.headers.append("Cache-Control", "s-maxage=3600"); 40 | 41 | await cache.put(cacheKey, res.clone()); 42 | } 43 | 44 | const body = await res.text(); 45 | // Get the font URL from the CSS text 46 | const fontUrl = body.match( 47 | /src: url\((.+)\) format\('(opentype|truetype)'\)/ 48 | )?.[1]; 49 | 50 | if (!fontUrl) { 51 | throw new Error("Could not find font URL"); 52 | } 53 | 54 | return fetch(fontUrl).then((res) => res.arrayBuffer()); 55 | } 56 | -------------------------------------------------------------------------------- /packages/workers-og/src/index.ts: -------------------------------------------------------------------------------- 1 | export { ImageResponse } from "./og"; 2 | export { loadGoogleFont } from "./font"; 3 | -------------------------------------------------------------------------------- /packages/workers-og/src/og.ts: -------------------------------------------------------------------------------- 1 | import satori, { init } from "satori/wasm"; 2 | import initYoga from "yoga-wasm-web"; 3 | import { Resvg, initWasm } from "@resvg/resvg-wasm"; 4 | import { parseHtml } from "./parseHtml"; 5 | import { loadGoogleFont } from "./font"; 6 | import type { ImageResponseOptions } from "./types"; 7 | 8 | // @ts-expect-error .wasm files are not typed 9 | import yogaWasm from "../vendors/yoga.wasm"; 10 | // @ts-expect-error .wasm files are not typed 11 | import resvgWasm from "../vendors/resvg.wasm"; 12 | 13 | const initResvgWasm = async () => { 14 | try { 15 | await initWasm(resvgWasm as WebAssembly.Module); 16 | } catch (err) { 17 | if (err instanceof Error && err.message.includes("Already initialized")) { 18 | return; 19 | } 20 | throw err; 21 | } 22 | }; 23 | 24 | const initYogaWasm = async () => { 25 | try { 26 | const yoga = await initYoga(yogaWasm); 27 | await init(yoga); 28 | } catch (err) { 29 | throw err; 30 | } 31 | }; 32 | 33 | interface Props { 34 | /** 35 | * The React element or HTML string to render into an image. 36 | * @example 37 | * ```tsx 38 | *
43 | *

Hello World

44 | *
45 | * ``` 46 | * @example 47 | * ```html 48 | *

Hello World

49 | * ``` 50 | */ 51 | element: string | React.ReactNode; 52 | /** 53 | * The options for the image response. 54 | */ 55 | options: ImageResponseOptions; 56 | } 57 | 58 | export const og = async ({ element, options }: Props) => { 59 | // 1. Init WASMs 60 | await Promise.allSettled([initResvgWasm(), initYogaWasm()]); 61 | 62 | // 2. Get React Element 63 | const reactElement = 64 | typeof element === "string" ? await parseHtml(element) : element; 65 | 66 | // 3. Convert React Element to SVG with Satori 67 | const width = options.width; 68 | const height = options.height; 69 | 70 | let widthHeight: 71 | | { width: number; height: number } 72 | | { width: number } 73 | | { height: number } = { 74 | width: 1200, 75 | height: 630, 76 | }; 77 | 78 | if (width && height) { 79 | widthHeight = { width, height }; 80 | } else if (width) { 81 | widthHeight = { width }; 82 | } else if (height) { 83 | widthHeight = { height }; 84 | } 85 | 86 | const svg = await satori(reactElement, { 87 | ...widthHeight, 88 | fonts: !!options?.fonts?.length 89 | ? options.fonts 90 | : [ 91 | { 92 | name: "Bitter", 93 | data: await loadGoogleFont({ family: "Bitter", weight: 600 }), 94 | weight: 500, 95 | style: "normal", 96 | }, 97 | ], 98 | }); 99 | 100 | const format = options?.format || "png"; 101 | 102 | if (format === "svg") { 103 | return svg; 104 | } 105 | 106 | // 4. Convert the SVG into a PNG 107 | const resvg = new Resvg(svg, { 108 | fitTo: 109 | "width" in widthHeight 110 | ? { 111 | mode: "width" as const, 112 | value: widthHeight.width, 113 | } 114 | : { 115 | mode: "height" as const, 116 | value: widthHeight.height, 117 | }, 118 | }); 119 | 120 | const pngData = resvg.render(); 121 | const pngBuffer = pngData.asPng(); 122 | 123 | return pngBuffer; 124 | }; 125 | 126 | export class ImageResponse extends Response { 127 | constructor( 128 | element: string | React.ReactNode, 129 | options: ImageResponseOptions 130 | ) { 131 | super(); 132 | 133 | if (options.format === "svg") { 134 | return (async () => { 135 | const svg = await og({ element, options }); 136 | return new Response(svg, { 137 | headers: { 138 | "Content-Type": "image/svg+xml", 139 | "Cache-Control": options.debug 140 | ? "no-cache, no-store" 141 | : "public, immutable, no-transform, max-age=31536000", 142 | ...options.headers, 143 | }, 144 | status: options.status || 200, 145 | statusText: options.statusText, 146 | }); 147 | })() as unknown as ImageResponse; 148 | } else { 149 | const body = new ReadableStream({ 150 | async start(controller) { 151 | const buffer = await og({ 152 | element, 153 | options, 154 | }); 155 | 156 | controller.enqueue(buffer); 157 | controller.close(); 158 | }, 159 | }); 160 | 161 | return new Response(body, { 162 | headers: { 163 | "Content-Type": "image/png", 164 | "Cache-Control": options.debug 165 | ? "no-cache, no-store" 166 | : "public, immutable, no-transform, max-age=31536000", 167 | ...options.headers, 168 | }, 169 | status: options.status || 200, 170 | statusText: options.statusText, 171 | }); 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /packages/workers-og/src/parseHtml.ts: -------------------------------------------------------------------------------- 1 | import { 2 | getAttributes, 3 | maybeRemoveTrailingComma, 4 | sanitizeJSON, 5 | } from "./parseUtils"; 6 | 7 | /** 8 | * Parses HTML into a ReactElementLike object 9 | * using Cloudflare Worker's own HTMLRewriter 10 | * 11 | * Given the ergonomics of HTMLRewriter, this 12 | * is the fastest way to transform HTML, but 13 | * is very error prone. So it might need more 14 | * hardening / testing in the future. 15 | * 16 | * Or use a different, more forgiving parser 17 | */ 18 | export async function parseHtml(html: string): Promise { 19 | let vdomStr = ``; 20 | 21 | const rewriter = new HTMLRewriter() 22 | .on("*", { 23 | element(element: Element) { 24 | const attrs = getAttributes(element); 25 | vdomStr += `{"type":"${element.tagName}", "props":{${attrs}"children": [`; 26 | try { 27 | element.onEndTag(() => { 28 | vdomStr = maybeRemoveTrailingComma(vdomStr); 29 | vdomStr += `]}},`; 30 | }); 31 | } catch (e) { 32 | vdomStr = maybeRemoveTrailingComma(vdomStr); 33 | vdomStr += `]}},`; 34 | } 35 | }, 36 | text(text: Text) { 37 | if (text.text) { 38 | const sanitized = sanitizeJSON(text.text); 39 | if (sanitized) { 40 | vdomStr += `"${sanitized}",`; 41 | } 42 | } 43 | }, 44 | }) 45 | .transform( 46 | new Response( 47 | // Add a parent to ensure that we're only dealing 48 | // with a single root element 49 | `
${html}
` 50 | ) 51 | ); 52 | 53 | await rewriter.text(); 54 | 55 | vdomStr = maybeRemoveTrailingComma(vdomStr); 56 | 57 | try { 58 | return JSON.parse(vdomStr); 59 | } catch (e) { 60 | console.error(e); 61 | return null; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /packages/workers-og/src/parseUtils.ts: -------------------------------------------------------------------------------- 1 | import camelCase from "just-camel-case"; 2 | 3 | export const sanitizeJSON = (unsanitized: string) => { 4 | return unsanitized 5 | .replace(/\\/g, "\\\\") 6 | .replace(/\n/g, "\\n") 7 | .replace(/\r/g, "\\r") 8 | .replace(/\t/g, "\\t") 9 | .replace(/\f/g, "\\f") 10 | .replace(/"/g, '\\"'); 11 | }; 12 | 13 | export const getAttributes = (element: Element) => { 14 | let attrs = ""; 15 | 16 | const style = element.getAttribute("style"); 17 | 18 | if (style) { 19 | const cleanStyle = style.replace(/\n/g, "").replace(/\s\s+/g, " "); 20 | 21 | // Split by semicolon, but not semicolon inside () 22 | let styleStr = cleanStyle 23 | .split(/;(?![^(]*\))/) 24 | .reduce((acc, cur) => { 25 | // Split only the first colon 26 | const [k, v] = cur.split(/:(.+)/); 27 | if (k && v) { 28 | acc += `"${camelCase(k.trim())}": "${sanitizeJSON(v.trim())}",`; 29 | } 30 | return acc; 31 | }, ""); 32 | 33 | if (styleStr.endsWith(",")) { 34 | styleStr = styleStr.slice(0, -1); 35 | } 36 | 37 | if (styleStr) { 38 | attrs += `"style":{${styleStr}},`; 39 | } 40 | } 41 | 42 | const src = element.getAttribute("src"); 43 | 44 | if (src) { 45 | const width = element.getAttribute("width"); 46 | const height = element.getAttribute("height"); 47 | 48 | if (width && height) { 49 | attrs += `"src":"${sanitizeJSON( 50 | src 51 | )}", "width":"${width}", "height":"${height}",`; 52 | } else { 53 | console.warn( 54 | "Image missing width or height attribute as required by Satori" 55 | ); 56 | attrs += `"src":"${sanitizeJSON(src)}",`; 57 | } 58 | } 59 | 60 | return attrs; 61 | }; 62 | 63 | export const maybeRemoveTrailingComma = (str: string) => { 64 | if (str.endsWith(",")) { 65 | return str.slice(0, -1); 66 | } 67 | return str; 68 | }; 69 | -------------------------------------------------------------------------------- /packages/workers-og/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { ImageResponse } from "@vercel/og"; 2 | 3 | type VercelImageResponseOptions = NonNullable< 4 | ConstructorParameters[1] 5 | >; 6 | 7 | export type ImageResponseOptions = Omit< 8 | VercelImageResponseOptions, 9 | "width" | "height" 10 | > & { 11 | /** 12 | * The format of the image. 13 | * @default "png" 14 | */ 15 | format?: "svg" | "png" | undefined; // Defaults to 'png' 16 | /** 17 | * The width of the image. If neither width nor height is provided, the default is 1200. 18 | * 19 | * @type {number} 20 | */ 21 | width?: number; 22 | /** 23 | * The height of the image. If neither width nor height is provided, the default is 630. 24 | * 25 | * @type {number} 26 | */ 27 | height?: number; 28 | }; 29 | -------------------------------------------------------------------------------- /packages/workers-og/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 | "lib": [ 16 | "es2021", 17 | "DOM", 18 | "DOM.Iterable" 19 | ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, 20 | "jsx": "react" /* Specify what JSX code is generated. */, 21 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 22 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 23 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 24 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 25 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 26 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 27 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 28 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 29 | 30 | /* Modules */ 31 | "module": "es2022" /* Specify what module code is generated. */, 32 | // "rootDir": "./", /* Specify the root folder within your source files. */ 33 | "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, 34 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 35 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 36 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 37 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 38 | "types": [ 39 | "@cloudflare/workers-types" 40 | ] /* Specify type package names to be included without being referenced in a source file. */, 41 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 42 | "resolveJsonModule": true /* Enable importing .json files */, 43 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 44 | 45 | /* JavaScript Support */ 46 | "allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */, 47 | "checkJs": false /* Enable error reporting in type-checked JavaScript files. */, 48 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 49 | 50 | /* Emit */ 51 | "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, 52 | // "declarationMap": true /* Create sourcemaps for d.ts files. */, 53 | "emitDeclarationOnly": true /* Only output d.ts files and not JavaScript files. */, 54 | // "sourceMap": true /* Create source map files for emitted JavaScript files. */, 55 | // "outFile": "./dist/index.js" /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */, 56 | "outDir": "./dist" /* Specify an output folder for all emitted files. */, 57 | // "removeComments": true, /* Disable emitting comments. */ 58 | // "noEmit": true /* Disable emitting files from a compilation. */, 59 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 60 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 61 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 62 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 63 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 64 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 65 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 66 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 67 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 68 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 69 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 70 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 71 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 72 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 73 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 74 | 75 | /* Interop Constraints */ 76 | // "isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */, 77 | "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, 78 | // "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, 79 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 80 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 81 | 82 | /* Type Checking */ 83 | "strict": true /* Enable all strict type-checking options. */, 84 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 85 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 86 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 87 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 88 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 89 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 90 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 91 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 92 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 93 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 94 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 95 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 96 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 97 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 98 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 99 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 100 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 101 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 102 | 103 | /* Completeness */ 104 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 105 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /packages/workers-og/vendors/resvg.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kvnang/workers-og/d28467a3d7fa2e532e736620d243e21f6004f2cf/packages/workers-og/vendors/resvg.wasm -------------------------------------------------------------------------------- /packages/workers-og/vendors/yoga.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kvnang/workers-og/d28467a3d7fa2e532e736620d243e21f6004f2cf/packages/workers-og/vendors/yoga.wasm -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | packages/worker: 10 | dependencies: 11 | workers-og: 12 | specifier: workspace:^ 13 | version: link:../workers-og 14 | devDependencies: 15 | '@cloudflare/workers-types': 16 | specifier: ^4.20231218.0 17 | version: 4.20231218.0 18 | '@types/react': 19 | specifier: ^18.2.47 20 | version: 18.2.47 21 | react: 22 | specifier: ^18.2.0 23 | version: 18.2.0 24 | wrangler: 25 | specifier: ^3.22.4 26 | version: 3.22.4 27 | 28 | packages/workers-og: 29 | dependencies: 30 | '@resvg/resvg-wasm': 31 | specifier: ^2.4.0 32 | version: 2.4.0 33 | just-camel-case: 34 | specifier: ^6.2.0 35 | version: 6.2.0 36 | satori: 37 | specifier: ^0.10.11 38 | version: 0.10.11 39 | yoga-wasm-web: 40 | specifier: ^0.3.3 41 | version: 0.3.3 42 | devDependencies: 43 | '@cloudflare/workers-types': 44 | specifier: ^4.20231218.0 45 | version: 4.20231218.0 46 | '@types/node': 47 | specifier: ^20.11.0 48 | version: 20.11.0 49 | '@vercel/og': 50 | specifier: ^0.6.2 51 | version: 0.6.2 52 | esbuild: 53 | specifier: ^0.19.11 54 | version: 0.19.11 55 | esbuild-plugin-d.ts: 56 | specifier: ^1.2.2 57 | version: 1.2.2(typescript@5.3.3) 58 | typescript: 59 | specifier: ^5.3.3 60 | version: 5.3.3 61 | 62 | packages: 63 | 64 | /@cloudflare/kv-asset-handler@0.2.0: 65 | resolution: {integrity: sha512-MVbXLbTcAotOPUj0pAMhVtJ+3/kFkwJqc5qNOleOZTv6QkZZABDMS21dSrSlVswEHwrpWC03e4fWytjqKvuE2A==} 66 | dependencies: 67 | mime: 3.0.0 68 | dev: true 69 | 70 | /@cloudflare/workerd-darwin-64@1.20231218.0: 71 | resolution: {integrity: sha512-547gOmTIVmRdDy7HNAGJUPELa+fSDm2Y0OCxqAtQOz0GLTDu1vX61xYmsb2rn91+v3xW6eMttEIpbYokKjtfJA==} 72 | engines: {node: '>=16'} 73 | cpu: [x64] 74 | os: [darwin] 75 | requiresBuild: true 76 | dev: true 77 | optional: true 78 | 79 | /@cloudflare/workerd-darwin-arm64@1.20231218.0: 80 | resolution: {integrity: sha512-b39qrU1bKolCfmKFDAnX4vXcqzISkEUVE/V8sMBsFzxrIpNAbcUHBZAQPYmS/OHIGB94KjOVokvDi7J6UNurPw==} 81 | engines: {node: '>=16'} 82 | cpu: [arm64] 83 | os: [darwin] 84 | requiresBuild: true 85 | dev: true 86 | optional: true 87 | 88 | /@cloudflare/workerd-linux-64@1.20231218.0: 89 | resolution: {integrity: sha512-dMUF1wA+0mybm6hHNOCgY/WMNMwomPPs4I7vvYCgwHSkch0Q2Wb7TnxQZSt8d1PK/myibaBwadrlIxpjxmpz3w==} 90 | engines: {node: '>=16'} 91 | cpu: [x64] 92 | os: [linux] 93 | requiresBuild: true 94 | dev: true 95 | optional: true 96 | 97 | /@cloudflare/workerd-linux-arm64@1.20231218.0: 98 | resolution: {integrity: sha512-2s5uc8IHt0QmWyKxAr1Fy+4b8Xy0b/oUtlPnm5MrKi2gDRlZzR7JvxENPJCpCnYENydS8lzvkMiAFECPBccmyQ==} 99 | engines: {node: '>=16'} 100 | cpu: [arm64] 101 | os: [linux] 102 | requiresBuild: true 103 | dev: true 104 | optional: true 105 | 106 | /@cloudflare/workerd-windows-64@1.20231218.0: 107 | resolution: {integrity: sha512-oN5hz6TXUDB5YKUN5N3QWAv6cYz9JjTZ9g16HVyoegVFEL6/zXU3tV19MBX2IvlE11ab/mRogEv9KXVIrHfKmA==} 108 | engines: {node: '>=16'} 109 | cpu: [x64] 110 | os: [win32] 111 | requiresBuild: true 112 | dev: true 113 | optional: true 114 | 115 | /@cloudflare/workers-types@4.20231218.0: 116 | resolution: {integrity: sha512-Vs1FKjfUjXYGbCsXzkl+ITp0Iyb6QiW6+vTERTNThC+v96T0IvPVAioH4tT20rXwoxAfxh380mAaxYtTrJUNVg==} 117 | dev: true 118 | 119 | /@cspotcode/source-map-support@0.8.1: 120 | resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} 121 | engines: {node: '>=12'} 122 | dependencies: 123 | '@jridgewell/trace-mapping': 0.3.9 124 | dev: true 125 | 126 | /@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19): 127 | resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} 128 | peerDependencies: 129 | esbuild: '*' 130 | dependencies: 131 | esbuild: 0.17.19 132 | dev: true 133 | 134 | /@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19): 135 | resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} 136 | peerDependencies: 137 | esbuild: '*' 138 | dependencies: 139 | esbuild: 0.17.19 140 | escape-string-regexp: 4.0.0 141 | rollup-plugin-node-polyfills: 0.2.1 142 | dev: true 143 | 144 | /@esbuild/aix-ppc64@0.19.11: 145 | resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==} 146 | engines: {node: '>=12'} 147 | cpu: [ppc64] 148 | os: [aix] 149 | requiresBuild: true 150 | dev: true 151 | optional: true 152 | 153 | /@esbuild/android-arm64@0.17.19: 154 | resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} 155 | engines: {node: '>=12'} 156 | cpu: [arm64] 157 | os: [android] 158 | requiresBuild: true 159 | dev: true 160 | optional: true 161 | 162 | /@esbuild/android-arm64@0.19.11: 163 | resolution: {integrity: sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==} 164 | engines: {node: '>=12'} 165 | cpu: [arm64] 166 | os: [android] 167 | requiresBuild: true 168 | dev: true 169 | optional: true 170 | 171 | /@esbuild/android-arm@0.17.19: 172 | resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} 173 | engines: {node: '>=12'} 174 | cpu: [arm] 175 | os: [android] 176 | requiresBuild: true 177 | dev: true 178 | optional: true 179 | 180 | /@esbuild/android-arm@0.19.11: 181 | resolution: {integrity: sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==} 182 | engines: {node: '>=12'} 183 | cpu: [arm] 184 | os: [android] 185 | requiresBuild: true 186 | dev: true 187 | optional: true 188 | 189 | /@esbuild/android-x64@0.17.19: 190 | resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} 191 | engines: {node: '>=12'} 192 | cpu: [x64] 193 | os: [android] 194 | requiresBuild: true 195 | dev: true 196 | optional: true 197 | 198 | /@esbuild/android-x64@0.19.11: 199 | resolution: {integrity: sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==} 200 | engines: {node: '>=12'} 201 | cpu: [x64] 202 | os: [android] 203 | requiresBuild: true 204 | dev: true 205 | optional: true 206 | 207 | /@esbuild/darwin-arm64@0.17.19: 208 | resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} 209 | engines: {node: '>=12'} 210 | cpu: [arm64] 211 | os: [darwin] 212 | requiresBuild: true 213 | dev: true 214 | optional: true 215 | 216 | /@esbuild/darwin-arm64@0.19.11: 217 | resolution: {integrity: sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==} 218 | engines: {node: '>=12'} 219 | cpu: [arm64] 220 | os: [darwin] 221 | requiresBuild: true 222 | dev: true 223 | optional: true 224 | 225 | /@esbuild/darwin-x64@0.17.19: 226 | resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} 227 | engines: {node: '>=12'} 228 | cpu: [x64] 229 | os: [darwin] 230 | requiresBuild: true 231 | dev: true 232 | optional: true 233 | 234 | /@esbuild/darwin-x64@0.19.11: 235 | resolution: {integrity: sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==} 236 | engines: {node: '>=12'} 237 | cpu: [x64] 238 | os: [darwin] 239 | requiresBuild: true 240 | dev: true 241 | optional: true 242 | 243 | /@esbuild/freebsd-arm64@0.17.19: 244 | resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} 245 | engines: {node: '>=12'} 246 | cpu: [arm64] 247 | os: [freebsd] 248 | requiresBuild: true 249 | dev: true 250 | optional: true 251 | 252 | /@esbuild/freebsd-arm64@0.19.11: 253 | resolution: {integrity: sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==} 254 | engines: {node: '>=12'} 255 | cpu: [arm64] 256 | os: [freebsd] 257 | requiresBuild: true 258 | dev: true 259 | optional: true 260 | 261 | /@esbuild/freebsd-x64@0.17.19: 262 | resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} 263 | engines: {node: '>=12'} 264 | cpu: [x64] 265 | os: [freebsd] 266 | requiresBuild: true 267 | dev: true 268 | optional: true 269 | 270 | /@esbuild/freebsd-x64@0.19.11: 271 | resolution: {integrity: sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==} 272 | engines: {node: '>=12'} 273 | cpu: [x64] 274 | os: [freebsd] 275 | requiresBuild: true 276 | dev: true 277 | optional: true 278 | 279 | /@esbuild/linux-arm64@0.17.19: 280 | resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} 281 | engines: {node: '>=12'} 282 | cpu: [arm64] 283 | os: [linux] 284 | requiresBuild: true 285 | dev: true 286 | optional: true 287 | 288 | /@esbuild/linux-arm64@0.19.11: 289 | resolution: {integrity: sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==} 290 | engines: {node: '>=12'} 291 | cpu: [arm64] 292 | os: [linux] 293 | requiresBuild: true 294 | dev: true 295 | optional: true 296 | 297 | /@esbuild/linux-arm@0.17.19: 298 | resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} 299 | engines: {node: '>=12'} 300 | cpu: [arm] 301 | os: [linux] 302 | requiresBuild: true 303 | dev: true 304 | optional: true 305 | 306 | /@esbuild/linux-arm@0.19.11: 307 | resolution: {integrity: sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==} 308 | engines: {node: '>=12'} 309 | cpu: [arm] 310 | os: [linux] 311 | requiresBuild: true 312 | dev: true 313 | optional: true 314 | 315 | /@esbuild/linux-ia32@0.17.19: 316 | resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} 317 | engines: {node: '>=12'} 318 | cpu: [ia32] 319 | os: [linux] 320 | requiresBuild: true 321 | dev: true 322 | optional: true 323 | 324 | /@esbuild/linux-ia32@0.19.11: 325 | resolution: {integrity: sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==} 326 | engines: {node: '>=12'} 327 | cpu: [ia32] 328 | os: [linux] 329 | requiresBuild: true 330 | dev: true 331 | optional: true 332 | 333 | /@esbuild/linux-loong64@0.17.19: 334 | resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} 335 | engines: {node: '>=12'} 336 | cpu: [loong64] 337 | os: [linux] 338 | requiresBuild: true 339 | dev: true 340 | optional: true 341 | 342 | /@esbuild/linux-loong64@0.19.11: 343 | resolution: {integrity: sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==} 344 | engines: {node: '>=12'} 345 | cpu: [loong64] 346 | os: [linux] 347 | requiresBuild: true 348 | dev: true 349 | optional: true 350 | 351 | /@esbuild/linux-mips64el@0.17.19: 352 | resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} 353 | engines: {node: '>=12'} 354 | cpu: [mips64el] 355 | os: [linux] 356 | requiresBuild: true 357 | dev: true 358 | optional: true 359 | 360 | /@esbuild/linux-mips64el@0.19.11: 361 | resolution: {integrity: sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==} 362 | engines: {node: '>=12'} 363 | cpu: [mips64el] 364 | os: [linux] 365 | requiresBuild: true 366 | dev: true 367 | optional: true 368 | 369 | /@esbuild/linux-ppc64@0.17.19: 370 | resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} 371 | engines: {node: '>=12'} 372 | cpu: [ppc64] 373 | os: [linux] 374 | requiresBuild: true 375 | dev: true 376 | optional: true 377 | 378 | /@esbuild/linux-ppc64@0.19.11: 379 | resolution: {integrity: sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==} 380 | engines: {node: '>=12'} 381 | cpu: [ppc64] 382 | os: [linux] 383 | requiresBuild: true 384 | dev: true 385 | optional: true 386 | 387 | /@esbuild/linux-riscv64@0.17.19: 388 | resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} 389 | engines: {node: '>=12'} 390 | cpu: [riscv64] 391 | os: [linux] 392 | requiresBuild: true 393 | dev: true 394 | optional: true 395 | 396 | /@esbuild/linux-riscv64@0.19.11: 397 | resolution: {integrity: sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==} 398 | engines: {node: '>=12'} 399 | cpu: [riscv64] 400 | os: [linux] 401 | requiresBuild: true 402 | dev: true 403 | optional: true 404 | 405 | /@esbuild/linux-s390x@0.17.19: 406 | resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} 407 | engines: {node: '>=12'} 408 | cpu: [s390x] 409 | os: [linux] 410 | requiresBuild: true 411 | dev: true 412 | optional: true 413 | 414 | /@esbuild/linux-s390x@0.19.11: 415 | resolution: {integrity: sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==} 416 | engines: {node: '>=12'} 417 | cpu: [s390x] 418 | os: [linux] 419 | requiresBuild: true 420 | dev: true 421 | optional: true 422 | 423 | /@esbuild/linux-x64@0.17.19: 424 | resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} 425 | engines: {node: '>=12'} 426 | cpu: [x64] 427 | os: [linux] 428 | requiresBuild: true 429 | dev: true 430 | optional: true 431 | 432 | /@esbuild/linux-x64@0.19.11: 433 | resolution: {integrity: sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==} 434 | engines: {node: '>=12'} 435 | cpu: [x64] 436 | os: [linux] 437 | requiresBuild: true 438 | dev: true 439 | optional: true 440 | 441 | /@esbuild/netbsd-x64@0.17.19: 442 | resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} 443 | engines: {node: '>=12'} 444 | cpu: [x64] 445 | os: [netbsd] 446 | requiresBuild: true 447 | dev: true 448 | optional: true 449 | 450 | /@esbuild/netbsd-x64@0.19.11: 451 | resolution: {integrity: sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==} 452 | engines: {node: '>=12'} 453 | cpu: [x64] 454 | os: [netbsd] 455 | requiresBuild: true 456 | dev: true 457 | optional: true 458 | 459 | /@esbuild/openbsd-x64@0.17.19: 460 | resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} 461 | engines: {node: '>=12'} 462 | cpu: [x64] 463 | os: [openbsd] 464 | requiresBuild: true 465 | dev: true 466 | optional: true 467 | 468 | /@esbuild/openbsd-x64@0.19.11: 469 | resolution: {integrity: sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==} 470 | engines: {node: '>=12'} 471 | cpu: [x64] 472 | os: [openbsd] 473 | requiresBuild: true 474 | dev: true 475 | optional: true 476 | 477 | /@esbuild/sunos-x64@0.17.19: 478 | resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} 479 | engines: {node: '>=12'} 480 | cpu: [x64] 481 | os: [sunos] 482 | requiresBuild: true 483 | dev: true 484 | optional: true 485 | 486 | /@esbuild/sunos-x64@0.19.11: 487 | resolution: {integrity: sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==} 488 | engines: {node: '>=12'} 489 | cpu: [x64] 490 | os: [sunos] 491 | requiresBuild: true 492 | dev: true 493 | optional: true 494 | 495 | /@esbuild/win32-arm64@0.17.19: 496 | resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} 497 | engines: {node: '>=12'} 498 | cpu: [arm64] 499 | os: [win32] 500 | requiresBuild: true 501 | dev: true 502 | optional: true 503 | 504 | /@esbuild/win32-arm64@0.19.11: 505 | resolution: {integrity: sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==} 506 | engines: {node: '>=12'} 507 | cpu: [arm64] 508 | os: [win32] 509 | requiresBuild: true 510 | dev: true 511 | optional: true 512 | 513 | /@esbuild/win32-ia32@0.17.19: 514 | resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} 515 | engines: {node: '>=12'} 516 | cpu: [ia32] 517 | os: [win32] 518 | requiresBuild: true 519 | dev: true 520 | optional: true 521 | 522 | /@esbuild/win32-ia32@0.19.11: 523 | resolution: {integrity: sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==} 524 | engines: {node: '>=12'} 525 | cpu: [ia32] 526 | os: [win32] 527 | requiresBuild: true 528 | dev: true 529 | optional: true 530 | 531 | /@esbuild/win32-x64@0.17.19: 532 | resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} 533 | engines: {node: '>=12'} 534 | cpu: [x64] 535 | os: [win32] 536 | requiresBuild: true 537 | dev: true 538 | optional: true 539 | 540 | /@esbuild/win32-x64@0.19.11: 541 | resolution: {integrity: sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==} 542 | engines: {node: '>=12'} 543 | cpu: [x64] 544 | os: [win32] 545 | requiresBuild: true 546 | dev: true 547 | optional: true 548 | 549 | /@fastify/busboy@2.1.0: 550 | resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} 551 | engines: {node: '>=14'} 552 | dev: true 553 | 554 | /@jridgewell/resolve-uri@3.1.1: 555 | resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} 556 | engines: {node: '>=6.0.0'} 557 | dev: true 558 | 559 | /@jridgewell/sourcemap-codec@1.4.15: 560 | resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} 561 | dev: true 562 | 563 | /@jridgewell/trace-mapping@0.3.9: 564 | resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} 565 | dependencies: 566 | '@jridgewell/resolve-uri': 3.1.1 567 | '@jridgewell/sourcemap-codec': 1.4.15 568 | dev: true 569 | 570 | /@resvg/resvg-wasm@2.4.0: 571 | resolution: {integrity: sha512-C7c51Nn4yTxXFKvgh2txJFNweaVcfUPQxwEUFw4aWsCmfiBDJsTSwviIF8EcwjQ6k8bPyMWCl1vw4BdxE569Cg==} 572 | engines: {node: '>= 10'} 573 | 574 | /@shuding/opentype.js@1.4.0-beta.0: 575 | resolution: {integrity: sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==} 576 | engines: {node: '>= 8.0.0'} 577 | hasBin: true 578 | dependencies: 579 | fflate: 0.7.4 580 | string.prototype.codepointat: 0.2.1 581 | 582 | /@types/node-forge@1.3.11: 583 | resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} 584 | dependencies: 585 | '@types/node': 20.11.0 586 | dev: true 587 | 588 | /@types/node@20.11.0: 589 | resolution: {integrity: sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==} 590 | dependencies: 591 | undici-types: 5.26.5 592 | dev: true 593 | 594 | /@types/prop-types@15.7.11: 595 | resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} 596 | dev: true 597 | 598 | /@types/react@18.2.47: 599 | resolution: {integrity: sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ==} 600 | dependencies: 601 | '@types/prop-types': 15.7.11 602 | '@types/scheduler': 0.16.8 603 | csstype: 3.1.3 604 | dev: true 605 | 606 | /@types/scheduler@0.16.8: 607 | resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} 608 | dev: true 609 | 610 | /@vercel/og@0.6.2: 611 | resolution: {integrity: sha512-OTe0KE37F5Y2eTys6eMnfopC+P4qr2ooXUTFyFPTplYSPwowmFk/HLD1FXtbKLjqsIH0SgekcJWad+C5uX4nkg==} 612 | engines: {node: '>=16'} 613 | dependencies: 614 | '@resvg/resvg-wasm': 2.4.0 615 | satori: 0.10.9 616 | yoga-wasm-web: 0.3.3 617 | dev: true 618 | 619 | /acorn-walk@8.3.2: 620 | resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} 621 | engines: {node: '>=0.4.0'} 622 | dev: true 623 | 624 | /acorn@8.11.3: 625 | resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} 626 | engines: {node: '>=0.4.0'} 627 | hasBin: true 628 | dev: true 629 | 630 | /ansi-styles@4.3.0: 631 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 632 | engines: {node: '>=8'} 633 | dependencies: 634 | color-convert: 2.0.1 635 | dev: true 636 | 637 | /anymatch@3.1.3: 638 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 639 | engines: {node: '>= 8'} 640 | dependencies: 641 | normalize-path: 3.0.0 642 | picomatch: 2.3.1 643 | dev: true 644 | 645 | /as-table@1.0.55: 646 | resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} 647 | dependencies: 648 | printable-characters: 1.0.42 649 | dev: true 650 | 651 | /base64-js@0.0.8: 652 | resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} 653 | engines: {node: '>= 0.4'} 654 | 655 | /binary-extensions@2.2.0: 656 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 657 | engines: {node: '>=8'} 658 | dev: true 659 | 660 | /blake3-wasm@2.1.5: 661 | resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} 662 | dev: true 663 | 664 | /braces@3.0.2: 665 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 666 | engines: {node: '>=8'} 667 | dependencies: 668 | fill-range: 7.0.1 669 | dev: true 670 | 671 | /camelize@1.0.1: 672 | resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} 673 | 674 | /capnp-ts@0.7.0: 675 | resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} 676 | dependencies: 677 | debug: 4.3.4 678 | tslib: 2.6.2 679 | transitivePeerDependencies: 680 | - supports-color 681 | dev: true 682 | 683 | /chalk@4.1.2: 684 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 685 | engines: {node: '>=10'} 686 | dependencies: 687 | ansi-styles: 4.3.0 688 | supports-color: 7.2.0 689 | dev: true 690 | 691 | /chokidar@3.5.3: 692 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 693 | engines: {node: '>= 8.10.0'} 694 | dependencies: 695 | anymatch: 3.1.3 696 | braces: 3.0.2 697 | glob-parent: 5.1.2 698 | is-binary-path: 2.1.0 699 | is-glob: 4.0.3 700 | normalize-path: 3.0.0 701 | readdirp: 3.6.0 702 | optionalDependencies: 703 | fsevents: 2.3.3 704 | dev: true 705 | 706 | /color-convert@2.0.1: 707 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 708 | engines: {node: '>=7.0.0'} 709 | dependencies: 710 | color-name: 1.1.4 711 | dev: true 712 | 713 | /color-name@1.1.4: 714 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 715 | 716 | /cookie@0.5.0: 717 | resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} 718 | engines: {node: '>= 0.6'} 719 | dev: true 720 | 721 | /css-background-parser@0.1.0: 722 | resolution: {integrity: sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==} 723 | 724 | /css-box-shadow@1.0.0-3: 725 | resolution: {integrity: sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==} 726 | 727 | /css-color-keywords@1.0.0: 728 | resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} 729 | engines: {node: '>=4'} 730 | 731 | /css-to-react-native@3.2.0: 732 | resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} 733 | dependencies: 734 | camelize: 1.0.1 735 | css-color-keywords: 1.0.0 736 | postcss-value-parser: 4.2.0 737 | 738 | /csstype@3.1.3: 739 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 740 | dev: true 741 | 742 | /data-uri-to-buffer@2.0.2: 743 | resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} 744 | dev: true 745 | 746 | /debug@4.3.4: 747 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 748 | engines: {node: '>=6.0'} 749 | peerDependencies: 750 | supports-color: '*' 751 | peerDependenciesMeta: 752 | supports-color: 753 | optional: true 754 | dependencies: 755 | ms: 2.1.2 756 | dev: true 757 | 758 | /emoji-regex@10.3.0: 759 | resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} 760 | 761 | /esbuild-plugin-d.ts@1.2.2(typescript@5.3.3): 762 | resolution: {integrity: sha512-ZmJTjICZYDx5GbTsMHWKdR7CVllc0zMTM7SX7u2o8n8y6R1iez5r6Ei4ybZXSAqrXN/chD0s4B0mqQxUhiYo4g==} 763 | engines: {node: '>=12.0.0'} 764 | peerDependencies: 765 | typescript: '*' 766 | dependencies: 767 | chalk: 4.1.2 768 | lodash.merge: 4.6.2 769 | typescript: 5.3.3 770 | dev: true 771 | 772 | /esbuild@0.17.19: 773 | resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} 774 | engines: {node: '>=12'} 775 | hasBin: true 776 | requiresBuild: true 777 | optionalDependencies: 778 | '@esbuild/android-arm': 0.17.19 779 | '@esbuild/android-arm64': 0.17.19 780 | '@esbuild/android-x64': 0.17.19 781 | '@esbuild/darwin-arm64': 0.17.19 782 | '@esbuild/darwin-x64': 0.17.19 783 | '@esbuild/freebsd-arm64': 0.17.19 784 | '@esbuild/freebsd-x64': 0.17.19 785 | '@esbuild/linux-arm': 0.17.19 786 | '@esbuild/linux-arm64': 0.17.19 787 | '@esbuild/linux-ia32': 0.17.19 788 | '@esbuild/linux-loong64': 0.17.19 789 | '@esbuild/linux-mips64el': 0.17.19 790 | '@esbuild/linux-ppc64': 0.17.19 791 | '@esbuild/linux-riscv64': 0.17.19 792 | '@esbuild/linux-s390x': 0.17.19 793 | '@esbuild/linux-x64': 0.17.19 794 | '@esbuild/netbsd-x64': 0.17.19 795 | '@esbuild/openbsd-x64': 0.17.19 796 | '@esbuild/sunos-x64': 0.17.19 797 | '@esbuild/win32-arm64': 0.17.19 798 | '@esbuild/win32-ia32': 0.17.19 799 | '@esbuild/win32-x64': 0.17.19 800 | dev: true 801 | 802 | /esbuild@0.19.11: 803 | resolution: {integrity: sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==} 804 | engines: {node: '>=12'} 805 | hasBin: true 806 | requiresBuild: true 807 | optionalDependencies: 808 | '@esbuild/aix-ppc64': 0.19.11 809 | '@esbuild/android-arm': 0.19.11 810 | '@esbuild/android-arm64': 0.19.11 811 | '@esbuild/android-x64': 0.19.11 812 | '@esbuild/darwin-arm64': 0.19.11 813 | '@esbuild/darwin-x64': 0.19.11 814 | '@esbuild/freebsd-arm64': 0.19.11 815 | '@esbuild/freebsd-x64': 0.19.11 816 | '@esbuild/linux-arm': 0.19.11 817 | '@esbuild/linux-arm64': 0.19.11 818 | '@esbuild/linux-ia32': 0.19.11 819 | '@esbuild/linux-loong64': 0.19.11 820 | '@esbuild/linux-mips64el': 0.19.11 821 | '@esbuild/linux-ppc64': 0.19.11 822 | '@esbuild/linux-riscv64': 0.19.11 823 | '@esbuild/linux-s390x': 0.19.11 824 | '@esbuild/linux-x64': 0.19.11 825 | '@esbuild/netbsd-x64': 0.19.11 826 | '@esbuild/openbsd-x64': 0.19.11 827 | '@esbuild/sunos-x64': 0.19.11 828 | '@esbuild/win32-arm64': 0.19.11 829 | '@esbuild/win32-ia32': 0.19.11 830 | '@esbuild/win32-x64': 0.19.11 831 | dev: true 832 | 833 | /escape-html@1.0.3: 834 | resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} 835 | 836 | /escape-string-regexp@4.0.0: 837 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 838 | engines: {node: '>=10'} 839 | dev: true 840 | 841 | /estree-walker@0.6.1: 842 | resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} 843 | dev: true 844 | 845 | /exit-hook@2.2.1: 846 | resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} 847 | engines: {node: '>=6'} 848 | dev: true 849 | 850 | /fflate@0.7.4: 851 | resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} 852 | 853 | /fill-range@7.0.1: 854 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 855 | engines: {node: '>=8'} 856 | dependencies: 857 | to-regex-range: 5.0.1 858 | dev: true 859 | 860 | /fsevents@2.3.3: 861 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 862 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 863 | os: [darwin] 864 | requiresBuild: true 865 | dev: true 866 | optional: true 867 | 868 | /get-source@2.0.12: 869 | resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} 870 | dependencies: 871 | data-uri-to-buffer: 2.0.2 872 | source-map: 0.6.1 873 | dev: true 874 | 875 | /glob-parent@5.1.2: 876 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 877 | engines: {node: '>= 6'} 878 | dependencies: 879 | is-glob: 4.0.3 880 | dev: true 881 | 882 | /glob-to-regexp@0.4.1: 883 | resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} 884 | dev: true 885 | 886 | /has-flag@4.0.0: 887 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 888 | engines: {node: '>=8'} 889 | dev: true 890 | 891 | /hex-rgb@4.3.0: 892 | resolution: {integrity: sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==} 893 | engines: {node: '>=6'} 894 | 895 | /is-binary-path@2.1.0: 896 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 897 | engines: {node: '>=8'} 898 | dependencies: 899 | binary-extensions: 2.2.0 900 | dev: true 901 | 902 | /is-extglob@2.1.1: 903 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 904 | engines: {node: '>=0.10.0'} 905 | dev: true 906 | 907 | /is-glob@4.0.3: 908 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 909 | engines: {node: '>=0.10.0'} 910 | dependencies: 911 | is-extglob: 2.1.1 912 | dev: true 913 | 914 | /is-number@7.0.0: 915 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 916 | engines: {node: '>=0.12.0'} 917 | dev: true 918 | 919 | /js-tokens@4.0.0: 920 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 921 | dev: true 922 | 923 | /just-camel-case@6.2.0: 924 | resolution: {integrity: sha512-ICenRLXwkQYLk3UyvLQZ+uKuwFVJ3JHFYFn7F2782G2Mv2hW8WPePqgdhpnjGaqkYtSVWnyCESZhGXUmY3/bEg==} 925 | dev: false 926 | 927 | /linebreak@1.1.0: 928 | resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} 929 | dependencies: 930 | base64-js: 0.0.8 931 | unicode-trie: 2.0.0 932 | 933 | /lodash.merge@4.6.2: 934 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 935 | dev: true 936 | 937 | /loose-envify@1.4.0: 938 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 939 | hasBin: true 940 | dependencies: 941 | js-tokens: 4.0.0 942 | dev: true 943 | 944 | /magic-string@0.25.9: 945 | resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} 946 | dependencies: 947 | sourcemap-codec: 1.4.8 948 | dev: true 949 | 950 | /mime@3.0.0: 951 | resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} 952 | engines: {node: '>=10.0.0'} 953 | hasBin: true 954 | dev: true 955 | 956 | /miniflare@3.20231218.1: 957 | resolution: {integrity: sha512-rl/wADgaRLpbl7EMobwbAt6BgVqkOoWsVQJAliIIUCRzC0s0xg7ZVeoV+DuQD4ffN4RySXsPnP97hp7ksc7ylA==} 958 | engines: {node: '>=16.13'} 959 | hasBin: true 960 | dependencies: 961 | '@cspotcode/source-map-support': 0.8.1 962 | acorn: 8.11.3 963 | acorn-walk: 8.3.2 964 | capnp-ts: 0.7.0 965 | exit-hook: 2.2.1 966 | glob-to-regexp: 0.4.1 967 | stoppable: 1.1.0 968 | undici: 5.28.2 969 | workerd: 1.20231218.0 970 | ws: 8.16.0 971 | youch: 3.3.3 972 | zod: 3.22.4 973 | transitivePeerDependencies: 974 | - bufferutil 975 | - supports-color 976 | - utf-8-validate 977 | dev: true 978 | 979 | /ms@2.1.2: 980 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 981 | dev: true 982 | 983 | /mustache@4.2.0: 984 | resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} 985 | hasBin: true 986 | dev: true 987 | 988 | /nanoid@3.3.7: 989 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 990 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 991 | hasBin: true 992 | dev: true 993 | 994 | /node-forge@1.3.1: 995 | resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} 996 | engines: {node: '>= 6.13.0'} 997 | dev: true 998 | 999 | /normalize-path@3.0.0: 1000 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 1001 | engines: {node: '>=0.10.0'} 1002 | dev: true 1003 | 1004 | /pako@0.2.9: 1005 | resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} 1006 | 1007 | /parse-css-color@0.2.1: 1008 | resolution: {integrity: sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==} 1009 | dependencies: 1010 | color-name: 1.1.4 1011 | hex-rgb: 4.3.0 1012 | 1013 | /path-to-regexp@6.2.1: 1014 | resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} 1015 | dev: true 1016 | 1017 | /picomatch@2.3.1: 1018 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1019 | engines: {node: '>=8.6'} 1020 | dev: true 1021 | 1022 | /postcss-value-parser@4.2.0: 1023 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} 1024 | 1025 | /printable-characters@1.0.42: 1026 | resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} 1027 | dev: true 1028 | 1029 | /react@18.2.0: 1030 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} 1031 | engines: {node: '>=0.10.0'} 1032 | dependencies: 1033 | loose-envify: 1.4.0 1034 | dev: true 1035 | 1036 | /readdirp@3.6.0: 1037 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 1038 | engines: {node: '>=8.10.0'} 1039 | dependencies: 1040 | picomatch: 2.3.1 1041 | dev: true 1042 | 1043 | /resolve.exports@2.0.2: 1044 | resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} 1045 | engines: {node: '>=10'} 1046 | dev: true 1047 | 1048 | /rollup-plugin-inject@3.0.2: 1049 | resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} 1050 | deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. 1051 | dependencies: 1052 | estree-walker: 0.6.1 1053 | magic-string: 0.25.9 1054 | rollup-pluginutils: 2.8.2 1055 | dev: true 1056 | 1057 | /rollup-plugin-node-polyfills@0.2.1: 1058 | resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} 1059 | dependencies: 1060 | rollup-plugin-inject: 3.0.2 1061 | dev: true 1062 | 1063 | /rollup-pluginutils@2.8.2: 1064 | resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} 1065 | dependencies: 1066 | estree-walker: 0.6.1 1067 | dev: true 1068 | 1069 | /satori@0.10.11: 1070 | resolution: {integrity: sha512-yLm1xPRPZUaKcBZJ6nmezoJjHB4MqV8x7Mu0PyZUJodRWRDD27UbeMwzuY9LEGG57WYLO4CQsGPlbHWV1Ex9TQ==} 1071 | engines: {node: '>=16'} 1072 | dependencies: 1073 | '@shuding/opentype.js': 1.4.0-beta.0 1074 | css-background-parser: 0.1.0 1075 | css-box-shadow: 1.0.0-3 1076 | css-to-react-native: 3.2.0 1077 | emoji-regex: 10.3.0 1078 | escape-html: 1.0.3 1079 | linebreak: 1.1.0 1080 | parse-css-color: 0.2.1 1081 | postcss-value-parser: 4.2.0 1082 | yoga-wasm-web: 0.3.3 1083 | dev: false 1084 | 1085 | /satori@0.10.9: 1086 | resolution: {integrity: sha512-XU9EELUEZuioT4acLIpCXxHcFzrsC8muvg0MY28d+TlqwxbkTzBmWbw+3+hnCzXT7YZ0Qm8k3eXktDaEu+qmEw==} 1087 | engines: {node: '>=16'} 1088 | dependencies: 1089 | '@shuding/opentype.js': 1.4.0-beta.0 1090 | css-background-parser: 0.1.0 1091 | css-box-shadow: 1.0.0-3 1092 | css-to-react-native: 3.2.0 1093 | emoji-regex: 10.3.0 1094 | escape-html: 1.0.3 1095 | linebreak: 1.1.0 1096 | parse-css-color: 0.2.1 1097 | postcss-value-parser: 4.2.0 1098 | yoga-wasm-web: 0.3.3 1099 | dev: true 1100 | 1101 | /selfsigned@2.4.1: 1102 | resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} 1103 | engines: {node: '>=10'} 1104 | dependencies: 1105 | '@types/node-forge': 1.3.11 1106 | node-forge: 1.3.1 1107 | dev: true 1108 | 1109 | /source-map@0.6.1: 1110 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 1111 | engines: {node: '>=0.10.0'} 1112 | dev: true 1113 | 1114 | /sourcemap-codec@1.4.8: 1115 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} 1116 | deprecated: Please use @jridgewell/sourcemap-codec instead 1117 | dev: true 1118 | 1119 | /stacktracey@2.1.8: 1120 | resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} 1121 | dependencies: 1122 | as-table: 1.0.55 1123 | get-source: 2.0.12 1124 | dev: true 1125 | 1126 | /stoppable@1.1.0: 1127 | resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} 1128 | engines: {node: '>=4', npm: '>=6'} 1129 | dev: true 1130 | 1131 | /string.prototype.codepointat@0.2.1: 1132 | resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==} 1133 | 1134 | /supports-color@7.2.0: 1135 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1136 | engines: {node: '>=8'} 1137 | dependencies: 1138 | has-flag: 4.0.0 1139 | dev: true 1140 | 1141 | /tiny-inflate@1.0.3: 1142 | resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} 1143 | 1144 | /to-regex-range@5.0.1: 1145 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1146 | engines: {node: '>=8.0'} 1147 | dependencies: 1148 | is-number: 7.0.0 1149 | dev: true 1150 | 1151 | /tslib@2.6.2: 1152 | resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} 1153 | dev: true 1154 | 1155 | /typescript@5.3.3: 1156 | resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} 1157 | engines: {node: '>=14.17'} 1158 | hasBin: true 1159 | dev: true 1160 | 1161 | /undici-types@5.26.5: 1162 | resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} 1163 | dev: true 1164 | 1165 | /undici@5.28.2: 1166 | resolution: {integrity: sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==} 1167 | engines: {node: '>=14.0'} 1168 | dependencies: 1169 | '@fastify/busboy': 2.1.0 1170 | dev: true 1171 | 1172 | /unicode-trie@2.0.0: 1173 | resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} 1174 | dependencies: 1175 | pako: 0.2.9 1176 | tiny-inflate: 1.0.3 1177 | 1178 | /workerd@1.20231218.0: 1179 | resolution: {integrity: sha512-AGIsDvqCrcwhoA9kb1hxOhVAe53/xJeaGZxL4FbYI9FvO17DZwrnqGq+6eqItJ6Cfw1ZLmf3BM+QdMWaL2bFWQ==} 1180 | engines: {node: '>=16'} 1181 | hasBin: true 1182 | requiresBuild: true 1183 | optionalDependencies: 1184 | '@cloudflare/workerd-darwin-64': 1.20231218.0 1185 | '@cloudflare/workerd-darwin-arm64': 1.20231218.0 1186 | '@cloudflare/workerd-linux-64': 1.20231218.0 1187 | '@cloudflare/workerd-linux-arm64': 1.20231218.0 1188 | '@cloudflare/workerd-windows-64': 1.20231218.0 1189 | dev: true 1190 | 1191 | /wrangler@3.22.4: 1192 | resolution: {integrity: sha512-AhqraOHTcIV9rrm0z5tlxFDhx+l+O6g4QnKL08J1wnLg3mdvTWwMm5QmhxN0JQ0YgS2jgRCwg0PR+Fa5cumP8A==} 1193 | engines: {node: '>=16.17.0'} 1194 | hasBin: true 1195 | dependencies: 1196 | '@cloudflare/kv-asset-handler': 0.2.0 1197 | '@cspotcode/source-map-support': 0.8.1 1198 | '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) 1199 | '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) 1200 | blake3-wasm: 2.1.5 1201 | chokidar: 3.5.3 1202 | esbuild: 0.17.19 1203 | miniflare: 3.20231218.1 1204 | nanoid: 3.3.7 1205 | path-to-regexp: 6.2.1 1206 | resolve.exports: 2.0.2 1207 | selfsigned: 2.4.1 1208 | source-map: 0.6.1 1209 | xxhash-wasm: 1.0.2 1210 | optionalDependencies: 1211 | fsevents: 2.3.3 1212 | transitivePeerDependencies: 1213 | - bufferutil 1214 | - supports-color 1215 | - utf-8-validate 1216 | dev: true 1217 | 1218 | /ws@8.16.0: 1219 | resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} 1220 | engines: {node: '>=10.0.0'} 1221 | peerDependencies: 1222 | bufferutil: ^4.0.1 1223 | utf-8-validate: '>=5.0.2' 1224 | peerDependenciesMeta: 1225 | bufferutil: 1226 | optional: true 1227 | utf-8-validate: 1228 | optional: true 1229 | dev: true 1230 | 1231 | /xxhash-wasm@1.0.2: 1232 | resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==} 1233 | dev: true 1234 | 1235 | /yoga-wasm-web@0.3.3: 1236 | resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==} 1237 | 1238 | /youch@3.3.3: 1239 | resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} 1240 | dependencies: 1241 | cookie: 0.5.0 1242 | mustache: 4.2.0 1243 | stacktracey: 2.1.8 1244 | dev: true 1245 | 1246 | /zod@3.22.4: 1247 | resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} 1248 | dev: true 1249 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/*" 3 | --------------------------------------------------------------------------------