├── .gitignore ├── src ├── .dockerignore ├── Dockerfile ├── models │ └── produto.js ├── routes │ └── produto.js ├── package.json ├── config │ └── system-life.js ├── controllers │ └── produto.js ├── .gitignore ├── app.js ├── swagger.yaml └── package-lock.json ├── Grafana ├── values.yaml └── dashboard.json ├── Prometheus └── values.yaml ├── Jenkinsfile ├── k8s └── deployment.yaml └── .github └── workflows └── main.yml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /src/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /Grafana/values.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabricioveronez/api-produto/HEAD/Grafana/values.yaml -------------------------------------------------------------------------------- /Prometheus/values.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabricioveronez/api-produto/HEAD/Prometheus/values.yaml -------------------------------------------------------------------------------- /src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14.16.1-alpine3.13 2 | WORKDIR /app 3 | COPY package*.json ./ 4 | RUN npm install 5 | COPY . . 6 | EXPOSE 8080 7 | CMD ["node", "app.js"] -------------------------------------------------------------------------------- /src/models/produto.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var Schema = mongoose.Schema; 3 | 4 | var ProdutoSchema = new Schema({ 5 | nome: {type: String, required: true, max: 100}, 6 | categoria: {type: String, required: true, max: 50}, 7 | preco: {type: Number, required: true}, 8 | }); 9 | 10 | module.exports = mongoose.model('Produto', ProdutoSchema); -------------------------------------------------------------------------------- /src/routes/produto.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | var product_controller = require('../controllers/produto'); 5 | 6 | router.post('', product_controller.productCreate); 7 | router.get('', product_controller.productAll); 8 | router.get('/:id', product_controller.productDetails); 9 | router.put('/:id', product_controller.productUpdate); 10 | router.delete('/:id', product_controller.productDelete); 11 | 12 | module.exports = router; -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jornadakubernetes", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "body-parser": "^1.19.0", 13 | "express": "^4.17.1", 14 | "express-prom-bundle": "^6.3.1", 15 | "mongoose": "^5.11.12", 16 | "nodehog": "^0.1.2", 17 | "prom-client": "12.0.0", 18 | "prometheus-api-metrics": "^3.1.0", 19 | "swagger-ui-express": "^4.1.6", 20 | "yamljs": "^0.3.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/config/system-life.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | let isHealth = true; 5 | let readTime = new Date(Date.now()); 6 | let isRead = () => { 7 | return readTime < new Date(Date.now()); 8 | }; 9 | 10 | router.get('/read', (req, res) => { 11 | 12 | if (isRead()) { 13 | res.statusCode = 200; 14 | return res.send('Ok'); 15 | } else { 16 | res.statusCode = 500; 17 | return res.send(''); 18 | } 19 | }); 20 | 21 | router.put('/unhealth', (req, res) => { 22 | 23 | isHealth = false; 24 | res.send("OK"); 25 | }); 26 | 27 | router.put('/unreadfor/:seconds', (req, res) => { 28 | 29 | const dado = new Date(new Date(Date.now()).getTime() + (1000 * req.params.seconds)); 30 | readTime = dado; 31 | res.send("OK"); 32 | }); 33 | 34 | var healthMid = function (req, res, next) { 35 | 36 | if (isHealth) { 37 | next(); 38 | } else { 39 | res.statusCode = 500; 40 | return res.send(''); 41 | } 42 | }; 43 | 44 | exports.routers = router; 45 | exports.middlewares = { healthMid}; -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent any 3 | 4 | stages { 5 | stage ('Build Image') { 6 | steps { 7 | script { 8 | dockerapp = docker.build("fabricioveronez/api-produto:${env.BUILD_ID}", '-f ./src/Dockerfile ./src') 9 | } 10 | } 11 | } 12 | 13 | stage ('Push Image') { 14 | steps { 15 | script { 16 | docker.withRegistry('https://registry.hub.docker.com', 'dockerhub') { 17 | dockerapp.push('latest') 18 | dockerapp.push("${env.BUILD_ID}") 19 | } 20 | } 21 | } 22 | } 23 | 24 | stage ('Deploy Kubernetes') { 25 | environment { 26 | tag_version = "${env.BUILD_ID}" 27 | } 28 | steps { 29 | withKubeConfig([credentialsId: 'kubeconfig']) { 30 | sh 'sed -i "s/{{tag}}/$tag_version/g" ./k8s/deployment.yaml' 31 | sh 'kubectl apply -f ./k8s/deployment.yaml' 32 | } 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /k8s/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mongodb 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: mongodb 9 | template: 10 | metadata: 11 | labels: 12 | app: mongodb 13 | spec: 14 | containers: 15 | - name: mongodb 16 | image: mongo:4.4.5 17 | ports: 18 | - containerPort: 27017 19 | env: 20 | - name: MONGO_INITDB_ROOT_USERNAME 21 | value: mongouser 22 | - name: MONGO_INITDB_ROOT_PASSWORD 23 | value: mongopwd 24 | --- 25 | apiVersion: v1 26 | kind: Service 27 | metadata: 28 | name: mongodb-service 29 | spec: 30 | selector: 31 | app: mongodb 32 | ports: 33 | - port: 27017 34 | targetPort: 27017 35 | type: ClusterIP 36 | --- 37 | apiVersion: apps/v1 38 | kind: Deployment 39 | metadata: 40 | name: api 41 | spec: 42 | replicas: 1 43 | selector: 44 | matchLabels: 45 | app: api 46 | template: 47 | metadata: 48 | annotations: 49 | prometheus.io/scrape: "true" 50 | prometheus.io/path: /metrics 51 | prometheus.io/port: "8080" 52 | labels: 53 | app: api 54 | spec: 55 | containers: 56 | - name: api 57 | image: fabricioveronez/api-produto:{{tag}} 58 | ports: 59 | - containerPort: 8080 60 | env: 61 | - name: MONGODB_URI 62 | value: mongodb://mongouser:mongopwd@mongodb-service:27017/admin 63 | --- 64 | apiVersion: v1 65 | kind: Service 66 | metadata: 67 | name: api-service 68 | spec: 69 | selector: 70 | app: api 71 | ports: 72 | - port: 80 73 | targetPort: 8080 74 | nodePort: 30000 75 | type: LoadBalancer 76 | 77 | -------------------------------------------------------------------------------- /src/controllers/produto.js: -------------------------------------------------------------------------------- 1 | var Product = require('../models/produto'); 2 | var os = require('os'); 3 | 4 | exports.productCreate = function (req, res) { 5 | var product = new Product( 6 | { 7 | nome: req.body.nome, 8 | preco: req.body.preco, 9 | categoria: req.body.categoria 10 | } 11 | ); 12 | 13 | product.save(function (err, productResult) { 14 | 15 | if (err) { 16 | res.statusCode = 404; 17 | return res.json(err); 18 | } 19 | 20 | res.statusCode = 201; 21 | res.json(productResult) 22 | }) 23 | }; 24 | 25 | exports.productDetails = function (req, res) { 26 | Product.findById(req.params.id, function (err, product) { 27 | 28 | if (err) { 29 | res.statusCode = 404; 30 | return res.json(err); 31 | } 32 | res.json(product); 33 | }) 34 | }; 35 | 36 | exports.productAll = function (req, res) { 37 | Product.find({}, function (err, product) { 38 | 39 | if (err) { 40 | res.statusCode = 500; 41 | return res.json(err); 42 | } 43 | 44 | var retu = { product, machine: os.hostname(), version: "3.0" }; 45 | 46 | res.json(retu); 47 | }) 48 | }; 49 | 50 | exports.productUpdate = function (req, res) { 51 | Product.findByIdAndUpdate(req.params.id, {$set: req.body}, function (err, product) { 52 | 53 | if (err) { 54 | res.statusCode = 404; 55 | return res.json(err); 56 | } 57 | res.statusCode = 204; 58 | res.send(''); 59 | }); 60 | }; 61 | 62 | exports.productDelete = function (req, res) { 63 | Product.findByIdAndRemove(req.params.id, function (err) { 64 | 65 | if (err) { 66 | res.statusCode = 404; 67 | return res.json(err); 68 | } 69 | res.statusCode = 204; 70 | res.send(''); 71 | }) 72 | }; -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node 3 | # Edit at https://www.gitignore.io/?templates=node 4 | 5 | ### Node ### 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | *.lcov 29 | 30 | # nyc test coverage 31 | .nyc_output 32 | 33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 34 | .grunt 35 | 36 | # Bower dependency directory (https://bower.io/) 37 | bower_components 38 | 39 | # node-waf configuration 40 | .lock-wscript 41 | 42 | # Compiled binary addons (https://nodejs.org/api/addons.html) 43 | build/Release 44 | 45 | # Dependency directories 46 | node_modules/ 47 | jspm_packages/ 48 | 49 | # TypeScript v1 declaration files 50 | typings/ 51 | 52 | # TypeScript cache 53 | *.tsbuildinfo 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional eslint cache 59 | .eslintcache 60 | 61 | # Optional REPL history 62 | .node_repl_history 63 | 64 | # Output of 'npm pack' 65 | *.tgz 66 | 67 | # Yarn Integrity file 68 | .yarn-integrity 69 | 70 | # dotenv environment variables file 71 | .env 72 | .env.test 73 | 74 | # parcel-bundler cache (https://parceljs.org/) 75 | .cache 76 | 77 | # next.js build output 78 | .next 79 | 80 | # nuxt.js build output 81 | .nuxt 82 | 83 | # rollup.js default build output 84 | dist/ 85 | 86 | # Uncomment the public line if your project uses Gatsby 87 | # https://nextjs.org/blog/next-9-1#public-directory-support 88 | # https://create-react-app.dev/docs/using-the-public-folder/#docsNav 89 | # public 90 | 91 | # Storybook build outputs 92 | .out 93 | .storybook-out 94 | 95 | # vuepress build output 96 | .vuepress/dist 97 | 98 | # Serverless directories 99 | .serverless/ 100 | 101 | # FuseBox cache 102 | .fusebox/ 103 | 104 | # DynamoDB Local files 105 | .dynamodb/ 106 | 107 | # Temporary folders 108 | tmp/ 109 | temp/ 110 | 111 | # End of https://www.gitignore.io/api/node -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | const mongoose = require('mongoose'); 4 | const bodyParser = require('body-parser'); 5 | const product = require('./routes/produto'); 6 | const swaggerUi = require('swagger-ui-express'); 7 | const YAML = require('yamljs'); 8 | const swaggerDocument = YAML.load('./swagger.yaml'); 9 | const NodeHog = require('nodehog'); 10 | const config = require('./config/system-life'); 11 | const promBundle = require("express-prom-bundle"); 12 | 13 | const metricsMiddleware = promBundle({ 14 | includeMethod: true, 15 | includePath: true, 16 | customLabels: 17 | { 18 | project_version: '3.0' 19 | } 20 | }); 21 | 22 | app.use(metricsMiddleware); 23 | app.use(config.middlewares.healthMid); 24 | app.use('/', config.routers); 25 | app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); 26 | app.use(bodyParser.json()); 27 | app.use(bodyParser.urlencoded({ extended: false })); 28 | 29 | const serverStatus = () => { 30 | return { 31 | state: 'up', 32 | dbState: mongoose.STATES[mongoose.connection.readyState] 33 | } 34 | }; 35 | 36 | app.get('/health', (res, req) => { 37 | let healthResult = serverStatus(); 38 | if (mongoose.connection.readyState == 0) { 39 | req.statusCode = 500; 40 | req.send('down'); 41 | } else { 42 | req.json(healthResult); 43 | } 44 | }); 45 | 46 | app.put('/stress/:elemento/tempostress/:tempoStress/intervalo/:intervalo/ciclos/:ciclos', (req, res) => { 47 | 48 | const elemento = req.params.elemento; 49 | const tempoStress = req.params.tempoStress * 1000; 50 | const tempoFolga = req.params.tempoFolga * 1000; 51 | const ciclos = req.params.ciclos; 52 | new NodeHog(elemento, tempoStress, tempoFolga, ciclos).start(); 53 | res.send("OK"); 54 | }); 55 | 56 | app.use('/api/produto', product); 57 | 58 | var developer_db_url = 'mongodb://mongouser:mongopwd@localhost:27017/admin'; 59 | var mongoUrl = process.env.MONGODB_URI || developer_db_url; 60 | 61 | mongoose.Promise = global.Promise; 62 | 63 | var connectWithRetry = function () { 64 | return mongoose.connect(mongoUrl, function (err) { 65 | if (err) { 66 | console.error('Failed to connect to mongo on startup - retrying in 5 sec', err); 67 | setTimeout(connectWithRetry, 5000); 68 | } 69 | }); 70 | }; 71 | 72 | connectWithRetry(); 73 | 74 | var port = process.env.SERVER_PORT || 8080; 75 | 76 | app.listen(port, () => { 77 | console.log('Servidor rodando na porta ' + port); 78 | }); 79 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI-CD 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the master branch 8 | push: 9 | branches: [ master ] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 15 | jobs: 16 | # This workflow contains a single job called "build" 17 | CI: 18 | # The type of runner that the job will run on 19 | runs-on: ubuntu-latest 20 | 21 | # Steps represent a sequence of tasks that will be executed as part of the job 22 | steps: 23 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 24 | - uses: actions/checkout@v2 25 | 26 | - name: Docker Login 27 | # You may pin to the exact commit or the version. 28 | # uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c 29 | uses: docker/login-action@v1.9.0 30 | with: 31 | # Server address of Docker registry. If not set then will default to Docker Hub 32 | username: ${{secrets.DOCKERHUB_USER}} 33 | # Password or personal access token used to log against the Docker registry 34 | password: ${{secrets.DOCKERHUB_PWD}} 35 | 36 | - name: Build and push Docker images 37 | # You may pin to the exact commit or the version. 38 | # uses: docker/build-push-action@e1b7f96249f2e4c8e4ac1519b9608c0d48944a1f 39 | uses: docker/build-push-action@v2.4.0 40 | with: 41 | # Build's context is the set of files located in the specified PATH or URL 42 | context: ./src 43 | # Path to the Dockerfile 44 | file: ./src/Dockerfile 45 | push: true 46 | tags: | 47 | fabricioveronez/api-bootcamp-produto:latest 48 | fabricioveronez/api-bootcamp-produto:${{github.run_number}} 49 | 50 | CD: 51 | runs-on: ubuntu-latest 52 | needs: [CI] 53 | steps: 54 | - uses: actions/checkout@v2 55 | 56 | - name: Kubernetes set context 57 | uses: Azure/k8s-set-context@v1 58 | with: 59 | # Acceptable values: kubeconfig or service-account 60 | method: kubeconfig 61 | # Kubernetes Config 62 | kubeconfig: ${{secrets.K8S_CONFIG}} 63 | 64 | - name: Deploy MongoDB 65 | uses: Azure/k8s-deploy@v1.3 66 | with: 67 | manifests: | 68 | k8s/mongodb/deployment.yaml 69 | k8s/mongodb/service.yaml 70 | 71 | - name: Deploy WebApi 72 | uses: Azure/k8s-deploy@v1.3 73 | with: 74 | images: fabricioveronez/api-bootcamp-produto:${{github.run_number}} 75 | manifests: | 76 | k8s/api/deployment.yaml 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /src/swagger.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | swagger: "2.0" 3 | info: 4 | description: "API de Cadastro de Produtos - Versão 1.0" 5 | version: "3.0.0" 6 | title: "Cadastro de Produtos - Versão 1.0" 7 | contact: 8 | email: "fabricio@veronez.dev" 9 | paths: 10 | /read: 11 | get: 12 | description: "Verificação se a aplicação está pronta" 13 | responses: 14 | "200": 15 | description: "Status pronto" 16 | "500": 17 | description: "Status não pronto" 18 | /unreadfor/{seconds}: 19 | put: 20 | description: "Atualização de um produto" 21 | parameters: 22 | - name: "seconds" 23 | in: "path" 24 | description: "Número de segundos como não pronto" 25 | required: true 26 | type: "string" 27 | responses: 28 | "200": 29 | description: "OK" 30 | /health: 31 | get: 32 | description: "Verificação se a aplicação está saudável" 33 | responses: 34 | "200": 35 | description: "Status saudável" 36 | "500": 37 | description: "Status não saudável" 38 | /unhealth: 39 | put: 40 | description: "Faz com que a aplicação pare de responder" 41 | responses: 42 | "200": 43 | description: "Ok" 44 | /stress/{elemento}/tempostress/{tempoStress}/intervalo/{intervalo}/ciclos/{ciclos}: 45 | put: 46 | description: "Faz a aplicação consumir mais recurso" 47 | parameters: 48 | - name: "elemento" 49 | in: "path" 50 | description: "Elemento pra estressar. Pode ser memory ou cpu" 51 | required: true 52 | type: "string" 53 | - name: "tempoStress" 54 | in: "path" 55 | description: "Tempo em segundos pra estressar o elemento" 56 | required: true 57 | type: "string" 58 | - name: "intervalo" 59 | in: "path" 60 | description: "Intervalo de tempo entre um stress e outro" 61 | required: true 62 | type: "string" 63 | - name: "ciclos" 64 | in: "path" 65 | description: "Número de ciclos de stress" 66 | required: true 67 | type: "string" 68 | responses: 69 | "200": 70 | description: "OK" 71 | /api/produto/{id}: 72 | get: 73 | description: "Listagem de um produto\n" 74 | produces: 75 | - "application/json" 76 | parameters: 77 | - name: "id" 78 | in: "path" 79 | description: "Id do produto" 80 | required: true 81 | type: "string" 82 | responses: 83 | "200": 84 | description: "Resultado da busca" 85 | schema: 86 | type: "array" 87 | items: 88 | $ref: "#/definitions/Produto" 89 | "400": 90 | description: "bad input parameter" 91 | put: 92 | description: "Atualização de um produto" 93 | parameters: 94 | - name: "id" 95 | in: "path" 96 | description: "Id do produto" 97 | required: true 98 | type: "string" 99 | - in: "body" 100 | name: "body" 101 | description: "Produto que será atualizado" 102 | required: true 103 | schema: 104 | $ref: "#/definitions/Produto" 105 | responses: 106 | "200": 107 | description: "OK" 108 | delete: 109 | description: "Exclusão de um produto" 110 | parameters: 111 | - name: "id" 112 | in: "path" 113 | description: "Id do produto" 114 | required: true 115 | type: "string" 116 | responses: 117 | "204": 118 | description: "OK" 119 | "400": 120 | description: "Produto inválido" 121 | "404": 122 | description: "Produto não encontrado" 123 | /api/produto: 124 | get: 125 | description: "Listagem de todos os produtos\n" 126 | produces: 127 | - "application/json" 128 | parameters: [] 129 | responses: 130 | "200": 131 | description: "Resultado da busca" 132 | schema: 133 | type: "array" 134 | items: 135 | $ref: "#/definitions/Produto" 136 | "400": 137 | description: "bad input parameter" 138 | post: 139 | description: "Cadastro de um produto" 140 | parameters: 141 | - in: "body" 142 | name: "body" 143 | description: "Produto que será cadastrado" 144 | required: true 145 | schema: 146 | $ref: "#/definitions/Produto" 147 | responses: 148 | "200": 149 | description: "OK" 150 | definitions: 151 | Produto: 152 | type: "object" 153 | required: 154 | - "categoria" 155 | - "nome" 156 | - "preco" 157 | properties: 158 | id: 159 | type: "string" 160 | format: "uuid" 161 | example: "d290f1ee-6c54-4b01-90e6-d701748f0851" 162 | nome: 163 | type: "string" 164 | example: "Geladeira" 165 | preco: 166 | type: "number" 167 | example: 500.0 168 | categoria: 169 | type: "string" 170 | example: "Eletrodomésticos" 171 | -------------------------------------------------------------------------------- /Grafana/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 | "__requires": [ 13 | { 14 | "type": "grafana", 15 | "id": "grafana", 16 | "name": "Grafana", 17 | "version": "6.0.0" 18 | }, 19 | { 20 | "type": "panel", 21 | "id": "graph", 22 | "name": "Graph", 23 | "version": "5.0.0" 24 | }, 25 | { 26 | "type": "datasource", 27 | "id": "prometheus", 28 | "name": "Prometheus", 29 | "version": "5.0.0" 30 | } 31 | ], 32 | "annotations": { 33 | "list": [ 34 | { 35 | "builtIn": 1, 36 | "datasource": "-- Grafana --", 37 | "enable": true, 38 | "hide": true, 39 | "iconColor": "rgba(0, 211, 255, 1)", 40 | "name": "Annotations & Alerts", 41 | "type": "dashboard" 42 | } 43 | ] 44 | }, 45 | "editable": true, 46 | "gnetId": null, 47 | "graphTooltip": 0, 48 | "id": null, 49 | "iteration": 1559766445973, 50 | "links": [], 51 | "panels": [ 52 | { 53 | "aliasColors": {}, 54 | "bars": false, 55 | "dashLength": 10, 56 | "dashes": false, 57 | "datasource": "${DS_PROMETHEUS}", 58 | "fill": 1, 59 | "gridPos": { 60 | "h": 8, 61 | "w": 12, 62 | "x": 0, 63 | "y": 0 64 | }, 65 | "id": 2, 66 | "legend": { 67 | "avg": false, 68 | "current": false, 69 | "max": false, 70 | "min": false, 71 | "show": true, 72 | "total": false, 73 | "values": false 74 | }, 75 | "lines": true, 76 | "linewidth": 1, 77 | "links": [], 78 | "nullPointMode": "null", 79 | "paceLength": 10, 80 | "percentage": false, 81 | "pointradius": 2, 82 | "points": false, 83 | "renderer": "flot", 84 | "seriesOverrides": [], 85 | "stack": false, 86 | "steppedLine": false, 87 | "targets": [ 88 | { 89 | "expr": "sum by (status_code, project_version)(rate(http_request_duration_seconds_count[2m]))", 90 | "format": "time_series", 91 | "intervalFactor": 1, 92 | "legendFormat": "HTTP {{status_code}} Versão {{project_version}}", 93 | "refId": "A" 94 | } 95 | ], 96 | "thresholds": [], 97 | "timeFrom": null, 98 | "timeRegions": [], 99 | "timeShift": null, 100 | "title": "Response Codes per Minute", 101 | "tooltip": { 102 | "shared": true, 103 | "sort": 0, 104 | "value_type": "individual" 105 | }, 106 | "type": "graph", 107 | "xaxis": { 108 | "buckets": null, 109 | "mode": "time", 110 | "name": null, 111 | "show": true, 112 | "values": [] 113 | }, 114 | "yaxes": [ 115 | { 116 | "format": "short", 117 | "label": null, 118 | "logBase": 1, 119 | "max": null, 120 | "min": null, 121 | "show": true 122 | }, 123 | { 124 | "format": "short", 125 | "label": null, 126 | "logBase": 1, 127 | "max": null, 128 | "min": null, 129 | "show": true 130 | } 131 | ], 132 | "yaxis": { 133 | "align": false, 134 | "alignLevel": null 135 | } 136 | }, 137 | { 138 | "aliasColors": {}, 139 | "bars": false, 140 | "dashLength": 10, 141 | "dashes": false, 142 | "datasource": "${DS_PROMETHEUS}", 143 | "fill": 1, 144 | "gridPos": { 145 | "h": 8, 146 | "w": 12, 147 | "x": 12, 148 | "y": 0 149 | }, 150 | "id": 8, 151 | "legend": { 152 | "avg": false, 153 | "current": false, 154 | "max": false, 155 | "min": false, 156 | "show": true, 157 | "total": false, 158 | "values": false 159 | }, 160 | "lines": true, 161 | "linewidth": 1, 162 | "links": [], 163 | "nullPointMode": "null", 164 | "paceLength": 10, 165 | "percentage": false, 166 | "pointradius": 2, 167 | "points": false, 168 | "renderer": "flot", 169 | "seriesOverrides": [], 170 | "stack": false, 171 | "steppedLine": false, 172 | "targets": [ 173 | { 174 | "expr": "sum(rate(http_request_duration_seconds_sum[5m])) by (status_code, project_version) /\nsum(rate(http_request_duration_seconds_count[5m])) by (status_code, project_version)", 175 | "format": "time_series", 176 | "intervalFactor": 1, 177 | "legendFormat": "HTTP {{status_code}} Versão {{project_version}}", 178 | "refId": "A" 179 | } 180 | ], 181 | "thresholds": [], 182 | "timeFrom": null, 183 | "timeRegions": [], 184 | "timeShift": null, 185 | "title": "Average Response Time", 186 | "tooltip": { 187 | "shared": true, 188 | "sort": 0, 189 | "value_type": "individual" 190 | }, 191 | "type": "graph", 192 | "xaxis": { 193 | "buckets": null, 194 | "mode": "time", 195 | "name": null, 196 | "show": true, 197 | "values": [] 198 | }, 199 | "yaxes": [ 200 | { 201 | "format": "short", 202 | "label": null, 203 | "logBase": 1, 204 | "max": null, 205 | "min": null, 206 | "show": true 207 | }, 208 | { 209 | "format": "short", 210 | "label": null, 211 | "logBase": 1, 212 | "max": null, 213 | "min": null, 214 | "show": true 215 | } 216 | ], 217 | "yaxis": { 218 | "align": false, 219 | "alignLevel": null 220 | } 221 | }, 222 | { 223 | "aliasColors": {}, 224 | "bars": false, 225 | "dashLength": 10, 226 | "dashes": false, 227 | "datasource": "${DS_PROMETHEUS}", 228 | "fill": 1, 229 | "gridPos": { 230 | "h": 8, 231 | "w": 12, 232 | "x": 0, 233 | "y": 8 234 | }, 235 | "id": 6, 236 | "legend": { 237 | "avg": false, 238 | "current": false, 239 | "max": false, 240 | "min": false, 241 | "show": true, 242 | "total": false, 243 | "values": false 244 | }, 245 | "lines": true, 246 | "linewidth": 1, 247 | "links": [], 248 | "nullPointMode": "null", 249 | "paceLength": 10, 250 | "percentage": false, 251 | "pointradius": 2, 252 | "points": false, 253 | "renderer": "flot", 254 | "seriesOverrides": [], 255 | "stack": false, 256 | "steppedLine": false, 257 | "targets": [ 258 | { 259 | "expr": "sum by (method, path, project_version)(rate(http_request_duration_seconds_count[2m]))", 260 | "format": "time_series", 261 | "intervalFactor": 1, 262 | "legendFormat": "{{method}} {{path}} {{project_version}}", 263 | "refId": "A" 264 | } 265 | ], 266 | "thresholds": [], 267 | "timeFrom": null, 268 | "timeRegions": [], 269 | "timeShift": null, 270 | "title": "Requests Per Minute", 271 | "tooltip": { 272 | "shared": true, 273 | "sort": 0, 274 | "value_type": "individual" 275 | }, 276 | "type": "graph", 277 | "xaxis": { 278 | "buckets": null, 279 | "mode": "time", 280 | "name": null, 281 | "show": true, 282 | "values": [] 283 | }, 284 | "yaxes": [ 285 | { 286 | "format": "short", 287 | "label": null, 288 | "logBase": 1, 289 | "max": null, 290 | "min": null, 291 | "show": true 292 | }, 293 | { 294 | "format": "short", 295 | "label": null, 296 | "logBase": 1, 297 | "max": null, 298 | "min": null, 299 | "show": true 300 | } 301 | ], 302 | "yaxis": { 303 | "align": false, 304 | "alignLevel": null 305 | } 306 | }, 307 | { 308 | "aliasColors": {}, 309 | "bars": false, 310 | "dashLength": 10, 311 | "dashes": false, 312 | "datasource": "${DS_PROMETHEUS}", 313 | "fill": 1, 314 | "gridPos": { 315 | "h": 8, 316 | "w": 12, 317 | "x": 12, 318 | "y": 8 319 | }, 320 | "id": 4, 321 | "legend": { 322 | "avg": false, 323 | "current": false, 324 | "max": false, 325 | "min": false, 326 | "show": true, 327 | "total": false, 328 | "values": false 329 | }, 330 | "lines": true, 331 | "linewidth": 1, 332 | "links": [], 333 | "nullPointMode": "null", 334 | "paceLength": 10, 335 | "percentage": false, 336 | "pointradius": 2, 337 | "points": false, 338 | "renderer": "flot", 339 | "seriesOverrides": [], 340 | "stack": false, 341 | "steppedLine": false, 342 | "targets": [ 343 | { 344 | "expr": "sum(rate(http_request_duration_seconds_sum[5m])) by (method, path, project_version) /\nsum(rate(http_request_duration_seconds_count[5m])) by (method, path, project_version)", 345 | "format": "time_series", 346 | "intervalFactor": 1, 347 | "legendFormat": "{{method}} {{path}} {{project_version}}", 348 | "refId": "A" 349 | } 350 | ], 351 | "thresholds": [], 352 | "timeFrom": null, 353 | "timeRegions": [], 354 | "timeShift": null, 355 | "title": "Response Time", 356 | "tooltip": { 357 | "shared": true, 358 | "sort": 0, 359 | "value_type": "individual" 360 | }, 361 | "type": "graph", 362 | "xaxis": { 363 | "buckets": null, 364 | "mode": "time", 365 | "name": null, 366 | "show": true, 367 | "values": [] 368 | }, 369 | "yaxes": [ 370 | { 371 | "format": "short", 372 | "label": null, 373 | "logBase": 1, 374 | "max": null, 375 | "min": null, 376 | "show": true 377 | }, 378 | { 379 | "format": "short", 380 | "label": null, 381 | "logBase": 1, 382 | "max": null, 383 | "min": null, 384 | "show": true 385 | } 386 | ], 387 | "yaxis": { 388 | "align": false, 389 | "alignLevel": null 390 | } 391 | } 392 | ], 393 | "schemaVersion": 18, 394 | "style": "dark", 395 | "tags": [], 396 | "templating": { 397 | "list": [ 398 | { 399 | "allValue": null, 400 | "current": {}, 401 | "datasource": "${DS_PROMETHEUS}", 402 | "definition": "label_values(http_request_duration_seconds_count, service)", 403 | "hide": 0, 404 | "includeAll": true, 405 | "label": "Service", 406 | "multi": false, 407 | "name": "service", 408 | "options": [], 409 | "query": "label_values(http_request_duration_seconds_count, service)", 410 | "refresh": 1, 411 | "regex": "", 412 | "skipUrlSync": false, 413 | "sort": 1, 414 | "tagValuesQuery": "", 415 | "tags": [], 416 | "tagsQuery": "", 417 | "type": "query", 418 | "useTags": false 419 | } 420 | ] 421 | }, 422 | "time": { 423 | "from": "now-6h", 424 | "to": "now" 425 | }, 426 | "timepicker": { 427 | "refresh_intervals": [ 428 | "5s", 429 | "10s", 430 | "30s", 431 | "1m", 432 | "5m", 433 | "15m", 434 | "30m", 435 | "1h", 436 | "2h", 437 | "1d" 438 | ], 439 | "time_options": [ 440 | "5m", 441 | "15m", 442 | "1h", 443 | "6h", 444 | "12h", 445 | "24h", 446 | "2d", 447 | "7d", 448 | "30d" 449 | ] 450 | }, 451 | "timezone": "", 452 | "title": "Express App", 453 | "uid": "mwTG5sGWz", 454 | "version": 4 455 | } -------------------------------------------------------------------------------- /src/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jornadakubernetes", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/accepts": { 8 | "version": "1.3.5", 9 | "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", 10 | "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", 11 | "requires": { 12 | "@types/node": "*" 13 | } 14 | }, 15 | "@types/body-parser": { 16 | "version": "1.19.0", 17 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", 18 | "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", 19 | "requires": { 20 | "@types/connect": "*", 21 | "@types/node": "*" 22 | } 23 | }, 24 | "@types/bson": { 25 | "version": "4.0.3", 26 | "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", 27 | "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==", 28 | "requires": { 29 | "@types/node": "*" 30 | } 31 | }, 32 | "@types/connect": { 33 | "version": "3.4.34", 34 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", 35 | "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", 36 | "requires": { 37 | "@types/node": "*" 38 | } 39 | }, 40 | "@types/content-disposition": { 41 | "version": "0.5.3", 42 | "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.3.tgz", 43 | "integrity": "sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg==" 44 | }, 45 | "@types/cookies": { 46 | "version": "0.7.6", 47 | "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.6.tgz", 48 | "integrity": "sha512-FK4U5Qyn7/Sc5ih233OuHO0qAkOpEcD/eG6584yEiLKizTFRny86qHLe/rej3HFQrkBuUjF4whFliAdODbVN/w==", 49 | "requires": { 50 | "@types/connect": "*", 51 | "@types/express": "*", 52 | "@types/keygrip": "*", 53 | "@types/node": "*" 54 | } 55 | }, 56 | "@types/express": { 57 | "version": "4.17.11", 58 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", 59 | "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", 60 | "requires": { 61 | "@types/body-parser": "*", 62 | "@types/express-serve-static-core": "^4.17.18", 63 | "@types/qs": "*", 64 | "@types/serve-static": "*" 65 | } 66 | }, 67 | "@types/express-serve-static-core": { 68 | "version": "4.17.18", 69 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz", 70 | "integrity": "sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA==", 71 | "requires": { 72 | "@types/node": "*", 73 | "@types/qs": "*", 74 | "@types/range-parser": "*" 75 | } 76 | }, 77 | "@types/http-assert": { 78 | "version": "1.5.1", 79 | "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", 80 | "integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==" 81 | }, 82 | "@types/http-errors": { 83 | "version": "1.8.0", 84 | "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.0.tgz", 85 | "integrity": "sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==" 86 | }, 87 | "@types/keygrip": { 88 | "version": "1.0.2", 89 | "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", 90 | "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==" 91 | }, 92 | "@types/koa": { 93 | "version": "2.11.8", 94 | "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.11.8.tgz", 95 | "integrity": "sha512-8LJHhlEjxvEb9MR06zencOxZyxpTHG2u6pcvJbSBN9DRBc+GYQ9hFI8sSH7dvYoITKeAGWo2eVPKx1Z/zX/yKw==", 96 | "requires": { 97 | "@types/accepts": "*", 98 | "@types/content-disposition": "*", 99 | "@types/cookies": "*", 100 | "@types/http-assert": "*", 101 | "@types/http-errors": "*", 102 | "@types/keygrip": "*", 103 | "@types/koa-compose": "*", 104 | "@types/node": "*" 105 | } 106 | }, 107 | "@types/koa-compose": { 108 | "version": "3.2.5", 109 | "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz", 110 | "integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==", 111 | "requires": { 112 | "@types/koa": "*" 113 | } 114 | }, 115 | "@types/mime": { 116 | "version": "1.3.2", 117 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", 118 | "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" 119 | }, 120 | "@types/mongodb": { 121 | "version": "3.6.3", 122 | "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.3.tgz", 123 | "integrity": "sha512-6YNqGP1hk5bjUFaim+QoFFuI61WjHiHE1BNeB41TA00Xd2K7zG4lcWyLLq/XtIp36uMavvS5hoAUJ+1u/GcX2Q==", 124 | "requires": { 125 | "@types/bson": "*", 126 | "@types/node": "*" 127 | } 128 | }, 129 | "@types/node": { 130 | "version": "14.14.22", 131 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", 132 | "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==" 133 | }, 134 | "@types/qs": { 135 | "version": "6.9.5", 136 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", 137 | "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==" 138 | }, 139 | "@types/range-parser": { 140 | "version": "1.2.3", 141 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", 142 | "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" 143 | }, 144 | "@types/serve-static": { 145 | "version": "1.13.9", 146 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", 147 | "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", 148 | "requires": { 149 | "@types/mime": "^1", 150 | "@types/node": "*" 151 | } 152 | }, 153 | "accepts": { 154 | "version": "1.3.7", 155 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 156 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 157 | "requires": { 158 | "mime-types": "~2.1.24", 159 | "negotiator": "0.6.2" 160 | } 161 | }, 162 | "argparse": { 163 | "version": "1.0.10", 164 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 165 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 166 | "requires": { 167 | "sprintf-js": "~1.0.2" 168 | } 169 | }, 170 | "array-flatten": { 171 | "version": "1.1.1", 172 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 173 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 174 | }, 175 | "balanced-match": { 176 | "version": "1.0.0", 177 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 178 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 179 | }, 180 | "bintrees": { 181 | "version": "1.0.1", 182 | "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", 183 | "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" 184 | }, 185 | "bl": { 186 | "version": "2.2.1", 187 | "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", 188 | "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", 189 | "requires": { 190 | "readable-stream": "^2.3.5", 191 | "safe-buffer": "^5.1.1" 192 | } 193 | }, 194 | "bluebird": { 195 | "version": "3.5.1", 196 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", 197 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" 198 | }, 199 | "body-parser": { 200 | "version": "1.19.0", 201 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 202 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 203 | "requires": { 204 | "bytes": "3.1.0", 205 | "content-type": "~1.0.4", 206 | "debug": "2.6.9", 207 | "depd": "~1.1.2", 208 | "http-errors": "1.7.2", 209 | "iconv-lite": "0.4.24", 210 | "on-finished": "~2.3.0", 211 | "qs": "6.7.0", 212 | "raw-body": "2.4.0", 213 | "type-is": "~1.6.17" 214 | } 215 | }, 216 | "brace-expansion": { 217 | "version": "1.1.11", 218 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 219 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 220 | "requires": { 221 | "balanced-match": "^1.0.0", 222 | "concat-map": "0.0.1" 223 | } 224 | }, 225 | "bson": { 226 | "version": "1.1.5", 227 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz", 228 | "integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg==" 229 | }, 230 | "bytes": { 231 | "version": "3.1.0", 232 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 233 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 234 | }, 235 | "concat-map": { 236 | "version": "0.0.1", 237 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 238 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 239 | }, 240 | "content-disposition": { 241 | "version": "0.5.3", 242 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 243 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 244 | "requires": { 245 | "safe-buffer": "5.1.2" 246 | } 247 | }, 248 | "content-type": { 249 | "version": "1.0.4", 250 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 251 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 252 | }, 253 | "cookie": { 254 | "version": "0.4.0", 255 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 256 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 257 | }, 258 | "cookie-signature": { 259 | "version": "1.0.6", 260 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 261 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 262 | }, 263 | "core-util-is": { 264 | "version": "1.0.2", 265 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 266 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 267 | }, 268 | "debug": { 269 | "version": "2.6.9", 270 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 271 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 272 | "requires": { 273 | "ms": "2.0.0" 274 | } 275 | }, 276 | "denque": { 277 | "version": "1.5.0", 278 | "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", 279 | "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==" 280 | }, 281 | "depd": { 282 | "version": "1.1.2", 283 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 284 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 285 | }, 286 | "destroy": { 287 | "version": "1.0.4", 288 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 289 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 290 | }, 291 | "ee-first": { 292 | "version": "1.1.1", 293 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 294 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 295 | }, 296 | "encodeurl": { 297 | "version": "1.0.2", 298 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 299 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 300 | }, 301 | "escape-html": { 302 | "version": "1.0.3", 303 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 304 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 305 | }, 306 | "etag": { 307 | "version": "1.8.1", 308 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 309 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 310 | }, 311 | "express": { 312 | "version": "4.17.1", 313 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 314 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 315 | "requires": { 316 | "accepts": "~1.3.7", 317 | "array-flatten": "1.1.1", 318 | "body-parser": "1.19.0", 319 | "content-disposition": "0.5.3", 320 | "content-type": "~1.0.4", 321 | "cookie": "0.4.0", 322 | "cookie-signature": "1.0.6", 323 | "debug": "2.6.9", 324 | "depd": "~1.1.2", 325 | "encodeurl": "~1.0.2", 326 | "escape-html": "~1.0.3", 327 | "etag": "~1.8.1", 328 | "finalhandler": "~1.1.2", 329 | "fresh": "0.5.2", 330 | "merge-descriptors": "1.0.1", 331 | "methods": "~1.1.2", 332 | "on-finished": "~2.3.0", 333 | "parseurl": "~1.3.3", 334 | "path-to-regexp": "0.1.7", 335 | "proxy-addr": "~2.0.5", 336 | "qs": "6.7.0", 337 | "range-parser": "~1.2.1", 338 | "safe-buffer": "5.1.2", 339 | "send": "0.17.1", 340 | "serve-static": "1.14.1", 341 | "setprototypeof": "1.1.1", 342 | "statuses": "~1.5.0", 343 | "type-is": "~1.6.18", 344 | "utils-merge": "1.0.1", 345 | "vary": "~1.1.2" 346 | } 347 | }, 348 | "express-prom-bundle": { 349 | "version": "6.3.1", 350 | "resolved": "https://registry.npmjs.org/express-prom-bundle/-/express-prom-bundle-6.3.1.tgz", 351 | "integrity": "sha512-7q7PeEQaCjJ/V24+PnGhPH56RABQb6sUanojcCacZryN63N0gs8Z5VTEyV0wBNjoBeqvGg/6BNJRnhGZEVCZ6w==", 352 | "requires": { 353 | "on-finished": "^2.3.0", 354 | "url-value-parser": "^2.0.0" 355 | } 356 | }, 357 | "finalhandler": { 358 | "version": "1.1.2", 359 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 360 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 361 | "requires": { 362 | "debug": "2.6.9", 363 | "encodeurl": "~1.0.2", 364 | "escape-html": "~1.0.3", 365 | "on-finished": "~2.3.0", 366 | "parseurl": "~1.3.3", 367 | "statuses": "~1.5.0", 368 | "unpipe": "~1.0.0" 369 | } 370 | }, 371 | "forwarded": { 372 | "version": "0.1.2", 373 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 374 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 375 | }, 376 | "fresh": { 377 | "version": "0.5.2", 378 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 379 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 380 | }, 381 | "fs.realpath": { 382 | "version": "1.0.0", 383 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 384 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 385 | }, 386 | "glob": { 387 | "version": "7.1.6", 388 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 389 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 390 | "requires": { 391 | "fs.realpath": "^1.0.0", 392 | "inflight": "^1.0.4", 393 | "inherits": "2", 394 | "minimatch": "^3.0.4", 395 | "once": "^1.3.0", 396 | "path-is-absolute": "^1.0.0" 397 | } 398 | }, 399 | "http-errors": { 400 | "version": "1.7.2", 401 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 402 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 403 | "requires": { 404 | "depd": "~1.1.2", 405 | "inherits": "2.0.3", 406 | "setprototypeof": "1.1.1", 407 | "statuses": ">= 1.5.0 < 2", 408 | "toidentifier": "1.0.0" 409 | } 410 | }, 411 | "iconv-lite": { 412 | "version": "0.4.24", 413 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 414 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 415 | "requires": { 416 | "safer-buffer": ">= 2.1.2 < 3" 417 | } 418 | }, 419 | "inflight": { 420 | "version": "1.0.6", 421 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 422 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 423 | "requires": { 424 | "once": "^1.3.0", 425 | "wrappy": "1" 426 | } 427 | }, 428 | "inherits": { 429 | "version": "2.0.3", 430 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 431 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 432 | }, 433 | "ipaddr.js": { 434 | "version": "1.9.1", 435 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 436 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 437 | }, 438 | "isarray": { 439 | "version": "1.0.0", 440 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 441 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 442 | }, 443 | "kareem": { 444 | "version": "2.3.2", 445 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", 446 | "integrity": "sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==" 447 | }, 448 | "lodash.get": { 449 | "version": "4.4.2", 450 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 451 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" 452 | }, 453 | "media-typer": { 454 | "version": "0.3.0", 455 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 456 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 457 | }, 458 | "memory-pager": { 459 | "version": "1.5.0", 460 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 461 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", 462 | "optional": true 463 | }, 464 | "merge-descriptors": { 465 | "version": "1.0.1", 466 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 467 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 468 | }, 469 | "methods": { 470 | "version": "1.1.2", 471 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 472 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 473 | }, 474 | "mime": { 475 | "version": "1.6.0", 476 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 477 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 478 | }, 479 | "mime-db": { 480 | "version": "1.45.0", 481 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", 482 | "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==" 483 | }, 484 | "mime-types": { 485 | "version": "2.1.28", 486 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", 487 | "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", 488 | "requires": { 489 | "mime-db": "1.45.0" 490 | } 491 | }, 492 | "minimatch": { 493 | "version": "3.0.4", 494 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 495 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 496 | "requires": { 497 | "brace-expansion": "^1.1.7" 498 | } 499 | }, 500 | "mongodb": { 501 | "version": "3.6.3", 502 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.3.tgz", 503 | "integrity": "sha512-rOZuR0QkodZiM+UbQE5kDsJykBqWi0CL4Ec2i1nrGrUI3KO11r6Fbxskqmq3JK2NH7aW4dcccBuUujAP0ERl5w==", 504 | "requires": { 505 | "bl": "^2.2.1", 506 | "bson": "^1.1.4", 507 | "denque": "^1.4.1", 508 | "require_optional": "^1.0.1", 509 | "safe-buffer": "^5.1.2", 510 | "saslprep": "^1.0.0" 511 | } 512 | }, 513 | "mongoose": { 514 | "version": "5.11.13", 515 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.11.13.tgz", 516 | "integrity": "sha512-rXbaxSJfLnKKO2RTm8MKt65glrtfKDc4ATEb6vEbbzsVGCiLut753K5axdpyvE7KeTH7GOh4LzmuQLOvaaWOmA==", 517 | "requires": { 518 | "@types/mongodb": "^3.5.27", 519 | "bson": "^1.1.4", 520 | "kareem": "2.3.2", 521 | "mongodb": "3.6.3", 522 | "mongoose-legacy-pluralize": "1.0.2", 523 | "mpath": "0.8.3", 524 | "mquery": "3.2.3", 525 | "ms": "2.1.2", 526 | "regexp-clone": "1.0.0", 527 | "safe-buffer": "5.2.1", 528 | "sift": "7.0.1", 529 | "sliced": "1.0.1" 530 | }, 531 | "dependencies": { 532 | "ms": { 533 | "version": "2.1.2", 534 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 535 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 536 | }, 537 | "safe-buffer": { 538 | "version": "5.2.1", 539 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 540 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 541 | } 542 | } 543 | }, 544 | "mongoose-legacy-pluralize": { 545 | "version": "1.0.2", 546 | "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", 547 | "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" 548 | }, 549 | "mpath": { 550 | "version": "0.8.3", 551 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.8.3.tgz", 552 | "integrity": "sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA==" 553 | }, 554 | "mquery": { 555 | "version": "3.2.3", 556 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.3.tgz", 557 | "integrity": "sha512-cIfbP4TyMYX+SkaQ2MntD+F2XbqaBHUYWk3j+kqdDztPWok3tgyssOZxMHMtzbV1w9DaSlvEea0Iocuro41A4g==", 558 | "requires": { 559 | "bluebird": "3.5.1", 560 | "debug": "3.1.0", 561 | "regexp-clone": "^1.0.0", 562 | "safe-buffer": "5.1.2", 563 | "sliced": "1.0.1" 564 | }, 565 | "dependencies": { 566 | "debug": { 567 | "version": "3.1.0", 568 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 569 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 570 | "requires": { 571 | "ms": "2.0.0" 572 | } 573 | } 574 | } 575 | }, 576 | "ms": { 577 | "version": "2.0.0", 578 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 579 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 580 | }, 581 | "negotiator": { 582 | "version": "0.6.2", 583 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 584 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 585 | }, 586 | "nodehog": { 587 | "version": "0.1.2", 588 | "resolved": "https://registry.npmjs.org/nodehog/-/nodehog-0.1.2.tgz", 589 | "integrity": "sha512-dhzZsMR5/0b9z56z7wngMeOb+OUPCYmTUMgYINlDn7MrRLk+jdkbjl5D8HIxb+o6nTjPxY6TiFR63I1aQZNvFQ==" 590 | }, 591 | "on-finished": { 592 | "version": "2.3.0", 593 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 594 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 595 | "requires": { 596 | "ee-first": "1.1.1" 597 | } 598 | }, 599 | "once": { 600 | "version": "1.4.0", 601 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 602 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 603 | "requires": { 604 | "wrappy": "1" 605 | } 606 | }, 607 | "parseurl": { 608 | "version": "1.3.3", 609 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 610 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 611 | }, 612 | "path-is-absolute": { 613 | "version": "1.0.1", 614 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 615 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 616 | }, 617 | "path-to-regexp": { 618 | "version": "0.1.7", 619 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 620 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 621 | }, 622 | "pkginfo": { 623 | "version": "0.4.1", 624 | "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", 625 | "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=" 626 | }, 627 | "process-nextick-args": { 628 | "version": "2.0.1", 629 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 630 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 631 | }, 632 | "prom-client": { 633 | "version": "12.0.0", 634 | "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-12.0.0.tgz", 635 | "integrity": "sha512-JbzzHnw0VDwCvoqf8y1WDtq4wSBAbthMB1pcVI/0lzdqHGJI3KBJDXle70XK+c7Iv93Gihqo0a5LlOn+g8+DrQ==", 636 | "requires": { 637 | "tdigest": "^0.1.1" 638 | } 639 | }, 640 | "prometheus-api-metrics": { 641 | "version": "3.1.0", 642 | "resolved": "https://registry.npmjs.org/prometheus-api-metrics/-/prometheus-api-metrics-3.1.0.tgz", 643 | "integrity": "sha512-EO+1/74htzL1y6UUGXtUmclr17de5yDXSmeTPaYkbia220yCYI3l6AmJFMBUG9WLf1SAq6EbhgdZhE4mRiO0xQ==", 644 | "requires": { 645 | "@types/express": "^4.17.8", 646 | "@types/express-serve-static-core": "^4.17.12", 647 | "@types/koa": "^2.11.4", 648 | "debug": "^3.2.6", 649 | "lodash.get": "^4.4.2", 650 | "pkginfo": "^0.4.1" 651 | }, 652 | "dependencies": { 653 | "debug": { 654 | "version": "3.2.7", 655 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", 656 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", 657 | "requires": { 658 | "ms": "^2.1.1" 659 | } 660 | }, 661 | "ms": { 662 | "version": "2.1.3", 663 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 664 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 665 | } 666 | } 667 | }, 668 | "proxy-addr": { 669 | "version": "2.0.6", 670 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", 671 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", 672 | "requires": { 673 | "forwarded": "~0.1.2", 674 | "ipaddr.js": "1.9.1" 675 | } 676 | }, 677 | "qs": { 678 | "version": "6.7.0", 679 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 680 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 681 | }, 682 | "range-parser": { 683 | "version": "1.2.1", 684 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 685 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 686 | }, 687 | "raw-body": { 688 | "version": "2.4.0", 689 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 690 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 691 | "requires": { 692 | "bytes": "3.1.0", 693 | "http-errors": "1.7.2", 694 | "iconv-lite": "0.4.24", 695 | "unpipe": "1.0.0" 696 | } 697 | }, 698 | "readable-stream": { 699 | "version": "2.3.7", 700 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 701 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 702 | "requires": { 703 | "core-util-is": "~1.0.0", 704 | "inherits": "~2.0.3", 705 | "isarray": "~1.0.0", 706 | "process-nextick-args": "~2.0.0", 707 | "safe-buffer": "~5.1.1", 708 | "string_decoder": "~1.1.1", 709 | "util-deprecate": "~1.0.1" 710 | } 711 | }, 712 | "regexp-clone": { 713 | "version": "1.0.0", 714 | "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", 715 | "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" 716 | }, 717 | "require_optional": { 718 | "version": "1.0.1", 719 | "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", 720 | "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", 721 | "requires": { 722 | "resolve-from": "^2.0.0", 723 | "semver": "^5.1.0" 724 | } 725 | }, 726 | "resolve-from": { 727 | "version": "2.0.0", 728 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", 729 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" 730 | }, 731 | "safe-buffer": { 732 | "version": "5.1.2", 733 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 734 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 735 | }, 736 | "safer-buffer": { 737 | "version": "2.1.2", 738 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 739 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 740 | }, 741 | "saslprep": { 742 | "version": "1.0.3", 743 | "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", 744 | "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", 745 | "optional": true, 746 | "requires": { 747 | "sparse-bitfield": "^3.0.3" 748 | } 749 | }, 750 | "semver": { 751 | "version": "5.7.1", 752 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 753 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 754 | }, 755 | "send": { 756 | "version": "0.17.1", 757 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 758 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 759 | "requires": { 760 | "debug": "2.6.9", 761 | "depd": "~1.1.2", 762 | "destroy": "~1.0.4", 763 | "encodeurl": "~1.0.2", 764 | "escape-html": "~1.0.3", 765 | "etag": "~1.8.1", 766 | "fresh": "0.5.2", 767 | "http-errors": "~1.7.2", 768 | "mime": "1.6.0", 769 | "ms": "2.1.1", 770 | "on-finished": "~2.3.0", 771 | "range-parser": "~1.2.1", 772 | "statuses": "~1.5.0" 773 | }, 774 | "dependencies": { 775 | "ms": { 776 | "version": "2.1.1", 777 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 778 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 779 | } 780 | } 781 | }, 782 | "serve-static": { 783 | "version": "1.14.1", 784 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 785 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 786 | "requires": { 787 | "encodeurl": "~1.0.2", 788 | "escape-html": "~1.0.3", 789 | "parseurl": "~1.3.3", 790 | "send": "0.17.1" 791 | } 792 | }, 793 | "setprototypeof": { 794 | "version": "1.1.1", 795 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 796 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 797 | }, 798 | "sift": { 799 | "version": "7.0.1", 800 | "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", 801 | "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==" 802 | }, 803 | "sliced": { 804 | "version": "1.0.1", 805 | "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", 806 | "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" 807 | }, 808 | "sparse-bitfield": { 809 | "version": "3.0.3", 810 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 811 | "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", 812 | "optional": true, 813 | "requires": { 814 | "memory-pager": "^1.0.2" 815 | } 816 | }, 817 | "sprintf-js": { 818 | "version": "1.0.3", 819 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 820 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 821 | }, 822 | "statuses": { 823 | "version": "1.5.0", 824 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 825 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 826 | }, 827 | "string_decoder": { 828 | "version": "1.1.1", 829 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 830 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 831 | "requires": { 832 | "safe-buffer": "~5.1.0" 833 | } 834 | }, 835 | "swagger-ui-dist": { 836 | "version": "3.40.0", 837 | "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.40.0.tgz", 838 | "integrity": "sha512-R0eaS61/cOE6wiFOY7AtmoTBV5lZqmyosuE14G9nAudp5MNsNfCTdI9MWJLs8iF28HXdtH8EACiFFtUbQomHog==" 839 | }, 840 | "swagger-ui-express": { 841 | "version": "4.1.6", 842 | "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.1.6.tgz", 843 | "integrity": "sha512-Xs2BGGudvDBtL7RXcYtNvHsFtP1DBFPMJFRxHe5ez/VG/rzVOEjazJOOSc/kSCyxreCTKfJrII6MJlL9a6t8vw==", 844 | "requires": { 845 | "swagger-ui-dist": "^3.18.1" 846 | } 847 | }, 848 | "tdigest": { 849 | "version": "0.1.1", 850 | "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", 851 | "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", 852 | "requires": { 853 | "bintrees": "1.0.1" 854 | } 855 | }, 856 | "toidentifier": { 857 | "version": "1.0.0", 858 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 859 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 860 | }, 861 | "type-is": { 862 | "version": "1.6.18", 863 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 864 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 865 | "requires": { 866 | "media-typer": "0.3.0", 867 | "mime-types": "~2.1.24" 868 | } 869 | }, 870 | "unpipe": { 871 | "version": "1.0.0", 872 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 873 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 874 | }, 875 | "url-value-parser": { 876 | "version": "2.0.1", 877 | "resolved": "https://registry.npmjs.org/url-value-parser/-/url-value-parser-2.0.1.tgz", 878 | "integrity": "sha512-bexECeREBIueboLGM3Y1WaAzQkIn+Tca/Xjmjmfd0S/hFHSCEoFkNh0/D0l9G4K74MkEP/lLFRlYnxX3d68Qgw==" 879 | }, 880 | "util-deprecate": { 881 | "version": "1.0.2", 882 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 883 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 884 | }, 885 | "utils-merge": { 886 | "version": "1.0.1", 887 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 888 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 889 | }, 890 | "vary": { 891 | "version": "1.1.2", 892 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 893 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 894 | }, 895 | "wrappy": { 896 | "version": "1.0.2", 897 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 898 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 899 | }, 900 | "yamljs": { 901 | "version": "0.3.0", 902 | "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", 903 | "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", 904 | "requires": { 905 | "argparse": "^1.0.7", 906 | "glob": "^7.0.5" 907 | } 908 | } 909 | } 910 | } 911 | --------------------------------------------------------------------------------