├── .github └── workflows │ └── playwright.yml ├── .gitignore ├── LICENSE ├── README.md ├── assets ├── html-report.png └── playwright-odottaa.png ├── db.json ├── global-setup.ts ├── package-lock.json ├── package.json ├── playwright.config.ts ├── server └── index.js └── tests └── posts.api.spec.ts /.github/workflows/playwright.yml: -------------------------------------------------------------------------------- 1 | name: Playwright API Tests 2 | 3 | on: 4 | push: 5 | branches: [ main, gh-pages ] 6 | pull_request: 7 | branches: [ main, gh-pages ] 8 | jobs: 9 | test: 10 | timeout-minutes: 5 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | with: 15 | fetch-depth: 0 16 | - uses: actions/setup-node@v2 17 | with: 18 | node-version: '14.x' 19 | 20 | - name: Install dependencies 21 | run: npm ci 22 | 23 | - name: Install Playwright 24 | run: npx playwright install-deps 25 | 26 | - name: Run Playwright API tests 27 | run: npm test 28 | 29 | - name: Upload test results 30 | if: always() 31 | uses: actions/upload-artifact@v2 32 | with: 33 | name: playwright-results 34 | path: playwright-report 35 | 36 | - name: Commit report to gh-pages branch 37 | run: | 38 | git config --global user.name 'Yevhen Laichenkov' 39 | git config --global user.email 'elaichenkov@gmail.com' 40 | git checkout gh-pages 41 | git pull 42 | mv playwright-report/index.html ./index.html 43 | git add ./index.html 44 | git commit -m "update playwright API tests report" 45 | git push origin gh-pages 46 | git checkout main -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | # Playwright 107 | playwright-report/ 108 | 109 | # VSCode 110 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Yevhen Laichenkov 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

An example of how to set up and run API tests with Playwright and odottaa

3 | sloth 9 |
10 | 11 | --- 12 | [![test](https://github.com/elaichenkov/playwright-api-testing-example/actions/workflows/playwright.yml/badge.svg)](https://github.com/elaichenkov/playwright-api-testing-example/actions/workflows/playwright.yml) 13 | 14 | Read my article about [API testing with Playwright & odottaa](https://elaichenkov.medium.com/api-testing-with-playwright-odottaa-77451917342f). 15 | 16 | Check out the [HTML report](https://elaichenkov.github.io/playwright-api-testing-example) that was published on GitHub pages. 17 | 18 | ## Usage 19 | 20 | Clone the repository and run the following command: 21 | 22 | ```sh 23 | npm install 24 | ``` 25 | 26 | ## Run tests 27 | 28 | ```sh 29 | npm test 30 | ``` 31 | 32 | Then, to open report run the following command: 33 | 34 | ```sh 35 | npm run report 36 | ``` 37 | 38 | It will open default browser and open the HTML report 39 | 40 | ![html report](assets/html-report.png) 41 | 42 | ## Run server (optionally) 43 | 44 | ```sh 45 | npm start 46 | ``` 47 | 48 | ## Author 49 | 50 | Yevhen Laichenkov 51 | 52 | ## License 53 | 54 | [MIT](LICENSE) 55 | -------------------------------------------------------------------------------- /assets/html-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elaichenkov/playwright-api-testing-example/ca976872f2125840386ab465fc0b3bf3e7984e9c/assets/html-report.png -------------------------------------------------------------------------------- /assets/playwright-odottaa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elaichenkov/playwright-api-testing-example/ca976872f2125840386ab465fc0b3bf3e7984e9c/assets/playwright-odottaa.png -------------------------------------------------------------------------------- /db.json: -------------------------------------------------------------------------------- 1 | { 2 | "posts": [ 3 | { 4 | "title": "My new post", 5 | "author": "typicode", 6 | "id": 2 7 | } 8 | ], 9 | "comments": [], 10 | "profile": { 11 | "name": "typicode" 12 | } 13 | } -------------------------------------------------------------------------------- /global-setup.ts: -------------------------------------------------------------------------------- 1 | // global-setup.ts 2 | import { request, FullConfig } from '@playwright/test'; 3 | 4 | const defaultPost = { 5 | title: 'json-server', 6 | author: 'typicode', 7 | id: 1, 8 | }; 9 | 10 | async function globalSetup(config: FullConfig) { 11 | const { baseURL } = config.projects[0].use; 12 | const req = await request.newContext({ 13 | baseURL, 14 | extraHTTPHeaders: { 15 | 'Content-Type': 'application/json', 16 | authorization: 'token 5jsBfMf72VYA9QzCXC5eXZkd3q6VB8Gc', 17 | }, 18 | }); 19 | 20 | const posts = await (await req.get('/posts')).json(); 21 | await Promise.all(posts.map(({ id }) => req.delete(`/posts/${id}`))); 22 | await req.post('/posts', { data: JSON.stringify(defaultPost) }); 23 | await req.dispose(); 24 | } 25 | 26 | export default globalSetup; 27 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playwright-api-testing-example", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "version": "1.0.0", 9 | "license": "ISC", 10 | "devDependencies": { 11 | "@playwright/test": "^1.26.1", 12 | "json-server": "^0.17.1", 13 | "odottaa": "^1.1.1" 14 | } 15 | }, 16 | "node_modules/@playwright/test": { 17 | "version": "1.26.1", 18 | "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.26.1.tgz", 19 | "integrity": "sha512-bNxyZASVt2adSZ9gbD7NCydzcb5JaI0OR9hc7s+nmPeH604gwp0zp17NNpwXY4c8nvuBGQQ9oGDx72LE+cUWvw==", 20 | "dev": true, 21 | "dependencies": { 22 | "@types/node": "*", 23 | "playwright-core": "1.26.1" 24 | }, 25 | "bin": { 26 | "playwright": "cli.js" 27 | }, 28 | "engines": { 29 | "node": ">=14" 30 | } 31 | }, 32 | "node_modules/@types/node": { 33 | "version": "18.8.2", 34 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.2.tgz", 35 | "integrity": "sha512-cRMwIgdDN43GO4xMWAfJAecYn8wV4JbsOGHNfNUIDiuYkUYAR5ec4Rj7IO2SAhFPEfpPtLtUTbbny/TCT7aDwA==", 36 | "dev": true 37 | }, 38 | "node_modules/accepts": { 39 | "version": "1.3.8", 40 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 41 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 42 | "dev": true, 43 | "dependencies": { 44 | "mime-types": "~2.1.34", 45 | "negotiator": "0.6.3" 46 | }, 47 | "engines": { 48 | "node": ">= 0.6" 49 | } 50 | }, 51 | "node_modules/ansi-regex": { 52 | "version": "5.0.1", 53 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 54 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 55 | "dev": true, 56 | "engines": { 57 | "node": ">=8" 58 | } 59 | }, 60 | "node_modules/ansi-styles": { 61 | "version": "4.3.0", 62 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 63 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 64 | "dev": true, 65 | "dependencies": { 66 | "color-convert": "^2.0.1" 67 | }, 68 | "engines": { 69 | "node": ">=8" 70 | }, 71 | "funding": { 72 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 73 | } 74 | }, 75 | "node_modules/array-flatten": { 76 | "version": "1.1.1", 77 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 78 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", 79 | "dev": true 80 | }, 81 | "node_modules/basic-auth": { 82 | "version": "2.0.1", 83 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", 84 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", 85 | "dev": true, 86 | "dependencies": { 87 | "safe-buffer": "5.1.2" 88 | }, 89 | "engines": { 90 | "node": ">= 0.8" 91 | } 92 | }, 93 | "node_modules/body-parser": { 94 | "version": "1.20.0", 95 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", 96 | "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", 97 | "dev": true, 98 | "dependencies": { 99 | "bytes": "3.1.2", 100 | "content-type": "~1.0.4", 101 | "debug": "2.6.9", 102 | "depd": "2.0.0", 103 | "destroy": "1.2.0", 104 | "http-errors": "2.0.0", 105 | "iconv-lite": "0.4.24", 106 | "on-finished": "2.4.1", 107 | "qs": "6.10.3", 108 | "raw-body": "2.5.1", 109 | "type-is": "~1.6.18", 110 | "unpipe": "1.0.0" 111 | }, 112 | "engines": { 113 | "node": ">= 0.8", 114 | "npm": "1.2.8000 || >= 1.4.16" 115 | } 116 | }, 117 | "node_modules/bytes": { 118 | "version": "3.1.2", 119 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 120 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 121 | "dev": true, 122 | "engines": { 123 | "node": ">= 0.8" 124 | } 125 | }, 126 | "node_modules/call-bind": { 127 | "version": "1.0.2", 128 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 129 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 130 | "dev": true, 131 | "dependencies": { 132 | "function-bind": "^1.1.1", 133 | "get-intrinsic": "^1.0.2" 134 | }, 135 | "funding": { 136 | "url": "https://github.com/sponsors/ljharb" 137 | } 138 | }, 139 | "node_modules/chalk": { 140 | "version": "4.1.2", 141 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 142 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 143 | "dev": true, 144 | "dependencies": { 145 | "ansi-styles": "^4.1.0", 146 | "supports-color": "^7.1.0" 147 | }, 148 | "engines": { 149 | "node": ">=10" 150 | }, 151 | "funding": { 152 | "url": "https://github.com/chalk/chalk?sponsor=1" 153 | } 154 | }, 155 | "node_modules/cliui": { 156 | "version": "7.0.4", 157 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 158 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 159 | "dev": true, 160 | "dependencies": { 161 | "string-width": "^4.2.0", 162 | "strip-ansi": "^6.0.0", 163 | "wrap-ansi": "^7.0.0" 164 | } 165 | }, 166 | "node_modules/color-convert": { 167 | "version": "2.0.1", 168 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 169 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 170 | "dev": true, 171 | "dependencies": { 172 | "color-name": "~1.1.4" 173 | }, 174 | "engines": { 175 | "node": ">=7.0.0" 176 | } 177 | }, 178 | "node_modules/color-name": { 179 | "version": "1.1.4", 180 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 181 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 182 | "dev": true 183 | }, 184 | "node_modules/compressible": { 185 | "version": "2.0.18", 186 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", 187 | "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", 188 | "dev": true, 189 | "dependencies": { 190 | "mime-db": ">= 1.43.0 < 2" 191 | }, 192 | "engines": { 193 | "node": ">= 0.6" 194 | } 195 | }, 196 | "node_modules/compression": { 197 | "version": "1.7.4", 198 | "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", 199 | "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", 200 | "dev": true, 201 | "dependencies": { 202 | "accepts": "~1.3.5", 203 | "bytes": "3.0.0", 204 | "compressible": "~2.0.16", 205 | "debug": "2.6.9", 206 | "on-headers": "~1.0.2", 207 | "safe-buffer": "5.1.2", 208 | "vary": "~1.1.2" 209 | }, 210 | "engines": { 211 | "node": ">= 0.8.0" 212 | } 213 | }, 214 | "node_modules/compression/node_modules/bytes": { 215 | "version": "3.0.0", 216 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 217 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", 218 | "dev": true, 219 | "engines": { 220 | "node": ">= 0.8" 221 | } 222 | }, 223 | "node_modules/connect-pause": { 224 | "version": "0.1.1", 225 | "resolved": "https://registry.npmjs.org/connect-pause/-/connect-pause-0.1.1.tgz", 226 | "integrity": "sha1-smmyu4Ldsaw9tQmcD7WCq6mfs3o=", 227 | "dev": true, 228 | "engines": { 229 | "node": "*" 230 | } 231 | }, 232 | "node_modules/content-disposition": { 233 | "version": "0.5.4", 234 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 235 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 236 | "dev": true, 237 | "dependencies": { 238 | "safe-buffer": "5.2.1" 239 | }, 240 | "engines": { 241 | "node": ">= 0.6" 242 | } 243 | }, 244 | "node_modules/content-disposition/node_modules/safe-buffer": { 245 | "version": "5.2.1", 246 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 247 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 248 | "dev": true, 249 | "funding": [ 250 | { 251 | "type": "github", 252 | "url": "https://github.com/sponsors/feross" 253 | }, 254 | { 255 | "type": "patreon", 256 | "url": "https://www.patreon.com/feross" 257 | }, 258 | { 259 | "type": "consulting", 260 | "url": "https://feross.org/support" 261 | } 262 | ] 263 | }, 264 | "node_modules/content-type": { 265 | "version": "1.0.4", 266 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 267 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 268 | "dev": true, 269 | "engines": { 270 | "node": ">= 0.6" 271 | } 272 | }, 273 | "node_modules/cookie": { 274 | "version": "0.4.2", 275 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", 276 | "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", 277 | "dev": true, 278 | "engines": { 279 | "node": ">= 0.6" 280 | } 281 | }, 282 | "node_modules/cookie-signature": { 283 | "version": "1.0.6", 284 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 285 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", 286 | "dev": true 287 | }, 288 | "node_modules/cors": { 289 | "version": "2.8.5", 290 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 291 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 292 | "dev": true, 293 | "dependencies": { 294 | "object-assign": "^4", 295 | "vary": "^1" 296 | }, 297 | "engines": { 298 | "node": ">= 0.10" 299 | } 300 | }, 301 | "node_modules/debug": { 302 | "version": "2.6.9", 303 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 304 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 305 | "dev": true, 306 | "dependencies": { 307 | "ms": "2.0.0" 308 | } 309 | }, 310 | "node_modules/depd": { 311 | "version": "2.0.0", 312 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 313 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 314 | "dev": true, 315 | "engines": { 316 | "node": ">= 0.8" 317 | } 318 | }, 319 | "node_modules/destroy": { 320 | "version": "1.2.0", 321 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 322 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 323 | "dev": true, 324 | "engines": { 325 | "node": ">= 0.8", 326 | "npm": "1.2.8000 || >= 1.4.16" 327 | } 328 | }, 329 | "node_modules/ee-first": { 330 | "version": "1.1.1", 331 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 332 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", 333 | "dev": true 334 | }, 335 | "node_modules/emoji-regex": { 336 | "version": "8.0.0", 337 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 338 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 339 | "dev": true 340 | }, 341 | "node_modules/encodeurl": { 342 | "version": "1.0.2", 343 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 344 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 345 | "dev": true, 346 | "engines": { 347 | "node": ">= 0.8" 348 | } 349 | }, 350 | "node_modules/errorhandler": { 351 | "version": "1.5.1", 352 | "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", 353 | "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", 354 | "dev": true, 355 | "dependencies": { 356 | "accepts": "~1.3.7", 357 | "escape-html": "~1.0.3" 358 | }, 359 | "engines": { 360 | "node": ">= 0.8" 361 | } 362 | }, 363 | "node_modules/escalade": { 364 | "version": "3.1.1", 365 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 366 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 367 | "dev": true, 368 | "engines": { 369 | "node": ">=6" 370 | } 371 | }, 372 | "node_modules/escape-html": { 373 | "version": "1.0.3", 374 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 375 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", 376 | "dev": true 377 | }, 378 | "node_modules/etag": { 379 | "version": "1.8.1", 380 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 381 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 382 | "dev": true, 383 | "engines": { 384 | "node": ">= 0.6" 385 | } 386 | }, 387 | "node_modules/express": { 388 | "version": "4.17.3", 389 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", 390 | "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", 391 | "dev": true, 392 | "dependencies": { 393 | "accepts": "~1.3.8", 394 | "array-flatten": "1.1.1", 395 | "body-parser": "1.19.2", 396 | "content-disposition": "0.5.4", 397 | "content-type": "~1.0.4", 398 | "cookie": "0.4.2", 399 | "cookie-signature": "1.0.6", 400 | "debug": "2.6.9", 401 | "depd": "~1.1.2", 402 | "encodeurl": "~1.0.2", 403 | "escape-html": "~1.0.3", 404 | "etag": "~1.8.1", 405 | "finalhandler": "~1.1.2", 406 | "fresh": "0.5.2", 407 | "merge-descriptors": "1.0.1", 408 | "methods": "~1.1.2", 409 | "on-finished": "~2.3.0", 410 | "parseurl": "~1.3.3", 411 | "path-to-regexp": "0.1.7", 412 | "proxy-addr": "~2.0.7", 413 | "qs": "6.9.7", 414 | "range-parser": "~1.2.1", 415 | "safe-buffer": "5.2.1", 416 | "send": "0.17.2", 417 | "serve-static": "1.14.2", 418 | "setprototypeof": "1.2.0", 419 | "statuses": "~1.5.0", 420 | "type-is": "~1.6.18", 421 | "utils-merge": "1.0.1", 422 | "vary": "~1.1.2" 423 | }, 424 | "engines": { 425 | "node": ">= 0.10.0" 426 | } 427 | }, 428 | "node_modules/express-urlrewrite": { 429 | "version": "1.4.0", 430 | "resolved": "https://registry.npmjs.org/express-urlrewrite/-/express-urlrewrite-1.4.0.tgz", 431 | "integrity": "sha512-PI5h8JuzoweS26vFizwQl6UTF25CAHSggNv0J25Dn/IKZscJHWZzPrI5z2Y2jgOzIaw2qh8l6+/jUcig23Z2SA==", 432 | "dev": true, 433 | "dependencies": { 434 | "debug": "*", 435 | "path-to-regexp": "^1.0.3" 436 | } 437 | }, 438 | "node_modules/express-urlrewrite/node_modules/path-to-regexp": { 439 | "version": "1.8.0", 440 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", 441 | "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", 442 | "dev": true, 443 | "dependencies": { 444 | "isarray": "0.0.1" 445 | } 446 | }, 447 | "node_modules/express/node_modules/body-parser": { 448 | "version": "1.19.2", 449 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", 450 | "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", 451 | "dev": true, 452 | "dependencies": { 453 | "bytes": "3.1.2", 454 | "content-type": "~1.0.4", 455 | "debug": "2.6.9", 456 | "depd": "~1.1.2", 457 | "http-errors": "1.8.1", 458 | "iconv-lite": "0.4.24", 459 | "on-finished": "~2.3.0", 460 | "qs": "6.9.7", 461 | "raw-body": "2.4.3", 462 | "type-is": "~1.6.18" 463 | }, 464 | "engines": { 465 | "node": ">= 0.8" 466 | } 467 | }, 468 | "node_modules/express/node_modules/depd": { 469 | "version": "1.1.2", 470 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 471 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 472 | "dev": true, 473 | "engines": { 474 | "node": ">= 0.6" 475 | } 476 | }, 477 | "node_modules/express/node_modules/http-errors": { 478 | "version": "1.8.1", 479 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", 480 | "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", 481 | "dev": true, 482 | "dependencies": { 483 | "depd": "~1.1.2", 484 | "inherits": "2.0.4", 485 | "setprototypeof": "1.2.0", 486 | "statuses": ">= 1.5.0 < 2", 487 | "toidentifier": "1.0.1" 488 | }, 489 | "engines": { 490 | "node": ">= 0.6" 491 | } 492 | }, 493 | "node_modules/express/node_modules/on-finished": { 494 | "version": "2.3.0", 495 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 496 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 497 | "dev": true, 498 | "dependencies": { 499 | "ee-first": "1.1.1" 500 | }, 501 | "engines": { 502 | "node": ">= 0.8" 503 | } 504 | }, 505 | "node_modules/express/node_modules/qs": { 506 | "version": "6.9.7", 507 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", 508 | "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", 509 | "dev": true, 510 | "engines": { 511 | "node": ">=0.6" 512 | }, 513 | "funding": { 514 | "url": "https://github.com/sponsors/ljharb" 515 | } 516 | }, 517 | "node_modules/express/node_modules/raw-body": { 518 | "version": "2.4.3", 519 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", 520 | "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", 521 | "dev": true, 522 | "dependencies": { 523 | "bytes": "3.1.2", 524 | "http-errors": "1.8.1", 525 | "iconv-lite": "0.4.24", 526 | "unpipe": "1.0.0" 527 | }, 528 | "engines": { 529 | "node": ">= 0.8" 530 | } 531 | }, 532 | "node_modules/express/node_modules/safe-buffer": { 533 | "version": "5.2.1", 534 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 535 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 536 | "dev": true, 537 | "funding": [ 538 | { 539 | "type": "github", 540 | "url": "https://github.com/sponsors/feross" 541 | }, 542 | { 543 | "type": "patreon", 544 | "url": "https://www.patreon.com/feross" 545 | }, 546 | { 547 | "type": "consulting", 548 | "url": "https://feross.org/support" 549 | } 550 | ] 551 | }, 552 | "node_modules/finalhandler": { 553 | "version": "1.1.2", 554 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 555 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 556 | "dev": true, 557 | "dependencies": { 558 | "debug": "2.6.9", 559 | "encodeurl": "~1.0.2", 560 | "escape-html": "~1.0.3", 561 | "on-finished": "~2.3.0", 562 | "parseurl": "~1.3.3", 563 | "statuses": "~1.5.0", 564 | "unpipe": "~1.0.0" 565 | }, 566 | "engines": { 567 | "node": ">= 0.8" 568 | } 569 | }, 570 | "node_modules/finalhandler/node_modules/on-finished": { 571 | "version": "2.3.0", 572 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 573 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 574 | "dev": true, 575 | "dependencies": { 576 | "ee-first": "1.1.1" 577 | }, 578 | "engines": { 579 | "node": ">= 0.8" 580 | } 581 | }, 582 | "node_modules/forwarded": { 583 | "version": "0.2.0", 584 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 585 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 586 | "dev": true, 587 | "engines": { 588 | "node": ">= 0.6" 589 | } 590 | }, 591 | "node_modules/fresh": { 592 | "version": "0.5.2", 593 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 594 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 595 | "dev": true, 596 | "engines": { 597 | "node": ">= 0.6" 598 | } 599 | }, 600 | "node_modules/function-bind": { 601 | "version": "1.1.1", 602 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 603 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 604 | "dev": true 605 | }, 606 | "node_modules/get-caller-file": { 607 | "version": "2.0.5", 608 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 609 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 610 | "dev": true, 611 | "engines": { 612 | "node": "6.* || 8.* || >= 10.*" 613 | } 614 | }, 615 | "node_modules/get-intrinsic": { 616 | "version": "1.1.1", 617 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", 618 | "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", 619 | "dev": true, 620 | "dependencies": { 621 | "function-bind": "^1.1.1", 622 | "has": "^1.0.3", 623 | "has-symbols": "^1.0.1" 624 | }, 625 | "funding": { 626 | "url": "https://github.com/sponsors/ljharb" 627 | } 628 | }, 629 | "node_modules/graceful-fs": { 630 | "version": "4.2.10", 631 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", 632 | "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", 633 | "dev": true 634 | }, 635 | "node_modules/has": { 636 | "version": "1.0.3", 637 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 638 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 639 | "dev": true, 640 | "dependencies": { 641 | "function-bind": "^1.1.1" 642 | }, 643 | "engines": { 644 | "node": ">= 0.4.0" 645 | } 646 | }, 647 | "node_modules/has-flag": { 648 | "version": "4.0.0", 649 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 650 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 651 | "dev": true, 652 | "engines": { 653 | "node": ">=8" 654 | } 655 | }, 656 | "node_modules/has-symbols": { 657 | "version": "1.0.3", 658 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 659 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 660 | "dev": true, 661 | "engines": { 662 | "node": ">= 0.4" 663 | }, 664 | "funding": { 665 | "url": "https://github.com/sponsors/ljharb" 666 | } 667 | }, 668 | "node_modules/http-errors": { 669 | "version": "2.0.0", 670 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 671 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 672 | "dev": true, 673 | "dependencies": { 674 | "depd": "2.0.0", 675 | "inherits": "2.0.4", 676 | "setprototypeof": "1.2.0", 677 | "statuses": "2.0.1", 678 | "toidentifier": "1.0.1" 679 | }, 680 | "engines": { 681 | "node": ">= 0.8" 682 | } 683 | }, 684 | "node_modules/http-errors/node_modules/statuses": { 685 | "version": "2.0.1", 686 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 687 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 688 | "dev": true, 689 | "engines": { 690 | "node": ">= 0.8" 691 | } 692 | }, 693 | "node_modules/iconv-lite": { 694 | "version": "0.4.24", 695 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 696 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 697 | "dev": true, 698 | "dependencies": { 699 | "safer-buffer": ">= 2.1.2 < 3" 700 | }, 701 | "engines": { 702 | "node": ">=0.10.0" 703 | } 704 | }, 705 | "node_modules/inherits": { 706 | "version": "2.0.4", 707 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 708 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 709 | "dev": true 710 | }, 711 | "node_modules/ipaddr.js": { 712 | "version": "1.9.1", 713 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 714 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 715 | "dev": true, 716 | "engines": { 717 | "node": ">= 0.10" 718 | } 719 | }, 720 | "node_modules/is-fullwidth-code-point": { 721 | "version": "3.0.0", 722 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 723 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 724 | "dev": true, 725 | "engines": { 726 | "node": ">=8" 727 | } 728 | }, 729 | "node_modules/is-promise": { 730 | "version": "2.2.2", 731 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", 732 | "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", 733 | "dev": true 734 | }, 735 | "node_modules/isarray": { 736 | "version": "0.0.1", 737 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 738 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", 739 | "dev": true 740 | }, 741 | "node_modules/jju": { 742 | "version": "1.4.0", 743 | "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", 744 | "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=", 745 | "dev": true 746 | }, 747 | "node_modules/json-parse-helpfulerror": { 748 | "version": "1.0.3", 749 | "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", 750 | "integrity": "sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w=", 751 | "dev": true, 752 | "dependencies": { 753 | "jju": "^1.1.0" 754 | } 755 | }, 756 | "node_modules/json-server": { 757 | "version": "0.17.1", 758 | "resolved": "https://registry.npmjs.org/json-server/-/json-server-0.17.1.tgz", 759 | "integrity": "sha512-2cR/IAL9xX4M1Y5ONMpnvRvJ5o9gJH5GsSQs7fQHdTKTKoN4YRZu1ApQKg/4P0XzwlLyUDqTlwhPq9nsvJ9acw==", 760 | "dev": true, 761 | "dependencies": { 762 | "body-parser": "^1.19.0", 763 | "chalk": "^4.1.2", 764 | "compression": "^1.7.4", 765 | "connect-pause": "^0.1.1", 766 | "cors": "^2.8.5", 767 | "errorhandler": "^1.5.1", 768 | "express": "^4.17.1", 769 | "express-urlrewrite": "^1.4.0", 770 | "json-parse-helpfulerror": "^1.0.3", 771 | "lodash": "^4.17.21", 772 | "lodash-id": "^0.14.1", 773 | "lowdb": "^1.0.0", 774 | "method-override": "^3.0.0", 775 | "morgan": "^1.10.0", 776 | "nanoid": "^3.1.23", 777 | "please-upgrade-node": "^3.2.0", 778 | "pluralize": "^8.0.0", 779 | "server-destroy": "^1.0.1", 780 | "yargs": "^17.0.1" 781 | }, 782 | "bin": { 783 | "json-server": "lib/cli/bin.js" 784 | }, 785 | "engines": { 786 | "node": ">=12" 787 | } 788 | }, 789 | "node_modules/lodash": { 790 | "version": "4.17.21", 791 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 792 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 793 | "dev": true 794 | }, 795 | "node_modules/lodash-id": { 796 | "version": "0.14.1", 797 | "resolved": "https://registry.npmjs.org/lodash-id/-/lodash-id-0.14.1.tgz", 798 | "integrity": "sha512-ikQPBTiq/d5m6dfKQlFdIXFzvThPi2Be9/AHxktOnDSfSxE1j9ICbBT5Elk1ke7HSTgM38LHTpmJovo9/klnLg==", 799 | "dev": true, 800 | "engines": { 801 | "node": ">= 4" 802 | } 803 | }, 804 | "node_modules/lowdb": { 805 | "version": "1.0.0", 806 | "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", 807 | "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", 808 | "dev": true, 809 | "dependencies": { 810 | "graceful-fs": "^4.1.3", 811 | "is-promise": "^2.1.0", 812 | "lodash": "4", 813 | "pify": "^3.0.0", 814 | "steno": "^0.4.1" 815 | }, 816 | "engines": { 817 | "node": ">=4" 818 | } 819 | }, 820 | "node_modules/media-typer": { 821 | "version": "0.3.0", 822 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 823 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", 824 | "dev": true, 825 | "engines": { 826 | "node": ">= 0.6" 827 | } 828 | }, 829 | "node_modules/merge-descriptors": { 830 | "version": "1.0.1", 831 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 832 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", 833 | "dev": true 834 | }, 835 | "node_modules/method-override": { 836 | "version": "3.0.0", 837 | "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", 838 | "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", 839 | "dev": true, 840 | "dependencies": { 841 | "debug": "3.1.0", 842 | "methods": "~1.1.2", 843 | "parseurl": "~1.3.2", 844 | "vary": "~1.1.2" 845 | }, 846 | "engines": { 847 | "node": ">= 0.10" 848 | } 849 | }, 850 | "node_modules/method-override/node_modules/debug": { 851 | "version": "3.1.0", 852 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 853 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 854 | "dev": true, 855 | "dependencies": { 856 | "ms": "2.0.0" 857 | } 858 | }, 859 | "node_modules/methods": { 860 | "version": "1.1.2", 861 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 862 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 863 | "dev": true, 864 | "engines": { 865 | "node": ">= 0.6" 866 | } 867 | }, 868 | "node_modules/mime": { 869 | "version": "1.6.0", 870 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 871 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 872 | "dev": true, 873 | "bin": { 874 | "mime": "cli.js" 875 | }, 876 | "engines": { 877 | "node": ">=4" 878 | } 879 | }, 880 | "node_modules/mime-db": { 881 | "version": "1.52.0", 882 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 883 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 884 | "dev": true, 885 | "engines": { 886 | "node": ">= 0.6" 887 | } 888 | }, 889 | "node_modules/mime-types": { 890 | "version": "2.1.35", 891 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 892 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 893 | "dev": true, 894 | "dependencies": { 895 | "mime-db": "1.52.0" 896 | }, 897 | "engines": { 898 | "node": ">= 0.6" 899 | } 900 | }, 901 | "node_modules/morgan": { 902 | "version": "1.10.0", 903 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", 904 | "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", 905 | "dev": true, 906 | "dependencies": { 907 | "basic-auth": "~2.0.1", 908 | "debug": "2.6.9", 909 | "depd": "~2.0.0", 910 | "on-finished": "~2.3.0", 911 | "on-headers": "~1.0.2" 912 | }, 913 | "engines": { 914 | "node": ">= 0.8.0" 915 | } 916 | }, 917 | "node_modules/morgan/node_modules/on-finished": { 918 | "version": "2.3.0", 919 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 920 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 921 | "dev": true, 922 | "dependencies": { 923 | "ee-first": "1.1.1" 924 | }, 925 | "engines": { 926 | "node": ">= 0.8" 927 | } 928 | }, 929 | "node_modules/ms": { 930 | "version": "2.0.0", 931 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 932 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 933 | "dev": true 934 | }, 935 | "node_modules/nanoid": { 936 | "version": "3.3.2", 937 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", 938 | "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==", 939 | "dev": true, 940 | "bin": { 941 | "nanoid": "bin/nanoid.cjs" 942 | }, 943 | "engines": { 944 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 945 | } 946 | }, 947 | "node_modules/negotiator": { 948 | "version": "0.6.3", 949 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 950 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 951 | "dev": true, 952 | "engines": { 953 | "node": ">= 0.6" 954 | } 955 | }, 956 | "node_modules/object-assign": { 957 | "version": "4.1.1", 958 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 959 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 960 | "dev": true, 961 | "engines": { 962 | "node": ">=0.10.0" 963 | } 964 | }, 965 | "node_modules/object-inspect": { 966 | "version": "1.12.0", 967 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", 968 | "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", 969 | "dev": true, 970 | "funding": { 971 | "url": "https://github.com/sponsors/ljharb" 972 | } 973 | }, 974 | "node_modules/odottaa": { 975 | "version": "1.1.1", 976 | "resolved": "https://registry.npmjs.org/odottaa/-/odottaa-1.1.1.tgz", 977 | "integrity": "sha512-ljdsnTSyiv1IYocDAaiCAQr0D5qqpnZZug2I1+PWBEaY4jCelNcgaQXJqlld1nu3+yc5V8L4nIx6EJ93IKB6Dw==", 978 | "dev": true 979 | }, 980 | "node_modules/on-finished": { 981 | "version": "2.4.1", 982 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 983 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 984 | "dev": true, 985 | "dependencies": { 986 | "ee-first": "1.1.1" 987 | }, 988 | "engines": { 989 | "node": ">= 0.8" 990 | } 991 | }, 992 | "node_modules/on-headers": { 993 | "version": "1.0.2", 994 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", 995 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", 996 | "dev": true, 997 | "engines": { 998 | "node": ">= 0.8" 999 | } 1000 | }, 1001 | "node_modules/parseurl": { 1002 | "version": "1.3.3", 1003 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1004 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1005 | "dev": true, 1006 | "engines": { 1007 | "node": ">= 0.8" 1008 | } 1009 | }, 1010 | "node_modules/path-to-regexp": { 1011 | "version": "0.1.7", 1012 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1013 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", 1014 | "dev": true 1015 | }, 1016 | "node_modules/pify": { 1017 | "version": "3.0.0", 1018 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 1019 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", 1020 | "dev": true, 1021 | "engines": { 1022 | "node": ">=4" 1023 | } 1024 | }, 1025 | "node_modules/playwright-core": { 1026 | "version": "1.26.1", 1027 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.26.1.tgz", 1028 | "integrity": "sha512-hzFchhhxnEiPc4qVPs9q2ZR+5eKNifY2hQDHtg1HnTTUuphYCBP8ZRb2si+B1TR7BHirgXaPi48LIye5SgrLAA==", 1029 | "dev": true, 1030 | "bin": { 1031 | "playwright": "cli.js" 1032 | }, 1033 | "engines": { 1034 | "node": ">=14" 1035 | } 1036 | }, 1037 | "node_modules/please-upgrade-node": { 1038 | "version": "3.2.0", 1039 | "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", 1040 | "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", 1041 | "dev": true, 1042 | "dependencies": { 1043 | "semver-compare": "^1.0.0" 1044 | } 1045 | }, 1046 | "node_modules/pluralize": { 1047 | "version": "8.0.0", 1048 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", 1049 | "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", 1050 | "dev": true, 1051 | "engines": { 1052 | "node": ">=4" 1053 | } 1054 | }, 1055 | "node_modules/proxy-addr": { 1056 | "version": "2.0.7", 1057 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1058 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1059 | "dev": true, 1060 | "dependencies": { 1061 | "forwarded": "0.2.0", 1062 | "ipaddr.js": "1.9.1" 1063 | }, 1064 | "engines": { 1065 | "node": ">= 0.10" 1066 | } 1067 | }, 1068 | "node_modules/qs": { 1069 | "version": "6.10.3", 1070 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", 1071 | "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", 1072 | "dev": true, 1073 | "dependencies": { 1074 | "side-channel": "^1.0.4" 1075 | }, 1076 | "engines": { 1077 | "node": ">=0.6" 1078 | }, 1079 | "funding": { 1080 | "url": "https://github.com/sponsors/ljharb" 1081 | } 1082 | }, 1083 | "node_modules/range-parser": { 1084 | "version": "1.2.1", 1085 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1086 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1087 | "dev": true, 1088 | "engines": { 1089 | "node": ">= 0.6" 1090 | } 1091 | }, 1092 | "node_modules/raw-body": { 1093 | "version": "2.5.1", 1094 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 1095 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 1096 | "dev": true, 1097 | "dependencies": { 1098 | "bytes": "3.1.2", 1099 | "http-errors": "2.0.0", 1100 | "iconv-lite": "0.4.24", 1101 | "unpipe": "1.0.0" 1102 | }, 1103 | "engines": { 1104 | "node": ">= 0.8" 1105 | } 1106 | }, 1107 | "node_modules/require-directory": { 1108 | "version": "2.1.1", 1109 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1110 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 1111 | "dev": true, 1112 | "engines": { 1113 | "node": ">=0.10.0" 1114 | } 1115 | }, 1116 | "node_modules/safe-buffer": { 1117 | "version": "5.1.2", 1118 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1119 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1120 | "dev": true 1121 | }, 1122 | "node_modules/safer-buffer": { 1123 | "version": "2.1.2", 1124 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1125 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1126 | "dev": true 1127 | }, 1128 | "node_modules/semver-compare": { 1129 | "version": "1.0.0", 1130 | "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", 1131 | "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", 1132 | "dev": true 1133 | }, 1134 | "node_modules/send": { 1135 | "version": "0.17.2", 1136 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", 1137 | "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", 1138 | "dev": true, 1139 | "dependencies": { 1140 | "debug": "2.6.9", 1141 | "depd": "~1.1.2", 1142 | "destroy": "~1.0.4", 1143 | "encodeurl": "~1.0.2", 1144 | "escape-html": "~1.0.3", 1145 | "etag": "~1.8.1", 1146 | "fresh": "0.5.2", 1147 | "http-errors": "1.8.1", 1148 | "mime": "1.6.0", 1149 | "ms": "2.1.3", 1150 | "on-finished": "~2.3.0", 1151 | "range-parser": "~1.2.1", 1152 | "statuses": "~1.5.0" 1153 | }, 1154 | "engines": { 1155 | "node": ">= 0.8.0" 1156 | } 1157 | }, 1158 | "node_modules/send/node_modules/depd": { 1159 | "version": "1.1.2", 1160 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 1161 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 1162 | "dev": true, 1163 | "engines": { 1164 | "node": ">= 0.6" 1165 | } 1166 | }, 1167 | "node_modules/send/node_modules/destroy": { 1168 | "version": "1.0.4", 1169 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 1170 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", 1171 | "dev": true 1172 | }, 1173 | "node_modules/send/node_modules/http-errors": { 1174 | "version": "1.8.1", 1175 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", 1176 | "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", 1177 | "dev": true, 1178 | "dependencies": { 1179 | "depd": "~1.1.2", 1180 | "inherits": "2.0.4", 1181 | "setprototypeof": "1.2.0", 1182 | "statuses": ">= 1.5.0 < 2", 1183 | "toidentifier": "1.0.1" 1184 | }, 1185 | "engines": { 1186 | "node": ">= 0.6" 1187 | } 1188 | }, 1189 | "node_modules/send/node_modules/ms": { 1190 | "version": "2.1.3", 1191 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1192 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1193 | "dev": true 1194 | }, 1195 | "node_modules/send/node_modules/on-finished": { 1196 | "version": "2.3.0", 1197 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1198 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1199 | "dev": true, 1200 | "dependencies": { 1201 | "ee-first": "1.1.1" 1202 | }, 1203 | "engines": { 1204 | "node": ">= 0.8" 1205 | } 1206 | }, 1207 | "node_modules/serve-static": { 1208 | "version": "1.14.2", 1209 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", 1210 | "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", 1211 | "dev": true, 1212 | "dependencies": { 1213 | "encodeurl": "~1.0.2", 1214 | "escape-html": "~1.0.3", 1215 | "parseurl": "~1.3.3", 1216 | "send": "0.17.2" 1217 | }, 1218 | "engines": { 1219 | "node": ">= 0.8.0" 1220 | } 1221 | }, 1222 | "node_modules/server-destroy": { 1223 | "version": "1.0.1", 1224 | "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", 1225 | "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", 1226 | "dev": true 1227 | }, 1228 | "node_modules/setprototypeof": { 1229 | "version": "1.2.0", 1230 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1231 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 1232 | "dev": true 1233 | }, 1234 | "node_modules/side-channel": { 1235 | "version": "1.0.4", 1236 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 1237 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 1238 | "dev": true, 1239 | "dependencies": { 1240 | "call-bind": "^1.0.0", 1241 | "get-intrinsic": "^1.0.2", 1242 | "object-inspect": "^1.9.0" 1243 | }, 1244 | "funding": { 1245 | "url": "https://github.com/sponsors/ljharb" 1246 | } 1247 | }, 1248 | "node_modules/statuses": { 1249 | "version": "1.5.0", 1250 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1251 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", 1252 | "dev": true, 1253 | "engines": { 1254 | "node": ">= 0.6" 1255 | } 1256 | }, 1257 | "node_modules/steno": { 1258 | "version": "0.4.4", 1259 | "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", 1260 | "integrity": "sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs=", 1261 | "dev": true, 1262 | "dependencies": { 1263 | "graceful-fs": "^4.1.3" 1264 | } 1265 | }, 1266 | "node_modules/string-width": { 1267 | "version": "4.2.3", 1268 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1269 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1270 | "dev": true, 1271 | "dependencies": { 1272 | "emoji-regex": "^8.0.0", 1273 | "is-fullwidth-code-point": "^3.0.0", 1274 | "strip-ansi": "^6.0.1" 1275 | }, 1276 | "engines": { 1277 | "node": ">=8" 1278 | } 1279 | }, 1280 | "node_modules/strip-ansi": { 1281 | "version": "6.0.1", 1282 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1283 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1284 | "dev": true, 1285 | "dependencies": { 1286 | "ansi-regex": "^5.0.1" 1287 | }, 1288 | "engines": { 1289 | "node": ">=8" 1290 | } 1291 | }, 1292 | "node_modules/supports-color": { 1293 | "version": "7.2.0", 1294 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1295 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1296 | "dev": true, 1297 | "dependencies": { 1298 | "has-flag": "^4.0.0" 1299 | }, 1300 | "engines": { 1301 | "node": ">=8" 1302 | } 1303 | }, 1304 | "node_modules/toidentifier": { 1305 | "version": "1.0.1", 1306 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1307 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 1308 | "dev": true, 1309 | "engines": { 1310 | "node": ">=0.6" 1311 | } 1312 | }, 1313 | "node_modules/type-is": { 1314 | "version": "1.6.18", 1315 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1316 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1317 | "dev": true, 1318 | "dependencies": { 1319 | "media-typer": "0.3.0", 1320 | "mime-types": "~2.1.24" 1321 | }, 1322 | "engines": { 1323 | "node": ">= 0.6" 1324 | } 1325 | }, 1326 | "node_modules/unpipe": { 1327 | "version": "1.0.0", 1328 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1329 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 1330 | "dev": true, 1331 | "engines": { 1332 | "node": ">= 0.8" 1333 | } 1334 | }, 1335 | "node_modules/utils-merge": { 1336 | "version": "1.0.1", 1337 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1338 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 1339 | "dev": true, 1340 | "engines": { 1341 | "node": ">= 0.4.0" 1342 | } 1343 | }, 1344 | "node_modules/vary": { 1345 | "version": "1.1.2", 1346 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1347 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 1348 | "dev": true, 1349 | "engines": { 1350 | "node": ">= 0.8" 1351 | } 1352 | }, 1353 | "node_modules/wrap-ansi": { 1354 | "version": "7.0.0", 1355 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 1356 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 1357 | "dev": true, 1358 | "dependencies": { 1359 | "ansi-styles": "^4.0.0", 1360 | "string-width": "^4.1.0", 1361 | "strip-ansi": "^6.0.0" 1362 | }, 1363 | "engines": { 1364 | "node": ">=10" 1365 | }, 1366 | "funding": { 1367 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 1368 | } 1369 | }, 1370 | "node_modules/y18n": { 1371 | "version": "5.0.8", 1372 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 1373 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 1374 | "dev": true, 1375 | "engines": { 1376 | "node": ">=10" 1377 | } 1378 | }, 1379 | "node_modules/yargs": { 1380 | "version": "17.4.0", 1381 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.0.tgz", 1382 | "integrity": "sha512-WJudfrk81yWFSOkZYpAZx4Nt7V4xp7S/uJkX0CnxovMCt1wCE8LNftPpNuF9X/u9gN5nsD7ycYtRcDf2pL3UiA==", 1383 | "dev": true, 1384 | "dependencies": { 1385 | "cliui": "^7.0.2", 1386 | "escalade": "^3.1.1", 1387 | "get-caller-file": "^2.0.5", 1388 | "require-directory": "^2.1.1", 1389 | "string-width": "^4.2.3", 1390 | "y18n": "^5.0.5", 1391 | "yargs-parser": "^21.0.0" 1392 | }, 1393 | "engines": { 1394 | "node": ">=12" 1395 | } 1396 | }, 1397 | "node_modules/yargs-parser": { 1398 | "version": "21.0.1", 1399 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", 1400 | "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", 1401 | "dev": true, 1402 | "engines": { 1403 | "node": ">=12" 1404 | } 1405 | } 1406 | }, 1407 | "dependencies": { 1408 | "@playwright/test": { 1409 | "version": "1.26.1", 1410 | "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.26.1.tgz", 1411 | "integrity": "sha512-bNxyZASVt2adSZ9gbD7NCydzcb5JaI0OR9hc7s+nmPeH604gwp0zp17NNpwXY4c8nvuBGQQ9oGDx72LE+cUWvw==", 1412 | "dev": true, 1413 | "requires": { 1414 | "@types/node": "*", 1415 | "playwright-core": "1.26.1" 1416 | } 1417 | }, 1418 | "@types/node": { 1419 | "version": "18.8.2", 1420 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.2.tgz", 1421 | "integrity": "sha512-cRMwIgdDN43GO4xMWAfJAecYn8wV4JbsOGHNfNUIDiuYkUYAR5ec4Rj7IO2SAhFPEfpPtLtUTbbny/TCT7aDwA==", 1422 | "dev": true 1423 | }, 1424 | "accepts": { 1425 | "version": "1.3.8", 1426 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 1427 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 1428 | "dev": true, 1429 | "requires": { 1430 | "mime-types": "~2.1.34", 1431 | "negotiator": "0.6.3" 1432 | } 1433 | }, 1434 | "ansi-regex": { 1435 | "version": "5.0.1", 1436 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1437 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1438 | "dev": true 1439 | }, 1440 | "ansi-styles": { 1441 | "version": "4.3.0", 1442 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1443 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1444 | "dev": true, 1445 | "requires": { 1446 | "color-convert": "^2.0.1" 1447 | } 1448 | }, 1449 | "array-flatten": { 1450 | "version": "1.1.1", 1451 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 1452 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", 1453 | "dev": true 1454 | }, 1455 | "basic-auth": { 1456 | "version": "2.0.1", 1457 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", 1458 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", 1459 | "dev": true, 1460 | "requires": { 1461 | "safe-buffer": "5.1.2" 1462 | } 1463 | }, 1464 | "body-parser": { 1465 | "version": "1.20.0", 1466 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", 1467 | "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", 1468 | "dev": true, 1469 | "requires": { 1470 | "bytes": "3.1.2", 1471 | "content-type": "~1.0.4", 1472 | "debug": "2.6.9", 1473 | "depd": "2.0.0", 1474 | "destroy": "1.2.0", 1475 | "http-errors": "2.0.0", 1476 | "iconv-lite": "0.4.24", 1477 | "on-finished": "2.4.1", 1478 | "qs": "6.10.3", 1479 | "raw-body": "2.5.1", 1480 | "type-is": "~1.6.18", 1481 | "unpipe": "1.0.0" 1482 | } 1483 | }, 1484 | "bytes": { 1485 | "version": "3.1.2", 1486 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 1487 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 1488 | "dev": true 1489 | }, 1490 | "call-bind": { 1491 | "version": "1.0.2", 1492 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 1493 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 1494 | "dev": true, 1495 | "requires": { 1496 | "function-bind": "^1.1.1", 1497 | "get-intrinsic": "^1.0.2" 1498 | } 1499 | }, 1500 | "chalk": { 1501 | "version": "4.1.2", 1502 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1503 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1504 | "dev": true, 1505 | "requires": { 1506 | "ansi-styles": "^4.1.0", 1507 | "supports-color": "^7.1.0" 1508 | } 1509 | }, 1510 | "cliui": { 1511 | "version": "7.0.4", 1512 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 1513 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 1514 | "dev": true, 1515 | "requires": { 1516 | "string-width": "^4.2.0", 1517 | "strip-ansi": "^6.0.0", 1518 | "wrap-ansi": "^7.0.0" 1519 | } 1520 | }, 1521 | "color-convert": { 1522 | "version": "2.0.1", 1523 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1524 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1525 | "dev": true, 1526 | "requires": { 1527 | "color-name": "~1.1.4" 1528 | } 1529 | }, 1530 | "color-name": { 1531 | "version": "1.1.4", 1532 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1533 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1534 | "dev": true 1535 | }, 1536 | "compressible": { 1537 | "version": "2.0.18", 1538 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", 1539 | "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", 1540 | "dev": true, 1541 | "requires": { 1542 | "mime-db": ">= 1.43.0 < 2" 1543 | } 1544 | }, 1545 | "compression": { 1546 | "version": "1.7.4", 1547 | "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", 1548 | "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", 1549 | "dev": true, 1550 | "requires": { 1551 | "accepts": "~1.3.5", 1552 | "bytes": "3.0.0", 1553 | "compressible": "~2.0.16", 1554 | "debug": "2.6.9", 1555 | "on-headers": "~1.0.2", 1556 | "safe-buffer": "5.1.2", 1557 | "vary": "~1.1.2" 1558 | }, 1559 | "dependencies": { 1560 | "bytes": { 1561 | "version": "3.0.0", 1562 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 1563 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", 1564 | "dev": true 1565 | } 1566 | } 1567 | }, 1568 | "connect-pause": { 1569 | "version": "0.1.1", 1570 | "resolved": "https://registry.npmjs.org/connect-pause/-/connect-pause-0.1.1.tgz", 1571 | "integrity": "sha1-smmyu4Ldsaw9tQmcD7WCq6mfs3o=", 1572 | "dev": true 1573 | }, 1574 | "content-disposition": { 1575 | "version": "0.5.4", 1576 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 1577 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 1578 | "dev": true, 1579 | "requires": { 1580 | "safe-buffer": "5.2.1" 1581 | }, 1582 | "dependencies": { 1583 | "safe-buffer": { 1584 | "version": "5.2.1", 1585 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1586 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1587 | "dev": true 1588 | } 1589 | } 1590 | }, 1591 | "content-type": { 1592 | "version": "1.0.4", 1593 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 1594 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 1595 | "dev": true 1596 | }, 1597 | "cookie": { 1598 | "version": "0.4.2", 1599 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", 1600 | "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", 1601 | "dev": true 1602 | }, 1603 | "cookie-signature": { 1604 | "version": "1.0.6", 1605 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 1606 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", 1607 | "dev": true 1608 | }, 1609 | "cors": { 1610 | "version": "2.8.5", 1611 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 1612 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 1613 | "dev": true, 1614 | "requires": { 1615 | "object-assign": "^4", 1616 | "vary": "^1" 1617 | } 1618 | }, 1619 | "debug": { 1620 | "version": "2.6.9", 1621 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1622 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1623 | "dev": true, 1624 | "requires": { 1625 | "ms": "2.0.0" 1626 | } 1627 | }, 1628 | "depd": { 1629 | "version": "2.0.0", 1630 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 1631 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 1632 | "dev": true 1633 | }, 1634 | "destroy": { 1635 | "version": "1.2.0", 1636 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 1637 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 1638 | "dev": true 1639 | }, 1640 | "ee-first": { 1641 | "version": "1.1.1", 1642 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 1643 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", 1644 | "dev": true 1645 | }, 1646 | "emoji-regex": { 1647 | "version": "8.0.0", 1648 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1649 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 1650 | "dev": true 1651 | }, 1652 | "encodeurl": { 1653 | "version": "1.0.2", 1654 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 1655 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 1656 | "dev": true 1657 | }, 1658 | "errorhandler": { 1659 | "version": "1.5.1", 1660 | "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", 1661 | "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", 1662 | "dev": true, 1663 | "requires": { 1664 | "accepts": "~1.3.7", 1665 | "escape-html": "~1.0.3" 1666 | } 1667 | }, 1668 | "escalade": { 1669 | "version": "3.1.1", 1670 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 1671 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 1672 | "dev": true 1673 | }, 1674 | "escape-html": { 1675 | "version": "1.0.3", 1676 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 1677 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", 1678 | "dev": true 1679 | }, 1680 | "etag": { 1681 | "version": "1.8.1", 1682 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 1683 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 1684 | "dev": true 1685 | }, 1686 | "express": { 1687 | "version": "4.17.3", 1688 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", 1689 | "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", 1690 | "dev": true, 1691 | "requires": { 1692 | "accepts": "~1.3.8", 1693 | "array-flatten": "1.1.1", 1694 | "body-parser": "1.19.2", 1695 | "content-disposition": "0.5.4", 1696 | "content-type": "~1.0.4", 1697 | "cookie": "0.4.2", 1698 | "cookie-signature": "1.0.6", 1699 | "debug": "2.6.9", 1700 | "depd": "~1.1.2", 1701 | "encodeurl": "~1.0.2", 1702 | "escape-html": "~1.0.3", 1703 | "etag": "~1.8.1", 1704 | "finalhandler": "~1.1.2", 1705 | "fresh": "0.5.2", 1706 | "merge-descriptors": "1.0.1", 1707 | "methods": "~1.1.2", 1708 | "on-finished": "~2.3.0", 1709 | "parseurl": "~1.3.3", 1710 | "path-to-regexp": "0.1.7", 1711 | "proxy-addr": "~2.0.7", 1712 | "qs": "6.9.7", 1713 | "range-parser": "~1.2.1", 1714 | "safe-buffer": "5.2.1", 1715 | "send": "0.17.2", 1716 | "serve-static": "1.14.2", 1717 | "setprototypeof": "1.2.0", 1718 | "statuses": "~1.5.0", 1719 | "type-is": "~1.6.18", 1720 | "utils-merge": "1.0.1", 1721 | "vary": "~1.1.2" 1722 | }, 1723 | "dependencies": { 1724 | "body-parser": { 1725 | "version": "1.19.2", 1726 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", 1727 | "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", 1728 | "dev": true, 1729 | "requires": { 1730 | "bytes": "3.1.2", 1731 | "content-type": "~1.0.4", 1732 | "debug": "2.6.9", 1733 | "depd": "~1.1.2", 1734 | "http-errors": "1.8.1", 1735 | "iconv-lite": "0.4.24", 1736 | "on-finished": "~2.3.0", 1737 | "qs": "6.9.7", 1738 | "raw-body": "2.4.3", 1739 | "type-is": "~1.6.18" 1740 | } 1741 | }, 1742 | "depd": { 1743 | "version": "1.1.2", 1744 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 1745 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 1746 | "dev": true 1747 | }, 1748 | "http-errors": { 1749 | "version": "1.8.1", 1750 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", 1751 | "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", 1752 | "dev": true, 1753 | "requires": { 1754 | "depd": "~1.1.2", 1755 | "inherits": "2.0.4", 1756 | "setprototypeof": "1.2.0", 1757 | "statuses": ">= 1.5.0 < 2", 1758 | "toidentifier": "1.0.1" 1759 | } 1760 | }, 1761 | "on-finished": { 1762 | "version": "2.3.0", 1763 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1764 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1765 | "dev": true, 1766 | "requires": { 1767 | "ee-first": "1.1.1" 1768 | } 1769 | }, 1770 | "qs": { 1771 | "version": "6.9.7", 1772 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", 1773 | "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", 1774 | "dev": true 1775 | }, 1776 | "raw-body": { 1777 | "version": "2.4.3", 1778 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", 1779 | "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", 1780 | "dev": true, 1781 | "requires": { 1782 | "bytes": "3.1.2", 1783 | "http-errors": "1.8.1", 1784 | "iconv-lite": "0.4.24", 1785 | "unpipe": "1.0.0" 1786 | } 1787 | }, 1788 | "safe-buffer": { 1789 | "version": "5.2.1", 1790 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1791 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1792 | "dev": true 1793 | } 1794 | } 1795 | }, 1796 | "express-urlrewrite": { 1797 | "version": "1.4.0", 1798 | "resolved": "https://registry.npmjs.org/express-urlrewrite/-/express-urlrewrite-1.4.0.tgz", 1799 | "integrity": "sha512-PI5h8JuzoweS26vFizwQl6UTF25CAHSggNv0J25Dn/IKZscJHWZzPrI5z2Y2jgOzIaw2qh8l6+/jUcig23Z2SA==", 1800 | "dev": true, 1801 | "requires": { 1802 | "debug": "*", 1803 | "path-to-regexp": "^1.0.3" 1804 | }, 1805 | "dependencies": { 1806 | "path-to-regexp": { 1807 | "version": "1.8.0", 1808 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", 1809 | "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", 1810 | "dev": true, 1811 | "requires": { 1812 | "isarray": "0.0.1" 1813 | } 1814 | } 1815 | } 1816 | }, 1817 | "finalhandler": { 1818 | "version": "1.1.2", 1819 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 1820 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 1821 | "dev": true, 1822 | "requires": { 1823 | "debug": "2.6.9", 1824 | "encodeurl": "~1.0.2", 1825 | "escape-html": "~1.0.3", 1826 | "on-finished": "~2.3.0", 1827 | "parseurl": "~1.3.3", 1828 | "statuses": "~1.5.0", 1829 | "unpipe": "~1.0.0" 1830 | }, 1831 | "dependencies": { 1832 | "on-finished": { 1833 | "version": "2.3.0", 1834 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1835 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1836 | "dev": true, 1837 | "requires": { 1838 | "ee-first": "1.1.1" 1839 | } 1840 | } 1841 | } 1842 | }, 1843 | "forwarded": { 1844 | "version": "0.2.0", 1845 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 1846 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 1847 | "dev": true 1848 | }, 1849 | "fresh": { 1850 | "version": "0.5.2", 1851 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1852 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 1853 | "dev": true 1854 | }, 1855 | "function-bind": { 1856 | "version": "1.1.1", 1857 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1858 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 1859 | "dev": true 1860 | }, 1861 | "get-caller-file": { 1862 | "version": "2.0.5", 1863 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 1864 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 1865 | "dev": true 1866 | }, 1867 | "get-intrinsic": { 1868 | "version": "1.1.1", 1869 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", 1870 | "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", 1871 | "dev": true, 1872 | "requires": { 1873 | "function-bind": "^1.1.1", 1874 | "has": "^1.0.3", 1875 | "has-symbols": "^1.0.1" 1876 | } 1877 | }, 1878 | "graceful-fs": { 1879 | "version": "4.2.10", 1880 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", 1881 | "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", 1882 | "dev": true 1883 | }, 1884 | "has": { 1885 | "version": "1.0.3", 1886 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1887 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1888 | "dev": true, 1889 | "requires": { 1890 | "function-bind": "^1.1.1" 1891 | } 1892 | }, 1893 | "has-flag": { 1894 | "version": "4.0.0", 1895 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1896 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1897 | "dev": true 1898 | }, 1899 | "has-symbols": { 1900 | "version": "1.0.3", 1901 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 1902 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 1903 | "dev": true 1904 | }, 1905 | "http-errors": { 1906 | "version": "2.0.0", 1907 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 1908 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 1909 | "dev": true, 1910 | "requires": { 1911 | "depd": "2.0.0", 1912 | "inherits": "2.0.4", 1913 | "setprototypeof": "1.2.0", 1914 | "statuses": "2.0.1", 1915 | "toidentifier": "1.0.1" 1916 | }, 1917 | "dependencies": { 1918 | "statuses": { 1919 | "version": "2.0.1", 1920 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1921 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1922 | "dev": true 1923 | } 1924 | } 1925 | }, 1926 | "iconv-lite": { 1927 | "version": "0.4.24", 1928 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1929 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1930 | "dev": true, 1931 | "requires": { 1932 | "safer-buffer": ">= 2.1.2 < 3" 1933 | } 1934 | }, 1935 | "inherits": { 1936 | "version": "2.0.4", 1937 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1938 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1939 | "dev": true 1940 | }, 1941 | "ipaddr.js": { 1942 | "version": "1.9.1", 1943 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 1944 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 1945 | "dev": true 1946 | }, 1947 | "is-fullwidth-code-point": { 1948 | "version": "3.0.0", 1949 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1950 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1951 | "dev": true 1952 | }, 1953 | "is-promise": { 1954 | "version": "2.2.2", 1955 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", 1956 | "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", 1957 | "dev": true 1958 | }, 1959 | "isarray": { 1960 | "version": "0.0.1", 1961 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 1962 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", 1963 | "dev": true 1964 | }, 1965 | "jju": { 1966 | "version": "1.4.0", 1967 | "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", 1968 | "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=", 1969 | "dev": true 1970 | }, 1971 | "json-parse-helpfulerror": { 1972 | "version": "1.0.3", 1973 | "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", 1974 | "integrity": "sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w=", 1975 | "dev": true, 1976 | "requires": { 1977 | "jju": "^1.1.0" 1978 | } 1979 | }, 1980 | "json-server": { 1981 | "version": "0.17.1", 1982 | "resolved": "https://registry.npmjs.org/json-server/-/json-server-0.17.1.tgz", 1983 | "integrity": "sha512-2cR/IAL9xX4M1Y5ONMpnvRvJ5o9gJH5GsSQs7fQHdTKTKoN4YRZu1ApQKg/4P0XzwlLyUDqTlwhPq9nsvJ9acw==", 1984 | "dev": true, 1985 | "requires": { 1986 | "body-parser": "^1.19.0", 1987 | "chalk": "^4.1.2", 1988 | "compression": "^1.7.4", 1989 | "connect-pause": "^0.1.1", 1990 | "cors": "^2.8.5", 1991 | "errorhandler": "^1.5.1", 1992 | "express": "^4.17.1", 1993 | "express-urlrewrite": "^1.4.0", 1994 | "json-parse-helpfulerror": "^1.0.3", 1995 | "lodash": "^4.17.21", 1996 | "lodash-id": "^0.14.1", 1997 | "lowdb": "^1.0.0", 1998 | "method-override": "^3.0.0", 1999 | "morgan": "^1.10.0", 2000 | "nanoid": "^3.1.23", 2001 | "please-upgrade-node": "^3.2.0", 2002 | "pluralize": "^8.0.0", 2003 | "server-destroy": "^1.0.1", 2004 | "yargs": "^17.0.1" 2005 | } 2006 | }, 2007 | "lodash": { 2008 | "version": "4.17.21", 2009 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 2010 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 2011 | "dev": true 2012 | }, 2013 | "lodash-id": { 2014 | "version": "0.14.1", 2015 | "resolved": "https://registry.npmjs.org/lodash-id/-/lodash-id-0.14.1.tgz", 2016 | "integrity": "sha512-ikQPBTiq/d5m6dfKQlFdIXFzvThPi2Be9/AHxktOnDSfSxE1j9ICbBT5Elk1ke7HSTgM38LHTpmJovo9/klnLg==", 2017 | "dev": true 2018 | }, 2019 | "lowdb": { 2020 | "version": "1.0.0", 2021 | "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", 2022 | "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", 2023 | "dev": true, 2024 | "requires": { 2025 | "graceful-fs": "^4.1.3", 2026 | "is-promise": "^2.1.0", 2027 | "lodash": "4", 2028 | "pify": "^3.0.0", 2029 | "steno": "^0.4.1" 2030 | } 2031 | }, 2032 | "media-typer": { 2033 | "version": "0.3.0", 2034 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 2035 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", 2036 | "dev": true 2037 | }, 2038 | "merge-descriptors": { 2039 | "version": "1.0.1", 2040 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 2041 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", 2042 | "dev": true 2043 | }, 2044 | "method-override": { 2045 | "version": "3.0.0", 2046 | "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", 2047 | "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", 2048 | "dev": true, 2049 | "requires": { 2050 | "debug": "3.1.0", 2051 | "methods": "~1.1.2", 2052 | "parseurl": "~1.3.2", 2053 | "vary": "~1.1.2" 2054 | }, 2055 | "dependencies": { 2056 | "debug": { 2057 | "version": "3.1.0", 2058 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 2059 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 2060 | "dev": true, 2061 | "requires": { 2062 | "ms": "2.0.0" 2063 | } 2064 | } 2065 | } 2066 | }, 2067 | "methods": { 2068 | "version": "1.1.2", 2069 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 2070 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 2071 | "dev": true 2072 | }, 2073 | "mime": { 2074 | "version": "1.6.0", 2075 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 2076 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 2077 | "dev": true 2078 | }, 2079 | "mime-db": { 2080 | "version": "1.52.0", 2081 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 2082 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 2083 | "dev": true 2084 | }, 2085 | "mime-types": { 2086 | "version": "2.1.35", 2087 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 2088 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 2089 | "dev": true, 2090 | "requires": { 2091 | "mime-db": "1.52.0" 2092 | } 2093 | }, 2094 | "morgan": { 2095 | "version": "1.10.0", 2096 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", 2097 | "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", 2098 | "dev": true, 2099 | "requires": { 2100 | "basic-auth": "~2.0.1", 2101 | "debug": "2.6.9", 2102 | "depd": "~2.0.0", 2103 | "on-finished": "~2.3.0", 2104 | "on-headers": "~1.0.2" 2105 | }, 2106 | "dependencies": { 2107 | "on-finished": { 2108 | "version": "2.3.0", 2109 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 2110 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 2111 | "dev": true, 2112 | "requires": { 2113 | "ee-first": "1.1.1" 2114 | } 2115 | } 2116 | } 2117 | }, 2118 | "ms": { 2119 | "version": "2.0.0", 2120 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 2121 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 2122 | "dev": true 2123 | }, 2124 | "nanoid": { 2125 | "version": "3.3.2", 2126 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz", 2127 | "integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==", 2128 | "dev": true 2129 | }, 2130 | "negotiator": { 2131 | "version": "0.6.3", 2132 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 2133 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 2134 | "dev": true 2135 | }, 2136 | "object-assign": { 2137 | "version": "4.1.1", 2138 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 2139 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 2140 | "dev": true 2141 | }, 2142 | "object-inspect": { 2143 | "version": "1.12.0", 2144 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", 2145 | "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", 2146 | "dev": true 2147 | }, 2148 | "odottaa": { 2149 | "version": "1.1.1", 2150 | "resolved": "https://registry.npmjs.org/odottaa/-/odottaa-1.1.1.tgz", 2151 | "integrity": "sha512-ljdsnTSyiv1IYocDAaiCAQr0D5qqpnZZug2I1+PWBEaY4jCelNcgaQXJqlld1nu3+yc5V8L4nIx6EJ93IKB6Dw==", 2152 | "dev": true 2153 | }, 2154 | "on-finished": { 2155 | "version": "2.4.1", 2156 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 2157 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 2158 | "dev": true, 2159 | "requires": { 2160 | "ee-first": "1.1.1" 2161 | } 2162 | }, 2163 | "on-headers": { 2164 | "version": "1.0.2", 2165 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", 2166 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", 2167 | "dev": true 2168 | }, 2169 | "parseurl": { 2170 | "version": "1.3.3", 2171 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 2172 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 2173 | "dev": true 2174 | }, 2175 | "path-to-regexp": { 2176 | "version": "0.1.7", 2177 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 2178 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", 2179 | "dev": true 2180 | }, 2181 | "pify": { 2182 | "version": "3.0.0", 2183 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 2184 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", 2185 | "dev": true 2186 | }, 2187 | "playwright-core": { 2188 | "version": "1.26.1", 2189 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.26.1.tgz", 2190 | "integrity": "sha512-hzFchhhxnEiPc4qVPs9q2ZR+5eKNifY2hQDHtg1HnTTUuphYCBP8ZRb2si+B1TR7BHirgXaPi48LIye5SgrLAA==", 2191 | "dev": true 2192 | }, 2193 | "please-upgrade-node": { 2194 | "version": "3.2.0", 2195 | "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", 2196 | "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", 2197 | "dev": true, 2198 | "requires": { 2199 | "semver-compare": "^1.0.0" 2200 | } 2201 | }, 2202 | "pluralize": { 2203 | "version": "8.0.0", 2204 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", 2205 | "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", 2206 | "dev": true 2207 | }, 2208 | "proxy-addr": { 2209 | "version": "2.0.7", 2210 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 2211 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 2212 | "dev": true, 2213 | "requires": { 2214 | "forwarded": "0.2.0", 2215 | "ipaddr.js": "1.9.1" 2216 | } 2217 | }, 2218 | "qs": { 2219 | "version": "6.10.3", 2220 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", 2221 | "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", 2222 | "dev": true, 2223 | "requires": { 2224 | "side-channel": "^1.0.4" 2225 | } 2226 | }, 2227 | "range-parser": { 2228 | "version": "1.2.1", 2229 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 2230 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 2231 | "dev": true 2232 | }, 2233 | "raw-body": { 2234 | "version": "2.5.1", 2235 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 2236 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 2237 | "dev": true, 2238 | "requires": { 2239 | "bytes": "3.1.2", 2240 | "http-errors": "2.0.0", 2241 | "iconv-lite": "0.4.24", 2242 | "unpipe": "1.0.0" 2243 | } 2244 | }, 2245 | "require-directory": { 2246 | "version": "2.1.1", 2247 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 2248 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 2249 | "dev": true 2250 | }, 2251 | "safe-buffer": { 2252 | "version": "5.1.2", 2253 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2254 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 2255 | "dev": true 2256 | }, 2257 | "safer-buffer": { 2258 | "version": "2.1.2", 2259 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2260 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 2261 | "dev": true 2262 | }, 2263 | "semver-compare": { 2264 | "version": "1.0.0", 2265 | "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", 2266 | "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", 2267 | "dev": true 2268 | }, 2269 | "send": { 2270 | "version": "0.17.2", 2271 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", 2272 | "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", 2273 | "dev": true, 2274 | "requires": { 2275 | "debug": "2.6.9", 2276 | "depd": "~1.1.2", 2277 | "destroy": "~1.0.4", 2278 | "encodeurl": "~1.0.2", 2279 | "escape-html": "~1.0.3", 2280 | "etag": "~1.8.1", 2281 | "fresh": "0.5.2", 2282 | "http-errors": "1.8.1", 2283 | "mime": "1.6.0", 2284 | "ms": "2.1.3", 2285 | "on-finished": "~2.3.0", 2286 | "range-parser": "~1.2.1", 2287 | "statuses": "~1.5.0" 2288 | }, 2289 | "dependencies": { 2290 | "depd": { 2291 | "version": "1.1.2", 2292 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 2293 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 2294 | "dev": true 2295 | }, 2296 | "destroy": { 2297 | "version": "1.0.4", 2298 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 2299 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", 2300 | "dev": true 2301 | }, 2302 | "http-errors": { 2303 | "version": "1.8.1", 2304 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", 2305 | "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", 2306 | "dev": true, 2307 | "requires": { 2308 | "depd": "~1.1.2", 2309 | "inherits": "2.0.4", 2310 | "setprototypeof": "1.2.0", 2311 | "statuses": ">= 1.5.0 < 2", 2312 | "toidentifier": "1.0.1" 2313 | } 2314 | }, 2315 | "ms": { 2316 | "version": "2.1.3", 2317 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 2318 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 2319 | "dev": true 2320 | }, 2321 | "on-finished": { 2322 | "version": "2.3.0", 2323 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 2324 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 2325 | "dev": true, 2326 | "requires": { 2327 | "ee-first": "1.1.1" 2328 | } 2329 | } 2330 | } 2331 | }, 2332 | "serve-static": { 2333 | "version": "1.14.2", 2334 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", 2335 | "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", 2336 | "dev": true, 2337 | "requires": { 2338 | "encodeurl": "~1.0.2", 2339 | "escape-html": "~1.0.3", 2340 | "parseurl": "~1.3.3", 2341 | "send": "0.17.2" 2342 | } 2343 | }, 2344 | "server-destroy": { 2345 | "version": "1.0.1", 2346 | "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", 2347 | "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", 2348 | "dev": true 2349 | }, 2350 | "setprototypeof": { 2351 | "version": "1.2.0", 2352 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 2353 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 2354 | "dev": true 2355 | }, 2356 | "side-channel": { 2357 | "version": "1.0.4", 2358 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 2359 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 2360 | "dev": true, 2361 | "requires": { 2362 | "call-bind": "^1.0.0", 2363 | "get-intrinsic": "^1.0.2", 2364 | "object-inspect": "^1.9.0" 2365 | } 2366 | }, 2367 | "statuses": { 2368 | "version": "1.5.0", 2369 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 2370 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", 2371 | "dev": true 2372 | }, 2373 | "steno": { 2374 | "version": "0.4.4", 2375 | "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", 2376 | "integrity": "sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs=", 2377 | "dev": true, 2378 | "requires": { 2379 | "graceful-fs": "^4.1.3" 2380 | } 2381 | }, 2382 | "string-width": { 2383 | "version": "4.2.3", 2384 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2385 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2386 | "dev": true, 2387 | "requires": { 2388 | "emoji-regex": "^8.0.0", 2389 | "is-fullwidth-code-point": "^3.0.0", 2390 | "strip-ansi": "^6.0.1" 2391 | } 2392 | }, 2393 | "strip-ansi": { 2394 | "version": "6.0.1", 2395 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2396 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2397 | "dev": true, 2398 | "requires": { 2399 | "ansi-regex": "^5.0.1" 2400 | } 2401 | }, 2402 | "supports-color": { 2403 | "version": "7.2.0", 2404 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2405 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2406 | "dev": true, 2407 | "requires": { 2408 | "has-flag": "^4.0.0" 2409 | } 2410 | }, 2411 | "toidentifier": { 2412 | "version": "1.0.1", 2413 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 2414 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 2415 | "dev": true 2416 | }, 2417 | "type-is": { 2418 | "version": "1.6.18", 2419 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 2420 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 2421 | "dev": true, 2422 | "requires": { 2423 | "media-typer": "0.3.0", 2424 | "mime-types": "~2.1.24" 2425 | } 2426 | }, 2427 | "unpipe": { 2428 | "version": "1.0.0", 2429 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2430 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 2431 | "dev": true 2432 | }, 2433 | "utils-merge": { 2434 | "version": "1.0.1", 2435 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 2436 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 2437 | "dev": true 2438 | }, 2439 | "vary": { 2440 | "version": "1.1.2", 2441 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 2442 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 2443 | "dev": true 2444 | }, 2445 | "wrap-ansi": { 2446 | "version": "7.0.0", 2447 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2448 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2449 | "dev": true, 2450 | "requires": { 2451 | "ansi-styles": "^4.0.0", 2452 | "string-width": "^4.1.0", 2453 | "strip-ansi": "^6.0.0" 2454 | } 2455 | }, 2456 | "y18n": { 2457 | "version": "5.0.8", 2458 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 2459 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 2460 | "dev": true 2461 | }, 2462 | "yargs": { 2463 | "version": "17.4.0", 2464 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.0.tgz", 2465 | "integrity": "sha512-WJudfrk81yWFSOkZYpAZx4Nt7V4xp7S/uJkX0CnxovMCt1wCE8LNftPpNuF9X/u9gN5nsD7ycYtRcDf2pL3UiA==", 2466 | "dev": true, 2467 | "requires": { 2468 | "cliui": "^7.0.2", 2469 | "escalade": "^3.1.1", 2470 | "get-caller-file": "^2.0.5", 2471 | "require-directory": "^2.1.1", 2472 | "string-width": "^4.2.3", 2473 | "y18n": "^5.0.5", 2474 | "yargs-parser": "^21.0.0" 2475 | } 2476 | }, 2477 | "yargs-parser": { 2478 | "version": "21.0.1", 2479 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", 2480 | "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", 2481 | "dev": true 2482 | } 2483 | } 2484 | } 2485 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playwright-api-testing-example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node server/index.js", 8 | "test": "npx playwright test", 9 | "report": "npx playwright show-report" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/elaichenkov/playwright-api-testing-example.git" 14 | }, 15 | "keywords": [], 16 | "author": "", 17 | "license": "ISC", 18 | "bugs": { 19 | "url": "https://github.com/elaichenkov/playwright-api-testing-example/issues" 20 | }, 21 | "homepage": "https://github.com/elaichenkov/playwright-api-testing-example#readme", 22 | "devDependencies": { 23 | "@playwright/test": "^1.26.1", 24 | "json-server": "^0.17.1", 25 | "odottaa": "^1.1.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { expect, PlaywrightTestConfig } from '@playwright/test'; 2 | import playwrightApiMatchers from 'odottaa'; 3 | 4 | expect.extend(playwrightApiMatchers); 5 | 6 | const config: PlaywrightTestConfig = { 7 | reporter: [['html', { open: 'never' }]], 8 | globalSetup: './global-setup', 9 | webServer: { 10 | command: 'npm start', 11 | timeout: 120 * 1000, 12 | url: 'http://localhost:1337', 13 | reuseExistingServer: true, 14 | }, 15 | use: { 16 | baseURL: 'http://localhost:1337', 17 | extraHTTPHeaders: { 18 | 'Content-Type': 'application/json', 19 | }, 20 | }, 21 | }; 22 | 23 | export default config; 24 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | const jsonServer = require('json-server'); 2 | const server = jsonServer.create(); 3 | const router = jsonServer.router('./db.json'); 4 | const middlewares = jsonServer.defaults(); 5 | 6 | const PORT = process.env.PORT || 1337; 7 | 8 | function isAuthorized(req, res, next) { 9 | if (req.method !== 'GET') { 10 | if (req.headers.authorization) { 11 | const authToken = 'token 5jsBfMf72VYA9QzCXC5eXZkd3q6VB8Gc'; 12 | 13 | if (req.headers.authorization === authToken) { 14 | return next(); 15 | } 16 | 17 | const userAndPassword = new Buffer(req.headers.authorization.split(' ')[1], 'base64').toString(); 18 | const user = userAndPassword.split(':')[0]; 19 | const password = userAndPassword.split(':')[1]; 20 | 21 | if (user === 'admin' && password === 'admin') { 22 | next(); 23 | } else { 24 | res.status(401).send({ 25 | error: 'Unauthorized', 26 | }); 27 | } 28 | } else { 29 | res.status(401).send({ 30 | error: 'Unauthorized', 31 | }); 32 | } 33 | } else { 34 | next(); 35 | } 36 | } 37 | 38 | server.use(middlewares); 39 | server.use(isAuthorized); 40 | server.use(router); 41 | 42 | server.listen(PORT, () => console.log(`JSON Server is running on port ${PORT}`)); 43 | -------------------------------------------------------------------------------- /tests/posts.api.spec.ts: -------------------------------------------------------------------------------- 1 | // posts.api.spec.ts 2 | import { test, expect } from '@playwright/test'; 3 | 4 | const defaultPost = { 5 | title: 'json-server', 6 | author: 'typicode', 7 | id: 1, 8 | }; 9 | const post = { title: 'My new post', author: 'typicode' }; 10 | const authorization = 'token 5jsBfMf72VYA9QzCXC5eXZkd3q6VB8Gc'; 11 | 12 | test.describe('/posts endpoint', () => { 13 | test('GET - retrieve all posts', async ({ request }) => { 14 | const response = await request.get('/posts'); 15 | 16 | await expect(response).toBeOK(); 17 | await expect(response).toContainJSON(defaultPost); 18 | }); 19 | 20 | test("GET - retrieve posts and verify that's an array of posts", async ({ request }) => { 21 | const response = await request.get('/posts'); 22 | 23 | await expect(response).toBeOK(); 24 | await expect(response).toHaveJSON([defaultPost]); 25 | }); 26 | 27 | test('POST - create post without auth token', async ({ request }) => { 28 | const response = await request.post('/posts', { 29 | data: JSON.stringify(post), 30 | }); 31 | 32 | await expect(response).toBeUnauthorized(); 33 | await expect(response).toHaveJSON({ error: 'Unauthorized' }); 34 | }); 35 | 36 | test('POST - create post', async ({ request }) => { 37 | const response = await request.post('/posts', { 38 | headers: { authorization }, 39 | data: JSON.stringify(post), 40 | }); 41 | 42 | await expect(response).toBeCreated(); 43 | await expect(response).toMatchJSON(post); 44 | }); 45 | 46 | test('DELETE - post', async ({ request }) => { 47 | const [{ id }] = await (await request.get('/posts')).json(); 48 | const response = await request.delete(`/posts/${id}`, { 49 | headers: { authorization }, 50 | }); 51 | 52 | await expect(response).toBeOK(); 53 | await expect(response).toHaveJSON({}); 54 | }); 55 | }); 56 | --------------------------------------------------------------------------------