├── .eslintrc.js ├── .gitignore ├── LICENSE ├── README.md ├── bin ├── cli.js └── deploy.js ├── docs └── integration-with-aircode.md ├── package.json ├── pnpm-lock.yaml ├── public ├── app.client.js ├── index.html └── style.css ├── src ├── faas-builder │ └── index.js ├── index.js ├── runtime │ ├── file-service.js │ └── index.js └── utils.js ├── test ├── .files │ └── 00d44100-0c3c-49b8-a747-24cecc8582fb │ │ └── pp0i65qn.css ├── README.md ├── abc.js ├── aircode.config.json ├── dbs.mjs ├── dbs2.mjs ├── def.cjs ├── delete.js ├── download.js ├── file.js ├── foo.mjs ├── hello.js ├── index.js ├── kkk.js ├── package.json ├── test.json ├── test.mjs ├── tt.ts └── upload.js └── tsconfig.json /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es2021": true, 6 | node: true, 7 | }, 8 | "extends": "eslint:recommended", 9 | "overrides": [ 10 | { 11 | "env": { 12 | "node": true 13 | }, 14 | "files": [ 15 | ".eslintrc.{js,cjs}" 16 | ], 17 | "parserOptions": { 18 | "sourceType": "script" 19 | } 20 | } 21 | ], 22 | "parserOptions": { 23 | "ecmaVersion": "latest", 24 | "sourceType": "module", 25 | }, 26 | "rules": { 27 | semi: 'error', 28 | complexity: ['warn', 25], 29 | 'no-var': 'error', 30 | 'no-unused-vars': 'warn', 31 | 'no-restricted-globals': 'off', 32 | 'max-params': ['warn', 7], 33 | 'no-console': 'warn', 34 | 'no-new-func': 'off', 35 | 'import/no-named-as-default': 'off', 36 | 'import/no-named-as-default-member': 'off', 37 | 'no-return-await': 'off', 38 | }, 39 | }; 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log* 3 | package-lock.json 4 | .nyc_*/ 5 | .dir-locals.el 6 | .DS_Store 7 | .test 8 | .db 9 | .meta -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 月影 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hydrogen 2 | 3 | 4 | 5 | The serverless framework creates web servers that can run anywhere. 6 | 7 | ## Features 8 | 9 | - 🐇 Rapid development with Hot Module Replacement (HMR) 🔥 10 | - 📦 Supports CommonJS (.js .cjs), ES modules (.mjs), and TypeScript (.ts) functions out of the box. 11 | - 🧸 Requires almost zero configurations. 12 | - 🗄️ Comes with a built-in, ready-to-use text database and file API. 13 | - 📁 Follows intuitive directory structure conventions. 14 | - 🤏 Written in Pure JavaScript with a sleek and minimalist design. 15 | - ⚡️ Optimized for runtime performance, regardless of development or production environments. 16 | - 🧊 Compatible and capable of running your app seamlessly on the AirCode platform. 17 | 18 | ## Getting Started 19 | 20 | 1. Create an aircode app 21 | 22 | ```bash 23 | npx create-aircode-app@latest my-aircode-app && cd my-aircode-app 24 | ``` 25 | 26 | 2. Install dependencies and run 27 | 28 | ```bash 29 | npm i && npm start 30 | ``` 31 | 32 | ## Directory Structure 33 | 34 | The default project directory structure is very simple. 35 | 36 | ```bash 37 | ├──functions # put your function api here. 38 | │ └── hello.js # http://localhost:3000/hello 39 | ├──public # put your static resources here. 40 | │ └── favicon.ico # http://localhost:3000/public/favicon.ico 41 | └── package.json 42 | ``` 43 | 44 | ## Build Cloud Functions 45 | 46 | You can easily build your function api in `./functions` directory. 47 | 48 | 1. With `*.js` or `*.cjs` 49 | 50 | ```js 51 | // myfun.js 52 | const aircode = require('aircode'); 53 | 54 | module.exports = async function(params, context) { 55 | console.log('Received params:', params); 56 | return { 57 | message: 'Hi, AirCode.' 58 | }; 59 | } 60 | ``` 61 | 62 | 2. Or with `*.mjs` 63 | 64 | ```js 65 | import aircode from 'aircode'; 66 | 67 | export default async function (params, context) { 68 | console.log('Received params:', params); 69 | return { 70 | message: 'Hi, AirCode.', 71 | }; 72 | }; 73 | ``` 74 | 75 | 3. Or with `*.ts` 76 | 77 | ```js 78 | import aircode from 'aircode'; 79 | 80 | export default async function (params: any, context: any) { 81 | console.log('Received params:', params); 82 | return { 83 | message: 'Hi, AirCode.', 84 | }; 85 | }; 86 | ``` 87 | 88 | Simply visit your built functions with `http://localhost:3000/`. 89 | 90 | And visit your static resources with `http://localhost:3000/public/`. 91 | 92 | ## Documentation 93 | 94 | - [Cloud Function](https://docs.aircode.io/guide/functions/) 95 | - [The Database](https://docs.aircode.io/guide/database/) 96 | - [The File API](https://docs.aircode.io/guide/files/) 97 | 98 | ## Configurations 99 | 100 | There are a few options that you can pass through process.env. 101 | 102 | ```js 103 | process.env.AC_FAAS_ROOT = process.env.AC_FAAS_ROOT || 'functions'; 104 | process.env.AC_PUBLIC_DIR = process.env.AC_PUBLIC_DIR || 'public'; 105 | process.env.AC_PORT = process.env.AC_PORT || 3000; 106 | ``` 107 | 108 | ## Integration 109 | 110 | [Integration Hydrogen with AirCode online](docs/integration-with-aircode.md) 111 | 112 | -------------------------------------------------------------------------------- /bin/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const fs = require('node:fs'); 4 | const path = require('node:path'); 5 | const command = process.argv[2]; 6 | 7 | process.env.AC_FAAS_ROOT = process.env.AC_FAAS_ROOT || 'functions'; 8 | process.env.AC_PUBLIC_DIR = process.env.AC_PUBLIC_DIR || 'public'; 9 | 10 | const template = `// @see https://docs.aircode.io/guide/functions/ 11 | const aircode = require('aircode'); 12 | 13 | module.exports = async function (params, context) { 14 | console.log('Received params:', params); 15 | return { 16 | message: 'Hi, AirCode.', 17 | }; 18 | }; 19 | `; 20 | 21 | if(command === '--init') { 22 | if(!fs.existsSync(process.env.AC_FAAS_ROOT)) { 23 | fs.mkdirSync(process.env.AC_FAAS_ROOT); 24 | const helloFile = path.join(process.env.AC_FAAS_ROOT, 'hello.js'); 25 | fs.writeFileSync(helloFile, template); 26 | } 27 | if(!fs.existsSync(process.env.AC_PUBLIC_DIR)) { 28 | fs.mkdirSync(process.env.AC_PUBLIC_DIR); 29 | } 30 | } 31 | 32 | const {start, file} = require('../src/index.js'); 33 | 34 | const app = start(); 35 | 36 | if(fs.existsSync(file('hello.js')) || fs.existsSync(file('hello.cjs')) || fs.existsSync(file('hello.mjs'))) { 37 | require('open')(`http://localhost:${app.PORT}/hello`); 38 | } 39 | -------------------------------------------------------------------------------- /bin/deploy.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const path = require('path'); 3 | const fs = require('fs'); 4 | 5 | const root = path.resolve('.', process.env.AC_FAAS_ROOT); 6 | const packageJSONPath = path.resolve('.', 'package.json'); 7 | 8 | const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath)); 9 | 10 | const dependencies = packageJSON.dependencies; 11 | delete dependencies['@aircodelabs/hydrogen']; 12 | dependencies['aircode'] = 'latest'; 13 | 14 | const destPackageJSONPath = path.resolve(root, 'package.json'); 15 | fs.writeFileSync(destPackageJSONPath, JSON.stringify({dependencies}, null, 2)); 16 | 17 | const isTypeScript = fs.existsSync(path.resolve('.', 'tsconfig.json')); 18 | 19 | const aircodeConfig = `{ 20 | "name": "${packageJSON.name}", 21 | "runtime": "node/v16", 22 | "timeout": 60, 23 | "region": "US", 24 | "envs": [], 25 | "typescript": ${isTypeScript} 26 | }`; 27 | 28 | fs.writeFileSync(path.resolve(root, 'aircode.config.json'), aircodeConfig); 29 | 30 | if(packageJSON.repository && packageJSON.repository.type === 'git') { 31 | let repository = packageJSON.repository.url; 32 | if(repository.startsWith('git+')) { 33 | repository = repository.substring(4); 34 | } 35 | if(repository.startsWith('https://github.com/')) { 36 | repository = repository.replace('https://github.com/', ''); 37 | } 38 | const parts = repository.split('/'); 39 | const owner = parts[0]; 40 | const repo = parts[1].replace('.git', ''); 41 | const deployUrl = `https://aircode.io/dashboard?owner=${owner}&repo=${repo}&branch=main&path=${process.env.AC_FAAS_ROOT}&appname=${packageJSON.name}`; 42 | 43 | const readmeTpl = `# ${packageJSON.name} 44 | 45 | ${packageJSON.name} github repo deploy to [AirCode](https://aircode.io). 46 | 47 | ## One-Click Deployment 48 | 49 | [](${deployUrl}) 50 | `; 51 | 52 | const readmePath = path.resolve(root, 'README.md'); 53 | if(!fs.existsSync(readmePath)) { 54 | fs.writeFileSync(readmePath, readmeTpl); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /docs/integration-with-aircode.md: -------------------------------------------------------------------------------- 1 | # Integrate Hydrogen with AirCode online 2 | 3 | Hydrogen and AirCode are highly compatible, making it easy to run the AirCode project locally using Hydrogen, and vice versa. 4 | 5 | ## Run AirCode Project with Hydrogen 6 | 7 | 1. Login to [AirCode dashboard](https://aircode.io/dashboard). Select your project or create a new one. 8 | 9 | 10 | 11 | 2. Deploy your project. 12 | 13 | 14 | 15 | 3. Click `Publish to GitHub` 16 | 17 | 18 | 19 | 20 | 21 | 3. Clone the GitHub repository code to your local machine. 22 | 23 | 4. Navigate to the local project directory. 24 | 25 | ```bash 26 | cd my-repo-dir/examples/test-project 27 | ``` 28 | 29 | 5. Run `npx create-aircode-app` 30 | 31 | ```bash 32 | npx create-aircode-app@latest 33 | ``` 34 | 35 | ```bash 36 | Updated aircode app in current directory. 37 | To get started, run the following commands: 38 | npm install 39 | npm start 40 | ``` 41 | 42 | 6. Install dependencies 43 | 44 | ```bash 45 | npm install 46 | ``` 47 | 48 | 7. Start the Hydrogen Server 49 | 50 | ```bash 51 | npm start 52 | ``` 53 | 54 | ## Deploy Hydrogen Project to AirCode 55 | 56 | If your project is created by `npx create-aircode-app@latest`, you can easily deploy your project to AirCode by the following steps: 57 | 58 | 1. Create a github repo, and set it into your `package.json` file, for example: 59 | 60 | ```json 61 | "repository": { 62 | "type": "git", 63 | "url": "git+https://github.com/akira-cn/aircode-app-example.git" 64 | }, 65 | ``` 66 | 67 | 2. Run `npm run deploy` to prepare the deploy info for AirCode. 68 | 69 | 3. Push your code to Github. 70 | 71 | 4. Visit your `functions/README.md`, Click the `Deploy` button to deploy your project to AirCode. 72 | 73 | 74 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@aircodelabs/hydrogen", 3 | "version": "0.7.0", 4 | "description": "", 5 | "main": "src/index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/AirCodeLabs/Hydrogen.git" 9 | }, 10 | "bin": { 11 | "run-aircode": "./bin/cli.js", 12 | "deploy-aircode": "./bin/deploy.js" 13 | }, 14 | "scripts": { 15 | "dev": "cross-env AC_FAAS_ROOT=test AC_PORT=3000 EXPRIMENTAL_ROUTE=1 node bin/cli.js", 16 | "deploy": "cross-env AC_FAAS_ROOT=test node bin/deploy.js", 17 | "test": "echo \"Error: no test specified\" && exit 1" 18 | }, 19 | "keywords": [], 20 | "author": "", 21 | "license": "MIT", 22 | "devDependencies": { 23 | "@types/node": "^20.4.5", 24 | "eslint": "^8.45.0" 25 | }, 26 | "dependencies": { 27 | "@koa/cors": "^4.0.0", 28 | "chokidar": "^3.5.3", 29 | "consola": "^3.2.3", 30 | "cookie": "^0.5.0", 31 | "cross-env": "^7.0.3", 32 | "esbuild": "^0.18.15", 33 | "koa": "^2.14.2", 34 | "koa-body": "^6.0.1", 35 | "koa-static": "^5.0.0", 36 | "mime": "^3.0.0", 37 | "module-alias": "^2.2.3", 38 | "node-fetch": "^2.6.12", 39 | "okeydb": "^0.1.1", 40 | "open": "^8.4.2" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | '@koa/bodyparser': 9 | specifier: ^5.0.0 10 | version: 5.0.0 11 | airdb-lite: 12 | specifier: ^0.4.0 13 | version: 0.4.0 14 | chokidar: 15 | specifier: ^3.5.3 16 | version: 3.5.3 17 | cross-env: 18 | specifier: ^7.0.3 19 | version: 7.0.3 20 | esbuild: 21 | specifier: ^0.18.15 22 | version: 0.18.15 23 | koa: 24 | specifier: ^2.14.2 25 | version: 2.14.2 26 | mime: 27 | specifier: ^3.0.0 28 | version: 3.0.0 29 | module-alias: 30 | specifier: ^2.2.3 31 | version: 2.2.3 32 | node-fetch: 33 | specifier: ^2.6.12 34 | version: 2.6.12 35 | open: 36 | specifier: ^8.4.2 37 | version: 8.4.2 38 | think-logger3: 39 | specifier: ^1.4.0 40 | version: 1.4.0 41 | 42 | devDependencies: 43 | eslint: 44 | specifier: ^8.45.0 45 | version: 8.45.0 46 | 47 | packages: 48 | 49 | /@aashutoshrathi/word-wrap@1.2.6: 50 | resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} 51 | engines: {node: '>=0.10.0'} 52 | 53 | /@esbuild/android-arm64@0.18.15: 54 | resolution: {integrity: sha512-NI/gnWcMl2kXt1HJKOn2H69SYn4YNheKo6NZt1hyfKWdMbaGadxjZIkcj4Gjk/WPxnbFXs9/3HjGHaknCqjrww==} 55 | engines: {node: '>=12'} 56 | cpu: [arm64] 57 | os: [android] 58 | requiresBuild: true 59 | dev: false 60 | optional: true 61 | 62 | /@esbuild/android-arm@0.18.15: 63 | resolution: {integrity: sha512-wlkQBWb79/jeEEoRmrxt/yhn5T1lU236OCNpnfRzaCJHZ/5gf82uYx1qmADTBWE0AR/v7FiozE1auk2riyQd3w==} 64 | engines: {node: '>=12'} 65 | cpu: [arm] 66 | os: [android] 67 | requiresBuild: true 68 | dev: false 69 | optional: true 70 | 71 | /@esbuild/android-x64@0.18.15: 72 | resolution: {integrity: sha512-FM9NQamSaEm/IZIhegF76aiLnng1kEsZl2eve/emxDeReVfRuRNmvT28l6hoFD9TsCxpK+i4v8LPpEj74T7yjA==} 73 | engines: {node: '>=12'} 74 | cpu: [x64] 75 | os: [android] 76 | requiresBuild: true 77 | dev: false 78 | optional: true 79 | 80 | /@esbuild/darwin-arm64@0.18.15: 81 | resolution: {integrity: sha512-XmrFwEOYauKte9QjS6hz60FpOCnw4zaPAb7XV7O4lx1r39XjJhTN7ZpXqJh4sN6q60zbP6QwAVVA8N/wUyBH/w==} 82 | engines: {node: '>=12'} 83 | cpu: [arm64] 84 | os: [darwin] 85 | requiresBuild: true 86 | dev: false 87 | optional: true 88 | 89 | /@esbuild/darwin-x64@0.18.15: 90 | resolution: {integrity: sha512-bMqBmpw1e//7Fh5GLetSZaeo9zSC4/CMtrVFdj+bqKPGJuKyfNJ5Nf2m3LknKZTS+Q4oyPiON+v3eaJ59sLB5A==} 91 | engines: {node: '>=12'} 92 | cpu: [x64] 93 | os: [darwin] 94 | requiresBuild: true 95 | dev: false 96 | optional: true 97 | 98 | /@esbuild/freebsd-arm64@0.18.15: 99 | resolution: {integrity: sha512-LoTK5N3bOmNI9zVLCeTgnk5Rk0WdUTrr9dyDAQGVMrNTh9EAPuNwSTCgaKOKiDpverOa0htPcO9NwslSE5xuLA==} 100 | engines: {node: '>=12'} 101 | cpu: [arm64] 102 | os: [freebsd] 103 | requiresBuild: true 104 | dev: false 105 | optional: true 106 | 107 | /@esbuild/freebsd-x64@0.18.15: 108 | resolution: {integrity: sha512-62jX5n30VzgrjAjOk5orYeHFq6sqjvsIj1QesXvn5OZtdt5Gdj0vUNJy9NIpjfdNdqr76jjtzBJKf+h2uzYuTQ==} 109 | engines: {node: '>=12'} 110 | cpu: [x64] 111 | os: [freebsd] 112 | requiresBuild: true 113 | dev: false 114 | optional: true 115 | 116 | /@esbuild/linux-arm64@0.18.15: 117 | resolution: {integrity: sha512-BWncQeuWDgYv0jTNzJjaNgleduV4tMbQjmk/zpPh/lUdMcNEAxy+jvneDJ6RJkrqloG7tB9S9rCrtfk/kuplsQ==} 118 | engines: {node: '>=12'} 119 | cpu: [arm64] 120 | os: [linux] 121 | requiresBuild: true 122 | dev: false 123 | optional: true 124 | 125 | /@esbuild/linux-arm@0.18.15: 126 | resolution: {integrity: sha512-dT4URUv6ir45ZkBqhwZwyFV6cH61k8MttIwhThp2BGiVtagYvCToF+Bggyx2VI57RG4Fbt21f9TmXaYx0DeUJg==} 127 | engines: {node: '>=12'} 128 | cpu: [arm] 129 | os: [linux] 130 | requiresBuild: true 131 | dev: false 132 | optional: true 133 | 134 | /@esbuild/linux-ia32@0.18.15: 135 | resolution: {integrity: sha512-JPXORvgHRHITqfms1dWT/GbEY89u848dC08o0yK3fNskhp0t2TuNUnsrrSgOdH28ceb1hJuwyr8R/1RnyPwocw==} 136 | engines: {node: '>=12'} 137 | cpu: [ia32] 138 | os: [linux] 139 | requiresBuild: true 140 | dev: false 141 | optional: true 142 | 143 | /@esbuild/linux-loong64@0.18.15: 144 | resolution: {integrity: sha512-kArPI0DopjJCEplsVj/H+2Qgzz7vdFSacHNsgoAKpPS6W/Ndh8Oe24HRDQ5QCu4jHgN6XOtfFfLpRx3TXv/mEg==} 145 | engines: {node: '>=12'} 146 | cpu: [loong64] 147 | os: [linux] 148 | requiresBuild: true 149 | dev: false 150 | optional: true 151 | 152 | /@esbuild/linux-mips64el@0.18.15: 153 | resolution: {integrity: sha512-b/tmngUfO02E00c1XnNTw/0DmloKjb6XQeqxaYuzGwHe0fHVgx5/D6CWi+XH1DvkszjBUkK9BX7n1ARTOst59w==} 154 | engines: {node: '>=12'} 155 | cpu: [mips64el] 156 | os: [linux] 157 | requiresBuild: true 158 | dev: false 159 | optional: true 160 | 161 | /@esbuild/linux-ppc64@0.18.15: 162 | resolution: {integrity: sha512-KXPY69MWw79QJkyvUYb2ex/OgnN/8N/Aw5UDPlgoRtoEfcBqfeLodPr42UojV3NdkoO4u10NXQdamWm1YEzSKw==} 163 | engines: {node: '>=12'} 164 | cpu: [ppc64] 165 | os: [linux] 166 | requiresBuild: true 167 | dev: false 168 | optional: true 169 | 170 | /@esbuild/linux-riscv64@0.18.15: 171 | resolution: {integrity: sha512-komK3NEAeeGRnvFEjX1SfVg6EmkfIi5aKzevdvJqMydYr9N+pRQK0PGJXk+bhoPZwOUgLO4l99FZmLGk/L1jWg==} 172 | engines: {node: '>=12'} 173 | cpu: [riscv64] 174 | os: [linux] 175 | requiresBuild: true 176 | dev: false 177 | optional: true 178 | 179 | /@esbuild/linux-s390x@0.18.15: 180 | resolution: {integrity: sha512-632T5Ts6gQ2WiMLWRRyeflPAm44u2E/s/TJvn+BP6M5mnHSk93cieaypj3VSMYO2ePTCRqAFXtuYi1yv8uZJNA==} 181 | engines: {node: '>=12'} 182 | cpu: [s390x] 183 | os: [linux] 184 | requiresBuild: true 185 | dev: false 186 | optional: true 187 | 188 | /@esbuild/linux-x64@0.18.15: 189 | resolution: {integrity: sha512-MsHtX0NgvRHsoOtYkuxyk4Vkmvk3PLRWfA4okK7c+6dT0Fu4SUqXAr9y4Q3d8vUf1VWWb6YutpL4XNe400iQ1g==} 190 | engines: {node: '>=12'} 191 | cpu: [x64] 192 | os: [linux] 193 | requiresBuild: true 194 | dev: false 195 | optional: true 196 | 197 | /@esbuild/netbsd-x64@0.18.15: 198 | resolution: {integrity: sha512-djST6s+jQiwxMIVQ5rlt24JFIAr4uwUnzceuFL7BQT4CbrRtqBPueS4GjXSiIpmwVri1Icj/9pFRJ7/aScvT+A==} 199 | engines: {node: '>=12'} 200 | cpu: [x64] 201 | os: [netbsd] 202 | requiresBuild: true 203 | dev: false 204 | optional: true 205 | 206 | /@esbuild/openbsd-x64@0.18.15: 207 | resolution: {integrity: sha512-naeRhUIvhsgeounjkF5mvrNAVMGAm6EJWiabskeE5yOeBbLp7T89tAEw0j5Jm/CZAwyLe3c67zyCWH6fsBLCpw==} 208 | engines: {node: '>=12'} 209 | cpu: [x64] 210 | os: [openbsd] 211 | requiresBuild: true 212 | dev: false 213 | optional: true 214 | 215 | /@esbuild/sunos-x64@0.18.15: 216 | resolution: {integrity: sha512-qkT2+WxyKbNIKV1AEhI8QiSIgTHMcRctzSaa/I3kVgMS5dl3fOeoqkb7pW76KwxHoriImhx7Mg3TwN/auMDsyQ==} 217 | engines: {node: '>=12'} 218 | cpu: [x64] 219 | os: [sunos] 220 | requiresBuild: true 221 | dev: false 222 | optional: true 223 | 224 | /@esbuild/win32-arm64@0.18.15: 225 | resolution: {integrity: sha512-HC4/feP+pB2Vb+cMPUjAnFyERs+HJN7E6KaeBlFdBv799MhD+aPJlfi/yk36SED58J9TPwI8MAcVpJgej4ud0A==} 226 | engines: {node: '>=12'} 227 | cpu: [arm64] 228 | os: [win32] 229 | requiresBuild: true 230 | dev: false 231 | optional: true 232 | 233 | /@esbuild/win32-ia32@0.18.15: 234 | resolution: {integrity: sha512-ovjwoRXI+gf52EVF60u9sSDj7myPixPxqzD5CmkEUmvs+W9Xd0iqISVBQn8xcx4ciIaIVlWCuTbYDOXOnOL44Q==} 235 | engines: {node: '>=12'} 236 | cpu: [ia32] 237 | os: [win32] 238 | requiresBuild: true 239 | dev: false 240 | optional: true 241 | 242 | /@esbuild/win32-x64@0.18.15: 243 | resolution: {integrity: sha512-imUxH9a3WJARyAvrG7srLyiK73XdX83NXQkjKvQ+7vPh3ZxoLrzvPkQKKw2DwZ+RV2ZB6vBfNHP8XScAmQC3aA==} 244 | engines: {node: '>=12'} 245 | cpu: [x64] 246 | os: [win32] 247 | requiresBuild: true 248 | dev: false 249 | optional: true 250 | 251 | /@eslint-community/eslint-utils@4.4.0(eslint@8.45.0): 252 | resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} 253 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 254 | peerDependencies: 255 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 256 | dependencies: 257 | eslint: 8.45.0 258 | eslint-visitor-keys: 3.4.1 259 | 260 | /@eslint-community/regexpp@4.5.1: 261 | resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} 262 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 263 | 264 | /@eslint/eslintrc@2.1.0: 265 | resolution: {integrity: sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==} 266 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 267 | dependencies: 268 | ajv: 6.12.6 269 | debug: 4.3.4 270 | espree: 9.6.1 271 | globals: 13.20.0 272 | ignore: 5.2.4 273 | import-fresh: 3.3.0 274 | js-yaml: 4.1.0 275 | minimatch: 3.1.2 276 | strip-json-comments: 3.1.1 277 | transitivePeerDependencies: 278 | - supports-color 279 | 280 | /@eslint/js@8.44.0: 281 | resolution: {integrity: sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==} 282 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 283 | 284 | /@humanwhocodes/config-array@0.11.10: 285 | resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} 286 | engines: {node: '>=10.10.0'} 287 | dependencies: 288 | '@humanwhocodes/object-schema': 1.2.1 289 | debug: 4.3.4 290 | minimatch: 3.1.2 291 | transitivePeerDependencies: 292 | - supports-color 293 | 294 | /@humanwhocodes/module-importer@1.0.1: 295 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} 296 | engines: {node: '>=12.22'} 297 | 298 | /@humanwhocodes/object-schema@1.2.1: 299 | resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} 300 | 301 | /@koa/bodyparser@5.0.0: 302 | resolution: {integrity: sha512-JEiZVe2e85qPOqA+Nw/SJC5fkFw3XSekh0RSoqz5F6lFYuhEspgqAb972rQRCJesv27QUsz96vU/Vb92wF1GUg==} 303 | engines: {node: '>= 16'} 304 | dependencies: 305 | co-body: 6.1.0 306 | lodash.merge: 4.6.2 307 | type-is: 1.6.18 308 | dev: false 309 | 310 | /@nodelib/fs.scandir@2.1.5: 311 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 312 | engines: {node: '>= 8'} 313 | dependencies: 314 | '@nodelib/fs.stat': 2.0.5 315 | run-parallel: 1.2.0 316 | 317 | /@nodelib/fs.stat@2.0.5: 318 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 319 | engines: {node: '>= 8'} 320 | 321 | /@nodelib/fs.walk@1.2.8: 322 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 323 | engines: {node: '>= 8'} 324 | dependencies: 325 | '@nodelib/fs.scandir': 2.1.5 326 | fastq: 1.15.0 327 | 328 | /accepts@1.3.8: 329 | resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} 330 | engines: {node: '>= 0.6'} 331 | dependencies: 332 | mime-types: 2.1.35 333 | negotiator: 0.6.3 334 | dev: false 335 | 336 | /acorn-jsx@5.3.2(acorn@8.10.0): 337 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 338 | peerDependencies: 339 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 340 | dependencies: 341 | acorn: 8.10.0 342 | 343 | /acorn@8.10.0: 344 | resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} 345 | engines: {node: '>=0.4.0'} 346 | hasBin: true 347 | 348 | /airdb-lite@0.4.0: 349 | resolution: {integrity: sha512-6YzkbukyhQGrs/T5eBVslbpoByqvQvzwduVuk9Nb+bJmA3zRQpRIpCRZjUB7zTDT/0xPKg23ZyUyTe3LmqyFZA==} 350 | dependencies: 351 | eslint: 8.45.0 352 | transitivePeerDependencies: 353 | - supports-color 354 | dev: false 355 | 356 | /ajv@6.12.6: 357 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 358 | dependencies: 359 | fast-deep-equal: 3.1.3 360 | fast-json-stable-stringify: 2.1.0 361 | json-schema-traverse: 0.4.1 362 | uri-js: 4.4.1 363 | 364 | /ansi-regex@5.0.1: 365 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 366 | engines: {node: '>=8'} 367 | 368 | /ansi-styles@4.3.0: 369 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 370 | engines: {node: '>=8'} 371 | dependencies: 372 | color-convert: 2.0.1 373 | 374 | /anymatch@3.1.3: 375 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 376 | engines: {node: '>= 8'} 377 | dependencies: 378 | normalize-path: 3.0.0 379 | picomatch: 2.3.1 380 | dev: false 381 | 382 | /argparse@2.0.1: 383 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 384 | 385 | /balanced-match@1.0.2: 386 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 387 | 388 | /binary-extensions@2.2.0: 389 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 390 | engines: {node: '>=8'} 391 | dev: false 392 | 393 | /brace-expansion@1.1.11: 394 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 395 | dependencies: 396 | balanced-match: 1.0.2 397 | concat-map: 0.0.1 398 | 399 | /braces@3.0.2: 400 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 401 | engines: {node: '>=8'} 402 | dependencies: 403 | fill-range: 7.0.1 404 | dev: false 405 | 406 | /bytes@3.1.2: 407 | resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} 408 | engines: {node: '>= 0.8'} 409 | dev: false 410 | 411 | /cache-content-type@1.0.1: 412 | resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==} 413 | engines: {node: '>= 6.0.0'} 414 | dependencies: 415 | mime-types: 2.1.35 416 | ylru: 1.3.2 417 | dev: false 418 | 419 | /call-bind@1.0.2: 420 | resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} 421 | dependencies: 422 | function-bind: 1.1.1 423 | get-intrinsic: 1.2.1 424 | dev: false 425 | 426 | /callsites@3.1.0: 427 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 428 | engines: {node: '>=6'} 429 | 430 | /chalk@4.1.2: 431 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 432 | engines: {node: '>=10'} 433 | dependencies: 434 | ansi-styles: 4.3.0 435 | supports-color: 7.2.0 436 | 437 | /chokidar@3.5.3: 438 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 439 | engines: {node: '>= 8.10.0'} 440 | dependencies: 441 | anymatch: 3.1.3 442 | braces: 3.0.2 443 | glob-parent: 5.1.2 444 | is-binary-path: 2.1.0 445 | is-glob: 4.0.3 446 | normalize-path: 3.0.0 447 | readdirp: 3.6.0 448 | optionalDependencies: 449 | fsevents: 2.3.2 450 | dev: false 451 | 452 | /co-body@6.1.0: 453 | resolution: {integrity: sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==} 454 | dependencies: 455 | inflation: 2.0.0 456 | qs: 6.11.2 457 | raw-body: 2.5.2 458 | type-is: 1.6.18 459 | dev: false 460 | 461 | /co@4.6.0: 462 | resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} 463 | engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} 464 | dev: false 465 | 466 | /color-convert@2.0.1: 467 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 468 | engines: {node: '>=7.0.0'} 469 | dependencies: 470 | color-name: 1.1.4 471 | 472 | /color-name@1.1.4: 473 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 474 | 475 | /concat-map@0.0.1: 476 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 477 | 478 | /content-disposition@0.5.4: 479 | resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} 480 | engines: {node: '>= 0.6'} 481 | dependencies: 482 | safe-buffer: 5.2.1 483 | dev: false 484 | 485 | /content-type@1.0.5: 486 | resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} 487 | engines: {node: '>= 0.6'} 488 | dev: false 489 | 490 | /cookies@0.8.0: 491 | resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} 492 | engines: {node: '>= 0.8'} 493 | dependencies: 494 | depd: 2.0.0 495 | keygrip: 1.1.0 496 | dev: false 497 | 498 | /cross-env@7.0.3: 499 | resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} 500 | engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} 501 | hasBin: true 502 | dependencies: 503 | cross-spawn: 7.0.3 504 | dev: false 505 | 506 | /cross-spawn@7.0.3: 507 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 508 | engines: {node: '>= 8'} 509 | dependencies: 510 | path-key: 3.1.1 511 | shebang-command: 2.0.0 512 | which: 2.0.2 513 | 514 | /date-format@4.0.14: 515 | resolution: {integrity: sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==} 516 | engines: {node: '>=4.0'} 517 | dev: false 518 | 519 | /debug@4.3.4: 520 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 521 | engines: {node: '>=6.0'} 522 | peerDependencies: 523 | supports-color: '*' 524 | peerDependenciesMeta: 525 | supports-color: 526 | optional: true 527 | dependencies: 528 | ms: 2.1.2 529 | 530 | /deep-equal@1.0.1: 531 | resolution: {integrity: sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==} 532 | dev: false 533 | 534 | /deep-is@0.1.4: 535 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 536 | 537 | /define-lazy-prop@2.0.0: 538 | resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} 539 | engines: {node: '>=8'} 540 | dev: false 541 | 542 | /delegates@1.0.0: 543 | resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} 544 | dev: false 545 | 546 | /depd@1.1.2: 547 | resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} 548 | engines: {node: '>= 0.6'} 549 | dev: false 550 | 551 | /depd@2.0.0: 552 | resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} 553 | engines: {node: '>= 0.8'} 554 | dev: false 555 | 556 | /destroy@1.2.0: 557 | resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} 558 | engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} 559 | dev: false 560 | 561 | /doctrine@3.0.0: 562 | resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} 563 | engines: {node: '>=6.0.0'} 564 | dependencies: 565 | esutils: 2.0.3 566 | 567 | /ee-first@1.1.1: 568 | resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} 569 | dev: false 570 | 571 | /encodeurl@1.0.2: 572 | resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} 573 | engines: {node: '>= 0.8'} 574 | dev: false 575 | 576 | /esbuild@0.18.15: 577 | resolution: {integrity: sha512-3WOOLhrvuTGPRzQPU6waSDWrDTnQriia72McWcn6UCi43GhCHrXH4S59hKMeez+IITmdUuUyvbU9JIp+t3xlPQ==} 578 | engines: {node: '>=12'} 579 | hasBin: true 580 | requiresBuild: true 581 | optionalDependencies: 582 | '@esbuild/android-arm': 0.18.15 583 | '@esbuild/android-arm64': 0.18.15 584 | '@esbuild/android-x64': 0.18.15 585 | '@esbuild/darwin-arm64': 0.18.15 586 | '@esbuild/darwin-x64': 0.18.15 587 | '@esbuild/freebsd-arm64': 0.18.15 588 | '@esbuild/freebsd-x64': 0.18.15 589 | '@esbuild/linux-arm': 0.18.15 590 | '@esbuild/linux-arm64': 0.18.15 591 | '@esbuild/linux-ia32': 0.18.15 592 | '@esbuild/linux-loong64': 0.18.15 593 | '@esbuild/linux-mips64el': 0.18.15 594 | '@esbuild/linux-ppc64': 0.18.15 595 | '@esbuild/linux-riscv64': 0.18.15 596 | '@esbuild/linux-s390x': 0.18.15 597 | '@esbuild/linux-x64': 0.18.15 598 | '@esbuild/netbsd-x64': 0.18.15 599 | '@esbuild/openbsd-x64': 0.18.15 600 | '@esbuild/sunos-x64': 0.18.15 601 | '@esbuild/win32-arm64': 0.18.15 602 | '@esbuild/win32-ia32': 0.18.15 603 | '@esbuild/win32-x64': 0.18.15 604 | dev: false 605 | 606 | /escape-html@1.0.3: 607 | resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} 608 | dev: false 609 | 610 | /escape-string-regexp@4.0.0: 611 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 612 | engines: {node: '>=10'} 613 | 614 | /eslint-scope@7.2.1: 615 | resolution: {integrity: sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==} 616 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 617 | dependencies: 618 | esrecurse: 4.3.0 619 | estraverse: 5.3.0 620 | 621 | /eslint-visitor-keys@3.4.1: 622 | resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} 623 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 624 | 625 | /eslint@8.45.0: 626 | resolution: {integrity: sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==} 627 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 628 | hasBin: true 629 | dependencies: 630 | '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) 631 | '@eslint-community/regexpp': 4.5.1 632 | '@eslint/eslintrc': 2.1.0 633 | '@eslint/js': 8.44.0 634 | '@humanwhocodes/config-array': 0.11.10 635 | '@humanwhocodes/module-importer': 1.0.1 636 | '@nodelib/fs.walk': 1.2.8 637 | ajv: 6.12.6 638 | chalk: 4.1.2 639 | cross-spawn: 7.0.3 640 | debug: 4.3.4 641 | doctrine: 3.0.0 642 | escape-string-regexp: 4.0.0 643 | eslint-scope: 7.2.1 644 | eslint-visitor-keys: 3.4.1 645 | espree: 9.6.1 646 | esquery: 1.5.0 647 | esutils: 2.0.3 648 | fast-deep-equal: 3.1.3 649 | file-entry-cache: 6.0.1 650 | find-up: 5.0.0 651 | glob-parent: 6.0.2 652 | globals: 13.20.0 653 | graphemer: 1.4.0 654 | ignore: 5.2.4 655 | imurmurhash: 0.1.4 656 | is-glob: 4.0.3 657 | is-path-inside: 3.0.3 658 | js-yaml: 4.1.0 659 | json-stable-stringify-without-jsonify: 1.0.1 660 | levn: 0.4.1 661 | lodash.merge: 4.6.2 662 | minimatch: 3.1.2 663 | natural-compare: 1.4.0 664 | optionator: 0.9.3 665 | strip-ansi: 6.0.1 666 | text-table: 0.2.0 667 | transitivePeerDependencies: 668 | - supports-color 669 | 670 | /espree@9.6.1: 671 | resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} 672 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 673 | dependencies: 674 | acorn: 8.10.0 675 | acorn-jsx: 5.3.2(acorn@8.10.0) 676 | eslint-visitor-keys: 3.4.1 677 | 678 | /esquery@1.5.0: 679 | resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} 680 | engines: {node: '>=0.10'} 681 | dependencies: 682 | estraverse: 5.3.0 683 | 684 | /esrecurse@4.3.0: 685 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 686 | engines: {node: '>=4.0'} 687 | dependencies: 688 | estraverse: 5.3.0 689 | 690 | /estraverse@5.3.0: 691 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 692 | engines: {node: '>=4.0'} 693 | 694 | /esutils@2.0.3: 695 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 696 | engines: {node: '>=0.10.0'} 697 | 698 | /fast-deep-equal@3.1.3: 699 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 700 | 701 | /fast-json-stable-stringify@2.1.0: 702 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 703 | 704 | /fast-levenshtein@2.0.6: 705 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 706 | 707 | /fastq@1.15.0: 708 | resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} 709 | dependencies: 710 | reusify: 1.0.4 711 | 712 | /file-entry-cache@6.0.1: 713 | resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} 714 | engines: {node: ^10.12.0 || >=12.0.0} 715 | dependencies: 716 | flat-cache: 3.0.4 717 | 718 | /fill-range@7.0.1: 719 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 720 | engines: {node: '>=8'} 721 | dependencies: 722 | to-regex-range: 5.0.1 723 | dev: false 724 | 725 | /find-up@5.0.0: 726 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 727 | engines: {node: '>=10'} 728 | dependencies: 729 | locate-path: 6.0.0 730 | path-exists: 4.0.0 731 | 732 | /flat-cache@3.0.4: 733 | resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} 734 | engines: {node: ^10.12.0 || >=12.0.0} 735 | dependencies: 736 | flatted: 3.2.7 737 | rimraf: 3.0.2 738 | 739 | /flatted@3.2.7: 740 | resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} 741 | 742 | /fresh@0.5.2: 743 | resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} 744 | engines: {node: '>= 0.6'} 745 | dev: false 746 | 747 | /fs-extra@8.1.0: 748 | resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} 749 | engines: {node: '>=6 <7 || >=8'} 750 | dependencies: 751 | graceful-fs: 4.2.11 752 | jsonfile: 4.0.0 753 | universalify: 0.1.2 754 | dev: false 755 | 756 | /fs.realpath@1.0.0: 757 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 758 | 759 | /fsevents@2.3.2: 760 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 761 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 762 | os: [darwin] 763 | requiresBuild: true 764 | dev: false 765 | optional: true 766 | 767 | /function-bind@1.1.1: 768 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 769 | dev: false 770 | 771 | /get-intrinsic@1.2.1: 772 | resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} 773 | dependencies: 774 | function-bind: 1.1.1 775 | has: 1.0.3 776 | has-proto: 1.0.1 777 | has-symbols: 1.0.3 778 | dev: false 779 | 780 | /glob-parent@5.1.2: 781 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 782 | engines: {node: '>= 6'} 783 | dependencies: 784 | is-glob: 4.0.3 785 | dev: false 786 | 787 | /glob-parent@6.0.2: 788 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 789 | engines: {node: '>=10.13.0'} 790 | dependencies: 791 | is-glob: 4.0.3 792 | 793 | /glob@7.2.3: 794 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 795 | dependencies: 796 | fs.realpath: 1.0.0 797 | inflight: 1.0.6 798 | inherits: 2.0.4 799 | minimatch: 3.1.2 800 | once: 1.4.0 801 | path-is-absolute: 1.0.1 802 | 803 | /globals@13.20.0: 804 | resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} 805 | engines: {node: '>=8'} 806 | dependencies: 807 | type-fest: 0.20.2 808 | 809 | /graceful-fs@4.2.11: 810 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 811 | dev: false 812 | 813 | /graphemer@1.4.0: 814 | resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} 815 | 816 | /has-flag@4.0.0: 817 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 818 | engines: {node: '>=8'} 819 | 820 | /has-proto@1.0.1: 821 | resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} 822 | engines: {node: '>= 0.4'} 823 | dev: false 824 | 825 | /has-symbols@1.0.3: 826 | resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} 827 | engines: {node: '>= 0.4'} 828 | dev: false 829 | 830 | /has-tostringtag@1.0.0: 831 | resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} 832 | engines: {node: '>= 0.4'} 833 | dependencies: 834 | has-symbols: 1.0.3 835 | dev: false 836 | 837 | /has@1.0.3: 838 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 839 | engines: {node: '>= 0.4.0'} 840 | dependencies: 841 | function-bind: 1.1.1 842 | dev: false 843 | 844 | /http-assert@1.5.0: 845 | resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==} 846 | engines: {node: '>= 0.8'} 847 | dependencies: 848 | deep-equal: 1.0.1 849 | http-errors: 1.8.1 850 | dev: false 851 | 852 | /http-errors@1.8.1: 853 | resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} 854 | engines: {node: '>= 0.6'} 855 | dependencies: 856 | depd: 1.1.2 857 | inherits: 2.0.4 858 | setprototypeof: 1.2.0 859 | statuses: 1.5.0 860 | toidentifier: 1.0.1 861 | dev: false 862 | 863 | /http-errors@2.0.0: 864 | resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} 865 | engines: {node: '>= 0.8'} 866 | dependencies: 867 | depd: 2.0.0 868 | inherits: 2.0.4 869 | setprototypeof: 1.2.0 870 | statuses: 2.0.1 871 | toidentifier: 1.0.1 872 | dev: false 873 | 874 | /iconv-lite@0.4.24: 875 | resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} 876 | engines: {node: '>=0.10.0'} 877 | dependencies: 878 | safer-buffer: 2.1.2 879 | dev: false 880 | 881 | /ignore@5.2.4: 882 | resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} 883 | engines: {node: '>= 4'} 884 | 885 | /import-fresh@3.3.0: 886 | resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} 887 | engines: {node: '>=6'} 888 | dependencies: 889 | parent-module: 1.0.1 890 | resolve-from: 4.0.0 891 | 892 | /imurmurhash@0.1.4: 893 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 894 | engines: {node: '>=0.8.19'} 895 | 896 | /inflation@2.0.0: 897 | resolution: {integrity: sha512-m3xv4hJYR2oXw4o4Y5l6P5P16WYmazYof+el6Al3f+YlggGj6qT9kImBAnzDelRALnP5d3h4jGBPKzYCizjZZw==} 898 | engines: {node: '>= 0.8.0'} 899 | dev: false 900 | 901 | /inflight@1.0.6: 902 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 903 | dependencies: 904 | once: 1.4.0 905 | wrappy: 1.0.2 906 | 907 | /inherits@2.0.4: 908 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 909 | 910 | /is-binary-path@2.1.0: 911 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 912 | engines: {node: '>=8'} 913 | dependencies: 914 | binary-extensions: 2.2.0 915 | dev: false 916 | 917 | /is-docker@2.2.1: 918 | resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} 919 | engines: {node: '>=8'} 920 | hasBin: true 921 | dev: false 922 | 923 | /is-extglob@2.1.1: 924 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 925 | engines: {node: '>=0.10.0'} 926 | 927 | /is-generator-function@1.0.10: 928 | resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} 929 | engines: {node: '>= 0.4'} 930 | dependencies: 931 | has-tostringtag: 1.0.0 932 | dev: false 933 | 934 | /is-glob@4.0.3: 935 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 936 | engines: {node: '>=0.10.0'} 937 | dependencies: 938 | is-extglob: 2.1.1 939 | 940 | /is-number@7.0.0: 941 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 942 | engines: {node: '>=0.12.0'} 943 | dev: false 944 | 945 | /is-path-inside@3.0.3: 946 | resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} 947 | engines: {node: '>=8'} 948 | 949 | /is-wsl@2.2.0: 950 | resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} 951 | engines: {node: '>=8'} 952 | dependencies: 953 | is-docker: 2.2.1 954 | dev: false 955 | 956 | /isexe@2.0.0: 957 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 958 | 959 | /js-yaml@4.1.0: 960 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 961 | hasBin: true 962 | dependencies: 963 | argparse: 2.0.1 964 | 965 | /json-schema-traverse@0.4.1: 966 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 967 | 968 | /json-stable-stringify-without-jsonify@1.0.1: 969 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 970 | 971 | /jsonfile@4.0.0: 972 | resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} 973 | optionalDependencies: 974 | graceful-fs: 4.2.11 975 | dev: false 976 | 977 | /keygrip@1.1.0: 978 | resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} 979 | engines: {node: '>= 0.6'} 980 | dependencies: 981 | tsscmp: 1.0.6 982 | dev: false 983 | 984 | /koa-compose@4.1.0: 985 | resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} 986 | dev: false 987 | 988 | /koa-convert@2.0.0: 989 | resolution: {integrity: sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==} 990 | engines: {node: '>= 10'} 991 | dependencies: 992 | co: 4.6.0 993 | koa-compose: 4.1.0 994 | dev: false 995 | 996 | /koa@2.14.2: 997 | resolution: {integrity: sha512-VFI2bpJaodz6P7x2uyLiX6RLYpZmOJqNmoCst/Yyd7hQlszyPwG/I9CQJ63nOtKSxpt5M7NH67V6nJL2BwCl7g==} 998 | engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} 999 | dependencies: 1000 | accepts: 1.3.8 1001 | cache-content-type: 1.0.1 1002 | content-disposition: 0.5.4 1003 | content-type: 1.0.5 1004 | cookies: 0.8.0 1005 | debug: 4.3.4 1006 | delegates: 1.0.0 1007 | depd: 2.0.0 1008 | destroy: 1.2.0 1009 | encodeurl: 1.0.2 1010 | escape-html: 1.0.3 1011 | fresh: 0.5.2 1012 | http-assert: 1.5.0 1013 | http-errors: 1.8.1 1014 | is-generator-function: 1.0.10 1015 | koa-compose: 4.1.0 1016 | koa-convert: 2.0.0 1017 | on-finished: 2.4.1 1018 | only: 0.0.2 1019 | parseurl: 1.3.3 1020 | statuses: 1.5.0 1021 | type-is: 1.6.18 1022 | vary: 1.1.2 1023 | transitivePeerDependencies: 1024 | - supports-color 1025 | dev: false 1026 | 1027 | /levn@0.4.1: 1028 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 1029 | engines: {node: '>= 0.8.0'} 1030 | dependencies: 1031 | prelude-ls: 1.2.1 1032 | type-check: 0.4.0 1033 | 1034 | /locate-path@6.0.0: 1035 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 1036 | engines: {node: '>=10'} 1037 | dependencies: 1038 | p-locate: 5.0.0 1039 | 1040 | /lodash.merge@4.6.2: 1041 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 1042 | 1043 | /log4js@6.9.1: 1044 | resolution: {integrity: sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==} 1045 | engines: {node: '>=8.0'} 1046 | dependencies: 1047 | date-format: 4.0.14 1048 | debug: 4.3.4 1049 | flatted: 3.2.7 1050 | rfdc: 1.3.0 1051 | streamroller: 3.1.5 1052 | transitivePeerDependencies: 1053 | - supports-color 1054 | dev: false 1055 | 1056 | /media-typer@0.3.0: 1057 | resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} 1058 | engines: {node: '>= 0.6'} 1059 | dev: false 1060 | 1061 | /mime-db@1.52.0: 1062 | resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} 1063 | engines: {node: '>= 0.6'} 1064 | dev: false 1065 | 1066 | /mime-types@2.1.35: 1067 | resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} 1068 | engines: {node: '>= 0.6'} 1069 | dependencies: 1070 | mime-db: 1.52.0 1071 | dev: false 1072 | 1073 | /mime@3.0.0: 1074 | resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} 1075 | engines: {node: '>=10.0.0'} 1076 | hasBin: true 1077 | dev: false 1078 | 1079 | /minimatch@3.1.2: 1080 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 1081 | dependencies: 1082 | brace-expansion: 1.1.11 1083 | 1084 | /module-alias@2.2.3: 1085 | resolution: {integrity: sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==} 1086 | dev: false 1087 | 1088 | /ms@2.1.2: 1089 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 1090 | 1091 | /natural-compare@1.4.0: 1092 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 1093 | 1094 | /negotiator@0.6.3: 1095 | resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} 1096 | engines: {node: '>= 0.6'} 1097 | dev: false 1098 | 1099 | /node-fetch@2.6.12: 1100 | resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==} 1101 | engines: {node: 4.x || >=6.0.0} 1102 | peerDependencies: 1103 | encoding: ^0.1.0 1104 | peerDependenciesMeta: 1105 | encoding: 1106 | optional: true 1107 | dependencies: 1108 | whatwg-url: 5.0.0 1109 | dev: false 1110 | 1111 | /normalize-path@3.0.0: 1112 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 1113 | engines: {node: '>=0.10.0'} 1114 | dev: false 1115 | 1116 | /object-inspect@1.12.3: 1117 | resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} 1118 | dev: false 1119 | 1120 | /on-finished@2.4.1: 1121 | resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} 1122 | engines: {node: '>= 0.8'} 1123 | dependencies: 1124 | ee-first: 1.1.1 1125 | dev: false 1126 | 1127 | /once@1.4.0: 1128 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 1129 | dependencies: 1130 | wrappy: 1.0.2 1131 | 1132 | /only@0.0.2: 1133 | resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==} 1134 | dev: false 1135 | 1136 | /open@8.4.2: 1137 | resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} 1138 | engines: {node: '>=12'} 1139 | dependencies: 1140 | define-lazy-prop: 2.0.0 1141 | is-docker: 2.2.1 1142 | is-wsl: 2.2.0 1143 | dev: false 1144 | 1145 | /optionator@0.9.3: 1146 | resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} 1147 | engines: {node: '>= 0.8.0'} 1148 | dependencies: 1149 | '@aashutoshrathi/word-wrap': 1.2.6 1150 | deep-is: 0.1.4 1151 | fast-levenshtein: 2.0.6 1152 | levn: 0.4.1 1153 | prelude-ls: 1.2.1 1154 | type-check: 0.4.0 1155 | 1156 | /p-limit@3.1.0: 1157 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 1158 | engines: {node: '>=10'} 1159 | dependencies: 1160 | yocto-queue: 0.1.0 1161 | 1162 | /p-locate@5.0.0: 1163 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 1164 | engines: {node: '>=10'} 1165 | dependencies: 1166 | p-limit: 3.1.0 1167 | 1168 | /parent-module@1.0.1: 1169 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 1170 | engines: {node: '>=6'} 1171 | dependencies: 1172 | callsites: 3.1.0 1173 | 1174 | /parseurl@1.3.3: 1175 | resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} 1176 | engines: {node: '>= 0.8'} 1177 | dev: false 1178 | 1179 | /path-exists@4.0.0: 1180 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 1181 | engines: {node: '>=8'} 1182 | 1183 | /path-is-absolute@1.0.1: 1184 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 1185 | engines: {node: '>=0.10.0'} 1186 | 1187 | /path-key@3.1.1: 1188 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 1189 | engines: {node: '>=8'} 1190 | 1191 | /picomatch@2.3.1: 1192 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1193 | engines: {node: '>=8.6'} 1194 | dev: false 1195 | 1196 | /prelude-ls@1.2.1: 1197 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 1198 | engines: {node: '>= 0.8.0'} 1199 | 1200 | /punycode@2.3.0: 1201 | resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} 1202 | engines: {node: '>=6'} 1203 | 1204 | /qs@6.11.2: 1205 | resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} 1206 | engines: {node: '>=0.6'} 1207 | dependencies: 1208 | side-channel: 1.0.4 1209 | dev: false 1210 | 1211 | /queue-microtask@1.2.3: 1212 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 1213 | 1214 | /raw-body@2.5.2: 1215 | resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} 1216 | engines: {node: '>= 0.8'} 1217 | dependencies: 1218 | bytes: 3.1.2 1219 | http-errors: 2.0.0 1220 | iconv-lite: 0.4.24 1221 | unpipe: 1.0.0 1222 | dev: false 1223 | 1224 | /readdirp@3.6.0: 1225 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 1226 | engines: {node: '>=8.10.0'} 1227 | dependencies: 1228 | picomatch: 2.3.1 1229 | dev: false 1230 | 1231 | /resolve-from@4.0.0: 1232 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 1233 | engines: {node: '>=4'} 1234 | 1235 | /reusify@1.0.4: 1236 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1237 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1238 | 1239 | /rfdc@1.3.0: 1240 | resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} 1241 | dev: false 1242 | 1243 | /rimraf@3.0.2: 1244 | resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} 1245 | hasBin: true 1246 | dependencies: 1247 | glob: 7.2.3 1248 | 1249 | /run-parallel@1.2.0: 1250 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1251 | dependencies: 1252 | queue-microtask: 1.2.3 1253 | 1254 | /safe-buffer@5.2.1: 1255 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 1256 | dev: false 1257 | 1258 | /safer-buffer@2.1.2: 1259 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 1260 | dev: false 1261 | 1262 | /setprototypeof@1.2.0: 1263 | resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} 1264 | dev: false 1265 | 1266 | /shebang-command@2.0.0: 1267 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1268 | engines: {node: '>=8'} 1269 | dependencies: 1270 | shebang-regex: 3.0.0 1271 | 1272 | /shebang-regex@3.0.0: 1273 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1274 | engines: {node: '>=8'} 1275 | 1276 | /side-channel@1.0.4: 1277 | resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} 1278 | dependencies: 1279 | call-bind: 1.0.2 1280 | get-intrinsic: 1.2.1 1281 | object-inspect: 1.12.3 1282 | dev: false 1283 | 1284 | /statuses@1.5.0: 1285 | resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} 1286 | engines: {node: '>= 0.6'} 1287 | dev: false 1288 | 1289 | /statuses@2.0.1: 1290 | resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} 1291 | engines: {node: '>= 0.8'} 1292 | dev: false 1293 | 1294 | /streamroller@3.1.5: 1295 | resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} 1296 | engines: {node: '>=8.0'} 1297 | dependencies: 1298 | date-format: 4.0.14 1299 | debug: 4.3.4 1300 | fs-extra: 8.1.0 1301 | transitivePeerDependencies: 1302 | - supports-color 1303 | dev: false 1304 | 1305 | /strip-ansi@6.0.1: 1306 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1307 | engines: {node: '>=8'} 1308 | dependencies: 1309 | ansi-regex: 5.0.1 1310 | 1311 | /strip-json-comments@3.1.1: 1312 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 1313 | engines: {node: '>=8'} 1314 | 1315 | /supports-color@7.2.0: 1316 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1317 | engines: {node: '>=8'} 1318 | dependencies: 1319 | has-flag: 4.0.0 1320 | 1321 | /text-table@0.2.0: 1322 | resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} 1323 | 1324 | /think-logger3@1.4.0: 1325 | resolution: {integrity: sha512-JySaFRc08BUvOHwB10Rt6qK4TRGpwmdJXxp5lPCS2rjZHmD9I6ko2jNK7q0H3yxmqNSJBcBwXz7TR5ypk003jQ==} 1326 | dependencies: 1327 | log4js: 6.9.1 1328 | transitivePeerDependencies: 1329 | - supports-color 1330 | dev: false 1331 | 1332 | /to-regex-range@5.0.1: 1333 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1334 | engines: {node: '>=8.0'} 1335 | dependencies: 1336 | is-number: 7.0.0 1337 | dev: false 1338 | 1339 | /toidentifier@1.0.1: 1340 | resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} 1341 | engines: {node: '>=0.6'} 1342 | dev: false 1343 | 1344 | /tr46@0.0.3: 1345 | resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} 1346 | dev: false 1347 | 1348 | /tsscmp@1.0.6: 1349 | resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} 1350 | engines: {node: '>=0.6.x'} 1351 | dev: false 1352 | 1353 | /type-check@0.4.0: 1354 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 1355 | engines: {node: '>= 0.8.0'} 1356 | dependencies: 1357 | prelude-ls: 1.2.1 1358 | 1359 | /type-fest@0.20.2: 1360 | resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} 1361 | engines: {node: '>=10'} 1362 | 1363 | /type-is@1.6.18: 1364 | resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} 1365 | engines: {node: '>= 0.6'} 1366 | dependencies: 1367 | media-typer: 0.3.0 1368 | mime-types: 2.1.35 1369 | dev: false 1370 | 1371 | /universalify@0.1.2: 1372 | resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} 1373 | engines: {node: '>= 4.0.0'} 1374 | dev: false 1375 | 1376 | /unpipe@1.0.0: 1377 | resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} 1378 | engines: {node: '>= 0.8'} 1379 | dev: false 1380 | 1381 | /uri-js@4.4.1: 1382 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 1383 | dependencies: 1384 | punycode: 2.3.0 1385 | 1386 | /vary@1.1.2: 1387 | resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} 1388 | engines: {node: '>= 0.8'} 1389 | dev: false 1390 | 1391 | /webidl-conversions@3.0.1: 1392 | resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} 1393 | dev: false 1394 | 1395 | /whatwg-url@5.0.0: 1396 | resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} 1397 | dependencies: 1398 | tr46: 0.0.3 1399 | webidl-conversions: 3.0.1 1400 | dev: false 1401 | 1402 | /which@2.0.2: 1403 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1404 | engines: {node: '>= 8'} 1405 | hasBin: true 1406 | dependencies: 1407 | isexe: 2.0.0 1408 | 1409 | /wrappy@1.0.2: 1410 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1411 | 1412 | /ylru@1.3.2: 1413 | resolution: {integrity: sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA==} 1414 | engines: {node: '>= 4.0.0'} 1415 | dev: false 1416 | 1417 | /yocto-queue@0.1.0: 1418 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 1419 | engines: {node: '>=10'} 1420 | -------------------------------------------------------------------------------- /public/app.client.js: -------------------------------------------------------------------------------- 1 | const dragArea = document.querySelector('.drag-area'); 2 | const fileName = document.querySelector('.file-name'); 3 | const uploadResult = document.querySelector('.upload-result'); 4 | 5 | let fileToUpload = null; 6 | 7 | dragArea.addEventListener('dragover', (event) => { 8 | event.preventDefault(); 9 | dragArea.classList.add('active'); 10 | }); 11 | 12 | dragArea.addEventListener('dragleave', (event) => { 13 | event.preventDefault(); 14 | dragArea.classList.remove('active'); 15 | }); 16 | 17 | dragArea.addEventListener('drop', (event) => { 18 | event.preventDefault(); 19 | dragArea.classList.remove('active'); 20 | const file = event.dataTransfer.files[0]; 21 | if (!file) return; 22 | fileName.textContent = file.name; 23 | fileToUpload = file; 24 | }); 25 | 26 | fileInput.addEventListener('change', (event) => { 27 | event.preventDefault(); 28 | const file = event.target.files.item(0); 29 | if (!file) return; 30 | fileName.textContent = file.name; 31 | fileToUpload = file; 32 | }); 33 | 34 | submitBtn.addEventListener('click', async (event) => { 35 | if(!fileToUpload) return; 36 | console.log('uploading', fileToUpload); 37 | await uploadFile(fileToUpload); 38 | }); 39 | 40 | async function uploadFile(file) { 41 | const formData = new FormData(); 42 | formData.append('myFile', file, file.name.replace(/[\u4e00-\u9fa5\s]/g, '')); 43 | formData.append('name', 'myFile'); 44 | const result = await (await fetch('http://localhost:3000/file', { 45 | method: 'POST', 46 | body: formData, 47 | // headers: { 48 | // "Accept-Encoding": "UTF-8", 49 | // }, 50 | })).json(); 51 | if(!result.error) { 52 | const resultDiv = document.createElement('div'); 53 | resultDiv.innerHTML = `${result.url}copy`; 54 | if(uploadResult.children[0]) { 55 | uploadResult.insertBefore(resultDiv, uploadResult.children[0]); 56 | } else { 57 | uploadResult.appendChild(resultDiv); 58 | } 59 | } else { 60 | const errorDiv = document.createElement('div'); 61 | errorDiv.className = 'error'; 62 | errorDiv.textContent = result.message; 63 | if(uploadResult.children[0]) { 64 | uploadResult.insertBefore(errorDiv, uploadResult.children[0]); 65 | } else { 66 | uploadResult.appendChild(errorDiv); 67 | } 68 | } 69 | // console.log(result); 70 | } 71 | 72 | uploadResult.addEventListener('click', async (event) => { 73 | if(event.target.className === 'copy') { 74 | const text = event.target.parentNode.children[0].textContent; 75 | await navigator.clipboard.writeText(text); 76 | console.log(text); 77 | } 78 | }); 79 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | {{ fileName }} 15 | 16 | 将文件拖拽至此,或 17 | 点此选择要上传的文件 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /public/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-size: 14px; 3 | } 4 | .drag-area { 5 | width: 90vw; 6 | border: dashed 1px gray; 7 | color: #777; 8 | margin: 20px auto; 9 | height: 40vh; 10 | max-height: 450px; 11 | } 12 | .drag-area.active { 13 | color:red; 14 | border-color:red; 15 | } 16 | .footer { 17 | float: right; 18 | margin-right: 5vw; 19 | } 20 | .uploader-tips { 21 | text-align: center; 22 | height: 200px; 23 | line-height: 200px; 24 | } 25 | .file-name { 26 | text-align: center; 27 | height: 200px; 28 | line-height: 200px; 29 | } 30 | .upload-result { 31 | margin-top: 60px; 32 | margin-left: 5vw; 33 | } 34 | .upload-result .error { 35 | color: red; 36 | } 37 | .upload-result .copy { 38 | margin-left: 10px; 39 | } -------------------------------------------------------------------------------- /src/faas-builder/index.js: -------------------------------------------------------------------------------- 1 | const path = require('node:path'); 2 | const fs = require('node:fs'); 3 | 4 | const esbuild = require('esbuild'); 5 | 6 | const { consola:logger } = require("consola"); 7 | 8 | const modules = new Set(); 9 | 10 | let isESMProject = false; 11 | if(fs.existsSync('./package.json')) { 12 | const pkg = require(path.resolve('.', 'package.json')); 13 | isESMProject = pkg.type === 'module'; 14 | } 15 | 16 | function isModule(filepath) { 17 | return filepath.endsWith('.mjs') || filepath.endsWith('.ts') || isESMProject && filepath.endsWith('.js'); 18 | } 19 | 20 | function moduleRequire(filepath) { 21 | modules.add(filepath); 22 | if(isModule(filepath)) { 23 | const outfile = filepath.replace(/\.(mjs|ts|js)$/, '.cjs'); 24 | if(fs.existsSync(outfile)) { 25 | throw new Error(`File ${outfile} already exists.`); 26 | } 27 | const options = { 28 | entryPoints: [filepath], 29 | bundle: true, 30 | platform: 'node', 31 | outfile, 32 | external: ['aircode', 'node:*'], 33 | }; 34 | if(filepath.endsWith('.ts')) { 35 | options.loader = { 36 | '.ts': 'ts', 37 | }; 38 | // const config = path.resolve('.', 'tsconfig.json'); 39 | // if(fs.existsSync(config)) { 40 | // options['tsconfig-raw'] = new Function(`return ${fs.readFileSync(config, 'utf-8')}`)(); 41 | // } 42 | } 43 | esbuild.buildSync(options); 44 | let ret = null; 45 | try { 46 | ret = require(outfile); 47 | } catch(ex) { 48 | logger.error(ex); 49 | } finally { 50 | fs.unlinkSync(outfile); 51 | } 52 | return ret; 53 | } else { 54 | return require(filepath); 55 | } 56 | } 57 | 58 | function clearRequireCache() { 59 | for(let module of modules) { 60 | if(isModule(module)) { 61 | module = module.replace(/\.(mjs|ts|js)$/, '.cjs'); 62 | } 63 | delete require.cache[module]; 64 | } 65 | } 66 | 67 | function reloadAllModules() { 68 | for(const module of modules) { 69 | moduleRequire(module); 70 | } 71 | } 72 | 73 | function file(faas) { 74 | return path.resolve('.', process.env.AC_FAAS_ROOT, faas); 75 | } 76 | 77 | function build(root = 'src') { 78 | const dir = path.resolve('.', root); 79 | const chokidar = require('chokidar'); 80 | chokidar.watch(dir, { 81 | ignored: [/node_modules\//, /\.client\.(mjs|cjs|js|ts)$/, /\.db$/, /\.meta$/, /\.files$/, /\.db\//, /\.files\//, /\.meta\//], 82 | }).on('all', (event, filepath) => { 83 | // logger.info(`${event}: ${filepath}`); 84 | if(filepath.endsWith('.js') || filepath.endsWith('.cjs') 85 | || filepath.endsWith('.mjs') || filepath.endsWith('.ts')) { 86 | if(event === 'add' || event === 'change') { 87 | // logger.info(`[${event}] ${filepath}`); 88 | try { 89 | if(modules.has(filepath)) { 90 | // reload all modules 91 | clearRequireCache(); 92 | reloadAllModules(); 93 | } else { 94 | moduleRequire(filepath); 95 | } 96 | } catch (ex) { 97 | // logger.error(ex.message); 98 | let modulePath = filepath; 99 | if(isModule(filepath)) { 100 | modulePath = filepath.replace(/\.(mjs|ts)$/, '.cjs'); 101 | } 102 | require.cache[modulePath] = async () => {return {error: ex.message};}; 103 | } 104 | } else if(event === 'unlink') { 105 | let modulePath = filepath; 106 | if(isModule(filepath)) { 107 | modulePath = filepath.replace(/\.(mjs|ts)$/, '.cjs'); 108 | } 109 | delete require.cache[modulePath]; 110 | } 111 | } 112 | }); 113 | } 114 | 115 | function requireModule(faas) { 116 | const faasname = file(faas); 117 | let module = faasname; 118 | if(!require.cache[module]) { 119 | module = `${faasname}.js`; 120 | } 121 | if(!require.cache[module]) { 122 | module = `${faasname}.cjs`; 123 | } 124 | try { 125 | return require(module); 126 | } catch (ex) { 127 | return require.cache[module]; 128 | } 129 | } 130 | 131 | module.exports = { 132 | file, 133 | build, 134 | requireModule, 135 | }; 136 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const path = require('node:path'); 2 | const fs = require('node:fs'); 3 | const Koa = require('koa'); 4 | const mime = require('mime'); 5 | 6 | const cors = require('@koa/cors'); 7 | 8 | const { koaBody } = require('koa-body'); 9 | const serve = require('koa-static'); 10 | 11 | const cookie = require('cookie'); 12 | 13 | const { build, file, requireModule } = require('./faas-builder'); 14 | 15 | const { consola:logger } = require("consola"); 16 | const { colors } = require('consola/utils'); 17 | 18 | const _symbolReceivedTime = Symbol('request-received.startTime'); 19 | 20 | const app = new Koa(); 21 | app.use(cors()); 22 | app.use(async (ctx, next) => { 23 | logger.info(`${colors.gray('<==')} ${ctx.method} ${ctx.url}`); 24 | ctx[_symbolReceivedTime] = Date.now(); 25 | await next(); 26 | }); 27 | app.use(koaBody({ 28 | multipart: true, 29 | jsonLimit: '4.5mb', 30 | formLimit: '4.5mb', 31 | textLimit: '4.5mb', 32 | formidable: { 33 | maxFileSize: 4.5 * 1024 * 1024, // 设置上传文件大小最大限制,默认2M 34 | }, 35 | })); 36 | 37 | if(fs.existsSync('./.aircoderc.js')) { 38 | require(path.resolve('.', '.aircoderc.js')); 39 | } 40 | 41 | process.env.AC_APP_ID = process.env.AC_APP_ID || 'aircode-hydrogen'; 42 | process.env.AC_MEMORY_SIZE = process.env.AC_MEMORY_SIZE || '1024'; 43 | process.env.AC_EXECUTION_TIMEOUT =process.env.AC_EXECUTION_TIMEOUT || 60; 44 | process.env.AC_DEPLOYMENT_VERSION = -1; 45 | process.env.AC_REGION = process.env.AC_REGION || 'local'; 46 | process.env.AC_NODE_JS_VERSION = process.version.match(/^v(\d+\.\d+)/)[1]; 47 | process.env.AC_FAAS_ROOT = process.env.AC_FAAS_ROOT || 'functions'; 48 | process.env.AC_PUBLIC_DIR = process.env.AC_PUBLIC_DIR || 'public'; 49 | if(process.env.AC_EXPOSE_CONFIG !== false) process.env.AC_EXPOSE_CONFIG = true; 50 | 51 | build(process.env.AC_FAAS_ROOT); 52 | 53 | const moduleAlias = require('module-alias'); 54 | moduleAlias.addAliases({ 55 | 'aircode': path.resolve(__dirname, 'runtime'), 56 | }); 57 | 58 | require('aircode'); // for cache 59 | 60 | // public dir 61 | app.use(async (ctx, next) => { 62 | if(ctx.url.slice(1).startsWith(`${process.env.AC_PUBLIC_DIR}/`)) 63 | await serve('.')(ctx, next); 64 | else 65 | await next(); 66 | }); 67 | 68 | // json/yaml/yml 69 | if(process.env.AC_EXPOSE_CONFIG) { 70 | app.use(async (ctx, next) => { 71 | const ext = path.extname(ctx.url); 72 | 73 | if (['.json', '.yaml', '.yml', '.ico'].includes(ext)) { 74 | logger.info(`response ${ext} file`); 75 | const faas = ctx.request.path.slice(1) || 'index'; 76 | const filepath = file(faas); 77 | logger.info(`sendFile filepath: ${filepath}`); 78 | const mimetype = mime.getType(filepath); 79 | ctx.set('Content-type', mimetype); 80 | ctx.body = fs.readFileSync(filepath, 'utf-8'); 81 | return; 82 | } 83 | 84 | await next(); 85 | }); 86 | } 87 | 88 | // patch files to body 89 | app.use(async (ctx, next) => { 90 | const files = ctx.request.files; 91 | if(files) { 92 | for(const [key, file] of Object.entries(files)) { 93 | ctx.request.body[key] = file; 94 | Object.defineProperties(file, { 95 | buffer: { 96 | get() { 97 | if(!this._buffer) { 98 | const filepath = this.filepath; 99 | this._buffer = fs.readFileSync(filepath); 100 | } 101 | return this._buffer; 102 | }, 103 | enumerable: true, 104 | }, 105 | name: { 106 | get() { 107 | return this.originalFilename; 108 | }, 109 | enumerable: true, 110 | }, 111 | type: { 112 | get() { 113 | return this.mimetype; 114 | }, 115 | enumerable: true, 116 | }, 117 | }); 118 | } 119 | } 120 | await next(); 121 | }); 122 | 123 | // response 124 | app.use(async (ctx, next) => { 125 | const {method} = ctx.request; 126 | const params = method === 'GET' ? ctx.request.query : ctx.request.body; 127 | const context = { 128 | headers: ctx.request.headers, 129 | method, 130 | query: ctx.request.query, 131 | tirgger: 'HTTP', 132 | set: (field, value) => ctx.set(field, value), 133 | remove: (field) => ctx.remove(field), 134 | status: (code) => { 135 | if(code) ctx.response.status = code; 136 | return ctx.response.status; 137 | }, 138 | redirect: (url, code = 302) => { 139 | ctx.status = code; 140 | return ctx.redirect(url); 141 | }, 142 | cookie: (name, value, options) => { 143 | ctx.cookies.set(name, value, options); 144 | }, 145 | clearCookie: (name) => { 146 | ctx.cookies.set(name, '', { expires: new Date(1) }); 147 | }, 148 | url: ctx.request.url, 149 | path: ctx.request.path, 150 | host: ctx.request.host, 151 | protocol: ctx.protocol, 152 | cookies: cookie.parse(ctx.request.headers.cookie || ''), 153 | }; 154 | 155 | Object.defineProperties(context, { 156 | req: { 157 | get() { 158 | return ctx.req; 159 | } 160 | }, 161 | res: { 162 | get() { 163 | return ctx.res; 164 | } 165 | }, 166 | request: { 167 | get() { 168 | return ctx.req; 169 | } 170 | }, 171 | response: { 172 | get() { 173 | return ctx.res; 174 | } 175 | }, 176 | }); 177 | const faas = ctx.request.path.slice(1) || 'index'; 178 | // console.log(faas); 179 | if(faas && !faas.startsWith('.')) { 180 | try { 181 | let module; 182 | if(process.env.EXPRIMENTAL_ROUTE) { 183 | const paths = faas.split('/'); 184 | for(let i = 1; i <= paths.length; i++) { 185 | const name = paths.slice(0, i).join('/'); 186 | module = requireModule(name); 187 | if(module) { 188 | let route = `/${paths.slice(i).join('/')}`; 189 | if (route === '/') { 190 | route = ''; 191 | } 192 | logger.info(`Route ${colors.gray('>>')} ${name} ${colors.gray('|')} ${route}`); 193 | if(route) context.route = route; 194 | break; 195 | } 196 | } 197 | } else { 198 | module = requireModule(faas); 199 | } 200 | if(module && typeof module !== 'function' && typeof module.default === 'function') { 201 | module = module.default; 202 | } 203 | if(typeof module === 'function') { 204 | try { 205 | ctx.body = await module(params, context); 206 | } catch(ex) { 207 | ctx.status = 500; 208 | logger.error(ex); 209 | } 210 | } else { 211 | ctx.status = 500; 212 | ctx.body = `Module ${faas} is not callable.`; 213 | } 214 | } catch (ex) { 215 | // do nothing 216 | } 217 | } else if(faas.startsWith('.files/')) { 218 | const filepath = file(faas); 219 | // console.log(filepath); 220 | if(fs.existsSync(filepath)) { 221 | const filestream = fs.createReadStream(filepath); 222 | // const filename = path.basename(filepath); 223 | // ctx.set('Content-disposition', 'attachment; filename=' + filename); 224 | const mimetype = mime.getType(filepath); 225 | ctx.set('Content-type', mimetype); 226 | ctx.body = filestream; 227 | } else { 228 | ctx.body = '404 Not Found File.'; 229 | } 230 | } else { 231 | ctx.body = '404 Not Found.'; 232 | } 233 | await next(); 234 | }); 235 | 236 | app.use(async (ctx) => { 237 | logger.info(`${colors.gray('==>')} ${ctx.method} ${ctx.url} ${ctx.response.status} ${Date.now() - ctx[_symbolReceivedTime]}ms`); 238 | }); 239 | 240 | function start(port = process.env.AC_PORT || 3000) { 241 | app.listen(port); 242 | app.PORT = port; 243 | logger.info(`Server running at http://127.0.0.1:${port}`); 244 | logger.info(`Public root: `); 245 | logger.info(`FaaS root: ${process.env.AC_FAAS_ROOT}`); 246 | return app; 247 | } 248 | 249 | module.exports = { 250 | start, 251 | file, 252 | }; 253 | -------------------------------------------------------------------------------- /src/runtime/file-service.js: -------------------------------------------------------------------------------- 1 | const path = require('node:path'); 2 | const fs = require('node:fs'); 3 | const { pathToFileURL, fileURLToPath } = require('node:url'); 4 | const fetch = require('node-fetch'); 5 | const {generateID} = require('../utils'); 6 | const mime = require('mime'); 7 | const { file } = require('../faas-builder'); 8 | 9 | function randomString(length = 8) { 10 | return Math.random().toString(36).substring(2, length + 2); 11 | } 12 | 13 | function createFilePath(name, type) { 14 | const basedir = path.resolve('.', process.env.AC_FAAS_ROOT, '.files'); 15 | const dir = generateID(); 16 | const ext = mime.getExtension(type); 17 | const filename = name || `${randomString()}.${ext}`; 18 | 19 | return path.join(basedir, dir, filename); 20 | } 21 | 22 | module.exports = class { 23 | constructor(table) { 24 | this.table = table; 25 | } 26 | 27 | async upload(content, name = null, options = {}) { 28 | let filepath = createFilePath(name, options.type); 29 | const dir = path.dirname(filepath); 30 | if(!fs.existsSync(dir)) { 31 | fs.mkdirSync(dir, { recursive: true }); 32 | } 33 | if(typeof content === 'string') { 34 | fs.writeFileSync(filepath, content, { encoding: 'utf-8' }); 35 | } else if(content instanceof Buffer) { 36 | fs.writeFileSync(filepath, content); 37 | } else if(content instanceof fs.ReadStream) { 38 | const filestream = fs.createWriteStream(filepath); 39 | content.pipe(filestream); 40 | } else if(content.url) { 41 | const res = await fetch(content.url); 42 | if(!name && !options.type) { 43 | const type = res.headers.get('content-type'); 44 | const ext = mime.getExtension(type); 45 | filepath = path.resolve(dir, `${randomString()}.${ext}`); 46 | } 47 | const data = await res.buffer(); 48 | fs.writeFileSync(filepath, data); 49 | } 50 | const relativePath = path.relative(path.resolve(process.env.AC_FAAS_ROOT), filepath); 51 | const url = pathToFileURL(path.join('/', relativePath)).toString().replace('file://', ''); 52 | const additions = options.additions || {}; 53 | const data = { 54 | url, 55 | name: path.basename(filepath), 56 | type: options.type || mime.getType(filepath), 57 | size: fs.statSync(filepath).size, 58 | ...additions, 59 | }; 60 | 61 | return await this.table.save(data); 62 | } 63 | 64 | async download(condition, options = {}) { 65 | const type = options.dateType || 'string'; 66 | const onProgress = options.onProgress; 67 | const fileRecord = await this.table.where(condition).findOne(); 68 | 69 | if(fileRecord) { 70 | const filepath = file(fileRecord.url.slice(1)); 71 | // console.log('filepath', filepath); 72 | 73 | const filestream = fs.createReadStream(filepath); 74 | const totalSize = fileRecord.size; 75 | let currentSize = 0; 76 | 77 | if(onProgress) { 78 | filestream.on('data', (chunk) => { 79 | currentSize += chunk.length; 80 | const percentage = Math.round(currentSize / totalSize * 100); 81 | const remainSize = totalSize - currentSize; 82 | onProgress(percentage, remainSize); 83 | }); 84 | } 85 | 86 | if(type === 'stream') { 87 | return filestream; 88 | } else if(type === 'string' || type === 'buffer') { 89 | return new Promise((resolve, reject) => { 90 | const chunks = []; 91 | filestream.on('data', (chunk) => chunks.push(chunk)); 92 | filestream.on('end', () => resolve(type === 'string' ? Buffer.concat(chunks).toString('utf-8') : Buffer.concat(chunks))); 93 | filestream.on('error', (err) => reject(err)); 94 | }); 95 | } 96 | } 97 | } 98 | 99 | async delete(condition = {}) { 100 | const fileRecord = await this.table.where(condition).findOne(); 101 | if(fileRecord) { 102 | let filepath = fileURLToPath(`file://${fileRecord.url}`); 103 | filepath = path.resolve(process.env.AC_FAAS_ROOT, filepath.slice(1)); 104 | fs.unlinkSync(filepath); 105 | fs.rmSync(path.dirname(filepath), { recursive: true }); 106 | return await this.table.where({_id: fileRecord._id}).delete(); 107 | } 108 | return null; 109 | } 110 | }; -------------------------------------------------------------------------------- /src/runtime/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { OkeyDB } = require('okeydb'); 3 | 4 | const FileService = require('./file-service'); 5 | 6 | const db = new OkeyDB({ 7 | root: path.join(process.env.AC_FAAS_ROOT, '.db'), 8 | meta: path.join(process.env.AC_FAAS_ROOT, '.meta'), 9 | }); 10 | 11 | const files = new FileService(db.table('_files')); 12 | 13 | module.exports = { 14 | db, 15 | files, 16 | }; 17 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | const { randomUUID } = require('node:crypto'); 2 | 3 | function generateID() { 4 | return randomUUID({ disableEntropyCache: true }); 5 | } 6 | 7 | module.exports = { 8 | generateID, 9 | }; -------------------------------------------------------------------------------- /test/.files/00d44100-0c3c-49b8-a747-24cecc8582fb/pp0i65qn.css: -------------------------------------------------------------------------------- 1 | pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! 2 | Theme: GitHub 3 | Description: Light theme as seen on github.com 4 | Author: github.com 5 | Maintainer: @Hirse 6 | Updated: 2021-05-15 7 | 8 | Outdated base version: https://github.com/primer/github-syntax-light 9 | Current colors taken from GitHub's CSS 10 | */.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0} -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # @aircodelabs/hydrogen 2 | 3 | @aircodelabs/hydrogen github repo deploy to [AirCode](https://aircode.io). 4 | 5 | ## One-Click Deployment 6 | 7 | [](https://aircode.io/dashboard?owner=AirCodeLabs&repo=Hydrogen&branch=main&path=test&appname=@aircodelabs/hydrogen) 8 | -------------------------------------------------------------------------------- /test/abc.js: -------------------------------------------------------------------------------- 1 | module.exports = async (params, context) => { 2 | context.set('content-type', 'application/json'); 3 | context.status(400); 4 | return { 5 | all: 423, 6 | params, 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /test/aircode.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@aircodelabs/hydrogen", 3 | "runtime": "node/v16", 4 | "timeout": 60, 5 | "region": "US", 6 | "envs": [], 7 | "typescript": true 8 | } -------------------------------------------------------------------------------- /test/dbs.mjs: -------------------------------------------------------------------------------- 1 | import aircode from 'aircode'; 2 | 3 | export default async function() { 4 | const dbs = aircode.db.table('persons'); 5 | await dbs.save({name: 'yvo'}); 6 | const query = dbs.where(); 7 | console.log('query start'); 8 | const result = await query.find(); 9 | console.log('query end'); 10 | return { 11 | result, 12 | }; 13 | } -------------------------------------------------------------------------------- /test/dbs2.mjs: -------------------------------------------------------------------------------- 1 | import aircode from 'aircode'; 2 | 3 | export default async function() { 4 | return { 5 | err: 'ok', 6 | }; 7 | } -------------------------------------------------------------------------------- /test/def.cjs: -------------------------------------------------------------------------------- 1 | // @see https://docs.aircode.io/guide/functions/ 2 | const aircode = require('aircode'); 3 | 4 | module.exports = async function (params, context) { 5 | console.log('Received params:', params); 6 | throw new Error('def'); 7 | return { 8 | message: 'Hi, AirCode. ~~', 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /test/delete.js: -------------------------------------------------------------------------------- 1 | const aircode = require('aircode'); 2 | 3 | module.exports = async (params, context) => { 4 | context.set('content-type', 'application/json'); 5 | const _id = params._id; 6 | const res = await aircode.files.delete( 7 | {_id}, 8 | ); 9 | 10 | return { 11 | res, 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /test/download.js: -------------------------------------------------------------------------------- 1 | const aircode = require('aircode'); 2 | 3 | module.exports = async (params, context) => { 4 | context.set('content-type', 'application/json'); 5 | const file = await aircode.files.download( 6 | {url : '/.files/00d44100-0c3c-49b8-a747-24cecc8582fb/pp0i65qn.css'}, 7 | ); 8 | 9 | return { 10 | file, 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /test/file.js: -------------------------------------------------------------------------------- 1 | module.exports = async (params, context) => { 2 | context.set('content-type', 'application/json'); 3 | console.log(params.myFile.buffer); 4 | // console.log(context.req.files); 5 | return { 6 | all: 423, 7 | params, 8 | }; 9 | }; -------------------------------------------------------------------------------- /test/foo.mjs: -------------------------------------------------------------------------------- 1 | export const all = 42; 2 | 3 | // throw new Error('abc'); -------------------------------------------------------------------------------- /test/hello.js: -------------------------------------------------------------------------------- 1 | // @see https://docs.aircode.io/guide/functions/ 2 | const aircode = require('aircode'); 3 | 4 | module.exports = async function (params, context) { 5 | console.log('Received params:', params); 6 | // console.log(context.req); 7 | // console.log(context); 8 | return { 9 | cookies: context.cookies, 10 | message: 'Hi, AirCode.', 11 | route: context.route, 12 | context, 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | // @see https://docs.aircode.io/guide/functions/ 2 | const aircode = require('aircode'); 3 | 4 | module.exports = async function (params, context) { 5 | console.log('Received params:', params); 6 | console.log(context); 7 | return { 8 | message: 'Hi, AirCode.', 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /test/kkk.js: -------------------------------------------------------------------------------- 1 | module.exports = {all: 42}; -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "airdb-lite": "^0.4.0", 4 | "chokidar": "^3.5.3", 5 | "consola": "^3.2.3", 6 | "cookie": "^0.5.0", 7 | "cross-env": "^7.0.3", 8 | "esbuild": "^0.18.15", 9 | "koa": "^2.14.2", 10 | "koa-body": "^6.0.1", 11 | "koa-static": "^5.0.0", 12 | "mime": "^3.0.0", 13 | "module-alias": "^2.2.3", 14 | "node-fetch": "^2.6.12", 15 | "open": "^8.4.2", 16 | "aircode": "latest" 17 | } 18 | } -------------------------------------------------------------------------------- /test/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "all": 42 3 | } -------------------------------------------------------------------------------- /test/test.mjs: -------------------------------------------------------------------------------- 1 | // @see https://docs.aircode.io/guide/functions/ 2 | import aircode from 'aircode'; 3 | import {all} from './foo.mjs'; 4 | 5 | export default async function (params, context) { 6 | console.log('Received params:', params); 7 | return { 8 | message: 'Hi, AirCode.2', 9 | all, 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /test/tt.ts: -------------------------------------------------------------------------------- 1 | // @see https://docs.aircode.io/guide/functions/ 2 | import aircode from 'aircode'; 3 | 4 | export default async function (params: any, context: any) { 5 | console.log('Received params:', params); 6 | return { 7 | message: 'Hi, AirCode.', 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /test/upload.js: -------------------------------------------------------------------------------- 1 | const aircode = require('aircode'); 2 | 3 | module.exports = async (params, context) => { 4 | context.set('content-type', 'application/json'); 5 | const file = await aircode.files.upload( 6 | // 'Hello World', 7 | // 'hello.txt', 8 | {url : 'https://unpkg.com/highlight.js@11.8.0/styles/github.css'}, 9 | null, 10 | { 11 | // type: 'text/plain', 12 | additions: { 13 | owner: 'Micheal' 14 | } 15 | } 16 | ); 17 | 18 | return { 19 | file, 20 | }; 21 | }; 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 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": "ES6", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "ES2020", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | "types": ["node"], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "resolveJsonModule": true, /* Enable importing .json files. */ 39 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 40 | 41 | /* JavaScript Support */ 42 | "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 43 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 44 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 45 | 46 | /* Emit */ 47 | "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 48 | "declarationDir": "./dist/@types", 49 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 50 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 51 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 52 | // "outFile": "./", /* 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. */ 53 | "outDir": "./dist", /* Specify an output folder for all emitted files. */ 54 | // "removeComments": true, /* Disable emitting comments. */ 55 | // "noEmit": true, /* Disable emitting files from a compilation. */ 56 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 57 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 58 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 59 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 60 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 61 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 62 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 63 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 64 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 65 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 66 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 67 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 68 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 69 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 70 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 71 | 72 | /* Interop Constraints */ 73 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 74 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 75 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 76 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 77 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 78 | 79 | /* Type Checking */ 80 | "strict": true, /* Enable all strict type-checking options. */ 81 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 82 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 83 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 84 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 85 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 86 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 87 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 88 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 89 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 90 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 91 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 92 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 93 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 94 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 95 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 96 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 97 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 98 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 99 | 100 | /* Completeness */ 101 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 102 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 103 | }, 104 | "include": [ 105 | "test", 106 | ], 107 | "exclude": [ 108 | "node_modules", 109 | "dist", 110 | "tests", 111 | ] 112 | } 113 | --------------------------------------------------------------------------------