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
index 6a877853..8abb2a29 100644
--- a/README.md
+++ b/README.md
@@ -2,93 +2,432 @@
# 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 😀
-
-
+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:askagi/desafio-backend.git
+
+# Acesse a pasta do projeto no terminal/cmd
+$ cd desafio_backend
+
+# 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](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)
+
+## 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/)**
+* **[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/askagi/desafio-backend/blob/master/package.json)
+
+#### **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
+
+
+[](https://www.linkedin.com/in/josecostasantosjr/)
+[](mailto:josecostasantos.js@gmail.com)
+
+---
diff --git a/media/dog.webp b/media/dog.webp
deleted file mode 100644
index 7fdb948e..00000000
Binary files a/media/dog.webp and /dev/null differ
diff --git a/media/logo.jpg b/media/logo.jpg
deleted file mode 100644
index 505e2b0f..00000000
Binary files a/media/logo.jpg and /dev/null differ
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..10cf1776
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2562 @@
+{
+ "name": "desafio_back_end_ow_interactive",
+ "version": "1.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "desafio_back_end_ow_interactive",
+ "version": "1.0.0",
+ "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"
+ }
+ },
+ "node_modules/@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==",
+ "engines": {
+ "node": ">=10"
+ },
+ "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..e4badfa8
--- /dev/null
+++ b/src/README.md
@@ -0,0 +1,433 @@
+
+# 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
+
+
+[](https://www.linkedin.com/in/josecostasantosjr/)
+[](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 00000000..9ab5d7a0
Binary files /dev/null and b/src/docs/modelagem_banco_de_dados.png differ
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