├── .dockerignore ├── .gitignore ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── db.json ├── deploy └── crocodile-deployment.yml ├── docs.md ├── grafana └── crocodile-metrics-dashboard.json ├── keda └── keda-prometheus-scaledobject.yml ├── package-lock.json ├── package.json ├── performance-test.js └── server.js /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.logdk -------------------------------------------------------------------------------- /.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 | build 107 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:slim 2 | WORKDIR /app 3 | COPY package*.json ./ 4 | RUN npm ci --only=production 5 | COPY . . 6 | EXPOSE 4000 7 | CMD npm start 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Michael Wanyoike 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 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: help 2 | 3 | help: 4 | @echo ---------------------------------- 5 | @echo CROCODILE API DEPLOYMENT COMMANDS 6 | @echo ---------------------------------- 7 | @echo make image - build and upload docker image to minikube environment 8 | @echo make apply - deploy crocodile-api and expose service 9 | @echo make test - test deployment 10 | @echo make delete - uninstall crocodile-api deployment and service 11 | 12 | delete: 13 | kubectl delete service crocodile-service 14 | kubectl delete deployment crocodile-api 15 | 16 | image: 17 | eval $(minikube docker-env) 18 | docker image prune -f 19 | docker build -t brandiqa/crocodile-api . 20 | 21 | apply: 22 | kubectl apply -f deploy/crocodile-deployment.yml 23 | kubectl get services | grep crocodile 24 | 25 | test: 26 | curl 10.98.55.109:4000/crocodiles 27 | 28 | local-run: 29 | ENDPOINT=http://localhost:4000/crocodiles k6 run performance-test.js 30 | 31 | local-influx-run: 32 | ENDPOINT=http://localhost:4000/crocodiles k6 run -o influxdb=http://localhost:8086/k6 performance-test.js 33 | 34 | run: 35 | ENDPOINT=http://10.98.55.109:4000/crocodiles k6 run -o influxdb=http://localhost:8086/k6 performance-test.js 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ⚠️ The examples in this project are outdated. For the instructions, please refer to: 2 | - [How to Autoscale Kubernetes Pods with Keda - Testing with k6](https://dev.to/k6/how-to-autoscale-kubernetes-pods-with-keda-testing-with-k6-4nl9) 3 | - [Example Instructions](./docs.md) -------------------------------------------------------------------------------- /db.json: -------------------------------------------------------------------------------- 1 | { 2 | "crocodiles": [ 3 | { 4 | "id": 1, 5 | "name": "Bert", 6 | "sex": "M", 7 | "date_of_birth": "2010-06-27", 8 | "age": 9 9 | }, 10 | { 11 | "id": 2, 12 | "name": "Ed", 13 | "sex": "M", 14 | "date_of_birth": "1995-02-27", 15 | "age": 25 16 | }, 17 | { 18 | "id": 3, 19 | "name": "Lyle the Crocodile", 20 | "sex": "M", 21 | "date_of_birth": "1985-03-03", 22 | "age": 35 23 | }, 24 | { 25 | "id": 4, 26 | "name": "Solomon", 27 | "sex": "M", 28 | "date_of_birth": "1993-12-25", 29 | "age": 26 30 | }, 31 | { 32 | "id": 5, 33 | "name": "The gharial", 34 | "sex": "F", 35 | "date_of_birth": "2004-06-28", 36 | "age": 15 37 | }, 38 | { 39 | "id": 6, 40 | "name": "Sang Buaya", 41 | "sex": "F", 42 | "date_of_birth": "2006-01-28", 43 | "age": 14 44 | }, 45 | { 46 | "id": 7, 47 | "name": "Sobek", 48 | "sex": "F", 49 | "date_of_birth": "1854-09-02", 50 | "age": 165 51 | }, 52 | { 53 | "id": 8, 54 | "name": "Curious George", 55 | "sex": "M", 56 | "date_of_birth": "1981-01-03", 57 | "age": 39 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /deploy/crocodile-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: crocodile-api 5 | labels: 6 | app: crocodile-api 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: crocodile-api 12 | template: 13 | metadata: 14 | labels: 15 | app: crocodile-api 16 | spec: 17 | containers: 18 | - name: crocodile 19 | image: brandiqa/crocodile-api 20 | imagePullPolicy: Never 21 | ports: 22 | - containerPort: 4000 23 | --- 24 | kind: Service 25 | apiVersion: v1 26 | metadata: 27 | name: crocodile-service 28 | annotations: 29 | prometheus.io/scrape: "true" 30 | prometheus.io/port: "4000" 31 | prometheus.io/path: "/metrics" 32 | spec: 33 | type: LoadBalancer 34 | selector: 35 | app: crocodile-api 36 | ports: 37 | - port: 4000 38 | targetPort: 4000 39 | protocol: TCP 40 | name: http 41 | -------------------------------------------------------------------------------- /docs.md: -------------------------------------------------------------------------------- 1 | ## Prerequisites 2 | 3 | You'll need to have the following installed: 4 | 5 | - [k6](https://k6.io/docs/getting-started/installation) 6 | - Node.js 7 | - Docker 8 | - GNU Make 9 | - [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) 10 | - [Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/) 11 | 12 | Here's a handy tutorial for [Ubuntu 18:04](https://computingforgeeks.com/how-to-install-minikube-on-ubuntu-18-04/) users. The instructions written for this project are meant for `minikube`. However, they can be modified to adapt to a different Kubernetes implementation. 13 | 14 | ## ENVIRONMENT SETUP 15 | 16 | ### 1. Configure Minikube 17 | 18 | Once your minikube is up and running, enable the following addons: 19 | 20 | ```bash 21 | $ minikube addons enable dashboard 22 | $ minikube addons enable ingress # optional 23 | $ minikube addons enable ingress-dns # optional 24 | ``` 25 | 26 | To access dashboard, type the following command from a terminal: `minikube dashboard`. You'll need to open a separate terminal and execute the following: 27 | 28 | ```bash 29 | minikube tunnel 30 | ``` 31 | 32 | This will allow you to easily access `ClusterPort` services via your web browser. 33 | 34 | ### 2. Deploy Prometheus, and Kube State Metrics Server 35 | 36 | We need to be able to collect and track metrics about our application. We'll use the following: 37 | 38 | - [Kube State metrics](https://github.com/kubernetes/kube-state-metrics): This is a service that extracts various metrics about all Kubernetes API objects such as deployments, pods e.t.c. Follow these [instructions](https://devopscube.com/setup-kube-state-metrics/) to deploy Kube State Metrics server to minikube. 39 | 40 | - [Prometheus](https://prometheus.io/) is an open source monitoring framework that scrapes(collects) metrics data from various sources such as the Kube State Metrics server. We can use it's query language to extract the information we need to determine if our application needs to be extracted. Use these [instructions](https://devopscube.com/setup-prometheus-monitoring-on-kubernetes/) to deploy Prometheus to minikube. 41 | 42 | ### 3. Install InfluxDb and Grafana Locally 43 | 44 | We can deploy InfluxDb and Grafana to Kubernetes as well. However, it's faster installing them locally: 45 | 46 | - InfluxDB 47 | - Grafana 48 | 49 | Ensure the above services are running. If you are on Linux, you can start with the command: 50 | 51 | ```bash 52 | sudo systemctl start influxdb grafana-server 53 | ``` 54 | 55 | Once Grafana is installed, you'll need to add **Prometheus** and **InfluxDB** as a data source. 56 | 57 | ### 4. Deploy Keda 58 | 59 | - [Keda]() will scale up or down our application based on the threshold we provide it. Follow these [instructions](https://keda.sh/docs/deploy/#yaml) to deploy Keda to minikube. 60 | 61 | At this point, Keda isn't configured to do anything. 62 | 63 | ### 5. Deploy Application 64 | 65 | Execute the following commands to download and run the project in your workspace: 66 | 67 | ```bash 68 | git clone git@github.com:k6io/example-kubernetes-autoscaling-nodejs-api.git 69 | cd test-node-api-k6 70 | npm i 71 | npm run dev 72 | ``` 73 | 74 | Point your browser URL to `localhost:4000`. Any changes you make to your source code will restart the server. You can also test the API from your command line like this: 75 | 76 | ```bash 77 | curl http://localhost:4000/crocodile 78 | ``` 79 | 80 | Next, deploy the application to Minikube, your Kubernetes node. Lucky for you, I've simplified the process. Just execute this one command: 81 | 82 | ```bash 83 | make image # build and upload docker image to minikube environment 84 | make apply # deploy crocodile-api and expose service 85 | ``` 86 | 87 | If you don't have GNU make on you platform, simply execute the following commands in a new terminal: 88 | 89 | ```bash 90 | # build and upload docker image to minikube environment 91 | eval $(minikube docker-env) 92 | docker image prune -f 93 | docker build -t brandiqa/crocodile-api . 94 | 95 | # deploy crocodile-api and expose service 96 | kubectl apply -f deploy/crocodile-deployment.yml 97 | ``` 98 | 99 | Execute the command to command `kubectl get pods` to confirm the pod is running. 100 | 101 | [todo screenshot] 102 | 103 | Execute the command to command `kubectl get services` to confirm the service is running. To ensure the service is exposed, perform a curl operation: 104 | 105 | ```bash 106 | curl 10.98.55.109:4000/crocodiles # replace ip address 107 | ``` 108 | 109 | If you get a timeout, ensure `minikube tunnel` is running on a separate terminal. 110 | 111 | ### 6. Run Load Testing without AutoScaling 112 | 113 | In this step, will run load testing test and send metrics to `influxdb`. Navigate to the root of the project and execute: 114 | 115 | ```bash 116 | # replace ip address 117 | ENDPOINT=http://10.98.55.109:4000/crocodiles k6 run -o influxdb=http://localhost:8086/k6 performance-test.js 118 | ``` 119 | 120 | ### 7. Run Load Testing WITH AutoScaling 121 | 122 | First deploy Keda's `scaledobject` configuration that scales up the project if the Prometheus expression, `sum(rate(node_http_requests_total[2m]))` exceeds 50 HTTP requests per second. 123 | 124 | ```bash 125 | kubectl deploy -f keda/keda-prometheus-scaledobject.yml 126 | ``` 127 | 128 | Next, run the `performance-test.js` again. You should see the number of pods gradually increase as traffic increases. -------------------------------------------------------------------------------- /grafana/crocodile-metrics-dashboard.json: -------------------------------------------------------------------------------- 1 | { 2 | "__inputs": [ 3 | { 4 | "name": "DS_PROMETHEUS", 5 | "label": "Prometheus", 6 | "description": "", 7 | "type": "datasource", 8 | "pluginId": "prometheus", 9 | "pluginName": "Prometheus" 10 | }, 11 | { 12 | "name": "DS_INFLUXDB-K6", 13 | "label": "InfluxDB-K6", 14 | "description": "", 15 | "type": "datasource", 16 | "pluginId": "influxdb", 17 | "pluginName": "InfluxDB" 18 | } 19 | ], 20 | "__requires": [ 21 | { 22 | "type": "panel", 23 | "id": "bargauge", 24 | "name": "Bar Gauge", 25 | "version": "" 26 | }, 27 | { 28 | "type": "panel", 29 | "id": "gauge", 30 | "name": "Gauge", 31 | "version": "" 32 | }, 33 | { 34 | "type": "grafana", 35 | "id": "grafana", 36 | "name": "Grafana", 37 | "version": "6.7.3" 38 | }, 39 | { 40 | "type": "panel", 41 | "id": "graph", 42 | "name": "Graph", 43 | "version": "" 44 | }, 45 | { 46 | "type": "datasource", 47 | "id": "influxdb", 48 | "name": "InfluxDB", 49 | "version": "1.0.0" 50 | }, 51 | { 52 | "type": "datasource", 53 | "id": "prometheus", 54 | "name": "Prometheus", 55 | "version": "1.0.0" 56 | } 57 | ], 58 | "annotations": { 59 | "list": [ 60 | { 61 | "$$hashKey": "object:155", 62 | "builtIn": 1, 63 | "datasource": "-- Grafana --", 64 | "enable": true, 65 | "hide": true, 66 | "iconColor": "rgba(0, 211, 255, 1)", 67 | "name": "Annotations & Alerts", 68 | "type": "dashboard" 69 | } 70 | ] 71 | }, 72 | "editable": true, 73 | "gnetId": null, 74 | "graphTooltip": 0, 75 | "id": null, 76 | "iteration": 1589906489073, 77 | "links": [], 78 | "panels": [ 79 | { 80 | "collapsed": false, 81 | "datasource": "${DS_PROMETHEUS}", 82 | "gridPos": { 83 | "h": 1, 84 | "w": 24, 85 | "x": 0, 86 | "y": 0 87 | }, 88 | "id": 12, 89 | "panels": [], 90 | "title": "K6 InfluxDB Metrics", 91 | "type": "row" 92 | }, 93 | { 94 | "aliasColors": {}, 95 | "bars": false, 96 | "dashLength": 10, 97 | "dashes": false, 98 | "datasource": "${DS_INFLUXDB-K6}", 99 | "fill": 1, 100 | "fillGradient": 0, 101 | "gridPos": { 102 | "h": 7, 103 | "w": 11, 104 | "x": 0, 105 | "y": 1 106 | }, 107 | "hiddenSeries": false, 108 | "id": 10, 109 | "interval": "1s", 110 | "legend": { 111 | "alignAsTable": true, 112 | "avg": true, 113 | "current": false, 114 | "max": true, 115 | "min": false, 116 | "rightSide": false, 117 | "show": true, 118 | "total": false, 119 | "values": true 120 | }, 121 | "lines": true, 122 | "linewidth": 1, 123 | "links": [], 124 | "nullPointMode": "connected", 125 | "options": { 126 | "dataLinks": [] 127 | }, 128 | "percentage": false, 129 | "pointradius": 1, 130 | "points": true, 131 | "renderer": "flot", 132 | "seriesOverrides": [], 133 | "spaceLength": 10, 134 | "stack": false, 135 | "steppedLine": false, 136 | "targets": [ 137 | { 138 | "alias": "Requests per Second", 139 | "dsType": "influxdb", 140 | "groupBy": [ 141 | { 142 | "params": [ 143 | "$__interval" 144 | ], 145 | "type": "time" 146 | }, 147 | { 148 | "params": [ 149 | "null" 150 | ], 151 | "type": "fill" 152 | } 153 | ], 154 | "measurement": "http_reqs", 155 | "orderByTime": "ASC", 156 | "policy": "default", 157 | "refId": "A", 158 | "resultFormat": "time_series", 159 | "select": [ 160 | [ 161 | { 162 | "params": [ 163 | "value" 164 | ], 165 | "type": "field" 166 | }, 167 | { 168 | "params": [], 169 | "type": "sum" 170 | } 171 | ] 172 | ], 173 | "tags": [] 174 | } 175 | ], 176 | "thresholds": [], 177 | "timeFrom": null, 178 | "timeRegions": [], 179 | "timeShift": null, 180 | "title": "Requests per Second", 181 | "tooltip": { 182 | "shared": true, 183 | "sort": 0, 184 | "value_type": "individual" 185 | }, 186 | "type": "graph", 187 | "xaxis": { 188 | "buckets": null, 189 | "mode": "time", 190 | "name": null, 191 | "show": true, 192 | "values": [] 193 | }, 194 | "yaxes": [ 195 | { 196 | "format": "short", 197 | "label": null, 198 | "logBase": 1, 199 | "max": null, 200 | "min": "0", 201 | "show": true 202 | }, 203 | { 204 | "format": "short", 205 | "label": null, 206 | "logBase": 1, 207 | "max": null, 208 | "min": null, 209 | "show": true 210 | } 211 | ], 212 | "yaxis": { 213 | "align": false, 214 | "alignLevel": null 215 | } 216 | }, 217 | { 218 | "aliasColors": {}, 219 | "bars": true, 220 | "dashLength": 10, 221 | "dashes": false, 222 | "datasource": "${DS_INFLUXDB-K6}", 223 | "fill": 1, 224 | "fillGradient": 0, 225 | "gridPos": { 226 | "h": 7, 227 | "w": 11, 228 | "x": 11, 229 | "y": 1 230 | }, 231 | "hiddenSeries": false, 232 | "id": 8, 233 | "interval": ">1s", 234 | "legend": { 235 | "alignAsTable": true, 236 | "avg": false, 237 | "current": true, 238 | "max": true, 239 | "min": false, 240 | "show": true, 241 | "total": false, 242 | "values": true 243 | }, 244 | "lines": false, 245 | "linewidth": 1, 246 | "links": [], 247 | "nullPointMode": "null", 248 | "options": { 249 | "dataLinks": [] 250 | }, 251 | "percentage": false, 252 | "pointradius": 5, 253 | "points": false, 254 | "renderer": "flot", 255 | "seriesOverrides": [], 256 | "spaceLength": 10, 257 | "stack": false, 258 | "steppedLine": false, 259 | "targets": [ 260 | { 261 | "alias": "Active VUs", 262 | "dsType": "influxdb", 263 | "groupBy": [ 264 | { 265 | "params": [ 266 | "$__interval" 267 | ], 268 | "type": "time" 269 | }, 270 | { 271 | "params": [ 272 | "none" 273 | ], 274 | "type": "fill" 275 | } 276 | ], 277 | "measurement": "vus", 278 | "orderByTime": "ASC", 279 | "policy": "default", 280 | "refId": "A", 281 | "resultFormat": "time_series", 282 | "select": [ 283 | [ 284 | { 285 | "params": [ 286 | "value" 287 | ], 288 | "type": "field" 289 | }, 290 | { 291 | "params": [], 292 | "type": "mean" 293 | } 294 | ] 295 | ], 296 | "tags": [] 297 | } 298 | ], 299 | "thresholds": [], 300 | "timeFrom": null, 301 | "timeRegions": [], 302 | "timeShift": null, 303 | "title": "Virtual Users", 304 | "tooltip": { 305 | "shared": true, 306 | "sort": 0, 307 | "value_type": "individual" 308 | }, 309 | "type": "graph", 310 | "xaxis": { 311 | "buckets": null, 312 | "mode": "time", 313 | "name": null, 314 | "show": true, 315 | "values": [] 316 | }, 317 | "yaxes": [ 318 | { 319 | "$$hashKey": "object:228", 320 | "format": "short", 321 | "label": null, 322 | "logBase": 1, 323 | "max": null, 324 | "min": "0", 325 | "show": true 326 | }, 327 | { 328 | "$$hashKey": "object:229", 329 | "format": "short", 330 | "label": null, 331 | "logBase": 1, 332 | "max": null, 333 | "min": null, 334 | "show": true 335 | } 336 | ], 337 | "yaxis": { 338 | "align": false, 339 | "alignLevel": null 340 | } 341 | }, 342 | { 343 | "collapsed": false, 344 | "datasource": "${DS_PROMETHEUS}", 345 | "gridPos": { 346 | "h": 1, 347 | "w": 24, 348 | "x": 0, 349 | "y": 8 350 | }, 351 | "id": 14, 352 | "panels": [], 353 | "title": "Crocodile Prometheus Metrics", 354 | "type": "row" 355 | }, 356 | { 357 | "aliasColors": {}, 358 | "bars": false, 359 | "dashLength": 10, 360 | "dashes": false, 361 | "datasource": "${DS_PROMETHEUS}", 362 | "fill": 1, 363 | "fillGradient": 0, 364 | "gridPos": { 365 | "h": 6, 366 | "w": 11, 367 | "x": 0, 368 | "y": 9 369 | }, 370 | "hiddenSeries": false, 371 | "id": 16, 372 | "legend": { 373 | "avg": false, 374 | "current": false, 375 | "max": false, 376 | "min": false, 377 | "show": true, 378 | "total": false, 379 | "values": false 380 | }, 381 | "lines": true, 382 | "linewidth": 1, 383 | "nullPointMode": "null", 384 | "options": { 385 | "dataLinks": [] 386 | }, 387 | "percentage": false, 388 | "pluginVersion": "6.7.3", 389 | "pointradius": 2, 390 | "points": false, 391 | "renderer": "flot", 392 | "seriesOverrides": [], 393 | "spaceLength": 10, 394 | "stack": false, 395 | "steppedLine": false, 396 | "targets": [ 397 | { 398 | "expr": "sum(kube_pod_status_phase{namespace=\"default\", phase=\"Running\"})", 399 | "instant": false, 400 | "interval": "", 401 | "legendFormat": "Running", 402 | "refId": "A" 403 | }, 404 | { 405 | "expr": "sum(kube_pod_status_phase{namespace=\"default\", phase=\"Pending\"})", 406 | "hide": true, 407 | "instant": false, 408 | "interval": "", 409 | "legendFormat": "Pending", 410 | "refId": "B" 411 | }, 412 | { 413 | "expr": "sum(kube_pod_status_phase{namespace=\"default\", phase=\"Failed\"})", 414 | "hide": true, 415 | "instant": false, 416 | "interval": "", 417 | "legendFormat": "Failed", 418 | "refId": "C" 419 | } 420 | ], 421 | "thresholds": [], 422 | "timeFrom": null, 423 | "timeRegions": [], 424 | "timeShift": null, 425 | "title": "Running Pods", 426 | "tooltip": { 427 | "shared": true, 428 | "sort": 0, 429 | "value_type": "individual" 430 | }, 431 | "type": "graph", 432 | "xaxis": { 433 | "buckets": null, 434 | "mode": "time", 435 | "name": null, 436 | "show": true, 437 | "values": [] 438 | }, 439 | "yaxes": [ 440 | { 441 | "$$hashKey": "object:662", 442 | "format": "short", 443 | "label": null, 444 | "logBase": 1, 445 | "max": null, 446 | "min": null, 447 | "show": true 448 | }, 449 | { 450 | "$$hashKey": "object:663", 451 | "format": "short", 452 | "label": null, 453 | "logBase": 1, 454 | "max": null, 455 | "min": null, 456 | "show": true 457 | } 458 | ], 459 | "yaxis": { 460 | "align": false, 461 | "alignLevel": null 462 | } 463 | }, 464 | { 465 | "datasource": "${DS_PROMETHEUS}", 466 | "gridPos": { 467 | "h": 6, 468 | "w": 11, 469 | "x": 11, 470 | "y": 9 471 | }, 472 | "id": 29, 473 | "options": { 474 | "displayMode": "lcd", 475 | "fieldOptions": { 476 | "calcs": [ 477 | "last" 478 | ], 479 | "defaults": { 480 | "mappings": [], 481 | "max": 10, 482 | "min": 1, 483 | "thresholds": { 484 | "mode": "absolute", 485 | "steps": [ 486 | { 487 | "color": "green", 488 | "value": null 489 | }, 490 | { 491 | "color": "#EAB839", 492 | "value": 6 493 | }, 494 | { 495 | "color": "red", 496 | "value": 8 497 | } 498 | ] 499 | } 500 | }, 501 | "overrides": [], 502 | "values": false 503 | }, 504 | "orientation": "vertical", 505 | "showUnfilled": true 506 | }, 507 | "pluginVersion": "6.7.3", 508 | "targets": [ 509 | { 510 | "expr": "sum(kube_pod_status_phase{namespace=\"default\", phase=\"Running\"})", 511 | "instant": false, 512 | "interval": "", 513 | "legendFormat": "Running", 514 | "refId": "A" 515 | }, 516 | { 517 | "expr": "sum(kube_pod_status_phase{namespace=\"default\", phase=\"Pending\"})", 518 | "instant": false, 519 | "interval": "", 520 | "legendFormat": "Pending", 521 | "refId": "B" 522 | }, 523 | { 524 | "expr": "sum(kube_pod_status_phase{namespace=\"default\", phase=\"Failed\"})", 525 | "instant": false, 526 | "interval": "", 527 | "legendFormat": "Failed", 528 | "refId": "C" 529 | } 530 | ], 531 | "timeFrom": null, 532 | "timeShift": null, 533 | "title": "Pod Status", 534 | "type": "bargauge" 535 | }, 536 | { 537 | "aliasColors": {}, 538 | "bars": false, 539 | "dashLength": 10, 540 | "dashes": false, 541 | "datasource": "${DS_PROMETHEUS}", 542 | "fill": 1, 543 | "fillGradient": 0, 544 | "gridPos": { 545 | "h": 9, 546 | "w": 7, 547 | "x": 0, 548 | "y": 15 549 | }, 550 | "hiddenSeries": false, 551 | "id": 4, 552 | "legend": { 553 | "alignAsTable": true, 554 | "avg": true, 555 | "current": true, 556 | "hideEmpty": true, 557 | "hideZero": true, 558 | "max": true, 559 | "min": false, 560 | "rightSide": false, 561 | "show": true, 562 | "total": false, 563 | "values": true 564 | }, 565 | "lines": true, 566 | "linewidth": 1, 567 | "nullPointMode": "null", 568 | "options": { 569 | "dataLinks": [] 570 | }, 571 | "percentage": false, 572 | "pointradius": 2, 573 | "points": false, 574 | "renderer": "flot", 575 | "seriesOverrides": [], 576 | "spaceLength": 10, 577 | "stack": false, 578 | "steppedLine": false, 579 | "targets": [ 580 | { 581 | "expr": "rate(node_http_requests_total{status=\"200\"}[2m])", 582 | "instant": false, 583 | "interval": "", 584 | "legendFormat": "address: {{instance}}", 585 | "refId": "A" 586 | } 587 | ], 588 | "thresholds": [], 589 | "timeFrom": null, 590 | "timeRegions": [], 591 | "timeShift": null, 592 | "title": "HTTP Request Rate/Second", 593 | "tooltip": { 594 | "shared": true, 595 | "sort": 0, 596 | "value_type": "individual" 597 | }, 598 | "type": "graph", 599 | "xaxis": { 600 | "buckets": null, 601 | "mode": "time", 602 | "name": null, 603 | "show": true, 604 | "values": [] 605 | }, 606 | "yaxes": [ 607 | { 608 | "$$hashKey": "object:410", 609 | "format": "short", 610 | "label": "Rate", 611 | "logBase": 1, 612 | "max": null, 613 | "min": null, 614 | "show": true 615 | }, 616 | { 617 | "$$hashKey": "object:411", 618 | "format": "short", 619 | "label": null, 620 | "logBase": 1, 621 | "max": null, 622 | "min": null, 623 | "show": true 624 | } 625 | ], 626 | "yaxis": { 627 | "align": false, 628 | "alignLevel": null 629 | } 630 | }, 631 | { 632 | "aliasColors": {}, 633 | "bars": false, 634 | "dashLength": 10, 635 | "dashes": false, 636 | "datasource": "${DS_PROMETHEUS}", 637 | "fill": 1, 638 | "fillGradient": 0, 639 | "gridPos": { 640 | "h": 9, 641 | "w": 6, 642 | "x": 7, 643 | "y": 15 644 | }, 645 | "hiddenSeries": false, 646 | "id": 6, 647 | "legend": { 648 | "alignAsTable": true, 649 | "avg": true, 650 | "current": true, 651 | "max": false, 652 | "min": false, 653 | "show": true, 654 | "total": false, 655 | "values": true 656 | }, 657 | "lines": true, 658 | "linewidth": 1, 659 | "nullPointMode": "null", 660 | "options": { 661 | "dataLinks": [] 662 | }, 663 | "percentage": false, 664 | "pointradius": 2, 665 | "points": false, 666 | "renderer": "flot", 667 | "seriesOverrides": [], 668 | "spaceLength": 10, 669 | "stack": false, 670 | "steppedLine": false, 671 | "targets": [ 672 | { 673 | "expr": "node_http_duration_seconds{quantile=\"0.99\"} * 1000", 674 | "interval": "", 675 | "legendFormat": "address {{instance}}", 676 | "refId": "A" 677 | } 678 | ], 679 | "thresholds": [], 680 | "timeFrom": null, 681 | "timeRegions": [], 682 | "timeShift": null, 683 | "title": "Response Time - 0.99 Percentiles", 684 | "tooltip": { 685 | "shared": true, 686 | "sort": 0, 687 | "value_type": "individual" 688 | }, 689 | "type": "graph", 690 | "xaxis": { 691 | "buckets": null, 692 | "mode": "time", 693 | "name": null, 694 | "show": true, 695 | "values": [] 696 | }, 697 | "yaxes": [ 698 | { 699 | "$$hashKey": "object:147", 700 | "format": "ms", 701 | "label": null, 702 | "logBase": 1, 703 | "max": null, 704 | "min": null, 705 | "show": true 706 | }, 707 | { 708 | "$$hashKey": "object:148", 709 | "format": "short", 710 | "label": null, 711 | "logBase": 1, 712 | "max": null, 713 | "min": null, 714 | "show": true 715 | } 716 | ], 717 | "yaxis": { 718 | "align": false, 719 | "alignLevel": null 720 | } 721 | }, 722 | { 723 | "aliasColors": {}, 724 | "bars": false, 725 | "dashLength": 10, 726 | "dashes": false, 727 | "datasource": "${DS_PROMETHEUS}", 728 | "fill": 1, 729 | "fillGradient": 0, 730 | "gridPos": { 731 | "h": 9, 732 | "w": 9, 733 | "x": 13, 734 | "y": 15 735 | }, 736 | "hiddenSeries": false, 737 | "id": 28, 738 | "legend": { 739 | "alignAsTable": true, 740 | "avg": false, 741 | "current": true, 742 | "hideEmpty": true, 743 | "hideZero": true, 744 | "max": true, 745 | "min": false, 746 | "rightSide": true, 747 | "show": true, 748 | "sort": "avg", 749 | "sortDesc": true, 750 | "total": false, 751 | "values": true 752 | }, 753 | "lines": true, 754 | "linewidth": 1, 755 | "links": [], 756 | "nullPointMode": "null", 757 | "options": { 758 | "dataLinks": [] 759 | }, 760 | "percentage": false, 761 | "pointradius": 5, 762 | "points": false, 763 | "renderer": "flot", 764 | "seriesOverrides": [], 765 | "spaceLength": 10, 766 | "stack": false, 767 | "steppedLine": false, 768 | "targets": [ 769 | { 770 | "expr": "sum(container_memory_usage_bytes{container=\"$container\", namespace=\"$namespace\"}) by (id,pod)", 771 | "format": "time_series", 772 | "interval": "", 773 | "intervalFactor": 2, 774 | "legendFormat": "pod", 775 | "refId": "A", 776 | "step": 2 777 | }, 778 | { 779 | "expr": "sum(container_spec_memory_limit_bytes{container=\"$container\", namespace=\"$namespace\"}) by (namespace,container) / count(container_memory_usage_bytes{container=\"$container\", namespace=\"$namespace\"}) by (container,namespace)", 780 | "hide": true, 781 | "interval": "", 782 | "intervalFactor": 2, 783 | "legendFormat": "limit", 784 | "refId": "B", 785 | "step": 2 786 | } 787 | ], 788 | "thresholds": [], 789 | "timeFrom": null, 790 | "timeRegions": [], 791 | "timeShift": null, 792 | "title": "Memory usage (per pod)", 793 | "tooltip": { 794 | "shared": true, 795 | "sort": 0, 796 | "value_type": "individual" 797 | }, 798 | "type": "graph", 799 | "xaxis": { 800 | "buckets": null, 801 | "mode": "time", 802 | "name": null, 803 | "show": true, 804 | "values": [] 805 | }, 806 | "yaxes": [ 807 | { 808 | "$$hashKey": "object:89", 809 | "format": "bytes", 810 | "label": null, 811 | "logBase": 1, 812 | "max": null, 813 | "min": "0", 814 | "show": true 815 | }, 816 | { 817 | "$$hashKey": "object:90", 818 | "decimals": null, 819 | "format": "short", 820 | "label": null, 821 | "logBase": 1, 822 | "max": null, 823 | "min": null, 824 | "show": true 825 | } 826 | ], 827 | "yaxis": { 828 | "align": true, 829 | "alignLevel": null 830 | } 831 | }, 832 | { 833 | "collapsed": true, 834 | "datasource": "${DS_PROMETHEUS}", 835 | "gridPos": { 836 | "h": 1, 837 | "w": 24, 838 | "x": 0, 839 | "y": 24 840 | }, 841 | "id": 31, 842 | "panels": [ 843 | { 844 | "aliasColors": {}, 845 | "bars": false, 846 | "dashLength": 10, 847 | "dashes": false, 848 | "datasource": "${DS_INFLUXDB-K6}", 849 | "fill": 0, 850 | "fillGradient": 0, 851 | "gridPos": { 852 | "h": 7, 853 | "w": 6, 854 | "x": 0, 855 | "y": 26 856 | }, 857 | "hiddenSeries": false, 858 | "id": 24, 859 | "interval": ">1s", 860 | "legend": { 861 | "alignAsTable": true, 862 | "avg": true, 863 | "current": false, 864 | "max": false, 865 | "min": false, 866 | "show": true, 867 | "total": true, 868 | "values": true 869 | }, 870 | "lines": true, 871 | "linewidth": 1, 872 | "links": [], 873 | "nullPointMode": "null", 874 | "options": { 875 | "dataLinks": [] 876 | }, 877 | "percentage": false, 878 | "pointradius": 0.5, 879 | "points": true, 880 | "renderer": "flot", 881 | "seriesOverrides": [ 882 | { 883 | "alias": "Num Errors", 884 | "color": "#BF1B00" 885 | } 886 | ], 887 | "spaceLength": 10, 888 | "stack": true, 889 | "steppedLine": false, 890 | "targets": [ 891 | { 892 | "alias": "$tag_check", 893 | "dsType": "influxdb", 894 | "groupBy": [ 895 | { 896 | "params": [ 897 | "$__interval" 898 | ], 899 | "type": "time" 900 | }, 901 | { 902 | "params": [ 903 | "check" 904 | ], 905 | "type": "tag" 906 | }, 907 | { 908 | "params": [ 909 | "none" 910 | ], 911 | "type": "fill" 912 | } 913 | ], 914 | "measurement": "checks", 915 | "orderByTime": "ASC", 916 | "policy": "default", 917 | "refId": "C", 918 | "resultFormat": "time_series", 919 | "select": [ 920 | [ 921 | { 922 | "params": [ 923 | "value" 924 | ], 925 | "type": "field" 926 | }, 927 | { 928 | "params": [], 929 | "type": "sum" 930 | } 931 | ] 932 | ], 933 | "tags": [] 934 | } 935 | ], 936 | "thresholds": [], 937 | "timeFrom": null, 938 | "timeRegions": [], 939 | "timeShift": null, 940 | "title": "Checks Per Second", 941 | "tooltip": { 942 | "shared": true, 943 | "sort": 0, 944 | "value_type": "individual" 945 | }, 946 | "type": "graph", 947 | "xaxis": { 948 | "buckets": null, 949 | "mode": "time", 950 | "name": null, 951 | "show": true, 952 | "values": [] 953 | }, 954 | "yaxes": [ 955 | { 956 | "format": "none", 957 | "label": null, 958 | "logBase": 1, 959 | "max": null, 960 | "min": null, 961 | "show": true 962 | }, 963 | { 964 | "format": "short", 965 | "label": null, 966 | "logBase": 1, 967 | "max": null, 968 | "min": null, 969 | "show": true 970 | } 971 | ], 972 | "yaxis": { 973 | "align": false, 974 | "alignLevel": null 975 | } 976 | }, 977 | { 978 | "datasource": "${DS_PROMETHEUS}", 979 | "gridPos": { 980 | "h": 7, 981 | "w": 4, 982 | "x": 6, 983 | "y": 26 984 | }, 985 | "id": 2, 986 | "options": { 987 | "fieldOptions": { 988 | "calcs": [ 989 | "last" 990 | ], 991 | "defaults": { 992 | "links": [], 993 | "mappings": [], 994 | "max": 10, 995 | "min": 1, 996 | "thresholds": { 997 | "mode": "absolute", 998 | "steps": [ 999 | { 1000 | "color": "green", 1001 | "value": null 1002 | }, 1003 | { 1004 | "color": "#EAB839", 1005 | "value": 6 1006 | }, 1007 | { 1008 | "color": "red", 1009 | "value": 9 1010 | } 1011 | ] 1012 | }, 1013 | "title": "Pods", 1014 | "unit": "short" 1015 | }, 1016 | "overrides": [], 1017 | "values": false 1018 | }, 1019 | "orientation": "auto", 1020 | "showThresholdLabels": false, 1021 | "showThresholdMarkers": true 1022 | }, 1023 | "pluginVersion": "6.7.3", 1024 | "targets": [ 1025 | { 1026 | "expr": "count(kube_pod_container_info{container=\"crocodile\"})", 1027 | "instant": false, 1028 | "interval": "", 1029 | "legendFormat": "", 1030 | "refId": "A" 1031 | } 1032 | ], 1033 | "timeFrom": null, 1034 | "timeShift": null, 1035 | "title": "Total Crocodile Pods", 1036 | "type": "gauge" 1037 | } 1038 | ], 1039 | "title": "Archived", 1040 | "type": "row" 1041 | } 1042 | ], 1043 | "refresh": " 5s", 1044 | "schemaVersion": 22, 1045 | "style": "dark", 1046 | "tags": [], 1047 | "templating": { 1048 | "list": [ 1049 | { 1050 | "allValue": null, 1051 | "current": {}, 1052 | "datasource": "${DS_PROMETHEUS}", 1053 | "definition": "label_values(container_memory_usage_bytes{namespace=~\".+\",container!=\"POD\"},namespace)", 1054 | "hide": 0, 1055 | "includeAll": false, 1056 | "index": -1, 1057 | "label": "Namespace", 1058 | "multi": false, 1059 | "name": "namespace", 1060 | "options": [], 1061 | "query": "label_values(container_memory_usage_bytes{namespace=~\".+\",container!=\"POD\"},namespace)", 1062 | "refresh": 1, 1063 | "regex": "", 1064 | "skipUrlSync": false, 1065 | "sort": 1, 1066 | "tagValuesQuery": "", 1067 | "tags": [], 1068 | "tagsQuery": "", 1069 | "type": "query", 1070 | "useTags": false 1071 | }, 1072 | { 1073 | "allValue": null, 1074 | "current": {}, 1075 | "datasource": "${DS_PROMETHEUS}", 1076 | "definition": "label_values(container_memory_usage_bytes{namespace=~\"$namespace\",container_name!=\"POD\"},container_name)", 1077 | "hide": 0, 1078 | "includeAll": false, 1079 | "index": -1, 1080 | "label": "Container", 1081 | "multi": false, 1082 | "name": "container", 1083 | "options": [], 1084 | "query": "label_values(container_memory_usage_bytes{namespace=~\"$namespace\",container_name!=\"POD\"},container_name)", 1085 | "refresh": 1, 1086 | "regex": "", 1087 | "skipUrlSync": false, 1088 | "sort": 1, 1089 | "tagValuesQuery": "", 1090 | "tags": [], 1091 | "tagsQuery": "", 1092 | "type": "query", 1093 | "useTags": false 1094 | } 1095 | ] 1096 | }, 1097 | "time": { 1098 | "from": "now-30m", 1099 | "to": "now" 1100 | }, 1101 | "timepicker": { 1102 | "refresh_intervals": [ 1103 | "1s", 1104 | " 5s", 1105 | "10s", 1106 | "30s", 1107 | "1m", 1108 | "5m", 1109 | "15m", 1110 | "30m", 1111 | "1h", 1112 | "2h", 1113 | "1d" 1114 | ] 1115 | }, 1116 | "timezone": "", 1117 | "title": "Crocodile Metrics dashboard", 1118 | "uid": "n1copReWk", 1119 | "variables": { 1120 | "list": [] 1121 | }, 1122 | "version": 44 1123 | } -------------------------------------------------------------------------------- /keda/keda-prometheus-scaledobject.yml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: keda.k8s.io/v1alpha1 3 | kind: ScaledObject 4 | metadata: 5 | name: prometheus-scaledobject 6 | namespace: default 7 | labels: 8 | deploymentName: crocodile-api 9 | spec: 10 | scaleTargetRef: 11 | deploymentName: crocodile-api 12 | pollingInterval: 10 # Optional. Default: 30 seconds 13 | cooldownPeriod: 15 # Optional. Default: 300 seconds 14 | minReplicaCount: 1 # Optional. Default: 0 15 | maxReplicaCount: 10 # Optional. Default: 100 16 | triggers: 17 | - type: prometheus 18 | metadata: 19 | # Required 20 | serverAddress: http://10.103.240.12:8080 21 | metricName: access_frequency 22 | threshold: '50' 23 | query: sum(rate(node_http_requests_total[2m])) -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-api-autoscaling-example", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@sindresorhus/is": { 8 | "version": "0.14.0", 9 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", 10 | "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" 11 | }, 12 | "@szmarczak/http-timer": { 13 | "version": "1.1.2", 14 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", 15 | "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", 16 | "requires": { 17 | "defer-to-connect": "^1.0.1" 18 | } 19 | }, 20 | "@tailorbrands/node-exporter-prometheus": { 21 | "version": "2.0.6", 22 | "resolved": "https://registry.npmjs.org/@tailorbrands/node-exporter-prometheus/-/node-exporter-prometheus-2.0.6.tgz", 23 | "integrity": "sha512-2E9fWA+thKnAGPBRxOrr1cjQ/fsKtAos3eJjjGu9kPRzAXZJErvEBEFwQcuBdLrZx9C/hS1D1ws9uVHu6TRFAg==", 24 | "requires": { 25 | "prom-client": "11.2.0" 26 | } 27 | }, 28 | "@types/color-name": { 29 | "version": "1.1.1", 30 | "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", 31 | "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" 32 | }, 33 | "abbrev": { 34 | "version": "1.1.1", 35 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 36 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", 37 | "dev": true 38 | }, 39 | "accepts": { 40 | "version": "1.3.7", 41 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 42 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 43 | "requires": { 44 | "mime-types": "~2.1.24", 45 | "negotiator": "0.6.2" 46 | } 47 | }, 48 | "ajv": { 49 | "version": "6.12.2", 50 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", 51 | "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", 52 | "requires": { 53 | "fast-deep-equal": "^3.1.1", 54 | "fast-json-stable-stringify": "^2.0.0", 55 | "json-schema-traverse": "^0.4.1", 56 | "uri-js": "^4.2.2" 57 | } 58 | }, 59 | "ansi-align": { 60 | "version": "3.0.0", 61 | "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", 62 | "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", 63 | "requires": { 64 | "string-width": "^3.0.0" 65 | }, 66 | "dependencies": { 67 | "string-width": { 68 | "version": "3.1.0", 69 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 70 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 71 | "requires": { 72 | "emoji-regex": "^7.0.1", 73 | "is-fullwidth-code-point": "^2.0.0", 74 | "strip-ansi": "^5.1.0" 75 | } 76 | } 77 | } 78 | }, 79 | "ansi-regex": { 80 | "version": "4.1.0", 81 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 82 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" 83 | }, 84 | "ansi-styles": { 85 | "version": "4.2.1", 86 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", 87 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", 88 | "requires": { 89 | "@types/color-name": "^1.1.1", 90 | "color-convert": "^2.0.1" 91 | } 92 | }, 93 | "anymatch": { 94 | "version": "3.1.1", 95 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", 96 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", 97 | "dev": true, 98 | "requires": { 99 | "normalize-path": "^3.0.0", 100 | "picomatch": "^2.0.4" 101 | } 102 | }, 103 | "array-flatten": { 104 | "version": "1.1.1", 105 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 106 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 107 | }, 108 | "asn1": { 109 | "version": "0.2.4", 110 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 111 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 112 | "requires": { 113 | "safer-buffer": "~2.1.0" 114 | } 115 | }, 116 | "assert-plus": { 117 | "version": "1.0.0", 118 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 119 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 120 | }, 121 | "asynckit": { 122 | "version": "0.4.0", 123 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 124 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 125 | }, 126 | "aws-sign2": { 127 | "version": "0.7.0", 128 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 129 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 130 | }, 131 | "aws4": { 132 | "version": "1.9.1", 133 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", 134 | "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" 135 | }, 136 | "balanced-match": { 137 | "version": "1.0.0", 138 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 139 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 140 | "dev": true 141 | }, 142 | "basic-auth": { 143 | "version": "2.0.1", 144 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", 145 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", 146 | "requires": { 147 | "safe-buffer": "5.1.2" 148 | } 149 | }, 150 | "bcrypt-pbkdf": { 151 | "version": "1.0.2", 152 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 153 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 154 | "requires": { 155 | "tweetnacl": "^0.14.3" 156 | } 157 | }, 158 | "binary-extensions": { 159 | "version": "2.0.0", 160 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", 161 | "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", 162 | "dev": true 163 | }, 164 | "bintrees": { 165 | "version": "1.0.1", 166 | "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", 167 | "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" 168 | }, 169 | "body-parser": { 170 | "version": "1.19.0", 171 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 172 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 173 | "requires": { 174 | "bytes": "3.1.0", 175 | "content-type": "~1.0.4", 176 | "debug": "2.6.9", 177 | "depd": "~1.1.2", 178 | "http-errors": "1.7.2", 179 | "iconv-lite": "0.4.24", 180 | "on-finished": "~2.3.0", 181 | "qs": "6.7.0", 182 | "raw-body": "2.4.0", 183 | "type-is": "~1.6.17" 184 | } 185 | }, 186 | "boxen": { 187 | "version": "4.2.0", 188 | "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", 189 | "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", 190 | "requires": { 191 | "ansi-align": "^3.0.0", 192 | "camelcase": "^5.3.1", 193 | "chalk": "^3.0.0", 194 | "cli-boxes": "^2.2.0", 195 | "string-width": "^4.1.0", 196 | "term-size": "^2.1.0", 197 | "type-fest": "^0.8.1", 198 | "widest-line": "^3.1.0" 199 | } 200 | }, 201 | "brace-expansion": { 202 | "version": "1.1.11", 203 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 204 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 205 | "dev": true, 206 | "requires": { 207 | "balanced-match": "^1.0.0", 208 | "concat-map": "0.0.1" 209 | } 210 | }, 211 | "braces": { 212 | "version": "3.0.2", 213 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 214 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 215 | "dev": true, 216 | "requires": { 217 | "fill-range": "^7.0.1" 218 | } 219 | }, 220 | "bytes": { 221 | "version": "3.1.0", 222 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 223 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 224 | }, 225 | "cacheable-request": { 226 | "version": "6.1.0", 227 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", 228 | "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", 229 | "requires": { 230 | "clone-response": "^1.0.2", 231 | "get-stream": "^5.1.0", 232 | "http-cache-semantics": "^4.0.0", 233 | "keyv": "^3.0.0", 234 | "lowercase-keys": "^2.0.0", 235 | "normalize-url": "^4.1.0", 236 | "responselike": "^1.0.2" 237 | }, 238 | "dependencies": { 239 | "get-stream": { 240 | "version": "5.1.0", 241 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", 242 | "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", 243 | "requires": { 244 | "pump": "^3.0.0" 245 | } 246 | }, 247 | "lowercase-keys": { 248 | "version": "2.0.0", 249 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 250 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" 251 | } 252 | } 253 | }, 254 | "camelcase": { 255 | "version": "5.3.1", 256 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 257 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" 258 | }, 259 | "caseless": { 260 | "version": "0.12.0", 261 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 262 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 263 | }, 264 | "chalk": { 265 | "version": "3.0.0", 266 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", 267 | "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", 268 | "requires": { 269 | "ansi-styles": "^4.1.0", 270 | "supports-color": "^7.1.0" 271 | } 272 | }, 273 | "chokidar": { 274 | "version": "3.4.0", 275 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", 276 | "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", 277 | "dev": true, 278 | "requires": { 279 | "anymatch": "~3.1.1", 280 | "braces": "~3.0.2", 281 | "fsevents": "~2.1.2", 282 | "glob-parent": "~5.1.0", 283 | "is-binary-path": "~2.1.0", 284 | "is-glob": "~4.0.1", 285 | "normalize-path": "~3.0.0", 286 | "readdirp": "~3.4.0" 287 | } 288 | }, 289 | "ci-info": { 290 | "version": "2.0.0", 291 | "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", 292 | "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" 293 | }, 294 | "cli-boxes": { 295 | "version": "2.2.0", 296 | "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", 297 | "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==" 298 | }, 299 | "cliui": { 300 | "version": "6.0.0", 301 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", 302 | "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", 303 | "requires": { 304 | "string-width": "^4.2.0", 305 | "strip-ansi": "^6.0.0", 306 | "wrap-ansi": "^6.2.0" 307 | }, 308 | "dependencies": { 309 | "ansi-regex": { 310 | "version": "5.0.0", 311 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 312 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" 313 | }, 314 | "strip-ansi": { 315 | "version": "6.0.0", 316 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 317 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 318 | "requires": { 319 | "ansi-regex": "^5.0.0" 320 | } 321 | } 322 | } 323 | }, 324 | "clone-response": { 325 | "version": "1.0.2", 326 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", 327 | "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", 328 | "requires": { 329 | "mimic-response": "^1.0.0" 330 | } 331 | }, 332 | "color-convert": { 333 | "version": "2.0.1", 334 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 335 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 336 | "requires": { 337 | "color-name": "~1.1.4" 338 | } 339 | }, 340 | "color-name": { 341 | "version": "1.1.4", 342 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 343 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 344 | }, 345 | "combined-stream": { 346 | "version": "1.0.8", 347 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 348 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 349 | "requires": { 350 | "delayed-stream": "~1.0.0" 351 | } 352 | }, 353 | "compressible": { 354 | "version": "2.0.18", 355 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", 356 | "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", 357 | "requires": { 358 | "mime-db": ">= 1.43.0 < 2" 359 | } 360 | }, 361 | "compression": { 362 | "version": "1.7.4", 363 | "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", 364 | "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", 365 | "requires": { 366 | "accepts": "~1.3.5", 367 | "bytes": "3.0.0", 368 | "compressible": "~2.0.16", 369 | "debug": "2.6.9", 370 | "on-headers": "~1.0.2", 371 | "safe-buffer": "5.1.2", 372 | "vary": "~1.1.2" 373 | }, 374 | "dependencies": { 375 | "bytes": { 376 | "version": "3.0.0", 377 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 378 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 379 | } 380 | } 381 | }, 382 | "concat-map": { 383 | "version": "0.0.1", 384 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 385 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 386 | "dev": true 387 | }, 388 | "configstore": { 389 | "version": "5.0.1", 390 | "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", 391 | "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", 392 | "requires": { 393 | "dot-prop": "^5.2.0", 394 | "graceful-fs": "^4.1.2", 395 | "make-dir": "^3.0.0", 396 | "unique-string": "^2.0.0", 397 | "write-file-atomic": "^3.0.0", 398 | "xdg-basedir": "^4.0.0" 399 | } 400 | }, 401 | "connect-pause": { 402 | "version": "0.1.1", 403 | "resolved": "https://registry.npmjs.org/connect-pause/-/connect-pause-0.1.1.tgz", 404 | "integrity": "sha1-smmyu4Ldsaw9tQmcD7WCq6mfs3o=" 405 | }, 406 | "content-disposition": { 407 | "version": "0.5.3", 408 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 409 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 410 | "requires": { 411 | "safe-buffer": "5.1.2" 412 | } 413 | }, 414 | "content-type": { 415 | "version": "1.0.4", 416 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 417 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 418 | }, 419 | "cookie": { 420 | "version": "0.4.0", 421 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 422 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 423 | }, 424 | "cookie-signature": { 425 | "version": "1.0.6", 426 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 427 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 428 | }, 429 | "core-util-is": { 430 | "version": "1.0.2", 431 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 432 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 433 | }, 434 | "cors": { 435 | "version": "2.8.5", 436 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 437 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 438 | "requires": { 439 | "object-assign": "^4", 440 | "vary": "^1" 441 | } 442 | }, 443 | "crypto-random-string": { 444 | "version": "2.0.0", 445 | "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", 446 | "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" 447 | }, 448 | "dashdash": { 449 | "version": "1.14.1", 450 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 451 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 452 | "requires": { 453 | "assert-plus": "^1.0.0" 454 | } 455 | }, 456 | "debug": { 457 | "version": "2.6.9", 458 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 459 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 460 | "requires": { 461 | "ms": "2.0.0" 462 | } 463 | }, 464 | "decamelize": { 465 | "version": "1.2.0", 466 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 467 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" 468 | }, 469 | "decompress-response": { 470 | "version": "3.3.0", 471 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", 472 | "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", 473 | "requires": { 474 | "mimic-response": "^1.0.0" 475 | } 476 | }, 477 | "deep-extend": { 478 | "version": "0.6.0", 479 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 480 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" 481 | }, 482 | "defer-to-connect": { 483 | "version": "1.1.3", 484 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", 485 | "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" 486 | }, 487 | "delayed-stream": { 488 | "version": "1.0.0", 489 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 490 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 491 | }, 492 | "depd": { 493 | "version": "1.1.2", 494 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 495 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 496 | }, 497 | "destroy": { 498 | "version": "1.0.4", 499 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 500 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 501 | }, 502 | "dot-prop": { 503 | "version": "5.2.0", 504 | "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", 505 | "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", 506 | "requires": { 507 | "is-obj": "^2.0.0" 508 | } 509 | }, 510 | "duplexer3": { 511 | "version": "0.1.4", 512 | "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", 513 | "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" 514 | }, 515 | "ecc-jsbn": { 516 | "version": "0.1.2", 517 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 518 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 519 | "requires": { 520 | "jsbn": "~0.1.0", 521 | "safer-buffer": "^2.1.0" 522 | } 523 | }, 524 | "ee-first": { 525 | "version": "1.1.1", 526 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 527 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 528 | }, 529 | "emoji-regex": { 530 | "version": "7.0.3", 531 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 532 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" 533 | }, 534 | "encodeurl": { 535 | "version": "1.0.2", 536 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 537 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 538 | }, 539 | "end-of-stream": { 540 | "version": "1.4.4", 541 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 542 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 543 | "requires": { 544 | "once": "^1.4.0" 545 | } 546 | }, 547 | "errorhandler": { 548 | "version": "1.5.1", 549 | "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", 550 | "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", 551 | "requires": { 552 | "accepts": "~1.3.7", 553 | "escape-html": "~1.0.3" 554 | } 555 | }, 556 | "escape-goat": { 557 | "version": "2.1.1", 558 | "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", 559 | "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==" 560 | }, 561 | "escape-html": { 562 | "version": "1.0.3", 563 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 564 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 565 | }, 566 | "etag": { 567 | "version": "1.8.1", 568 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 569 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 570 | }, 571 | "express": { 572 | "version": "4.17.1", 573 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 574 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 575 | "requires": { 576 | "accepts": "~1.3.7", 577 | "array-flatten": "1.1.1", 578 | "body-parser": "1.19.0", 579 | "content-disposition": "0.5.3", 580 | "content-type": "~1.0.4", 581 | "cookie": "0.4.0", 582 | "cookie-signature": "1.0.6", 583 | "debug": "2.6.9", 584 | "depd": "~1.1.2", 585 | "encodeurl": "~1.0.2", 586 | "escape-html": "~1.0.3", 587 | "etag": "~1.8.1", 588 | "finalhandler": "~1.1.2", 589 | "fresh": "0.5.2", 590 | "merge-descriptors": "1.0.1", 591 | "methods": "~1.1.2", 592 | "on-finished": "~2.3.0", 593 | "parseurl": "~1.3.3", 594 | "path-to-regexp": "0.1.7", 595 | "proxy-addr": "~2.0.5", 596 | "qs": "6.7.0", 597 | "range-parser": "~1.2.1", 598 | "safe-buffer": "5.1.2", 599 | "send": "0.17.1", 600 | "serve-static": "1.14.1", 601 | "setprototypeof": "1.1.1", 602 | "statuses": "~1.5.0", 603 | "type-is": "~1.6.18", 604 | "utils-merge": "1.0.1", 605 | "vary": "~1.1.2" 606 | } 607 | }, 608 | "express-urlrewrite": { 609 | "version": "1.2.0", 610 | "resolved": "https://registry.npmjs.org/express-urlrewrite/-/express-urlrewrite-1.2.0.tgz", 611 | "integrity": "sha1-jmZ7d2H/HH/9sO+gXWQDU4fII+s=", 612 | "requires": { 613 | "debug": "*", 614 | "path-to-regexp": "^1.0.3" 615 | }, 616 | "dependencies": { 617 | "path-to-regexp": { 618 | "version": "1.8.0", 619 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", 620 | "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", 621 | "requires": { 622 | "isarray": "0.0.1" 623 | } 624 | } 625 | } 626 | }, 627 | "extend": { 628 | "version": "3.0.2", 629 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 630 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 631 | }, 632 | "extsprintf": { 633 | "version": "1.3.0", 634 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 635 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 636 | }, 637 | "fast-deep-equal": { 638 | "version": "3.1.1", 639 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", 640 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" 641 | }, 642 | "fast-json-stable-stringify": { 643 | "version": "2.1.0", 644 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 645 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" 646 | }, 647 | "fill-range": { 648 | "version": "7.0.1", 649 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 650 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 651 | "dev": true, 652 | "requires": { 653 | "to-regex-range": "^5.0.1" 654 | } 655 | }, 656 | "finalhandler": { 657 | "version": "1.1.2", 658 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 659 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 660 | "requires": { 661 | "debug": "2.6.9", 662 | "encodeurl": "~1.0.2", 663 | "escape-html": "~1.0.3", 664 | "on-finished": "~2.3.0", 665 | "parseurl": "~1.3.3", 666 | "statuses": "~1.5.0", 667 | "unpipe": "~1.0.0" 668 | } 669 | }, 670 | "find-up": { 671 | "version": "4.1.0", 672 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 673 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 674 | "requires": { 675 | "locate-path": "^5.0.0", 676 | "path-exists": "^4.0.0" 677 | } 678 | }, 679 | "forever-agent": { 680 | "version": "0.6.1", 681 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 682 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 683 | }, 684 | "form-data": { 685 | "version": "2.3.3", 686 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 687 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 688 | "requires": { 689 | "asynckit": "^0.4.0", 690 | "combined-stream": "^1.0.6", 691 | "mime-types": "^2.1.12" 692 | } 693 | }, 694 | "forwarded": { 695 | "version": "0.1.2", 696 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 697 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 698 | }, 699 | "fresh": { 700 | "version": "0.5.2", 701 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 702 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 703 | }, 704 | "fsevents": { 705 | "version": "2.1.3", 706 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", 707 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", 708 | "dev": true, 709 | "optional": true 710 | }, 711 | "get-caller-file": { 712 | "version": "2.0.5", 713 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 714 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" 715 | }, 716 | "get-stream": { 717 | "version": "4.1.0", 718 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", 719 | "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", 720 | "requires": { 721 | "pump": "^3.0.0" 722 | } 723 | }, 724 | "getpass": { 725 | "version": "0.1.7", 726 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 727 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 728 | "requires": { 729 | "assert-plus": "^1.0.0" 730 | } 731 | }, 732 | "glob-parent": { 733 | "version": "5.1.2", 734 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 735 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 736 | "dev": true, 737 | "requires": { 738 | "is-glob": "^4.0.1" 739 | } 740 | }, 741 | "global-dirs": { 742 | "version": "2.0.1", 743 | "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", 744 | "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", 745 | "requires": { 746 | "ini": "^1.3.5" 747 | } 748 | }, 749 | "got": { 750 | "version": "9.6.0", 751 | "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", 752 | "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", 753 | "requires": { 754 | "@sindresorhus/is": "^0.14.0", 755 | "@szmarczak/http-timer": "^1.1.2", 756 | "cacheable-request": "^6.0.0", 757 | "decompress-response": "^3.3.0", 758 | "duplexer3": "^0.1.4", 759 | "get-stream": "^4.1.0", 760 | "lowercase-keys": "^1.0.1", 761 | "mimic-response": "^1.0.1", 762 | "p-cancelable": "^1.0.0", 763 | "to-readable-stream": "^1.0.0", 764 | "url-parse-lax": "^3.0.0" 765 | } 766 | }, 767 | "graceful-fs": { 768 | "version": "4.2.4", 769 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", 770 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" 771 | }, 772 | "har-schema": { 773 | "version": "2.0.0", 774 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 775 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 776 | }, 777 | "har-validator": { 778 | "version": "5.1.3", 779 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", 780 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 781 | "requires": { 782 | "ajv": "^6.5.5", 783 | "har-schema": "^2.0.0" 784 | } 785 | }, 786 | "has-flag": { 787 | "version": "4.0.0", 788 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 789 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" 790 | }, 791 | "has-yarn": { 792 | "version": "2.1.0", 793 | "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", 794 | "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" 795 | }, 796 | "http-cache-semantics": { 797 | "version": "4.1.0", 798 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", 799 | "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" 800 | }, 801 | "http-errors": { 802 | "version": "1.7.2", 803 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 804 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 805 | "requires": { 806 | "depd": "~1.1.2", 807 | "inherits": "2.0.3", 808 | "setprototypeof": "1.1.1", 809 | "statuses": ">= 1.5.0 < 2", 810 | "toidentifier": "1.0.0" 811 | } 812 | }, 813 | "http-signature": { 814 | "version": "1.2.0", 815 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 816 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 817 | "requires": { 818 | "assert-plus": "^1.0.0", 819 | "jsprim": "^1.2.2", 820 | "sshpk": "^1.7.0" 821 | } 822 | }, 823 | "iconv-lite": { 824 | "version": "0.4.24", 825 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 826 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 827 | "requires": { 828 | "safer-buffer": ">= 2.1.2 < 3" 829 | } 830 | }, 831 | "ignore-by-default": { 832 | "version": "1.0.1", 833 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", 834 | "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", 835 | "dev": true 836 | }, 837 | "import-lazy": { 838 | "version": "2.1.0", 839 | "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", 840 | "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" 841 | }, 842 | "imurmurhash": { 843 | "version": "0.1.4", 844 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 845 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" 846 | }, 847 | "inherits": { 848 | "version": "2.0.3", 849 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 850 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 851 | }, 852 | "ini": { 853 | "version": "1.3.5", 854 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 855 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 856 | }, 857 | "ipaddr.js": { 858 | "version": "1.9.1", 859 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 860 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 861 | }, 862 | "is-binary-path": { 863 | "version": "2.1.0", 864 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 865 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 866 | "dev": true, 867 | "requires": { 868 | "binary-extensions": "^2.0.0" 869 | } 870 | }, 871 | "is-ci": { 872 | "version": "2.0.0", 873 | "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", 874 | "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", 875 | "requires": { 876 | "ci-info": "^2.0.0" 877 | } 878 | }, 879 | "is-extglob": { 880 | "version": "2.1.1", 881 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 882 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 883 | "dev": true 884 | }, 885 | "is-fullwidth-code-point": { 886 | "version": "2.0.0", 887 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 888 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 889 | }, 890 | "is-glob": { 891 | "version": "4.0.1", 892 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 893 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 894 | "dev": true, 895 | "requires": { 896 | "is-extglob": "^2.1.1" 897 | } 898 | }, 899 | "is-installed-globally": { 900 | "version": "0.3.2", 901 | "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", 902 | "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", 903 | "requires": { 904 | "global-dirs": "^2.0.1", 905 | "is-path-inside": "^3.0.1" 906 | } 907 | }, 908 | "is-npm": { 909 | "version": "4.0.0", 910 | "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", 911 | "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" 912 | }, 913 | "is-number": { 914 | "version": "7.0.0", 915 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 916 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 917 | "dev": true 918 | }, 919 | "is-obj": { 920 | "version": "2.0.0", 921 | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", 922 | "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" 923 | }, 924 | "is-path-inside": { 925 | "version": "3.0.2", 926 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", 927 | "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==" 928 | }, 929 | "is-promise": { 930 | "version": "2.2.2", 931 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", 932 | "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" 933 | }, 934 | "is-typedarray": { 935 | "version": "1.0.0", 936 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 937 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 938 | }, 939 | "is-yarn-global": { 940 | "version": "0.3.0", 941 | "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", 942 | "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" 943 | }, 944 | "isarray": { 945 | "version": "0.0.1", 946 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 947 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 948 | }, 949 | "isstream": { 950 | "version": "0.1.2", 951 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 952 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 953 | }, 954 | "jju": { 955 | "version": "1.4.0", 956 | "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", 957 | "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=" 958 | }, 959 | "jsbn": { 960 | "version": "0.1.1", 961 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 962 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 963 | }, 964 | "json-buffer": { 965 | "version": "3.0.0", 966 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", 967 | "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" 968 | }, 969 | "json-parse-helpfulerror": { 970 | "version": "1.0.3", 971 | "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", 972 | "integrity": "sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w=", 973 | "requires": { 974 | "jju": "^1.1.0" 975 | } 976 | }, 977 | "json-schema": { 978 | "version": "0.2.3", 979 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 980 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 981 | }, 982 | "json-schema-traverse": { 983 | "version": "0.4.1", 984 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 985 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 986 | }, 987 | "json-server": { 988 | "version": "0.16.1", 989 | "resolved": "https://registry.npmjs.org/json-server/-/json-server-0.16.1.tgz", 990 | "integrity": "sha512-aVUTdpt+X27iIuWuxBChJywykPSP4opEiFrH044pG+34Gde3eHZRTzeMyx8ts5/kY2gK1Ru2YBmF2k/vI0lQug==", 991 | "requires": { 992 | "body-parser": "^1.19.0", 993 | "chalk": "^3.0.0", 994 | "compression": "^1.7.4", 995 | "connect-pause": "^0.1.1", 996 | "cors": "^2.8.5", 997 | "errorhandler": "^1.5.1", 998 | "express": "^4.17.1", 999 | "express-urlrewrite": "^1.2.0", 1000 | "json-parse-helpfulerror": "^1.0.3", 1001 | "lodash": "^4.17.15", 1002 | "lodash-id": "^0.14.0", 1003 | "lowdb": "^1.0.0", 1004 | "method-override": "^3.0.0", 1005 | "morgan": "^1.9.1", 1006 | "nanoid": "^2.1.11", 1007 | "please-upgrade-node": "^3.2.0", 1008 | "pluralize": "^8.0.0", 1009 | "request": "^2.88.2", 1010 | "server-destroy": "^1.0.1", 1011 | "update-notifier": "^4.0.0", 1012 | "yargs": "^15.1.0" 1013 | } 1014 | }, 1015 | "json-stringify-safe": { 1016 | "version": "5.0.1", 1017 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 1018 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 1019 | }, 1020 | "jsprim": { 1021 | "version": "1.4.1", 1022 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 1023 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 1024 | "requires": { 1025 | "assert-plus": "1.0.0", 1026 | "extsprintf": "1.3.0", 1027 | "json-schema": "0.2.3", 1028 | "verror": "1.10.0" 1029 | } 1030 | }, 1031 | "keyv": { 1032 | "version": "3.1.0", 1033 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", 1034 | "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", 1035 | "requires": { 1036 | "json-buffer": "3.0.0" 1037 | } 1038 | }, 1039 | "latest-version": { 1040 | "version": "5.1.0", 1041 | "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", 1042 | "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", 1043 | "requires": { 1044 | "package-json": "^6.3.0" 1045 | } 1046 | }, 1047 | "locate-path": { 1048 | "version": "5.0.0", 1049 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 1050 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 1051 | "requires": { 1052 | "p-locate": "^4.1.0" 1053 | } 1054 | }, 1055 | "lodash": { 1056 | "version": "4.17.21", 1057 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1058 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 1059 | }, 1060 | "lodash-id": { 1061 | "version": "0.14.0", 1062 | "resolved": "https://registry.npmjs.org/lodash-id/-/lodash-id-0.14.0.tgz", 1063 | "integrity": "sha1-uvSJNOVDobXWNG+MhGmLGoyAOJY=" 1064 | }, 1065 | "lowdb": { 1066 | "version": "1.0.0", 1067 | "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", 1068 | "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", 1069 | "requires": { 1070 | "graceful-fs": "^4.1.3", 1071 | "is-promise": "^2.1.0", 1072 | "lodash": "4", 1073 | "pify": "^3.0.0", 1074 | "steno": "^0.4.1" 1075 | } 1076 | }, 1077 | "lowercase-keys": { 1078 | "version": "1.0.1", 1079 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", 1080 | "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" 1081 | }, 1082 | "make-dir": { 1083 | "version": "3.1.0", 1084 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 1085 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 1086 | "requires": { 1087 | "semver": "^6.0.0" 1088 | } 1089 | }, 1090 | "media-typer": { 1091 | "version": "0.3.0", 1092 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1093 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 1094 | }, 1095 | "merge-descriptors": { 1096 | "version": "1.0.1", 1097 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1098 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 1099 | }, 1100 | "method-override": { 1101 | "version": "3.0.0", 1102 | "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", 1103 | "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", 1104 | "requires": { 1105 | "debug": "3.1.0", 1106 | "methods": "~1.1.2", 1107 | "parseurl": "~1.3.2", 1108 | "vary": "~1.1.2" 1109 | }, 1110 | "dependencies": { 1111 | "debug": { 1112 | "version": "3.1.0", 1113 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1114 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1115 | "requires": { 1116 | "ms": "2.0.0" 1117 | } 1118 | } 1119 | } 1120 | }, 1121 | "methods": { 1122 | "version": "1.1.2", 1123 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1124 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 1125 | }, 1126 | "mime": { 1127 | "version": "1.6.0", 1128 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1129 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 1130 | }, 1131 | "mime-db": { 1132 | "version": "1.44.0", 1133 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", 1134 | "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" 1135 | }, 1136 | "mime-types": { 1137 | "version": "2.1.27", 1138 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", 1139 | "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", 1140 | "requires": { 1141 | "mime-db": "1.44.0" 1142 | } 1143 | }, 1144 | "mimic-response": { 1145 | "version": "1.0.1", 1146 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 1147 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" 1148 | }, 1149 | "minimatch": { 1150 | "version": "3.0.4", 1151 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1152 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1153 | "dev": true, 1154 | "requires": { 1155 | "brace-expansion": "^1.1.7" 1156 | } 1157 | }, 1158 | "minimist": { 1159 | "version": "1.2.5", 1160 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 1161 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" 1162 | }, 1163 | "morgan": { 1164 | "version": "1.10.0", 1165 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", 1166 | "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", 1167 | "requires": { 1168 | "basic-auth": "~2.0.1", 1169 | "debug": "2.6.9", 1170 | "depd": "~2.0.0", 1171 | "on-finished": "~2.3.0", 1172 | "on-headers": "~1.0.2" 1173 | }, 1174 | "dependencies": { 1175 | "depd": { 1176 | "version": "2.0.0", 1177 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 1178 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 1179 | } 1180 | } 1181 | }, 1182 | "ms": { 1183 | "version": "2.0.0", 1184 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1185 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1186 | }, 1187 | "nanoid": { 1188 | "version": "2.1.11", 1189 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", 1190 | "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" 1191 | }, 1192 | "negotiator": { 1193 | "version": "0.6.2", 1194 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 1195 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 1196 | }, 1197 | "nodemon": { 1198 | "version": "2.0.3", 1199 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.3.tgz", 1200 | "integrity": "sha512-lLQLPS90Lqwc99IHe0U94rDgvjo+G9I4uEIxRG3evSLROcqQ9hwc0AxlSHKS4T1JW/IMj/7N5mthiN58NL/5kw==", 1201 | "dev": true, 1202 | "requires": { 1203 | "chokidar": "^3.2.2", 1204 | "debug": "^3.2.6", 1205 | "ignore-by-default": "^1.0.1", 1206 | "minimatch": "^3.0.4", 1207 | "pstree.remy": "^1.1.7", 1208 | "semver": "^5.7.1", 1209 | "supports-color": "^5.5.0", 1210 | "touch": "^3.1.0", 1211 | "undefsafe": "^2.0.2", 1212 | "update-notifier": "^4.0.0" 1213 | }, 1214 | "dependencies": { 1215 | "debug": { 1216 | "version": "3.2.6", 1217 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 1218 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 1219 | "dev": true, 1220 | "requires": { 1221 | "ms": "^2.1.1" 1222 | } 1223 | }, 1224 | "has-flag": { 1225 | "version": "3.0.0", 1226 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1227 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1228 | "dev": true 1229 | }, 1230 | "ms": { 1231 | "version": "2.1.2", 1232 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1233 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1234 | "dev": true 1235 | }, 1236 | "semver": { 1237 | "version": "5.7.1", 1238 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1239 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1240 | "dev": true 1241 | }, 1242 | "supports-color": { 1243 | "version": "5.5.0", 1244 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1245 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1246 | "dev": true, 1247 | "requires": { 1248 | "has-flag": "^3.0.0" 1249 | } 1250 | } 1251 | } 1252 | }, 1253 | "nopt": { 1254 | "version": "1.0.10", 1255 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", 1256 | "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", 1257 | "dev": true, 1258 | "requires": { 1259 | "abbrev": "1" 1260 | } 1261 | }, 1262 | "normalize-path": { 1263 | "version": "3.0.0", 1264 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1265 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1266 | "dev": true 1267 | }, 1268 | "normalize-url": { 1269 | "version": "4.5.0", 1270 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", 1271 | "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" 1272 | }, 1273 | "oauth-sign": { 1274 | "version": "0.9.0", 1275 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 1276 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 1277 | }, 1278 | "object-assign": { 1279 | "version": "4.1.1", 1280 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1281 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1282 | }, 1283 | "on-finished": { 1284 | "version": "2.3.0", 1285 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1286 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1287 | "requires": { 1288 | "ee-first": "1.1.1" 1289 | } 1290 | }, 1291 | "on-headers": { 1292 | "version": "1.0.2", 1293 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", 1294 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" 1295 | }, 1296 | "once": { 1297 | "version": "1.4.0", 1298 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1299 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1300 | "requires": { 1301 | "wrappy": "1" 1302 | } 1303 | }, 1304 | "p-cancelable": { 1305 | "version": "1.1.0", 1306 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", 1307 | "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" 1308 | }, 1309 | "p-limit": { 1310 | "version": "2.3.0", 1311 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 1312 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 1313 | "requires": { 1314 | "p-try": "^2.0.0" 1315 | } 1316 | }, 1317 | "p-locate": { 1318 | "version": "4.1.0", 1319 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 1320 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 1321 | "requires": { 1322 | "p-limit": "^2.2.0" 1323 | } 1324 | }, 1325 | "p-try": { 1326 | "version": "2.2.0", 1327 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 1328 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" 1329 | }, 1330 | "package-json": { 1331 | "version": "6.5.0", 1332 | "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", 1333 | "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", 1334 | "requires": { 1335 | "got": "^9.6.0", 1336 | "registry-auth-token": "^4.0.0", 1337 | "registry-url": "^5.0.0", 1338 | "semver": "^6.2.0" 1339 | } 1340 | }, 1341 | "parseurl": { 1342 | "version": "1.3.3", 1343 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1344 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 1345 | }, 1346 | "path-exists": { 1347 | "version": "4.0.0", 1348 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1349 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" 1350 | }, 1351 | "path-to-regexp": { 1352 | "version": "0.1.7", 1353 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1354 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 1355 | }, 1356 | "performance-now": { 1357 | "version": "2.1.0", 1358 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 1359 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 1360 | }, 1361 | "picomatch": { 1362 | "version": "2.2.2", 1363 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 1364 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 1365 | "dev": true 1366 | }, 1367 | "pify": { 1368 | "version": "3.0.0", 1369 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 1370 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" 1371 | }, 1372 | "please-upgrade-node": { 1373 | "version": "3.2.0", 1374 | "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", 1375 | "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", 1376 | "requires": { 1377 | "semver-compare": "^1.0.0" 1378 | } 1379 | }, 1380 | "pluralize": { 1381 | "version": "8.0.0", 1382 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", 1383 | "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" 1384 | }, 1385 | "prepend-http": { 1386 | "version": "2.0.0", 1387 | "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", 1388 | "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" 1389 | }, 1390 | "prom-client": { 1391 | "version": "11.2.0", 1392 | "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.2.0.tgz", 1393 | "integrity": "sha512-4gUAq/GR5C8q5eWxOa7tA60AtmkMpbyBd/2btCayvd3h/7HzS0p/kESKRwggJgbFrfdhTCBpOwPAwKiI01Q0VQ==", 1394 | "requires": { 1395 | "tdigest": "^0.1.1" 1396 | } 1397 | }, 1398 | "proxy-addr": { 1399 | "version": "2.0.6", 1400 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", 1401 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", 1402 | "requires": { 1403 | "forwarded": "~0.1.2", 1404 | "ipaddr.js": "1.9.1" 1405 | } 1406 | }, 1407 | "psl": { 1408 | "version": "1.8.0", 1409 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 1410 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" 1411 | }, 1412 | "pstree.remy": { 1413 | "version": "1.1.7", 1414 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", 1415 | "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", 1416 | "dev": true 1417 | }, 1418 | "pump": { 1419 | "version": "3.0.0", 1420 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 1421 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 1422 | "requires": { 1423 | "end-of-stream": "^1.1.0", 1424 | "once": "^1.3.1" 1425 | } 1426 | }, 1427 | "punycode": { 1428 | "version": "2.1.1", 1429 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1430 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 1431 | }, 1432 | "pupa": { 1433 | "version": "2.0.1", 1434 | "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", 1435 | "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", 1436 | "requires": { 1437 | "escape-goat": "^2.0.0" 1438 | } 1439 | }, 1440 | "qs": { 1441 | "version": "6.7.0", 1442 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 1443 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 1444 | }, 1445 | "range-parser": { 1446 | "version": "1.2.1", 1447 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1448 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 1449 | }, 1450 | "raw-body": { 1451 | "version": "2.4.0", 1452 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 1453 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 1454 | "requires": { 1455 | "bytes": "3.1.0", 1456 | "http-errors": "1.7.2", 1457 | "iconv-lite": "0.4.24", 1458 | "unpipe": "1.0.0" 1459 | } 1460 | }, 1461 | "rc": { 1462 | "version": "1.2.8", 1463 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 1464 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 1465 | "requires": { 1466 | "deep-extend": "^0.6.0", 1467 | "ini": "~1.3.0", 1468 | "minimist": "^1.2.0", 1469 | "strip-json-comments": "~2.0.1" 1470 | } 1471 | }, 1472 | "readdirp": { 1473 | "version": "3.4.0", 1474 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", 1475 | "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", 1476 | "dev": true, 1477 | "requires": { 1478 | "picomatch": "^2.2.1" 1479 | } 1480 | }, 1481 | "registry-auth-token": { 1482 | "version": "4.1.1", 1483 | "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", 1484 | "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", 1485 | "requires": { 1486 | "rc": "^1.2.8" 1487 | } 1488 | }, 1489 | "registry-url": { 1490 | "version": "5.1.0", 1491 | "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", 1492 | "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", 1493 | "requires": { 1494 | "rc": "^1.2.8" 1495 | } 1496 | }, 1497 | "request": { 1498 | "version": "2.88.2", 1499 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", 1500 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", 1501 | "requires": { 1502 | "aws-sign2": "~0.7.0", 1503 | "aws4": "^1.8.0", 1504 | "caseless": "~0.12.0", 1505 | "combined-stream": "~1.0.6", 1506 | "extend": "~3.0.2", 1507 | "forever-agent": "~0.6.1", 1508 | "form-data": "~2.3.2", 1509 | "har-validator": "~5.1.3", 1510 | "http-signature": "~1.2.0", 1511 | "is-typedarray": "~1.0.0", 1512 | "isstream": "~0.1.2", 1513 | "json-stringify-safe": "~5.0.1", 1514 | "mime-types": "~2.1.19", 1515 | "oauth-sign": "~0.9.0", 1516 | "performance-now": "^2.1.0", 1517 | "qs": "~6.5.2", 1518 | "safe-buffer": "^5.1.2", 1519 | "tough-cookie": "~2.5.0", 1520 | "tunnel-agent": "^0.6.0", 1521 | "uuid": "^3.3.2" 1522 | }, 1523 | "dependencies": { 1524 | "qs": { 1525 | "version": "6.5.2", 1526 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 1527 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 1528 | } 1529 | } 1530 | }, 1531 | "require-directory": { 1532 | "version": "2.1.1", 1533 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1534 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" 1535 | }, 1536 | "require-main-filename": { 1537 | "version": "2.0.0", 1538 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 1539 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" 1540 | }, 1541 | "responselike": { 1542 | "version": "1.0.2", 1543 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", 1544 | "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", 1545 | "requires": { 1546 | "lowercase-keys": "^1.0.0" 1547 | } 1548 | }, 1549 | "safe-buffer": { 1550 | "version": "5.1.2", 1551 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1552 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1553 | }, 1554 | "safer-buffer": { 1555 | "version": "2.1.2", 1556 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1557 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1558 | }, 1559 | "semver": { 1560 | "version": "6.3.0", 1561 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1562 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" 1563 | }, 1564 | "semver-compare": { 1565 | "version": "1.0.0", 1566 | "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", 1567 | "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" 1568 | }, 1569 | "semver-diff": { 1570 | "version": "3.1.1", 1571 | "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", 1572 | "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", 1573 | "requires": { 1574 | "semver": "^6.3.0" 1575 | } 1576 | }, 1577 | "send": { 1578 | "version": "0.17.1", 1579 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 1580 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 1581 | "requires": { 1582 | "debug": "2.6.9", 1583 | "depd": "~1.1.2", 1584 | "destroy": "~1.0.4", 1585 | "encodeurl": "~1.0.2", 1586 | "escape-html": "~1.0.3", 1587 | "etag": "~1.8.1", 1588 | "fresh": "0.5.2", 1589 | "http-errors": "~1.7.2", 1590 | "mime": "1.6.0", 1591 | "ms": "2.1.1", 1592 | "on-finished": "~2.3.0", 1593 | "range-parser": "~1.2.1", 1594 | "statuses": "~1.5.0" 1595 | }, 1596 | "dependencies": { 1597 | "ms": { 1598 | "version": "2.1.1", 1599 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1600 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 1601 | } 1602 | } 1603 | }, 1604 | "serve-static": { 1605 | "version": "1.14.1", 1606 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 1607 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 1608 | "requires": { 1609 | "encodeurl": "~1.0.2", 1610 | "escape-html": "~1.0.3", 1611 | "parseurl": "~1.3.3", 1612 | "send": "0.17.1" 1613 | } 1614 | }, 1615 | "server-destroy": { 1616 | "version": "1.0.1", 1617 | "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", 1618 | "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=" 1619 | }, 1620 | "set-blocking": { 1621 | "version": "2.0.0", 1622 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 1623 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 1624 | }, 1625 | "setprototypeof": { 1626 | "version": "1.1.1", 1627 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 1628 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 1629 | }, 1630 | "signal-exit": { 1631 | "version": "3.0.3", 1632 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 1633 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" 1634 | }, 1635 | "sshpk": { 1636 | "version": "1.16.1", 1637 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 1638 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 1639 | "requires": { 1640 | "asn1": "~0.2.3", 1641 | "assert-plus": "^1.0.0", 1642 | "bcrypt-pbkdf": "^1.0.0", 1643 | "dashdash": "^1.12.0", 1644 | "ecc-jsbn": "~0.1.1", 1645 | "getpass": "^0.1.1", 1646 | "jsbn": "~0.1.0", 1647 | "safer-buffer": "^2.0.2", 1648 | "tweetnacl": "~0.14.0" 1649 | } 1650 | }, 1651 | "statuses": { 1652 | "version": "1.5.0", 1653 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1654 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 1655 | }, 1656 | "steno": { 1657 | "version": "0.4.4", 1658 | "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", 1659 | "integrity": "sha1-BxEFvfwobmYVwEA8J+nXtdy4Vcs=", 1660 | "requires": { 1661 | "graceful-fs": "^4.1.3" 1662 | } 1663 | }, 1664 | "string-width": { 1665 | "version": "4.2.0", 1666 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 1667 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 1668 | "requires": { 1669 | "emoji-regex": "^8.0.0", 1670 | "is-fullwidth-code-point": "^3.0.0", 1671 | "strip-ansi": "^6.0.0" 1672 | }, 1673 | "dependencies": { 1674 | "ansi-regex": { 1675 | "version": "5.0.0", 1676 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 1677 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" 1678 | }, 1679 | "emoji-regex": { 1680 | "version": "8.0.0", 1681 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1682 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 1683 | }, 1684 | "is-fullwidth-code-point": { 1685 | "version": "3.0.0", 1686 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1687 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" 1688 | }, 1689 | "strip-ansi": { 1690 | "version": "6.0.0", 1691 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1692 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1693 | "requires": { 1694 | "ansi-regex": "^5.0.0" 1695 | } 1696 | } 1697 | } 1698 | }, 1699 | "strip-ansi": { 1700 | "version": "5.2.0", 1701 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1702 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1703 | "requires": { 1704 | "ansi-regex": "^4.1.0" 1705 | } 1706 | }, 1707 | "strip-json-comments": { 1708 | "version": "2.0.1", 1709 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1710 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 1711 | }, 1712 | "supports-color": { 1713 | "version": "7.1.0", 1714 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", 1715 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", 1716 | "requires": { 1717 | "has-flag": "^4.0.0" 1718 | } 1719 | }, 1720 | "tdigest": { 1721 | "version": "0.1.1", 1722 | "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", 1723 | "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", 1724 | "requires": { 1725 | "bintrees": "1.0.1" 1726 | } 1727 | }, 1728 | "term-size": { 1729 | "version": "2.2.0", 1730 | "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", 1731 | "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==" 1732 | }, 1733 | "to-readable-stream": { 1734 | "version": "1.0.0", 1735 | "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", 1736 | "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" 1737 | }, 1738 | "to-regex-range": { 1739 | "version": "5.0.1", 1740 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1741 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1742 | "dev": true, 1743 | "requires": { 1744 | "is-number": "^7.0.0" 1745 | } 1746 | }, 1747 | "toidentifier": { 1748 | "version": "1.0.0", 1749 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 1750 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 1751 | }, 1752 | "touch": { 1753 | "version": "3.1.0", 1754 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", 1755 | "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", 1756 | "dev": true, 1757 | "requires": { 1758 | "nopt": "~1.0.10" 1759 | } 1760 | }, 1761 | "tough-cookie": { 1762 | "version": "2.5.0", 1763 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", 1764 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", 1765 | "requires": { 1766 | "psl": "^1.1.28", 1767 | "punycode": "^2.1.1" 1768 | } 1769 | }, 1770 | "tunnel-agent": { 1771 | "version": "0.6.0", 1772 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 1773 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 1774 | "requires": { 1775 | "safe-buffer": "^5.0.1" 1776 | } 1777 | }, 1778 | "tweetnacl": { 1779 | "version": "0.14.5", 1780 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 1781 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 1782 | }, 1783 | "type-fest": { 1784 | "version": "0.8.1", 1785 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 1786 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" 1787 | }, 1788 | "type-is": { 1789 | "version": "1.6.18", 1790 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1791 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1792 | "requires": { 1793 | "media-typer": "0.3.0", 1794 | "mime-types": "~2.1.24" 1795 | } 1796 | }, 1797 | "typedarray-to-buffer": { 1798 | "version": "3.1.5", 1799 | "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", 1800 | "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", 1801 | "requires": { 1802 | "is-typedarray": "^1.0.0" 1803 | } 1804 | }, 1805 | "undefsafe": { 1806 | "version": "2.0.3", 1807 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", 1808 | "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", 1809 | "dev": true, 1810 | "requires": { 1811 | "debug": "^2.2.0" 1812 | } 1813 | }, 1814 | "unique-string": { 1815 | "version": "2.0.0", 1816 | "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", 1817 | "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", 1818 | "requires": { 1819 | "crypto-random-string": "^2.0.0" 1820 | } 1821 | }, 1822 | "unpipe": { 1823 | "version": "1.0.0", 1824 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1825 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1826 | }, 1827 | "update-notifier": { 1828 | "version": "4.1.0", 1829 | "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", 1830 | "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", 1831 | "requires": { 1832 | "boxen": "^4.2.0", 1833 | "chalk": "^3.0.0", 1834 | "configstore": "^5.0.1", 1835 | "has-yarn": "^2.1.0", 1836 | "import-lazy": "^2.1.0", 1837 | "is-ci": "^2.0.0", 1838 | "is-installed-globally": "^0.3.1", 1839 | "is-npm": "^4.0.0", 1840 | "is-yarn-global": "^0.3.0", 1841 | "latest-version": "^5.0.0", 1842 | "pupa": "^2.0.1", 1843 | "semver-diff": "^3.1.1", 1844 | "xdg-basedir": "^4.0.0" 1845 | } 1846 | }, 1847 | "uri-js": { 1848 | "version": "4.2.2", 1849 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 1850 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 1851 | "requires": { 1852 | "punycode": "^2.1.0" 1853 | } 1854 | }, 1855 | "url-parse-lax": { 1856 | "version": "3.0.0", 1857 | "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", 1858 | "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", 1859 | "requires": { 1860 | "prepend-http": "^2.0.0" 1861 | } 1862 | }, 1863 | "utils-merge": { 1864 | "version": "1.0.1", 1865 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1866 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 1867 | }, 1868 | "uuid": { 1869 | "version": "3.4.0", 1870 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", 1871 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" 1872 | }, 1873 | "vary": { 1874 | "version": "1.1.2", 1875 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1876 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1877 | }, 1878 | "verror": { 1879 | "version": "1.10.0", 1880 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 1881 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 1882 | "requires": { 1883 | "assert-plus": "^1.0.0", 1884 | "core-util-is": "1.0.2", 1885 | "extsprintf": "^1.2.0" 1886 | } 1887 | }, 1888 | "which-module": { 1889 | "version": "2.0.0", 1890 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 1891 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" 1892 | }, 1893 | "widest-line": { 1894 | "version": "3.1.0", 1895 | "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", 1896 | "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", 1897 | "requires": { 1898 | "string-width": "^4.0.0" 1899 | } 1900 | }, 1901 | "wrap-ansi": { 1902 | "version": "6.2.0", 1903 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", 1904 | "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", 1905 | "requires": { 1906 | "ansi-styles": "^4.0.0", 1907 | "string-width": "^4.1.0", 1908 | "strip-ansi": "^6.0.0" 1909 | }, 1910 | "dependencies": { 1911 | "ansi-regex": { 1912 | "version": "5.0.0", 1913 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 1914 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" 1915 | }, 1916 | "strip-ansi": { 1917 | "version": "6.0.0", 1918 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1919 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1920 | "requires": { 1921 | "ansi-regex": "^5.0.0" 1922 | } 1923 | } 1924 | } 1925 | }, 1926 | "wrappy": { 1927 | "version": "1.0.2", 1928 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1929 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1930 | }, 1931 | "write-file-atomic": { 1932 | "version": "3.0.3", 1933 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", 1934 | "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", 1935 | "requires": { 1936 | "imurmurhash": "^0.1.4", 1937 | "is-typedarray": "^1.0.0", 1938 | "signal-exit": "^3.0.2", 1939 | "typedarray-to-buffer": "^3.1.5" 1940 | } 1941 | }, 1942 | "xdg-basedir": { 1943 | "version": "4.0.0", 1944 | "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", 1945 | "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" 1946 | }, 1947 | "y18n": { 1948 | "version": "4.0.0", 1949 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", 1950 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" 1951 | }, 1952 | "yargs": { 1953 | "version": "15.3.1", 1954 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", 1955 | "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", 1956 | "requires": { 1957 | "cliui": "^6.0.0", 1958 | "decamelize": "^1.2.0", 1959 | "find-up": "^4.1.0", 1960 | "get-caller-file": "^2.0.1", 1961 | "require-directory": "^2.1.1", 1962 | "require-main-filename": "^2.0.0", 1963 | "set-blocking": "^2.0.0", 1964 | "string-width": "^4.2.0", 1965 | "which-module": "^2.0.0", 1966 | "y18n": "^4.0.0", 1967 | "yargs-parser": "^18.1.1" 1968 | } 1969 | }, 1970 | "yargs-parser": { 1971 | "version": "18.1.3", 1972 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", 1973 | "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", 1974 | "requires": { 1975 | "camelcase": "^5.0.0", 1976 | "decamelize": "^1.2.0" 1977 | } 1978 | } 1979 | } 1980 | } 1981 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-kubernetes-autoscaling-nodejs-api", 3 | "version": "1.0.0", 4 | "description": "Node API Auto Scaling Example", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node server.js", 8 | "dev": "nodemon server.js" 9 | }, 10 | "keywords": [], 11 | "author": "Michael Wanyoike", 12 | "license": "MIT", 13 | "dependencies": { 14 | "@tailorbrands/node-exporter-prometheus": "^2.0.6", 15 | "json-server": "^0.16.1" 16 | }, 17 | "devDependencies": { 18 | "nodemon": "^2.0.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /performance-test.js: -------------------------------------------------------------------------------- 1 | import { check, sleep } from 'k6'; 2 | import http from "k6/http"; 3 | 4 | export let options = { 5 | duration: "3m", 6 | vus: 200, 7 | thresholds: { 8 | http_req_duration: ["p(95)<700"] 9 | } 10 | }; 11 | 12 | // export let options = { 13 | // stages: [ 14 | // { duration: '1m', target: 50 }, 15 | // { duration: '1m', target: 150 }, 16 | // { duration: '1m', target: 300 }, 17 | // { duration: '2m', target: 500 }, 18 | // { duration: '2m', target: 800 }, 19 | // { duration: '3m', target: 1200 }, 20 | // { duration: '3m', target: 50 }, 21 | // ], 22 | // }; 23 | 24 | export default function () { 25 | let r = http.get(`${__ENV.ENDPOINT}`); 26 | check(r, { 27 | 'status is 200': r => r.status === 200, 28 | }); 29 | sleep(3); 30 | } -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | // server.js 2 | const jsonServer = require('json-server'); 3 | const app = jsonServer.create(); 4 | const minDelay = 30; 5 | const maxDelay = 250; 6 | 7 | // Collect metrics 8 | const prometheusExporter = require('@tailorbrands/node-exporter-prometheus'); 9 | const options = { 10 | appName: "crocodile-api", 11 | collectDefaultMetrics: true, 12 | ignoredRoutes: ['/metrics', '/favicon.ico', '/__rules'] 13 | }; 14 | const promExporter = prometheusExporter(options); 15 | app.use(promExporter.middleware); 16 | app.get('/metrics', promExporter.metrics); 17 | 18 | const middlewares = jsonServer.defaults() 19 | app.use(middlewares); 20 | 21 | // Add a delay to /crocodiles requests only 22 | app.use('/crocodiles', function (req, res, next) { 23 | let delay = Math.floor(Math.random() * (maxDelay - minDelay)) + minDelay; 24 | setTimeout(next, delay) 25 | }); 26 | 27 | const router = jsonServer.router('db.json'); 28 | app.use(router); 29 | 30 | const port = 4000; 31 | app.listen(port, () => { 32 | console.log( 33 | `JSON server listening on 127.0.0.1:${port}`, 34 | ); 35 | }); 36 | --------------------------------------------------------------------------------