From ee53512c36e8bbdea9698e1f64f88321813f27f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= Date: Wed, 21 Sep 2022 16:44:37 -0300 Subject: [PATCH 01/12] Desafio finalizado --- .gitignore | 2 + README.md | 94 - media/dog.webp | Bin 63114 -> 0 bytes package-lock.json | 2562 +++++++++++++++++++++++++ package.json | 27 + src/.env.example | 5 + src/README.md | 434 +++++ src/controllers/transaction.js | 122 ++ src/controllers/user.js | 73 + src/database/Dump.sql | 238 +++ src/database/connect.js | 12 + src/database/schema.sql | 24 + src/docs/Insomnia.json | 337 ++++ src/docs/modelagem_banco_de_dados.png | Bin 0 -> 27692 bytes src/index.js | 15 + src/middlewares/transaction.js | 75 + src/middlewares/user.js | 67 + src/router.js | 21 + src/validations/config.js | 5 + src/validations/schemaTransaction.js | 11 + src/validations/schemaUser.js | 18 + 21 files changed, 4048 insertions(+), 94 deletions(-) create mode 100644 .gitignore delete mode 100644 README.md delete mode 100644 media/dog.webp create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/.env.example create mode 100644 src/README.md create mode 100644 src/controllers/transaction.js create mode 100644 src/controllers/user.js create mode 100644 src/database/Dump.sql create mode 100644 src/database/connect.js create mode 100644 src/database/schema.sql create mode 100644 src/docs/Insomnia.json create mode 100644 src/docs/modelagem_banco_de_dados.png create mode 100644 src/index.js create mode 100644 src/middlewares/transaction.js create mode 100644 src/middlewares/user.js create mode 100644 src/router.js create mode 100644 src/validations/config.js create mode 100644 src/validations/schemaTransaction.js create mode 100644 src/validations/schemaUser.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..37d7e734 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +.env diff --git a/README.md b/README.md deleted file mode 100644 index 6a877853..00000000 --- a/README.md +++ /dev/null @@ -1,94 +0,0 @@ -![Logo OW Interactive](https://github.com/owInteractive/desafio-backend/raw/master/media/logo.jpg "OW Interactive") - -# Desafio Back-End - OW Interactive 21/22 - -## Sobre a OW Interactive -Fazemos parte do universo digital, focada em criar e desenvolver experiências interativas, integrando planejamento, criatividade e tecnologia. - -Conheça mais sobre nós em: [OW Interactive - Quem somos](http://www.owinteractive.com/quem-somos/). - -## Sobre a Vaga -Esse desafio é destinado todos os níveis e não é exigido que você consiga realizar esse desafio por completo. - -Sua avaliação será dada pelas etapas que conseguir entregar. - -Para saber mais sobre as vagas acesse: [OW Interactive - Vagas](http://www.owinteractive.com/vagas/). - -Caso você tenha caido aqui por curiosidade sinta-se a vontade para enviar o desafio e aplicar para alguma vaga de backend. - -## Pré-requisitos -- Lógica de programação; -- Conhecimentos sobre Banco de dados; -- Conhecimentos sobre REST, HTTP e API's; -- Conhecimentos sobre Git; - -## Requisitos Obrigatórios -- Utilizar a linguagem [PHP](https://www.php.net/) ou [NodeJS](https://nodejs.org) -
OBS: Caso seja enviado em PHP e sem docker enviar o projeto para que rode no PHP 8+ -- Utilizar MySQL (ou MariaDB) como base de dados. -- Código bem documentado, legível e limpo; -- Fazer uma API simples e objetiva em REST, com o retorno em JSON; -- Adicionar ao README instruções claras para rodar o projeto, caso não conseguirmos rodar o projeto será desconsiderado o desafio; -- Deve ser usado [Postman](https://www.php.net/), [Insomnia](https://insomnia.rest/), [Swagger](https://swagger.io/) e etc.Para montar o exemplos da API e adicione ao repósitorio o arquivo gerado pelo programa e especificar qual o arquivo e programa devem ser usados, caso não seja enviado será desconsiderado o desafio; -- Em qualquer caso de erro ou não encontrada a API deve retorna uma resposta condizente com o problema apresentado, por exemplo um retorno 500 ou 404; - -## Diferenciais -- Utilizar o [Laravel (PHP)](https://laravel.com/docs/7.x), [Adonis/JS (Node)](https://adonisjs.com/docs/4.1/installation), [Nest JS (Node)](https://nestjs.com/) ou TypeScript; -- Utilizar o [Docker](https://www.docker.com/get-started) para conteinerização da aplicação; -- Pensar em desempenho e escalabilidade, quando for uma quantidade muito grande de dados como o sistema se comportaria; -- Criar testes (Apenas um exemplo, algo bem simples como validação do login ou consumo de um endpoint com ou sem autenticação, no README adicionar qual o comando utilizado para rodar o teste); -- Utilizar apenas as ferramentas do framework caso use um, evitando criar dependência de outros pacotes ou bibliotecas; - -## Desafio - -### Etapa 1 - Cadastrar Usuários / Endpoint Dos Usuários -Nessa etapa daremos algumas premissas que devem ser seguidas. - -- Criar um endpoint onde é cadastrado um usuário. - - Esses usuários devem ter obrigátoriamente os seguintes dados modelados, caso você ache necessário outros campos fique a vontade. - - **name** | string (Nome) - - **email** | string (E-mail) - - **birthday** | date (Data de aniversário) - - **created_at** | datetime (Criado Em) - - **updated_at** | datetime (Atualizado Em) -- Criar um endpoint para listagem desses usuários, ordernados por ordem de cadastro decrescente (mais novo para mais antigo); -- Criar um endpoint para listar um único usuário através do seu id; -- Criar um endpoint para excluir um usuário através do seu id. - -### Etapa 2 - Cadastrar Movimentações / Endpoint De Movimentações -Nessa etapa você precisará criar a modelagem e lógica para implementar as funcionalidades abaixo: - -- Criar um endpoint ou endpoint`s onde é possível associar uma operação de débito, crédito ou estorno para o usuário; -- Criar um endpoint onde seja possível visualizar toda a movimentação (páginada) do usuários mais as suas informações pessoais; -- Criar um endpoint onde seja possível excluir uma movimentação relacionada a um usuário; -- Criar um endpoint onde é retornado um arquivo no formato (csv) com 3 tipos de filtros para as movimentações: - - Últimos 30 dias; - - Passando o mês e ano por exemplo: 06/20; - - Todo as movimentações; - -### Etapa 3 - Nova Funcionalidades -Nessa etapa serão itens onde veremos como você pensou e como chegou ao resultado final. - -- Adicionar dentro do usuário um campo para saldo inicial, e criar um endpoint para alterar esse valor; -- Criar um endpoint com a soma de todas as movimentações (débito, crédito e estorno) mais o saldo inicial do usuário; -- No endpoint que exclui um usuário, adicionar a funcionalidade que agora não será mais possível excluir um usuário que tenha qualquer tipo de movimentação ou saldo; -- No endpoint que cadastra usuário, adicionar a funcionalidade que apenas maiores de 18 anos podem criar uma conta; -- No endpoint que exporta o arquivo CSV criar um cabeçalho com os dados do cliente e o seu saldo atual; - -### Etapa 4 - Diferenciais -- Criar validações com base na Request; -- Utilizar cache para otimizar as consultas e buscas; -- Criar Seeders ou Inicializadores de dados para o usuários e suas movimentações; -- Criar os métodos baseados em algum método de autênticação. -- Documentação dos endpoint`s; - -## Conclusão -Crie um Fork e submeta uma Pull Request ao Github com o seu desafio. Após isso envie um e-mail para [letsrock@owinteractive.com](mailto:letsrock@owinteractive.com), com o assunto [DESAFIO BACK-END] com o link para o seu desafio, sua apresentação e currículo anexado em formato PDF. - -Caso tenha alguma sugestão sobre o teste ela é bem vinda, fique a vontade para envia-la junto ao e-mail. - -E fique a vontade para usar os programas e ferramentas que se sentir bem, lembrando que aqui somos team [VS Code](https://code.visualstudio.com/) rs. - -Obrigado por participar e boa sorte 😀 - -![Cachorro programando](https://github.com/owInteractive/desafio-backend/raw/master/media/dog.webp "Cachorro programando") diff --git a/media/dog.webp b/media/dog.webp deleted file mode 100644 index 7fdb948e4e44b254024c601d3a5315ae76d96902..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63114 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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/runtime": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz", + "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@types/geojson": { + "version": "7946.0.10", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", + "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==" + }, + "node_modules/@types/lodash": { + "version": "4.14.185", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.185.tgz", + "integrity": "sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==" + }, + "node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "node_modules/commander": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz", + "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/csv-writer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/csv-writer/-/csv-writer-1.6.0.tgz", + "integrity": "sha512-NOx7YDFWEsM/fTRAJjRpPp8t+MKRVvniAg9wQlUKx20MFrPs73WLJhFf5iteqrxNYnsy924K3Iroh3yNHeYd2g==" + }, + "node_modules/date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.2.tgz", + "integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/getopts": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", + "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==" + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, + "node_modules/knex": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/knex/-/knex-2.3.0.tgz", + "integrity": "sha512-WMizPaq9wRMkfnwKXKXgBZeZFOSHGdtoSz5SaLAVNs3WRDfawt9O89T4XyH52PETxjV8/kRk0Yf+8WBEP/zbYw==", + "dependencies": { + "colorette": "2.0.19", + "commander": "^9.1.0", + "debug": "4.3.4", + "escalade": "^3.1.1", + "esm": "^3.2.25", + "get-package-type": "^0.1.0", + "getopts": "2.3.0", + "interpret": "^2.2.0", + "lodash": "^4.17.21", + "pg-connection-string": "2.5.0", + "rechoir": "^0.8.0", + "resolve-from": "^5.0.0", + "tarn": "^3.0.2", + "tildify": "2.0.0" + }, + "bin": { + "knex": "bin/cli.js" + }, + "engines": { + "node": ">=12" + }, + "peerDependenciesMeta": { + "better-sqlite3": { + "optional": true + }, + "mysql": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-native": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "tedious": { + "optional": true + } + } + }, + "node_modules/knex/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/knex/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mariadb": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mariadb/-/mariadb-3.0.1.tgz", + "integrity": "sha512-orYg4JojWszNWlI1a+We2TUe4h+S5WIkjUa0U4DF0jjrOtxBVtCsQtioXxURWCxVfxwQ5wZVZkBoa53lqRuQeQ==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@types/geojson": "^7946.0.8", + "@types/node": "^17.0.10", + "denque": "^2.0.1", + "iconv-lite": "^0.6.3", + "moment-timezone": "^0.5.34", + "please-upgrade-node": "^3.2.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/mariadb/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.37", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", + "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", + "dependencies": { + "moment": ">= 2.9.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/mysql2": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", + "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", + "dependencies": { + "denque": "^2.0.1", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^4.0.0", + "lru-cache": "^6.0.0", + "named-placeholders": "^1.1.2", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/mysql2/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", + "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "dependencies": { + "lru-cache": "^4.1.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/named-placeholders/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/named-placeholders/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + }, + "node_modules/nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/property-expr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", + "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", + "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tarn": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", + "integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/tildify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", + "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yup-locales": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/yup-locales/-/yup-locales-1.2.10.tgz", + "integrity": "sha512-8VF3d6d1tLM1Uc8pmyY+/cKnsZpjoZJfEw7XjqVUGuNuO+Bk/oEk50F9KyO8oaYpnj5bJb/Rbf5zpzkV5A5LbA==" + } + }, + "dependencies": { + "@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==" + }, + "@babel/runtime": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz", + "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@types/geojson": { + "version": "7946.0.10", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", + "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==" + }, + "@types/lodash": { + "version": "4.14.185", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.185.tgz", + "integrity": "sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==" + }, + "@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "commander": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz", + "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "csv-writer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/csv-writer/-/csv-writer-1.6.0.tgz", + "integrity": "sha512-NOx7YDFWEsM/fTRAJjRpPp8t+MKRVvniAg9wQlUKx20MFrPs73WLJhFf5iteqrxNYnsy924K3Iroh3yNHeYd2g==" + }, + "date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "dotenv": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.2.tgz", + "integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "express": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + }, + "getopts": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", + "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==" + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, + "knex": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/knex/-/knex-2.3.0.tgz", + "integrity": "sha512-WMizPaq9wRMkfnwKXKXgBZeZFOSHGdtoSz5SaLAVNs3WRDfawt9O89T4XyH52PETxjV8/kRk0Yf+8WBEP/zbYw==", + "requires": { + "colorette": "2.0.19", + "commander": "^9.1.0", + "debug": "4.3.4", + "escalade": "^3.1.1", + "esm": "^3.2.25", + "get-package-type": "^0.1.0", + "getopts": "2.3.0", + "interpret": "^2.2.0", + "lodash": "^4.17.21", + "pg-connection-string": "2.5.0", + "rechoir": "^0.8.0", + "resolve-from": "^5.0.0", + "tarn": "^3.0.2", + "tildify": "2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "mariadb": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mariadb/-/mariadb-3.0.1.tgz", + "integrity": "sha512-orYg4JojWszNWlI1a+We2TUe4h+S5WIkjUa0U4DF0jjrOtxBVtCsQtioXxURWCxVfxwQ5wZVZkBoa53lqRuQeQ==", + "requires": { + "@alloc/quick-lru": "^5.2.0", + "@types/geojson": "^7946.0.8", + "@types/node": "^17.0.10", + "denque": "^2.0.1", + "iconv-lite": "^0.6.3", + "moment-timezone": "^0.5.34", + "please-upgrade-node": "^3.2.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" + }, + "moment-timezone": { + "version": "0.5.37", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", + "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "mysql2": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.3.3.tgz", + "integrity": "sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==", + "requires": { + "denque": "^2.0.1", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^4.0.0", + "lru-cache": "^6.0.0", + "named-placeholders": "^1.1.2", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "named-placeholders": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", + "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", + "requires": { + "lru-cache": "^4.1.3" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + } + } + }, + "nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "requires": { + "semver-compare": "^1.0.0" + } + }, + "property-expr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", + "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "requires": { + "resolve": "^1.20.0" + } + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "simple-update-notifier": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz", + "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==", + "dev": true, + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==" + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "tarn": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", + "integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==" + }, + "tildify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", + "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "requires": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + } + }, + "yup-locales": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/yup-locales/-/yup-locales-1.2.10.tgz", + "integrity": "sha512-8VF3d6d1tLM1Uc8pmyY+/cKnsZpjoZJfEw7XjqVUGuNuO+Bk/oEk50F9KyO8oaYpnj5bJb/Rbf5zpzkV5A5LbA==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..ecf667e5 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "desafio_back_end_ow_interactive", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "dev": "nodemon ./src/index.js" + }, + "keywords": [], + "author": "José Costa", + "license": "ISC", + "dependencies": { + "cors": "^2.8.5", + "csv-writer": "^1.6.0", + "date-fns": "^2.29.3", + "dotenv": "^16.0.2", + "express": "^4.18.1", + "knex": "^2.3.0", + "mariadb": "^3.0.1", + "mysql2": "^2.3.3", + "yup": "^0.32.11", + "yup-locales": "^1.2.10" + }, + "devDependencies": { + "nodemon": "^2.0.20" + } +} diff --git a/src/.env.example b/src/.env.example new file mode 100644 index 00000000..6aed74ab --- /dev/null +++ b/src/.env.example @@ -0,0 +1,5 @@ +DATABASE_HOST= +DATABASE_PORT= +DATABASE_USER= +DATABASE_PASSWORD= +DATABASE_DATABASE= \ No newline at end of file diff --git a/src/README.md b/src/README.md new file mode 100644 index 00000000..5b72b14d --- /dev/null +++ b/src/README.md @@ -0,0 +1,434 @@ +![](https://i.imgur.com/xG74tOh.png) + +# Desafio Back-End - OW Interactive 21/22 + +Tabela de conteúdos +================= + +* [Como executar o projeto](#-Como-executar-o-projeto) +* [Tecnologias](#-Tecnologias) +* [Utilitários](#-Utilitários) + + +* [Endpoints Usuários](#-Endpoints-Usuários) + * [Criar usuário](#Criar-usuário) + * [Listar usuários](#Listar-todos-os-usuários) + * [Listar um usuário](#Listar-um-usuário) + * [Alterar saldo inicial](#Alterar-saldo-inicial) + * [Excluir usuário](#Excluir-usuário) + --- +* [Endpoints Transações](#-Endpoints-ransações) + * [Criar transação](#Criar-transação) + * [Listar transações](#Listar-transações) + * [Resumo das transações](#Resumo-das-transações) + * [Emitir transações em CSV](#Emitir-transações-em-CSV) + * [Excluir transação](#Excluir-transação) + +* [Autor](#-Autor) + +--- + +# 🎲 Como execultar o projeto + +```bash + +# Clone este repositório +$ git clone git@github.com:tgmarinho/README-ecoleta.git + +# Acesse a pasta do projeto no terminal/cmd +$ cd desafio_OWInteractive + +# Instale as dependências +$ npm install + +# Execute a aplicação em modo de desenvolvimento +$ npm run dev + +# O servidor inciará na porta:3333 - acesse http://localhost:3000 + +``` + +## No diretório em seu banco de dado execulte os scripts SQL na seguinte ordem + +* ### 1 - Schema.sql + + * > Arquivo localizado em [src/database/schema.sql]() + +* ### 2 - Dump.sql + + * > Arquivo localizado em [src/database/dump.sql]() + +## Para testes deve ser instalado o [Insomnia](https://insomnia.rest/), em seguida baixe a coleção + + + +--- + +# Tecnologias + +As seguintes ferramentas foram usadas na construção do projeto: + +#### **Server** ([NodeJS](https://nodejs.org/en/)) + +* **[Express](https://expressjs.com/)** +* **[KnexJS](http://knexjs.org/)** + + +* **[csv-writer](https://www.npmjs.com/package/csv-writer)** +* **[date-fns](https://date-fns.org/)** +* **[mariadb](https://mariadb.org/)** +* **[mysql2](https://www.npmjs.com/package/mysql2)** +* **[yup](https://www.npmjs.com/package/yup)** + +> Veja o arquivo [package.json](https://github.com/tgmarinho/README-ecoleta/blob/master/server/package.json) + +#### [](https://github.com/tgmarinho/Ecoleta#utilit%C3%A1rios)**Utilitários** + +* Editor: **[Visual Studio Code](https://code.visualstudio.com/)** +* Markdown: **[Hackmd](https://hackmd.io/)** +* Teste de API: **[Insomnia](https://insomnia.rest/)** +* Modelagem para banco de dados : **[Sqldbm](https://sqldbm.com/)** + +--- + +# Usuários + +## Criar usuário + +### `POST` `/users` + +* **Requisição** + * **Body** + + ```typescript + // Interface + { + "name": string, + "email": string, + "birthday": date + } + ``` + +* **Exemplo de Retorno** + + ```javascript + // POST /user + { + "name": "Folano de Tal", + "email": "fulano@email.com", + "birthday": "1995-08-10" + } + ``` + +--- + +## Listar todos os usuários + +### `GET` `/users` + +* **Resposta** + * listagem de todos so usuários existentes, ordernados por ordem de cadastro decrescente (mais novo para mais antigo) + +* #### Exemplo de resposta + + ```javascript + // HTTP Status 200 + [ + { + "id": 3, + "name": "Regiane Teixeira", + "email": "regianeteixeira@email.com", + "birthday": "1995-09-06T03:00:00.000Z", + "created_at": "2022-09-20T17:43:32.000Z", + "updated_at": "2022-09-21T07:41:43.000Z", + "opening_balance": 0 + }, + { + "id": 2, + "name": "Maria Das Graças", + "email": "mariadasgraacas@email.com", + "birthday": "1971-05-30T03:00:00.000Z", + "created_at": "2022-09-20T06:51:26.000Z", + "updated_at": null, + "opening_balance": 0 + }, + { + "id": 1, + "name": "José Costa", + "email": "josecosta@email.com", + "birthday": "1991-08-10T03:00:00.000Z", + "created_at": "2022-09-19T22:57:36.000Z", + "updated_at": null, + "opening_balance": 300000 + } + ] + + // nenhum usuário encontrado + [] + ``` + +--- + +## Listar um usuário + +### `GET` `/user/:user_id` + +* **Requisição** + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + GET/user/1 + ``` + +* **Exemplo de Retorno** + + ```javascript + // GET /user/1 + { + "id": 1, + "name": "José Costa", + "email": "josecosta@email.com", + "birthday": "1991-08-10T03:00:00.000Z", + "created_at": "2022-09-19T22:57:36.000Z", + "updated_at": null, + "opening_balance": 900000 + } + ``` + +--- + +## Alterar saldo inicial + +### `PATCH` `/user/:user_id` + +* **Requisição** + * **Body** + + ```typescript + // Interface + { + opening_balance: number + } + ``` + + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + GET/user/1 + ``` + +* **Exemplo de Retorno** + + ```javascript + // PATCH /user/1 + { + "opening_balance": 300000 + } + ``` + +## Excluir usuário + +### `DELETE` `/user/:user_id` + +* **Requisição** + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + DELETE/user/1 + ``` + +--- + +# Transações + +## Criar transação + +### `POST` `/transaction/:user_id` + +* **Requisição** + * **Body** + + ```typescript + // Interface + { + type: "debit" | "credit" | "reversal", + amount: number, + description?: string + } + ``` + + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + POST/transaction/1 + ``` + +* **Exemplo de Retorno** + + ```javascript + // POST /transaction/1 + { + "type": "debit", + "amount": 1050, + "description": "Descrição..." + } + ``` + +--- + +## Listar transações + +### `GET` `/transactions/user/:user_id` + +* **Requisição** + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + GET/transactions/user/1 + ``` + + * **URL Query Params** - Paginção: por padão a primeira pagina é 0, cada página retorna no maximo 5 transações (opicional) + + ``` + GET/transaction/user/1?page=1 + ``` + +* **Exemplo de Retorno** + + ```javascript + // GET /transaction/user/1 + + { + "id": 1, + "name": "José Costa", + "email": "josecosta@email.com", + "birthday": "1991-08-10T03:00:00.000Z", + "created_at": "2022-09-19T22:57:36.000Z", + "updated_at": null, + "opening_balance": 300000, + "page": 0, + "transactions": [ + { + "id": 25, + "user_id": 1, + "type": "reversal", + "amount": 12000, + "description": "Compra duplicada de vestido", + "moment": "2022-09-20T16:56:47.000Z" + }, + { + "id": 24, + "user_id": 1, + "type": "reversal", + "amount": 12000, + "description": "Compra duplicada de vestido", + "moment": "2022-09-20T16:56:47.000Z" + }, + { + "id": 19, + "user_id": 1, + "type": "reversal", + "amount": 12000, + "description": "Compra duplicada de vestido", + "moment": "2022-09-20T16:56:46.000Z" + } + ] + } + + ``` + +--- + +## Resumo das transações + +### `GET` `/transactions/user/:user_id/summary` + +* **Requisição** + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + GET/transactions/user/1/summary + ``` + +* **Exemplo de Retorno** + + ```javascript + /// GET/transactions/user/1/summary + + { + "opening_balance": 300000, + "debit": 4300, + "credit": 1800, + "reversal": 228000 + } + ``` + +--- + +## Emitir transações em CSV + +### `GET` `/transactions/user/:user_id/csv` + +* **Requisição** + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + GET/transactions/user/1/csv + ``` + + * **URL Query Params** + * **filtros para as transações:** + + ```typescript + { + last_days: number //Retorna transaçoẽs referente a quantidade de dias informado + month_year: date //Retorna transações no mês e ano informado. Ex: 02/22 + } + ``` + + * **Exemplos de requisição** + + ``` + GET/transaction/user/1/csv + ``` + + ``` + GET/transaction/user/1/csv?laste_day=30 + ``` + + ``` + GET/transaction/user/1/csv?month_year=02/22 + ``` + +* **Exemplo de Retorno** + * Retorna uma arquivo no formato CSV com as transações do usuário + +--- + +## Excluir transação + +### `DELETE` `/transactions/:transaction_id` + +* **Requisição** + * **URL Params** - ID da transação (passado como parâmetro na rota) + + ``` + DELETE/transactions/1 + ``` + +--- + +# 🦸 Autor + + + +
🎧 + José Costa
+
+ +[![Linkedin Badge](https://img.shields.io/badge/-José_Costa-blue?style=flat-square&logo=Linkedin&logoColor=white&link=https://www.linkedin.com/in/josecostasantosjr/)](https://www.linkedin.com/in/josecostasantosjr/) +[![Gmail Badge](https://img.shields.io/badge/-josecostasantos.jr@gmail.com-c14438?style=flat-square&logo=Gmail&logoColor=white&link=mailto:josecostasantos.jr@gmail.com)](mailto:josecostasantos.js@gmail.com) + +--- diff --git a/src/controllers/transaction.js b/src/controllers/transaction.js new file mode 100644 index 00000000..8e1e1e7a --- /dev/null +++ b/src/controllers/transaction.js @@ -0,0 +1,122 @@ +const kenx = require('../database/connect'); +const { createArrayCsvWriter } = require('csv-writer'); + +async function createTransaction(req, res) { + + const { user } = req; + const { type, amount, description } = req.body; + + try { + + const newTransactionId = await kenx('transactions').insert({ user_id: user.id, type, amount, description, moment: new Date() }); + + const transaction = await kenx('transactions').where({ id: newTransactionId }).first(); + + return res.status(201).json(transaction); + + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} + +async function getTransactionsByUser(req, res) { + + const { user } = req; + const { page } = req.query; + + const limit_value = 5; + const offset_value = page ? page * limit_value : 0; + + try { + const transactions = await kenx('transactions').where({ user_id: user.id }).orderBy('moment', 'desc').limit(limit_value).offset(offset_value); + + user.page = page ? Number(page) : 0; + user.transactions = transactions + + + return res.status(200).json(user); + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} + +async function deleteTransaction(req, res) { + + const { transaction } = req; + + try { + await kenx('transactions').where({ id: transaction.id }).delete(); + + return res.status(200).json({ message: 'Transação excluida com sucesso!' }); + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} + +async function getTransactionsCSV(req, res) { + const { transactions } = req; + + try { + + const header = Object.getOwnPropertyNames(transactions[0]); + const path = `./src/temp/${new Date().getTime()}.csv` + + const csvWriter = createArrayCsvWriter({ + path, + header: [...header] + }); + + + let records = []; + + for (const transaction of transactions) { + records.push(Object.values(transaction)); + } + + await csvWriter.writeRecords(records); + + return res.download(path); + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} + +async function getTransactionsSummary(req, res) { + const { user } = req; + + try { + const transactions = await kenx('transactions').where({ user_id: user.id }); + + const transactions_summary = { + opening_balance: user.opening_balance, + debit: 0, + credit: 0, + reversal: 0 + } + + transactions.forEach(transaction => { + if (transaction.type === 'debit') { + transactions_summary.debit += transaction.amount; + } + else if (transaction.type === 'credit') { + transactions_summary.credit += transaction.amount; + } + else if (transaction.type === 'reversal') { + transactions_summary.reversal += transaction.amount; + } + }); + + return res.status(200).json(transactions_summary); + } catch (error) { + return res.status(500).json({ error: error.message }); + } + +} + +module.exports = { + createTransaction, + getTransactionsByUser, + deleteTransaction, + getTransactionsCSV, + getTransactionsSummary +} \ No newline at end of file diff --git a/src/controllers/user.js b/src/controllers/user.js new file mode 100644 index 00000000..0be7a825 --- /dev/null +++ b/src/controllers/user.js @@ -0,0 +1,73 @@ +const knex = require('../database/connect'); +const { schemaUpdateOpeningBalance } = require('../validations/schemaUser'); + +async function getAllUsers(req, res) { + + try { + const users = await knex('users').orderBy('created_at', 'desc'); + res.status(200).json(users); + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} + +async function createUser(req, res) { + + try { + const newUser = await knex('users').insert({ ...req.body, created_at: new Date() }); + + if (newUser.length === 0) { + return res.status(400).json({ message: "Erro ao cadastrar usuário. Usuário não foi cadastrado!" }) + } + + res.status(201).json({ message: 'Usuário cadastrado com sucesso!' }); + + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} + +async function getUser(req, res) { + const { user } = req; + + try { + return res.status(200).json(user); + } catch (error) { + return res.status(500).json({ error: error.message }) + } +} + +async function deleteUser(req, res) { + const { id } = req.user; + try { + await knex('users').where({ id }).delete(); + return res.status(200).json({ message: 'Usuário excluido com sucesso!' }); + } catch (error) { + return res.status(400).json({ error: error.message }) + } +} + +async function updateUserOpeningBalance(req, res) { + + const { user } = req; + const { opening_balance } = req.body; + + try { + await schemaUpdateOpeningBalance.validate({ opening_balance }); + + await knex('users').where({ id: user.id }).update({ opening_balance, updated_at: new Date() }); + + return res.status(200).json({ message: 'Saldo inicial alterado com sucesso!' }); + } catch (error) { + return res.status(500).json({ error: error.message }) + } +} + + +module.exports = { + getAllUsers, + createUser, + getUser, + deleteUser, + updateUserOpeningBalance +} \ No newline at end of file diff --git a/src/database/Dump.sql b/src/database/Dump.sql new file mode 100644 index 00000000..ff6708dd --- /dev/null +++ b/src/database/Dump.sql @@ -0,0 +1,238 @@ +INSERT INTO users (name,email,birthday,created_at) +VALUES + ("Derek Flowers","fermentum.arcu@outlook.com","1990-12-12", NOW()), + ("Ryan Pitts","nunc.commodo@protonmail.com","1990-02-23", NOW()), + ("Uriel Higgins","semper.erat@icloud.edu","1990-06-12", NOW()), + ("Gary Lowe","vel.mauris.integer@hotmail.edu","1990-10-03", NOW()), + ("Brenda Hart","a.felis@google.ca","1990-07-05", NOW()), + ("Margaret Haley","ac@icloud.couk","1990-12-27", NOW()), + ("Gregory Moon","elit.pede@protonmail.edu","1990-10-12", NOW()), + ("Blossom Porter","eget.venenatis@google.edu","1990-07-18", NOW()), + ("Gareth Hurst","metus.in@aol.couk","1990-05-05", NOW()), + ("Garth Booker","aliquam.iaculis@yahoo.edu","1990-08-01", NOW()), + ("Hall Pollard","in.consectetuer@outlook.ca","2021-11-24", NOW()), + ("Isabelle Carney","cras.eget@aol.org","1990-12-20", NOW()), + ("Keely Wilcox","nec.mauris@hotmail.edu","1990-03-18", NOW()), + ("Reagan Hopper","nisl.arcu@yahoo.com","1990-03-24", NOW()), + ("Prescott Rich","elementum.at.egestas@aol.ca","1990-09-01", NOW()), + ("Neil Schmidt","sit.amet@outlook.ca","1990-08-12", NOW()), + ("Chaney Montoya","sem.consequat@hotmail.net","1990-07-14", NOW()), + ("Dustin Horn","mauris@yahoo.edu","1990-06-14", NOW()), + ("Laurel Fuller","sit.amet.ultricies@outlook.couk","1990-06-11", NOW()), + ("Jarrod Cleveland","cras@outlook.org","1990-10-19", NOW()), + ("Ivana Foreman","at@protonmail.couk","1990-12-10", NOW()), + ("Jamal Mcguire","lorem.ut@aol.com","1990-07-04", NOW()), + ("Meredith Kinney","eget@outlook.edu","1990-10-20", NOW()), + ("Vanna Perry","ultrices.iaculis.odio@hotmail.couk","1990-06-21", NOW()), + ("Suki Burnett","adipiscing.lacus@aol.edu","1990-04-15", NOW()), + ("Lenore Peterson","aliquam.adipiscing@protonmail.ca","1990-03-29", NOW()), + ("Rinah Carson","pellentesque@hotmail.net","1990-02-01", NOW()), + ("Derek Barron","donec.egestas@hotmail.couk","1990-08-02", NOW()), + ("Nasim Osborne","ipsum.leo@yahoo.ca","1990-06-10", NOW()), + ("Isabella Fry","cum@aol.ca","1990-02-23", NOW()), + ("Coby Stout","iaculis.odio@yahoo.edu","1990-09-21", NOW()), + ("Graiden Wong","senectus.et@protonmail.org","1990-10-06", NOW()), + ("Serina Hurley","proin.eget.odio@outlook.ca","1990-07-27", NOW()), + ("Velma Stephens","et.magnis@hotmail.net","1990-09-18", NOW()), + ("Xanthus Fields","dui@aol.couk","1990-04-04", NOW()), + ("Gannon Huff","et@protonmail.com","1990-05-10", NOW()), + ("Nerea Brady","vulputate.risus@icloud.ca","1990-03-27", NOW()), + ("Griffin Banks","sed@protonmail.ca","1990-06-14", NOW()), + ("Florence Mathews","sapien@aol.edu","1990-02-02", NOW()); + +INSERT INTO transactions (user_id,type, amount, description, moment) +VALUES + (33,"credit",496605,"Uma descrição...", NOW()), + (34,"reversal",602625,"Uma descrição...", NOW()), + (32,"reversal",604050,"Uma descrição...", NOW()), + (22,"reversal",810782,"Uma descrição...", NOW()), + (20,"credit",533303,"Uma descrição...", NOW()), + (19,"reversal",312160,"Uma descrição...", NOW()), + (1,"debit",559927,"Uma descrição...", NOW()), + (5,"credit",457430,"Uma descrição...", NOW()), + (37,"credit",341760,"Uma descrição...", NOW()), + (23,"credit",369551,"Uma descrição...", NOW()), + (6,"credit",937224,"Uma descrição...", NOW()), + (10,"credit",823922,"Uma descrição...", NOW()), + (21,"reversal",964897,"Uma descrição...", NOW()), + (25,"credit",198864,"Uma descrição...", NOW()), + (21,"reversal",419590,"Uma descrição...", NOW()), + (33,"debit",231889,"Uma descrição...", NOW()), + (5,"reversal",851301,"Uma descrição...", NOW()), + (17,"debit",125170,"Uma descrição...", NOW()), + (26,"reversal",23403,"Uma descrição...", NOW()), + (33,"credit",496605,"Uma descrição...", NOW()), + (34,"reversal",602625,"Uma descrição...", NOW()), + (32,"reversal",604050,"Uma descrição...", NOW()), + (22,"reversal",810782,"Uma descrição...", NOW()), + (20,"credit",533303,"Uma descrição...", NOW()), + (19,"reversal",312160,"Uma descrição...", NOW()), + (1,"debit",559927,"Uma descrição...", NOW()), + (5,"credit",457430,"Uma descrição...", NOW()), + (37,"credit",341760,"Uma descrição...", NOW()), + (23,"credit",369551,"Uma descrição...", NOW()), + (6,"credit",937224,"Uma descrição...", NOW()), + (10,"credit",823922,"Uma descrição...", NOW()), + (21,"reversal",964897,"Uma descrição...", NOW()), + (25,"credit",198864,"Uma descrição...", NOW()), + (21,"reversal",419590,"Uma descrição...", NOW()), + (33,"debit",231889,"Uma descrição...", NOW()), + (5,"reversal",851301,"Uma descrição...", NOW()), + (17,"debit",125170,"Uma descrição...", NOW()), + (26,"reversal",23403,"Uma descrição...", NOW()), + (33,"credit",496605,"Uma descrição...", NOW()), + (34,"reversal",602625,"Uma descrição...", NOW()), + (32,"reversal",604050,"Uma descrição...", NOW()), + (22,"reversal",810782,"Uma descrição...", NOW()), + (20,"credit",533303,"Uma descrição...", NOW()), + (19,"reversal",312160,"Uma descrição...", NOW()), + (1,"debit",559927,"Uma descrição...", NOW()), + (5,"credit",457430,"Uma descrição...", NOW()), + (37,"credit",341760,"Uma descrição...", NOW()), + (23,"credit",369551,"Uma descrição...", NOW()), + (6,"credit",937224,"Uma descrição...", NOW()), + (10,"credit",823922,"Uma descrição...", NOW()), + (21,"reversal",964897,"Uma descrição...", NOW()), + (25,"credit",198864,"Uma descrição...", NOW()), + (21,"reversal",419590,"Uma descrição...", NOW()), + (33,"debit",231889,"Uma descrição...", NOW()), + (5,"reversal",851301,"Uma descrição...", NOW()), + (17,"debit",125170,"Uma descrição...", NOW()), + (26,"reversal",23403,"Uma descrição...", NOW()), + (33,"credit",496605,"Uma descrição...", NOW()), + (34,"reversal",602625,"Uma descrição...", NOW()), + (32,"reversal",604050,"Uma descrição...", NOW()), + (22,"reversal",810782,"Uma descrição...", NOW()), + (20,"credit",533303,"Uma descrição...", NOW()), + (19,"reversal",312160,"Uma descrição...", NOW()), + (1,"debit",559927,"Uma descrição...", NOW()), + (5,"credit",457430,"Uma descrição...", NOW()), + (37,"credit",341760,"Uma descrição...", NOW()), + (23,"credit",369551,"Uma descrição...", NOW()), + (6,"credit",937224,"Uma descrição...", NOW()), + (10,"credit",823922,"Uma descrição...", NOW()), + (21,"reversal",964897,"Uma descrição...", NOW()), + (25,"credit",198864,"Uma descrição...", NOW()), + (21,"reversal",419590,"Uma descrição...", NOW()), + (33,"debit",231889,"Uma descrição...", NOW()), + (5,"reversal",851301,"Uma descrição...", NOW()), + (17,"debit",125170,"Uma descrição...", NOW()), + (26,"reversal",23403,"Uma descrição...", NOW()), + (33,"credit",496605,"Uma descrição...", NOW()), + (34,"reversal",602625,"Uma descrição...", NOW()), + (32,"reversal",604050,"Uma descrição...", NOW()), + (22,"reversal",810782,"Uma descrição...", NOW()), + (20,"credit",533303,"Uma descrição...", NOW()), + (19,"reversal",312160,"Uma descrição...", NOW()), + (1,"debit",559927,"Uma descrição...", NOW()), + (5,"credit",457430,"Uma descrição...", NOW()), + (37,"credit",341760,"Uma descrição...", NOW()), + (23,"credit",369551,"Uma descrição...", NOW()), + (6,"credit",937224,"Uma descrição...", NOW()), + (10,"credit",823922,"Uma descrição...", NOW()), + (21,"reversal",964897,"Uma descrição...", NOW()), + (25,"credit",198864,"Uma descrição...", NOW()), + (21,"reversal",419590,"Uma descrição...", NOW()), + (33,"debit",231889,"Uma descrição...", NOW()), + (5,"reversal",851301,"Uma descrição...", NOW()), + (17,"debit",125170,"Uma descrição...", NOW()), + (26,"reversal",23403,"Uma descrição...", NOW()), + (33,"credit",496605,"Uma descrição...", NOW()), + (34,"reversal",602625,"Uma descrição...", NOW()), + (32,"reversal",604050,"Uma descrição...", NOW()), + (22,"reversal",810782,"Uma descrição...", NOW()), + (20,"credit",533303,"Uma descrição...", NOW()), + (19,"reversal",312160,"Uma descrição...", NOW()), + (1,"debit",559927,"Uma descrição...", NOW()), + (5,"credit",457430,"Uma descrição...", NOW()), + (37,"credit",341760,"Uma descrição...", NOW()), + (23,"credit",369551,"Uma descrição...", NOW()), + (6,"credit",937224,"Uma descrição...", NOW()), + (10,"credit",823922,"Uma descrição...", NOW()), + (21,"reversal",964897,"Uma descrição...", NOW()), + (25,"credit",198864,"Uma descrição...", NOW()), + (21,"reversal",419590,"Uma descrição...", NOW()), + (33,"debit",231889,"Uma descrição...", NOW()), + (5,"reversal",851301,"Uma descrição...", NOW()), + (17,"debit",125170,"Uma descrição...", NOW()), + (26,"reversal",23403,"Uma descrição...", NOW()), + (33,"credit",496605,"Uma descrição...", NOW()), + (34,"reversal",602625,"Uma descrição...", NOW()), + (32,"reversal",604050,"Uma descrição...", NOW()), + (22,"reversal",810782,"Uma descrição...", NOW()), + (20,"credit",533303,"Uma descrição...", NOW()), + (19,"reversal",312160,"Uma descrição...", NOW()), + (1,"debit",559927,"Uma descrição...", NOW()), + (5,"credit",457430,"Uma descrição...", NOW()), + (37,"credit",341760,"Uma descrição...", NOW()), + (23,"credit",369551,"Uma descrição...", NOW()), + (6,"credit",937224,"Uma descrição...", NOW()), + (10,"credit",823922,"Uma descrição...", NOW()), + (21,"reversal",964897,"Uma descrição...", NOW()), + (25,"credit",198864,"Uma descrição...", NOW()), + (21,"reversal",419590,"Uma descrição...", NOW()), + (33,"debit",231889,"Uma descrição...", NOW()), + (5,"reversal",851301,"Uma descrição...", NOW()), + (17,"debit",125170,"Uma descrição...", NOW()), + (26,"reversal",23403,"Uma descrição...", NOW()), + (33,"credit",496605,"Uma descrição...", NOW()), + (34,"reversal",602625,"Uma descrição...", NOW()), + (32,"reversal",604050,"Uma descrição...", NOW()), + (22,"reversal",810782,"Uma descrição...", NOW()), + (20,"credit",533303,"Uma descrição...", NOW()), + (19,"reversal",312160,"Uma descrição...", NOW()), + (1,"debit",559927,"Uma descrição...", NOW()), + (5,"credit",457430,"Uma descrição...", NOW()), + (37,"credit",341760,"Uma descrição...", NOW()), + (23,"credit",369551,"Uma descrição...", NOW()), + (6,"credit",937224,"Uma descrição...", NOW()), + (10,"credit",823922,"Uma descrição...", NOW()), + (21,"reversal",964897,"Uma descrição...", NOW()), + (25,"credit",198864,"Uma descrição...", NOW()), + (21,"reversal",419590,"Uma descrição...", NOW()), + (33,"debit",231889,"Uma descrição...", NOW()), + (5,"reversal",851301,"Uma descrição...", NOW()), + (17,"debit",125170,"Uma descrição...", NOW()), + (26,"reversal",23403,"Uma descrição...", NOW()), + (33,"credit",496605,"Uma descrição...", NOW()), + (34,"reversal",602625,"Uma descrição...", NOW()), + (32,"reversal",604050,"Uma descrição...", NOW()), + (22,"reversal",810782,"Uma descrição...", NOW()), + (20,"credit",533303,"Uma descrição...", NOW()), + (19,"reversal",312160,"Uma descrição...", NOW()), + (1,"debit",559927,"Uma descrição...", NOW()), + (5,"credit",457430,"Uma descrição...", NOW()), + (37,"credit",341760,"Uma descrição...", NOW()), + (23,"credit",369551,"Uma descrição...", NOW()), + (6,"credit",937224,"Uma descrição...", NOW()), + (10,"credit",823922,"Uma descrição...", NOW()), + (21,"reversal",964897,"Uma descrição...", NOW()), + (25,"credit",198864,"Uma descrição...", NOW()), + (21,"reversal",419590,"Uma descrição...", NOW()), + (33,"debit",231889,"Uma descrição...", NOW()), + (5,"reversal",851301,"Uma descrição...", NOW()), + (17,"debit",125170,"Uma descrição...", NOW()), + (26,"reversal",23403,"Uma descrição...", NOW()), + (33,"credit",496605,"Uma descrição...", NOW()), + (34,"reversal",602625,"Uma descrição...", NOW()), + (32,"reversal",604050,"Uma descrição...", NOW()), + (22,"reversal",810782,"Uma descrição...", NOW()), + (20,"credit",533303,"Uma descrição...", NOW()), + (19,"reversal",312160,"Uma descrição...", NOW()), + (1,"debit",559927,"Uma descrição...", NOW()), + (5,"credit",457430,"Uma descrição...", NOW()), + (37,"credit",341760,"Uma descrição...", NOW()), + (23,"credit",369551,"Uma descrição...", NOW()), + (6,"credit",937224,"Uma descrição...", NOW()), + (10,"credit",823922,"Uma descrição...", NOW()), + (21,"reversal",964897,"Uma descrição...", NOW()), + (25,"credit",198864,"Uma descrição...", NOW()), + (21,"reversal",419590,"Uma descrição...", NOW()), + (33,"debit",231889,"Uma descrição...", NOW()), + (5,"reversal",851301,"Uma descrição...", NOW()), + (17,"debit",125170,"Uma descrição...", NOW()), + (26,"reversal",23403,"Uma descrição...", NOW()), + (31,"reversal",259048,"Uma descrição...", NOW()); + + + diff --git a/src/database/connect.js b/src/database/connect.js new file mode 100644 index 00000000..cbadc281 --- /dev/null +++ b/src/database/connect.js @@ -0,0 +1,12 @@ +const knex = require('knex')({ + client: 'mysql2', + connection: { + host: 'localhost', + port: 3306, + user: 'admin', + database: 'ow_interactive_challenge', + password: 'mariadb', + } +}); + +module.exports = knex \ No newline at end of file diff --git a/src/database/schema.sql b/src/database/schema.sql new file mode 100644 index 00000000..ff865cdc --- /dev/null +++ b/src/database/schema.sql @@ -0,0 +1,24 @@ +drop table if exists transactions; + +drop table if exists users; + +create table users ( + id bigint primary key auto_increment, + name varchar(255) not null, + email text not null, + birthday date not null, + created_at datetime not null, + updated_at datetime +); + +create table transactions ( + id bigint primary key auto_increment, + user_id bigint not null, + type varchar(50) not null, + amount bigint not null, + description text, + moment datetime not null, + foreign key (user_id) references users(id) +); + +alter table users add column opening_balance int default 0 not null \ No newline at end of file diff --git a/src/docs/Insomnia.json b/src/docs/Insomnia.json new file mode 100644 index 00000000..a0de6824 --- /dev/null +++ b/src/docs/Insomnia.json @@ -0,0 +1,337 @@ +{ + "_type": "export", + "__export_format": 4, + "__export_date": "2022-09-21T08:31:20.433Z", + "__export_source": "insomnia.desktop.app:v2022.5.1", + "resources": [ + { + "_id": "req_391ff64925274b3d8d552bebeb1419d3", + "parentId": "fld_d075a0fc035c4257ba56a6e6977237fe", + "modified": 1663743508437, + "created": 1663434705487, + "url": "{{ _.baseURL }}/users", + "name": "Listar Usuários", + "description": "", + "method": "GET", + "body": {}, + "parameters": [], + "headers": [], + "authentication": {}, + "metaSortKey": -1663434705487, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "fld_d075a0fc035c4257ba56a6e6977237fe", + "parentId": "wrk_6bb0d6aca7c24aee94403560f8c76b75", + "modified": 1663434702828, + "created": 1663434702828, + "name": "User", + "description": "", + "environment": {}, + "environmentPropertyOrder": null, + "metaSortKey": -1663434702828, + "_type": "request_group" + }, + { + "_id": "wrk_6bb0d6aca7c24aee94403560f8c76b75", + "parentId": null, + "modified": 1663426088356, + "created": 1663426088356, + "name": "owInteractive_challenge", + "description": "", + "scope": "collection", + "_type": "workspace" + }, + { + "_id": "req_bbdd8013c331444f962752adf1f4b6cf", + "parentId": "fld_d075a0fc035c4257ba56a6e6977237fe", + "modified": 1663743530890, + "created": 1663439675771, + "url": "{{ _.baseURL }}/user/1", + "name": "Listar Usuário por ID", + "description": "", + "method": "GET", + "body": {}, + "parameters": [], + "headers": [], + "authentication": {}, + "metaSortKey": -1663432557778.25, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "req_9b1fadf981994d419590440c942c367d", + "parentId": "fld_d075a0fc035c4257ba56a6e6977237fe", + "modified": 1663743559223, + "created": 1663440960184, + "url": "{{ _.baseURL }}/user/6", + "name": "Excluir Usuário", + "description": "", + "method": "DELETE", + "body": {}, + "parameters": [], + "headers": [], + "authentication": {}, + "metaSortKey": -1663431483923.875, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "req_77a8a9d1855c43f9a2ddbe3ca12ae9fa", + "parentId": "fld_d075a0fc035c4257ba56a6e6977237fe", + "modified": 1663748866205, + "created": 1663739024540, + "url": "{{ _.baseURL }}/user/3", + "name": "Alterar saldo inicial", + "description": "", + "method": "PATCH", + "body": { + "mimeType": "application/json", + "text": "{\n\t\"opening_balance\": 0\n}" + }, + "parameters": [], + "headers": [ + { + "name": "Content-Type", + "value": "application/json", + "id": "pair_e064eca5571947bfb02abc85cbeb5a4f" + } + ], + "authentication": {}, + "metaSortKey": -1663430946996.6875, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "req_ce7e453c5fc04ba39f6bfc353018697f", + "parentId": "fld_d075a0fc035c4257ba56a6e6977237fe", + "modified": 1663748868495, + "created": 1663434764247, + "url": "{{ _.baseURL }}/user", + "name": "Criar Usuário", + "description": "", + "method": "POST", + "body": { + "mimeType": "application/json", + "text": "{\n\t\"name\": \"Validação Yup\",\n\t\"email\": \"fulano@email.com\",\n\t\"birthday\": \"2000-09-06\"\n}" + }, + "parameters": [], + "headers": [ + { + "name": "Content-Type", + "value": "application/json", + "id": "pair_c3f61a5ba0e34b1bafb15c56feae21f6" + } + ], + "authentication": {}, + "metaSortKey": -1663430410069.5, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "req_e4470742216544a0b76a4f8e71bd3d7e", + "parentId": "fld_a8b94ab921c74c4694b054389ff40399", + "modified": 1663748877927, + "created": 1663653082063, + "url": "{{ _.baseURL }}/transactions/user/3", + "name": "Listar Transações por Usuário", + "description": "", + "method": "GET", + "body": {}, + "parameters": [], + "headers": [], + "authentication": {}, + "metaSortKey": -1663434705487, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "fld_a8b94ab921c74c4694b054389ff40399", + "parentId": "wrk_6bb0d6aca7c24aee94403560f8c76b75", + "modified": 1663653082061, + "created": 1663653082061, + "name": "Transactions", + "description": "", + "environment": {}, + "environmentPropertyOrder": null, + "metaSortKey": -1663430407920, + "_type": "request_group" + }, + { + "_id": "req_e6fc7b27231a42f19693737102c3fed5", + "parentId": "fld_a8b94ab921c74c4694b054389ff40399", + "modified": 1663743675448, + "created": 1663743152253, + "url": "{{ _.baseURL }}/transactions/user/3/summary", + "name": "Resumo das transações por Usuário", + "description": "", + "method": "GET", + "body": {}, + "parameters": [], + "headers": [], + "authentication": {}, + "metaSortKey": -1663434168559.8125, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "req_24f1f71765cf4526a4f20f9c1961aff8", + "parentId": "fld_a8b94ab921c74c4694b054389ff40399", + "modified": 1663743729713, + "created": 1663701345235, + "url": "{{ _.baseURL }}/transactions/user/1/csv?last_days=1", + "name": "Download arquivo CSV de Transações", + "description": "", + "method": "GET", + "body": {}, + "parameters": [], + "headers": [], + "authentication": {}, + "metaSortKey": -1663433631632.625, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "req_8d7d0729d5a34113b8ffbad297fdb32b", + "parentId": "fld_a8b94ab921c74c4694b054389ff40399", + "modified": 1663748936131, + "created": 1663653082064, + "url": "{{ _.baseURL }}/transaction/3", + "name": "Criar Transação por Usuário", + "description": "", + "method": "POST", + "body": { + "mimeType": "application/json", + "text": "{\n\t\"type\": \"reversal\",\n\t\"amount\": 1050,\n\t\"description\": \"descrição\"\n}" + }, + "parameters": [], + "headers": [ + { + "name": "Content-Type", + "value": "application/json", + "id": "pair_c3f61a5ba0e34b1bafb15c56feae21f6" + } + ], + "authentication": {}, + "metaSortKey": -1663430410069.5, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "req_248900d1b1d6458ba13bb25e77115548", + "parentId": "fld_a8b94ab921c74c4694b054389ff40399", + "modified": 1663748906639, + "created": 1663693098884, + "url": "{{ _.baseURL }}/transaction/32", + "name": "Excluir Transação", + "description": "", + "method": "DELETE", + "body": {}, + "parameters": [], + "headers": [], + "authentication": {}, + "metaSortKey": -1663428262360.75, + "isPrivate": false, + "settingStoreCookies": true, + "settingSendCookies": true, + "settingDisableRenderRequestBody": false, + "settingEncodeUrl": true, + "settingRebuildPath": true, + "settingFollowRedirects": "global", + "_type": "request" + }, + { + "_id": "env_dd64fb37750d3ee19806999f4a72f17928ec55ff", + "parentId": "wrk_6bb0d6aca7c24aee94403560f8c76b75", + "modified": 1663615947315, + "created": 1663426088362, + "name": "Base Environment", + "data": { + "baseURL": "http://localhost:3000" + }, + "dataPropertyOrder": { + "&": [ + "baseURL" + ] + }, + "color": null, + "isPrivate": false, + "metaSortKey": 1663426088362, + "_type": "environment" + }, + { + "_id": "jar_dd64fb37750d3ee19806999f4a72f17928ec55ff", + "parentId": "wrk_6bb0d6aca7c24aee94403560f8c76b75", + "modified": 1663426088363, + "created": 1663426088363, + "name": "Default Jar", + "cookies": [], + "_type": "cookie_jar" + }, + { + "_id": "spc_e868c607f68f408d91a06f5dda2ab388", + "parentId": "wrk_6bb0d6aca7c24aee94403560f8c76b75", + "modified": 1663426088358, + "created": 1663426088358, + "fileName": "owInteractive_challenge", + "contents": "", + "contentType": "yaml", + "_type": "api_spec" + } + ] +} \ No newline at end of file diff --git a/src/docs/modelagem_banco_de_dados.png b/src/docs/modelagem_banco_de_dados.png new file mode 100644 index 0000000000000000000000000000000000000000..9ab5d7a06f186b8d7de0bd49479d184bb320712b GIT binary patch literal 27692 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 Xm?U!MK1u-$DF{>#cDeY{wR`^s@=pN* literal 0 HcmV?d00001 diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..d79df82a --- /dev/null +++ b/src/index.js @@ -0,0 +1,15 @@ +require('dotenv').config(); +const cors = require('cors'); +const express = require('express'); +const routes = require('./router'); + +console.log(process.env.DATABASE_HOST); +const app = express(); + +app.use(express.json()); +app.use(routes); +app.use(cors()); + +const port = 3000; + +app.listen(port, () => { console.log(`Started server in port ${port}`); }) \ No newline at end of file diff --git a/src/middlewares/transaction.js b/src/middlewares/transaction.js new file mode 100644 index 00000000..225d4724 --- /dev/null +++ b/src/middlewares/transaction.js @@ -0,0 +1,75 @@ +const { subDays, format } = require('date-fns'); +const knex = require('../database/connect'); +const { schemaCreateTransaction } = require('../validations/schemaTransaction'); + +async function validateCreateTransaction(req, res, next) { + const { type } = req.body; + + if (type !== 'debit' && type !== 'credit' && type !== 'reversal') { + return res.status(400).json({ error: 'Type incorreto. O campo type tem as seguintes opções: debit, credit ou reversal' }); + } + try { + await schemaCreateTransaction.validate(req.body); + return next(); + } catch (error) { + return res.status(400).json({ error: error.message }); + } +} + +async function verifyTransactionId(req, res, next) { + + const { transaction_id } = req.params; + + try { + const transaction = await knex('transactions').where({ id: transaction_id }).first(); + + if (!transaction) { + return res.status(404).json({ error: `Transação inexistente!` }); + } + + req.transaction = transaction; + + return next(); + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} + +async function transactionsFilter(req, res, next) { + + try { + const { user } = req; + const { last_days, month_year } = req.query; + + const transactions = await knex('transactions').where({ user_id: user.id }).orderBy('moment', 'desc'); + + if (last_days) { + const dateDifferences = subDays(new Date(), last_days); + const filteredForDay = transactions.filter((transaction) => ( + +new Date(transaction.moment) >= +dateDifferences + )); + req.transactions = filteredForDay; + return next(); + } + + if (month_year) { + const filteredForMonthAndYear = transactions.filter((transaction) => ( + format(new Date(transaction.moment), 'MM/yy') === month_year + )); + req.transactions = filteredForMonthAndYear; + return next(); + } + + req.transactions = transactions + return next(); + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} + +module.exports = { + validateCreateTransaction, + verifyTransactionId, + transactionsFilter +} + diff --git a/src/middlewares/user.js b/src/middlewares/user.js new file mode 100644 index 00000000..45d667d9 --- /dev/null +++ b/src/middlewares/user.js @@ -0,0 +1,67 @@ +const { differenceInYears } = require("date-fns"); +const knex = require("../database/connect"); +const { schemaCreateUser, schemaUpdateOpeningBalance } = require('../validations/schemaUser'); + + +async function validateCreateUser(req, res, next) { + const { birthday } = req.body; + + if (differenceInYears(new Date(), new Date(birthday)) < 18) { + return res.status(400).json({ error: 'Usuário precisa ter a idade maior que 18 anos.' }); + } + + try { + await schemaCreateUser.validate(req.body); + + return next(); + } catch (error) { + return res.status(400).json({ error: error.message }); + } + +} + +async function verifyUserId(req, res, next) { + + const { user_id } = req.params; + + try { + const user = await knex('users').where({ id: user_id }).first(); + + if (!user) { + return res.status(404).json({ error: `Usuário inexistente!` }); + } + + req.user = user; + + return next(); + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} + +async function validateDeleteUser(req, res, next) { + + const { user } = req; + + if (user.opening_balance !== 0) { + return res.status(400).json({ error: 'Não é possível excluir usuários com saldo inicial diferente de 0.' }) + } + + try { + const transactions = await knex('transactions').where({ user_id: user.id }); + + if (transactions.length !== 0) { + return res.status(400).json({ error: 'Não é possível excluir usuários com movimentações vinculadas.' }) + } + + return next(); + } catch (error) { + return res.status(500).json({ error: error.message }); + } +} + +module.exports = { + verifyUserId, + validateCreateUser, + validateDeleteUser +} \ No newline at end of file diff --git a/src/router.js b/src/router.js new file mode 100644 index 00000000..89d25268 --- /dev/null +++ b/src/router.js @@ -0,0 +1,21 @@ +const { Router } = require('express'); +const { createTransaction, getTransactionsByUser, deleteTransaction, getTransactionsCSV, getTransactionsSummary } = require('./controllers/transaction'); +const { getAllUsers, createUser, getUser, deleteUser, updateUserOpeningBalance } = require('./controllers/user'); +const { validateCreateTransaction, verifyTransactionId, transactionsFilter } = require('./middlewares/transaction'); +const { verifyUserId, validateCreateUser, validateDeleteUser } = require('./middlewares/user'); + +const routes = Router(); + +routes.get('/users', getAllUsers); +routes.post('/user', validateCreateUser, createUser); +routes.get('/user/:user_id', verifyUserId, getUser); +routes.delete('/user/:user_id', verifyUserId, validateDeleteUser, deleteUser); +routes.patch('/user/:user_id', verifyUserId, updateUserOpeningBalance); + +routes.post('/transaction/:user_id', validateCreateTransaction, verifyUserId, createTransaction); +routes.get('/transactions/user/:user_id', verifyUserId, getTransactionsByUser); +routes.delete('/transaction/:transaction_id', verifyTransactionId, deleteTransaction); +routes.get('/transactions/user/:user_id/csv', verifyUserId, transactionsFilter, getTransactionsCSV); +routes.get('/transactions/user/:user_id/summary', verifyUserId, getTransactionsSummary); + +module.exports = routes; \ No newline at end of file diff --git a/src/validations/config.js b/src/validations/config.js new file mode 100644 index 00000000..42fbf5e2 --- /dev/null +++ b/src/validations/config.js @@ -0,0 +1,5 @@ +const yup = require('yup'); +const { pt } = require('yup-locales'); +yup.setLocale(pt); + +module.exports = yup; \ No newline at end of file diff --git a/src/validations/schemaTransaction.js b/src/validations/schemaTransaction.js new file mode 100644 index 00000000..e518981d --- /dev/null +++ b/src/validations/schemaTransaction.js @@ -0,0 +1,11 @@ +const yup = require('./config'); + +const schemaCreateTransaction = yup.object().shape({ + type: yup.string().required(), + amount: yup.number().integer().required(), + description: yup.string() +}); + +module.exports = { + schemaCreateTransaction, +}; \ No newline at end of file diff --git a/src/validations/schemaUser.js b/src/validations/schemaUser.js new file mode 100644 index 00000000..98fcb765 --- /dev/null +++ b/src/validations/schemaUser.js @@ -0,0 +1,18 @@ +const yup = require('./config'); + +const schemaCreateUser = yup.object().shape({ + name: yup.string().required(), + email: yup.string().email().required(), + birthday: yup.date().required() +}); + +const schemaUpdateOpeningBalance = yup.object().shape({ + opening_balance: yup.number().integer().required() +}); + + + +module.exports = { + schemaCreateUser, + schemaUpdateOpeningBalance +}; \ No newline at end of file From 8471712d22f96b3e503acc23df3c588444cc3699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= Date: Wed, 21 Sep 2022 16:46:01 -0300 Subject: [PATCH 02/12] README --- README.md | 434 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 434 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..5b72b14d --- /dev/null +++ b/README.md @@ -0,0 +1,434 @@ +![](https://i.imgur.com/xG74tOh.png) + +# Desafio Back-End - OW Interactive 21/22 + +Tabela de conteúdos +================= + +* [Como executar o projeto](#-Como-executar-o-projeto) +* [Tecnologias](#-Tecnologias) +* [Utilitários](#-Utilitários) + + +* [Endpoints Usuários](#-Endpoints-Usuários) + * [Criar usuário](#Criar-usuário) + * [Listar usuários](#Listar-todos-os-usuários) + * [Listar um usuário](#Listar-um-usuário) + * [Alterar saldo inicial](#Alterar-saldo-inicial) + * [Excluir usuário](#Excluir-usuário) + --- +* [Endpoints Transações](#-Endpoints-ransações) + * [Criar transação](#Criar-transação) + * [Listar transações](#Listar-transações) + * [Resumo das transações](#Resumo-das-transações) + * [Emitir transações em CSV](#Emitir-transações-em-CSV) + * [Excluir transação](#Excluir-transação) + +* [Autor](#-Autor) + +--- + +# 🎲 Como execultar o projeto + +```bash + +# Clone este repositório +$ git clone git@github.com:tgmarinho/README-ecoleta.git + +# Acesse a pasta do projeto no terminal/cmd +$ cd desafio_OWInteractive + +# Instale as dependências +$ npm install + +# Execute a aplicação em modo de desenvolvimento +$ npm run dev + +# O servidor inciará na porta:3333 - acesse http://localhost:3000 + +``` + +## No diretório em seu banco de dado execulte os scripts SQL na seguinte ordem + +* ### 1 - Schema.sql + + * > Arquivo localizado em [src/database/schema.sql]() + +* ### 2 - Dump.sql + + * > Arquivo localizado em [src/database/dump.sql]() + +## Para testes deve ser instalado o [Insomnia](https://insomnia.rest/), em seguida baixe a coleção + +

+ Run in Insomnia +

+ +--- + +# Tecnologias + +As seguintes ferramentas foram usadas na construção do projeto: + +#### **Server** ([NodeJS](https://nodejs.org/en/)) + +* **[Express](https://expressjs.com/)** +* **[KnexJS](http://knexjs.org/)** + + +* **[csv-writer](https://www.npmjs.com/package/csv-writer)** +* **[date-fns](https://date-fns.org/)** +* **[mariadb](https://mariadb.org/)** +* **[mysql2](https://www.npmjs.com/package/mysql2)** +* **[yup](https://www.npmjs.com/package/yup)** + +> Veja o arquivo [package.json](https://github.com/tgmarinho/README-ecoleta/blob/master/server/package.json) + +#### [](https://github.com/tgmarinho/Ecoleta#utilit%C3%A1rios)**Utilitários** + +* Editor: **[Visual Studio Code](https://code.visualstudio.com/)** +* Markdown: **[Hackmd](https://hackmd.io/)** +* Teste de API: **[Insomnia](https://insomnia.rest/)** +* Modelagem para banco de dados : **[Sqldbm](https://sqldbm.com/)** + +--- + +# Usuários + +## Criar usuário + +### `POST` `/users` + +* **Requisição** + * **Body** + + ```typescript + // Interface + { + "name": string, + "email": string, + "birthday": date + } + ``` + +* **Exemplo de Retorno** + + ```javascript + // POST /user + { + "name": "Folano de Tal", + "email": "fulano@email.com", + "birthday": "1995-08-10" + } + ``` + +--- + +## Listar todos os usuários + +### `GET` `/users` + +* **Resposta** + * listagem de todos so usuários existentes, ordernados por ordem de cadastro decrescente (mais novo para mais antigo) + +* #### Exemplo de resposta + + ```javascript + // HTTP Status 200 + [ + { + "id": 3, + "name": "Regiane Teixeira", + "email": "regianeteixeira@email.com", + "birthday": "1995-09-06T03:00:00.000Z", + "created_at": "2022-09-20T17:43:32.000Z", + "updated_at": "2022-09-21T07:41:43.000Z", + "opening_balance": 0 + }, + { + "id": 2, + "name": "Maria Das Graças", + "email": "mariadasgraacas@email.com", + "birthday": "1971-05-30T03:00:00.000Z", + "created_at": "2022-09-20T06:51:26.000Z", + "updated_at": null, + "opening_balance": 0 + }, + { + "id": 1, + "name": "José Costa", + "email": "josecosta@email.com", + "birthday": "1991-08-10T03:00:00.000Z", + "created_at": "2022-09-19T22:57:36.000Z", + "updated_at": null, + "opening_balance": 300000 + } + ] + + // nenhum usuário encontrado + [] + ``` + +--- + +## Listar um usuário + +### `GET` `/user/:user_id` + +* **Requisição** + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + GET/user/1 + ``` + +* **Exemplo de Retorno** + + ```javascript + // GET /user/1 + { + "id": 1, + "name": "José Costa", + "email": "josecosta@email.com", + "birthday": "1991-08-10T03:00:00.000Z", + "created_at": "2022-09-19T22:57:36.000Z", + "updated_at": null, + "opening_balance": 900000 + } + ``` + +--- + +## Alterar saldo inicial + +### `PATCH` `/user/:user_id` + +* **Requisição** + * **Body** + + ```typescript + // Interface + { + opening_balance: number + } + ``` + + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + GET/user/1 + ``` + +* **Exemplo de Retorno** + + ```javascript + // PATCH /user/1 + { + "opening_balance": 300000 + } + ``` + +## Excluir usuário + +### `DELETE` `/user/:user_id` + +* **Requisição** + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + DELETE/user/1 + ``` + +--- + +# Transações + +## Criar transação + +### `POST` `/transaction/:user_id` + +* **Requisição** + * **Body** + + ```typescript + // Interface + { + type: "debit" | "credit" | "reversal", + amount: number, + description?: string + } + ``` + + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + POST/transaction/1 + ``` + +* **Exemplo de Retorno** + + ```javascript + // POST /transaction/1 + { + "type": "debit", + "amount": 1050, + "description": "Descrição..." + } + ``` + +--- + +## Listar transações + +### `GET` `/transactions/user/:user_id` + +* **Requisição** + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + GET/transactions/user/1 + ``` + + * **URL Query Params** - Paginção: por padão a primeira pagina é 0, cada página retorna no maximo 5 transações (opicional) + + ``` + GET/transaction/user/1?page=1 + ``` + +* **Exemplo de Retorno** + + ```javascript + // GET /transaction/user/1 + + { + "id": 1, + "name": "José Costa", + "email": "josecosta@email.com", + "birthday": "1991-08-10T03:00:00.000Z", + "created_at": "2022-09-19T22:57:36.000Z", + "updated_at": null, + "opening_balance": 300000, + "page": 0, + "transactions": [ + { + "id": 25, + "user_id": 1, + "type": "reversal", + "amount": 12000, + "description": "Compra duplicada de vestido", + "moment": "2022-09-20T16:56:47.000Z" + }, + { + "id": 24, + "user_id": 1, + "type": "reversal", + "amount": 12000, + "description": "Compra duplicada de vestido", + "moment": "2022-09-20T16:56:47.000Z" + }, + { + "id": 19, + "user_id": 1, + "type": "reversal", + "amount": 12000, + "description": "Compra duplicada de vestido", + "moment": "2022-09-20T16:56:46.000Z" + } + ] + } + + ``` + +--- + +## Resumo das transações + +### `GET` `/transactions/user/:user_id/summary` + +* **Requisição** + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + GET/transactions/user/1/summary + ``` + +* **Exemplo de Retorno** + + ```javascript + /// GET/transactions/user/1/summary + + { + "opening_balance": 300000, + "debit": 4300, + "credit": 1800, + "reversal": 228000 + } + ``` + +--- + +## Emitir transações em CSV + +### `GET` `/transactions/user/:user_id/csv` + +* **Requisição** + * **URL Params** - ID do usuário (passado como parâmetro na rota) + + ``` + GET/transactions/user/1/csv + ``` + + * **URL Query Params** + * **filtros para as transações:** + + ```typescript + { + last_days: number //Retorna transaçoẽs referente a quantidade de dias informado + month_year: date //Retorna transações no mês e ano informado. Ex: 02/22 + } + ``` + + * **Exemplos de requisição** + + ``` + GET/transaction/user/1/csv + ``` + + ``` + GET/transaction/user/1/csv?laste_day=30 + ``` + + ``` + GET/transaction/user/1/csv?month_year=02/22 + ``` + +* **Exemplo de Retorno** + * Retorna uma arquivo no formato CSV com as transações do usuário + +--- + +## Excluir transação + +### `DELETE` `/transactions/:transaction_id` + +* **Requisição** + * **URL Params** - ID da transação (passado como parâmetro na rota) + + ``` + DELETE/transactions/1 + ``` + +--- + +# 🦸 Autor + + + +
🎧 + José Costa
+
+ +[![Linkedin Badge](https://img.shields.io/badge/-José_Costa-blue?style=flat-square&logo=Linkedin&logoColor=white&link=https://www.linkedin.com/in/josecostasantosjr/)](https://www.linkedin.com/in/josecostasantosjr/) +[![Gmail Badge](https://img.shields.io/badge/-josecostasantos.jr@gmail.com-c14438?style=flat-square&logo=Gmail&logoColor=white&link=mailto:josecostasantos.jr@gmail.com)](mailto:josecostasantos.js@gmail.com) + +--- From e435d03e9f8740bab0a45f344c885539468e4e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= <58970300+askagi@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:46:47 -0300 Subject: [PATCH 03/12] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 5b72b14d..514d4b9c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -![](https://i.imgur.com/xG74tOh.png) - # Desafio Back-End - OW Interactive 21/22 Tabela de conteúdos From 44357479e0f31b9e81b6e76300301a3d4e27634a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= <58970300+askagi@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:50:10 -0300 Subject: [PATCH 04/12] Update README.md --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 514d4b9c..e227f6cc 100644 --- a/README.md +++ b/README.md @@ -50,16 +50,16 @@ $ npm run dev * ### 1 - Schema.sql - * > Arquivo localizado em [src/database/schema.sql]() + * > Arquivo localizado em [src/database/schema.sql](#https://github.com/askagi/desafio-backend/blob/master/src/database/Dump.sql) * ### 2 - Dump.sql - * > Arquivo localizado em [src/database/dump.sql]() + * > Arquivo localizado em [src/database/dump.sql](#https://github.com/askagi/desafio-backend/blob/master/src/database/schema.sql) ## Para testes deve ser instalado o [Insomnia](https://insomnia.rest/), em seguida baixe a coleção

- Run in Insomnia + Run in Insomnia

--- @@ -72,15 +72,14 @@ As seguintes ferramentas foram usadas na construção do projeto: * **[Express](https://expressjs.com/)** * **[KnexJS](http://knexjs.org/)** - - +* **[dotENV](https://github.com/motdotla/dotenv)** * **[csv-writer](https://www.npmjs.com/package/csv-writer)** * **[date-fns](https://date-fns.org/)** * **[mariadb](https://mariadb.org/)** * **[mysql2](https://www.npmjs.com/package/mysql2)** * **[yup](https://www.npmjs.com/package/yup)** -> Veja o arquivo [package.json](https://github.com/tgmarinho/README-ecoleta/blob/master/server/package.json) +> Veja o arquivo [package.json]([https://github.com/tgmarinho/README-ecoleta/blob/master/server/package.json](https://github.com/askagi/desafio-backend/blob/master/package.json)) #### [](https://github.com/tgmarinho/Ecoleta#utilit%C3%A1rios)**Utilitários** From 72a925c53a89bcf3488d649d768701910596ff79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= <58970300+askagi@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:50:54 -0300 Subject: [PATCH 05/12] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e227f6cc..c4bb168c 100644 --- a/README.md +++ b/README.md @@ -50,11 +50,11 @@ $ npm run dev * ### 1 - Schema.sql - * > Arquivo localizado em [src/database/schema.sql](#https://github.com/askagi/desafio-backend/blob/master/src/database/Dump.sql) + * > Arquivo localizado em [src/database/schema.sql](https://github.com/askagi/desafio-backend/blob/master/src/database/Dump.sql) * ### 2 - Dump.sql - * > Arquivo localizado em [src/database/dump.sql](#https://github.com/askagi/desafio-backend/blob/master/src/database/schema.sql) + * > Arquivo localizado em [src/database/dump.sql](https://github.com/askagi/desafio-backend/blob/master/src/database/schema.sql) ## Para testes deve ser instalado o [Insomnia](https://insomnia.rest/), em seguida baixe a coleção From 12c1b28b3afa12345665827d37f7c25339cdbe13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= <58970300+askagi@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:52:39 -0300 Subject: [PATCH 06/12] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c4bb168c..20fcd9bc 100644 --- a/README.md +++ b/README.md @@ -79,9 +79,9 @@ As seguintes ferramentas foram usadas na construção do projeto: * **[mysql2](https://www.npmjs.com/package/mysql2)** * **[yup](https://www.npmjs.com/package/yup)** -> Veja o arquivo [package.json]([https://github.com/tgmarinho/README-ecoleta/blob/master/server/package.json](https://github.com/askagi/desafio-backend/blob/master/package.json)) +> Veja o arquivo [package.json](https://github.com/askagi/desafio-backend/blob/master/package.json) -#### [](https://github.com/tgmarinho/Ecoleta#utilit%C3%A1rios)**Utilitários** +#### **Utilitários** * Editor: **[Visual Studio Code](https://code.visualstudio.com/)** * Markdown: **[Hackmd](https://hackmd.io/)** From 7ec8a93e313c0159f214b1e8a917c9d11ddd526a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= <58970300+askagi@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:54:33 -0300 Subject: [PATCH 07/12] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 20fcd9bc..5a79a6ff 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +![Logo OW Interactive](https://github.com/owInteractive/desafio-backend/raw/master/media/logo.jpg "OW Interactive") + # Desafio Back-End - OW Interactive 21/22 Tabela de conteúdos From 0942f05b27ae91f4b6ce89ed273319c41e088d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= Date: Wed, 21 Sep 2022 16:56:33 -0300 Subject: [PATCH 08/12] README --- README.md | 12 ++++++------ media/logo.jpg | Bin 15114 -> 0 bytes 2 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 media/logo.jpg diff --git a/README.md b/README.md index 5a79a6ff..7a057396 100644 --- a/README.md +++ b/README.md @@ -5,26 +5,26 @@ Tabela de conteúdos ================= -* [Como executar o projeto](#-Como-executar-o-projeto) -* [Tecnologias](#-Tecnologias) -* [Utilitários](#-Utilitários) +* [Como executar o projeto](#Como-executar-o-projeto) +* [Tecnologias](#Tecnologias) +* [Utilitários](#Utilitários) -* [Endpoints Usuários](#-Endpoints-Usuários) +* [Endpoints Usuários](#Endpoints-Usuários) * [Criar usuário](#Criar-usuário) * [Listar usuários](#Listar-todos-os-usuários) * [Listar um usuário](#Listar-um-usuário) * [Alterar saldo inicial](#Alterar-saldo-inicial) * [Excluir usuário](#Excluir-usuário) --- -* [Endpoints Transações](#-Endpoints-ransações) +* [Endpoints Transações](#Endpoints-ransações) * [Criar transação](#Criar-transação) * [Listar transações](#Listar-transações) * [Resumo das transações](#Resumo-das-transações) * [Emitir transações em CSV](#Emitir-transações-em-CSV) * [Excluir transação](#Excluir-transação) -* [Autor](#-Autor) +* [Autor](#Autor) --- diff --git a/media/logo.jpg b/media/logo.jpg deleted file mode 100644 index 505e2b0f1185e43ba20556fbb51fb08969274a50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15114 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 b@viU3vgY6M|Jz%*KRA2`{>VH3iXZtO5nisH From fa5737b3b67585888ff3267eff89b1716344a98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= <58970300+askagi@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:58:18 -0300 Subject: [PATCH 09/12] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7a057396..8abb2a29 100644 --- a/README.md +++ b/README.md @@ -28,15 +28,15 @@ Tabela de conteúdos --- -# 🎲 Como execultar o projeto +# Como execultar o projeto ```bash # Clone este repositório -$ git clone git@github.com:tgmarinho/README-ecoleta.git +$ git clone git@github.com:askagi/desafio-backend.git # Acesse a pasta do projeto no terminal/cmd -$ cd desafio_OWInteractive +$ cd desafio_backend # Instale as dependências $ npm install From 3b85455fcfe5d1cb6a11727db94d2b278c828c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= <58970300+askagi@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:59:30 -0300 Subject: [PATCH 10/12] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8abb2a29..178fd7fe 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,8 @@ As seguintes ferramentas foram usadas na construção do projeto: --- +# Endpoints Usuários + # Usuários ## Criar usuário From 9f8a65e272d7a98a24c805cb1cf1593a6b3f8eaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= <58970300+askagi@users.noreply.github.com> Date: Wed, 21 Sep 2022 17:00:07 -0300 Subject: [PATCH 11/12] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 178fd7fe..8abb2a29 100644 --- a/README.md +++ b/README.md @@ -92,8 +92,6 @@ As seguintes ferramentas foram usadas na construção do projeto: --- -# Endpoints Usuários - # Usuários ## Criar usuário From 7c0d22e978f70734b5fb487aefe36ef4801588f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Costa?= <58970300+askagi@users.noreply.github.com> Date: Mon, 26 Sep 2022 22:08:10 -0300 Subject: [PATCH 12/12] Update README.md --- src/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/README.md b/src/README.md index 5b72b14d..e4badfa8 100644 --- a/src/README.md +++ b/src/README.md @@ -1,4 +1,3 @@ -![](https://i.imgur.com/xG74tOh.png) # Desafio Back-End - OW Interactive 21/22

+ Run in Insomnia +