From c152840501cc14fbc2a79d7a716aaf9c295c34ec Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Tue, 24 Aug 2021 11:38:09 -0300 Subject: [PATCH 001/121] Initial configuration --- .editorconfig | 12 + .eslintignore | 3 + .eslintrc.json | 73 ++ package.json | 31 + src/server.ts | 5 + tsconfig.json | 72 ++ yarn.lock | 2204 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 2400 insertions(+) create mode 100644 .editorconfig create mode 100644 .eslintignore create mode 100644 .eslintrc.json create mode 100644 package.json create mode 100644 src/server.ts create mode 100644 tsconfig.json create mode 100644 yarn.lock diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ebe51d3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = false \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..cf6bd3c --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +/*.js +node_modules +dist \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..aabcfcd --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,73 @@ +{ + "env": { + "es2020": true, + "node": true + }, + "extends": [ + "standard", + "prettier", + "plugin:prettier/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 12, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint", + "eslint-plugin-import-helpers", + "prettier" + ], + "rules": { + "camelcase": [2, {"properties": "always"}], + "import/no-unresolved": "error", + "@typescript-eslint/naming-convention": [ + "error", + { + "selector": "interface", + "format": ["PascalCase"], + "custom": { + "regex": "^I[A-Z]", + "match": true + } + } + ], + "class-methods-use-this": "off", + "import/prefer-default-export": "off", + "no-shadow": "off", + "no-console": "off", + "no-useless-constructor": "off", + "no-empty-function": "off", + "lines-between-class-members": "off", + "import/extensions": [ + "error", + "ignorePackages", + { + "ts": "never" + } + ], + "import-helpers/order-imports": [ + "warn", + { + // example configuration + "newlinesBetween": "always", + "groups": ["module", "/^@shared/", ["parent", "sibling", "index"]], + "alphabetize": { "order": "asc", "ignoreCase": true } + } + ], + "import/no-extraneous-dependencies": [ + "error", + {"devDependencies": ["/*.test.ts", "/.test.tsx", "**/.ts"]} + ], + "space-before-blocks": ["error", "always"], + "prettier/prettier": ["error",{ + "semi":false, + "singleQuote": true + }] + }, + "settings": { + "import/resolver": { + "typescript": {} + } + } +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..21d0b8f --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "amazonia-minada-back", + "version": "1.0.0", + "main": "index.js", + "repository": "git@github.com:geodatin/amazonia-minada-back.git", + "author": "Iago Machado ", + "license": "MIT", + "scripts": { + "dev": "ts-node-dev --transpile-only --ignore-watch node_modules --respawn src/server.ts" + }, + "dependencies": { + "express": "^4.17.1" + }, + "devDependencies": { + "@types/express": "^4.17.13", + "@typescript-eslint/eslint-plugin": "^4.29.3", + "@typescript-eslint/parser": "^4.29.3", + "eslint": "^7.32.0", + "eslint-config-prettier": "^8.3.0", + "eslint-config-standard": "^16.0.3", + "eslint-import-resolver-typescript": "^2.4.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-import-helpers": "^1.1.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-promise": "^4.2.1", + "prettier": "^2.3.2", + "ts-node-dev": "^1.1.8", + "typescript": "^4.3.5" + } +} diff --git a/src/server.ts b/src/server.ts new file mode 100644 index 0000000..91aaea8 --- /dev/null +++ b/src/server.ts @@ -0,0 +1,5 @@ +import express from 'express' + +const app = express() + +app.listen(8080, () => console.log('Server is running!')) diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..08d6d3d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,72 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "./dist", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "skipLibCheck": true, /* Skip type checking of declaration files. */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..18c174c --- /dev/null +++ b/yarn.lock @@ -0,0 +1,2204 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/helper-validator-identifier@^7.14.5": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" + integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== + +"@babel/highlight@^7.10.4": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" + integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" + integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@types/body-parser@*": + version "1.19.1" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.1.tgz#0c0174c42a7d017b818303d4b5d969cb0b75929c" + integrity sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/express-serve-static-core@^4.17.18": + version "4.17.24" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz#ea41f93bf7e0d59cd5a76665068ed6aab6815c07" + integrity sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/json-schema@^7.0.7": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + +"@types/node@*": + version "16.7.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.7.1.tgz#c6b9198178da504dfca1fd0be9b2e1002f1586f0" + integrity sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/strip-bom@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" + integrity sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I= + +"@types/strip-json-comments@0.0.30": + version "0.0.30" + resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" + integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== + +"@typescript-eslint/eslint-plugin@^4.29.3": + version "4.29.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.3.tgz#95cb8029a8bd8bd9c7f4ab95074a7cb2115adefa" + integrity sha512-tBgfA3K/3TsZY46ROGvoRxQr1wBkclbVqRQep97MjVHJzcRBURRY3sNFqLk0/Xr//BY5hM9H2p/kp+6qim85SA== + dependencies: + "@typescript-eslint/experimental-utils" "4.29.3" + "@typescript-eslint/scope-manager" "4.29.3" + debug "^4.3.1" + functional-red-black-tree "^1.0.1" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@4.29.3": + version "4.29.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.3.tgz#52e437a689ccdef73e83c5106b34240a706f15e1" + integrity sha512-ffIvbytTVWz+3keg+Sy94FG1QeOvmV9dP2YSdLFHw/ieLXWCa3U1TYu8IRCOpMv2/SPS8XqhM1+ou1YHsdzKrg== + dependencies: + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.29.3" + "@typescript-eslint/types" "4.29.3" + "@typescript-eslint/typescript-estree" "4.29.3" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@^4.29.3": + version "4.29.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.3.tgz#2ac25535f34c0e98f50c0e6b28c679c2357d45f2" + integrity sha512-jrHOV5g2u8ROghmspKoW7pN8T/qUzk0+DITun0MELptvngtMrwUJ1tv5zMI04CYVEUsSrN4jV7AKSv+I0y0EfQ== + dependencies: + "@typescript-eslint/scope-manager" "4.29.3" + "@typescript-eslint/types" "4.29.3" + "@typescript-eslint/typescript-estree" "4.29.3" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@4.29.3": + version "4.29.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.3.tgz#497dec66f3a22e459f6e306cf14021e40ec86e19" + integrity sha512-x+w8BLXO7iWPkG5mEy9bA1iFRnk36p/goVlYobVWHyDw69YmaH9q6eA+Fgl7kYHmFvWlebUTUfhtIg4zbbl8PA== + dependencies: + "@typescript-eslint/types" "4.29.3" + "@typescript-eslint/visitor-keys" "4.29.3" + +"@typescript-eslint/types@4.29.3": + version "4.29.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.3.tgz#d7980c49aef643d0af8954c9f14f656b7fd16017" + integrity sha512-s1eV1lKNgoIYLAl1JUba8NhULmf+jOmmeFO1G5MN/RBCyyzg4TIOfIOICVNC06lor+Xmy4FypIIhFiJXOknhIg== + +"@typescript-eslint/typescript-estree@4.29.3": + version "4.29.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.3.tgz#1bafad610015c4ded35c85a70b6222faad598b40" + integrity sha512-45oQJA0bxna4O5TMwz55/TpgjX1YrAPOI/rb6kPgmdnemRZx/dB0rsx+Ku8jpDvqTxcE1C/qEbVHbS3h0hflag== + dependencies: + "@typescript-eslint/types" "4.29.3" + "@typescript-eslint/visitor-keys" "4.29.3" + debug "^4.3.1" + globby "^11.0.3" + is-glob "^4.0.1" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@4.29.3": + version "4.29.3" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.3.tgz#c691760a00bd86bf8320d2a90a93d86d322f1abf" + integrity sha512-MGGfJvXT4asUTeVs0Q2m+sY63UsfnA+C/FDgBKV3itLBmM9H0u+URcneePtkd0at1YELmZK6HSolCqM4Fzs6yA== + dependencies: + "@typescript-eslint/types" "4.29.3" + eslint-visitor-keys "^2.0.0" + +accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-jsx@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.6.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" + integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-includes@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" + integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + get-intrinsic "^1.1.1" + is-string "^1.0.5" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.flat@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" + integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + 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" + optionalDependencies: + fsevents "~2.3.2" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@2.6.9, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dynamic-dedupe@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz#06e44c223f5e4e94d78ef9db23a6515ce2f962a1" + integrity sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE= + dependencies: + xtend "^4.0.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: + version "1.18.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.5.tgz#9b10de7d4c206a3581fd5b2124233e04db49ae19" + integrity sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.3" + is-string "^1.0.6" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-prettier@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" + integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== + +eslint-config-standard@^16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz#6c8761e544e96c531ff92642eeb87842b8488516" + integrity sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg== + +eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== + dependencies: + debug "^3.2.7" + resolve "^1.20.0" + +eslint-import-resolver-typescript@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.4.0.tgz#ec1e7063ebe807f0362a7320543aaed6fe1100e1" + integrity sha512-useJKURidCcldRLCNKWemr1fFQL1SzB3G4a0li6lFGvlc5xGe1hY343bvG07cbpCzPuM/lK19FIJB3XGFSkplA== + dependencies: + debug "^4.1.1" + glob "^7.1.6" + is-glob "^4.0.1" + resolve "^1.17.0" + tsconfig-paths "^3.9.0" + +eslint-module-utils@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz#94e5540dd15fe1522e8ffa3ec8db3b7fa7e7a534" + integrity sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q== + dependencies: + debug "^3.2.7" + pkg-dir "^2.0.0" + +eslint-plugin-es@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" + integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + +eslint-plugin-import-helpers@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import-helpers/-/eslint-plugin-import-helpers-1.1.0.tgz#ab5c3f33de2a2f461061e8a13b143e8499c3baa0" + integrity sha512-a7l1Sj6hZybVHVkxVRVWm1WaAyk9yDjWvSVhUfnDR23i0vQ8RS1wv9k617qGIWPqkttzg299aEtx+bCHA2EoqQ== + +eslint-plugin-import@^2.22.1: + version "2.24.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.1.tgz#64aba8b567a1ba9921d5465586e86c491b8e2135" + integrity sha512-KSFWhNxPH8OGJwpRJJs+Z7I0a13E2iFQZJIvSnCu6KUs4qmgAm3xN9GYBCSoiGWmwA7gERZPXqYQjcoCROnYhQ== + dependencies: + array-includes "^3.1.3" + array.prototype.flat "^1.2.4" + debug "^2.6.9" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.6.2" + find-up "^2.0.0" + has "^1.0.3" + is-core-module "^2.6.0" + minimatch "^3.0.4" + object.values "^1.1.4" + pkg-up "^2.0.0" + read-pkg-up "^3.0.0" + resolve "^1.20.0" + tsconfig-paths "^3.10.1" + +eslint-plugin-node@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + dependencies: + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + +eslint-plugin-prettier@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz#e9ddb200efb6f3d05ffe83b1665a716af4a387e5" + integrity sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-promise@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz#61485df2a359e03149fdafc0a68b0e030ad2ac45" + integrity sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ== + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.0.0, eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint@^7.32.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.1.2" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^3.1.1: + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastq@^1.6.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.12.0.tgz#ed7b6ab5d62393fb2cc591c853652a5c318bf794" + integrity sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561" + integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3, glob@^7.1.6: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.6.0, globals@^13.9.0: + version "13.11.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.11.0.tgz#40ef678da117fe7bd2e28f1fab24951bd0255be7" + integrity sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g== + dependencies: + type-fest "^0.20.2" + +globby@^11.0.3: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +graceful-fs@^4.1.2: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.1, ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.4, is-callable@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-core-module@^2.2.0, is-core-module@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.6.0.tgz#d7553b2526fe59b92ba3e40c8df757ec8a709e19" + integrity sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-regex@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-string@^1.0.5, is-string@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json5@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.49.0: + version "1.49.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed" + integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA== + +mime-types@~2.1.24: + version "2.1.32" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.32.tgz#1d00e89e7de7fe02008db61001d9e02852670fd5" + integrity sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A== + dependencies: + mime-db "1.49.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" + integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.values@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30" + integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.2" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" + integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +proxy-addr@~2.0.5: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +regexpp@^3.0.0, regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@^1.0.0, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.17.0, resolve@^1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^2.6.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +"semver@2 || 3 || 4 || 5": + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.1.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.2.1, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +source-map-support@^0.5.12, source-map-support@^0.5.17: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.10" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" + integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-json-comments@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +table@^6.0.9: + version "6.7.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" + integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== + dependencies: + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.0" + strip-ansi "^6.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +ts-node-dev@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ts-node-dev/-/ts-node-dev-1.1.8.tgz#95520d8ab9d45fffa854d6668e2f8f9286241066" + integrity sha512-Q/m3vEwzYwLZKmV6/0VlFxcZzVV/xcgOt+Tx/VjaaRHyiBcFlV0541yrT09QjzzCxlDZ34OzKjrFAynlmtflEg== + dependencies: + chokidar "^3.5.1" + dynamic-dedupe "^0.3.0" + minimist "^1.2.5" + mkdirp "^1.0.4" + resolve "^1.0.0" + rimraf "^2.6.1" + source-map-support "^0.5.12" + tree-kill "^1.2.2" + ts-node "^9.0.0" + tsconfig "^7.0.0" + +ts-node@^9.0.0: + version "9.1.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" + integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== + dependencies: + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + +tsconfig-paths@^3.10.1, tsconfig-paths@^3.9.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz#79ae67a68c15289fdf5c51cb74f397522d795ed7" + integrity sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q== + dependencies: + json5 "^2.2.0" + minimist "^1.2.0" + strip-bom "^3.0.0" + +tsconfig@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-7.0.0.tgz#84538875a4dc216e5c4a5432b3a4dec3d54e91b7" + integrity sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw== + dependencies: + "@types/strip-bom" "^3.0.0" + "@types/strip-json-comments" "0.0.30" + strip-bom "^3.0.0" + strip-json-comments "^2.0.0" + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typescript@^4.3.5: + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== From 4b09354b0e6a95316567dfda7dbd7a4703f15eae Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 30 Aug 2021 14:28:17 -0300 Subject: [PATCH 002/121] Add docker --- Dockerfile | 13 +++++++++++++ docker-compose.yml | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..cd97e3f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM node + +WORKDIR /usr/app + +COPY package.json ./ + +RUN npm install + +COPY . . + +EXPOSE 3333 + +CMD ["npm","run","dev"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ed99a47 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,35 @@ +version: '2' + +services: + server: + build: . + container_name: infoamazonia + working_dir: /usr/app + command: npm run dev + volumes: + - .:/usr/app + ports: + - 3333:3333 + links: + - database + depends_on: + - database + env_file: + - .env + environment: + MONGO_DB_USERNAME: ${MONGO_DB_USERNAME} + MONGO_DB_PASSWORD: ${MONGO_DB_PASSWORD} + + database: + image: mongo + container_name: mongodb + volumes: + - ./sysbkp/data:/data + ports: + - 27017:27017 + restart: always + env_file: + - .env + environment: + MONGO_INITDB_ROOT_USERNAME: ${MONGO_DB_USERNAME} + MONGO_INITDB_ROOT_PASSWORD: ${MONGO_DB_PASSWORD} \ No newline at end of file From 242607394a998e90e6e715c293f4bc97c16b6167 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 30 Aug 2021 14:29:12 -0300 Subject: [PATCH 003/121] Create .env --- .env.example | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c59bee5 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +MONGO_DB_USERNAME= +MONGO_DB_PASSWORD= \ No newline at end of file From da60f846e2fa3747c3b45a575090fc162475cdb4 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 30 Aug 2021 14:32:34 -0300 Subject: [PATCH 004/121] Add tsyringe --- package.json | 7 +- src/server.ts | 10 +- src/shared/container/index.ts | 16 +++ tsconfig.json | 4 +- yarn.lock | 199 ++++++++++++++++++++++++++++++++-- 5 files changed, 223 insertions(+), 13 deletions(-) create mode 100644 src/shared/container/index.ts diff --git a/package.json b/package.json index 21d0b8f..22936b6 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,14 @@ "dev": "ts-node-dev --transpile-only --ignore-watch node_modules --respawn src/server.ts" }, "dependencies": { - "express": "^4.17.1" + "dotenv-safe": "^8.2.0", + "express": "^4.17.1", + "mongoose": "^6.0.0", + "reflect-metadata": "^0.1.13", + "tsyringe": "^4.6.0" }, "devDependencies": { + "@types/dotenv-safe": "^8.1.2", "@types/express": "^4.17.13", "@typescript-eslint/eslint-plugin": "^4.29.3", "@typescript-eslint/parser": "^4.29.3", diff --git a/src/server.ts b/src/server.ts index 91aaea8..fa014a3 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,5 +1,13 @@ +import 'reflect-metadata' import express from 'express' +import { router } from './routes' + +import './database' +import './shared/container' + const app = express() -app.listen(8080, () => console.log('Server is running!')) +app.use(router) + +app.listen(3333, () => console.log('Server is running!')) diff --git a/src/shared/container/index.ts b/src/shared/container/index.ts new file mode 100644 index 0000000..a5a6727 --- /dev/null +++ b/src/shared/container/index.ts @@ -0,0 +1,16 @@ +import { container } from 'tsyringe' + +import { IInvasionRepository } from '../../repositories/IInvasionRepository' +import { InvasionRepository } from '../../repositories/implementations/InvasionRepository' +import { ReserveInvasionRepository } from '../../repositories/implementations/ReserveInvasionRepository' +import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' + +container.registerSingleton( + 'ReserveInvasionRepository', + ReserveInvasionRepository +) + +container.registerSingleton( + 'InvasionRepository', + InvasionRepository +) diff --git a/tsconfig.json b/tsconfig.json index 08d6d3d..c8b1202 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -62,8 +62,8 @@ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ "skipLibCheck": true, /* Skip type checking of declaration files. */ diff --git a/yarn.lock b/yarn.lock index 18c174c..2bf26c8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -88,6 +88,13 @@ dependencies: "@types/node" "*" +"@types/dotenv-safe@^8.1.2": + version "8.1.2" + resolved "https://registry.yarnpkg.com/@types/dotenv-safe/-/dotenv-safe-8.1.2.tgz#72f126969f445af5654efd3167deabc2cbc6c24e" + integrity sha512-R/B/wIMda6lRE2P1H0vwSoJsV78IOkhccE4vIvmKZQNXOIjiU0QyJsUXwSotBxOPZFZ/oOnjCa3+kK5kVJwGyw== + dependencies: + dotenv "^8.2.0" + "@types/express-serve-static-core@^4.17.18": version "4.17.24" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz#ea41f93bf7e0d59cd5a76665068ed6aab6815c07" @@ -150,6 +157,19 @@ resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== +"@types/webidl-conversions@*": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz#e33bc8ea812a01f63f90481c666334844b12a09e" + integrity sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q== + +"@types/whatwg-url@^8.2.1": + version "8.2.1" + resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-8.2.1.tgz#f1aac222dab7c59e011663a0cb0a3117b2ef05d4" + integrity sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ== + dependencies: + "@types/node" "*" + "@types/webidl-conversions" "*" + "@typescript-eslint/eslint-plugin@^4.29.3": version "4.29.3" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.3.tgz#95cb8029a8bd8bd9c7f4ab95074a7cb2115adefa" @@ -341,6 +361,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -377,11 +402,26 @@ braces@^3.0.1, braces@~3.0.2: dependencies: fill-range "^7.0.1" +bson@^4.2.2, bson@^4.5.1: + version "4.5.1" + resolved "https://registry.yarnpkg.com/bson/-/bson-4.5.1.tgz#02e9d649ce017ab14ed258737756c11809963d6c" + integrity sha512-XqFP74pbTVLyLy5KFxVfTUyRrC1mgOlmu/iXHfXqfCKT59jyP9lwbotGfbN59cHBRbJSamZNkrSopjv+N0SqAA== + dependencies: + buffer "^5.6.0" + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + bytes@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" @@ -504,6 +544,13 @@ debug@2.6.9, debug@^2.6.9: dependencies: ms "2.0.0" +debug@4.x, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -511,13 +558,6 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - deep-is@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -530,6 +570,11 @@ define-properties@^1.1.3: dependencies: object-keys "^1.0.12" +denque@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf" + integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw== + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -566,6 +611,18 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dotenv-safe@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv-safe/-/dotenv-safe-8.2.0.tgz#8d548c7318a62c09a66c4dc8c31864cc007c78ba" + integrity sha512-uWwWWdUQkSs5a3mySDB22UtNwyEYi0JtEQu+vDzIqr9OjbDdC2Ip13PnSpi/fctqlYmzkxCeabiyCAOROuAIaA== + dependencies: + dotenv "^8.2.0" + +dotenv@^8.2.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" + integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== + dynamic-dedupe@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz#06e44c223f5e4e94d78ef9db23a6515ce2f962a1" @@ -1141,6 +1198,11 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -1343,6 +1405,11 @@ json5@^2.2.0: dependencies: minimist "^1.2.5" +kareem@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.3.2.tgz#78c4508894985b8d38a0dc15e1a8e11078f2ca93" + integrity sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ== + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -1401,6 +1468,11 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= +memory-pager@^1.0.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" + integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -1458,6 +1530,54 @@ mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mongodb-connection-string-url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-2.0.0.tgz#72cea65084ffa45655670070efb57bb0a5da46bc" + integrity sha512-M0I1vyLoq5+HQTuPSJWbt+hIXsMCfE8sS1fS5mvP9R2DOMoi2ZD32yWqgBIITyu0dFu4qtS50erxKjvUeBiyog== + dependencies: + "@types/whatwg-url" "^8.2.1" + whatwg-url "^9.1.0" + +mongodb@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-4.1.1.tgz#d328e832675e7351f58b642f833126dc89ac2e66" + integrity sha512-fbACrWEyvr6yl0sSiCGV0sqEiBwTtDJ8iSojmkDjAfw9JnOZSAkUyv9seFSPYhPPKwxp1PDtyjvBNfMDz0WBLQ== + dependencies: + bson "^4.5.1" + denque "^1.5.0" + mongodb-connection-string-url "^2.0.0" + optionalDependencies: + saslprep "^1.0.0" + +mongoose@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-6.0.0.tgz#215319291d23f3768203f5392ba5229debe9702f" + integrity sha512-aS1y1xEjFLz8wYVvJiI9T/ut/BssC2Q4K/XtG1oqHcyiMuV+qPOpRpklSmC2Z/Q7A2fE2NlBZatQGf7FnoAlrA== + dependencies: + bson "^4.2.2" + kareem "2.3.2" + mongodb "4.1.1" + mpath "0.8.3" + mquery "4.0.0" + ms "2.1.2" + regexp-clone "1.0.0" + sift "13.5.2" + sliced "1.0.1" + +mpath@0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.8.3.tgz#828ac0d187f7f42674839d74921970979abbdd8f" + integrity sha512-eb9rRvhDltXVNL6Fxd2zM9D4vKBxjVVQNLNijlj7uoXUy19zNDsIif5zR+pWmPCWNKwAtqyo4JveQm4nfD5+eA== + +mquery@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mquery/-/mquery-4.0.0.tgz#6c62160ad25289e99e0840907757cdfd62bde775" + integrity sha512-nGjm89lHja+T/b8cybAby6H0YgA4qYC/lx6UlwvHGqvTq8bDaNeCwl1sY8uRELrNbVWJzIihxVd+vphGGn1vBw== + dependencies: + debug "4.x" + regexp-clone "^1.0.0" + sliced "1.0.1" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -1688,7 +1808,7 @@ proxy-addr@~2.0.5: forwarded "0.2.0" ipaddr.js "1.9.1" -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -1742,6 +1862,16 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +reflect-metadata@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + +regexp-clone@1.0.0, regexp-clone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-1.0.0.tgz#222db967623277056260b992626354a04ce9bf63" + integrity sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw== + regexpp@^3.0.0, regexpp@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" @@ -1801,6 +1931,13 @@ safe-buffer@5.1.2: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +saslprep@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226" + integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag== + dependencies: + sparse-bitfield "^3.0.3" + "semver@2 || 3 || 4 || 5": version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -1873,6 +2010,11 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +sift@13.5.2: + version "13.5.2" + resolved "https://registry.yarnpkg.com/sift/-/sift-13.5.2.tgz#24a715e13c617b086166cd04917d204a591c9da6" + integrity sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -1887,6 +2029,11 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +sliced@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41" + integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E= + source-map-support@^0.5.12, source-map-support@^0.5.17: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" @@ -1900,6 +2047,13 @@ source-map@^0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sparse-bitfield@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" + integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE= + dependencies: + memory-pager "^1.0.2" + spdx-correct@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" @@ -2026,6 +2180,13 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== + dependencies: + punycode "^2.1.1" + tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -2078,7 +2239,7 @@ tsconfig@^7.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -tslib@^1.8.1: +tslib@^1.8.1, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -2090,6 +2251,13 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tsyringe@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/tsyringe/-/tsyringe-4.6.0.tgz#14915d3d7f0db35e1cf7269bdbf7c440713c8d07" + integrity sha512-BMQAZamSfEmIQzH8WJeRu1yZGQbPSDuI9g+yEiKZFIcO46GPZuMOC2d0b52cVBdw1d++06JnDSIIZvEnogMdAw== + dependencies: + tslib "^1.9.3" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -2160,6 +2328,19 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +whatwg-url@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-9.1.0.tgz#1b112cf237d72cd64fa7882b9c3f6234a1c3050d" + integrity sha512-CQ0UcrPHyomtlOCot1TL77WyMIm/bCwrJ2D6AOKGwEczU9EpyoqAokfqrf/MioU9kHcMsmJZcg1egXix2KYEsA== + dependencies: + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" From ef804a2353f1ad841d6f3e642d5ef3192356e703 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 30 Aug 2021 14:33:07 -0300 Subject: [PATCH 005/121] Add entities and Search function --- src/database/entities/IInvasion.ts | 29 ++++++++++++++ src/database/entities/IReserveInvasion.ts | 30 ++++++++++++++ src/database/index.ts | 13 ++++++ src/database/models/Invasion.ts | 33 +++++++++++++++ src/database/models/ReserveInvasion.ts | 39 ++++++++++++++++++ src/dtos/ISearchDTO.ts | 6 +++ src/repositories/IInvasionRepository.ts | 7 ++++ .../IReserveInvasionRepository.ts | 7 ++++ .../implementations/InvasionRepository.ts | 33 +++++++++++++++ .../ReserveInvasionRepository.ts | 33 +++++++++++++++ src/routes/index.ts | 11 +++++ src/services/search/SearchController.ts | 18 +++++++++ src/services/search/SearchService.ts | 40 +++++++++++++++++++ 13 files changed, 299 insertions(+) create mode 100644 src/database/entities/IInvasion.ts create mode 100644 src/database/entities/IReserveInvasion.ts create mode 100644 src/database/index.ts create mode 100644 src/database/models/Invasion.ts create mode 100644 src/database/models/ReserveInvasion.ts create mode 100644 src/dtos/ISearchDTO.ts create mode 100644 src/repositories/IInvasionRepository.ts create mode 100644 src/repositories/IReserveInvasionRepository.ts create mode 100644 src/repositories/implementations/InvasionRepository.ts create mode 100644 src/repositories/implementations/ReserveInvasionRepository.ts create mode 100644 src/routes/index.ts create mode 100644 src/services/search/SearchController.ts create mode 100644 src/services/search/SearchService.ts diff --git a/src/database/entities/IInvasion.ts b/src/database/entities/IInvasion.ts new file mode 100644 index 0000000..59e6d3c --- /dev/null +++ b/src/database/entities/IInvasion.ts @@ -0,0 +1,29 @@ +interface IInvasion { + type: string + properties: { + PROCESSO: string + ID: string + NUMERO: number + ANO: number + AREA_HA: string + AREA_K2: string + FASE: string + ULT_EVENTO: string + NOME: string + SUBS: string + USO: string + UF: string + UC_COD: string + UC_NOME: string + UC_NOMEABREV: string + UC_SIGLA: string + UC_BIOMA: string + ANO_ATUAL: number + EN_UC_NOME: string + EN_FASE: string + EN_SUBS: string + } + geometry: {} +} + +export { IInvasion } diff --git a/src/database/entities/IReserveInvasion.ts b/src/database/entities/IReserveInvasion.ts new file mode 100644 index 0000000..65e8bb1 --- /dev/null +++ b/src/database/entities/IReserveInvasion.ts @@ -0,0 +1,30 @@ +interface IReserveInvasion { + type: string + properties: { + PROCESSO: string + ID: string + NUMERO: number + ANO: number + AREA_HA: string + AREA_K2: string + FASE: string + ULT_EVENTO: string + NOME: string + SUBS: string + USO: string + UF: string + TI_NOME: string + TI_ETNIA: string + TI_MUNICIPIO: string + TI_UF: string + TI_SUPERFICIE: string + TI_FASE: string + TI_MODALIDADE: string + ANO_ATUAL: number + EN_FASE: string + EN_SUBS: string + } + geometry: {} +} + +export { IReserveInvasion } diff --git a/src/database/index.ts b/src/database/index.ts new file mode 100644 index 0000000..8ee4b43 --- /dev/null +++ b/src/database/index.ts @@ -0,0 +1,13 @@ +import dotenv from 'dotenv-safe' +import mongoose from 'mongoose' + +dotenv.config() + +async function main() { + await mongoose.connect( + `mongodb://${process.env.MONGO_DB_USERNAME}:${process.env.MONGO_DB_PASSWORD}@database:27017/infoamdm?authSource=admin` + ) + console.log('Database connected!') +} + +main().catch((err) => console.log(err)) diff --git a/src/database/models/Invasion.ts b/src/database/models/Invasion.ts new file mode 100644 index 0000000..cf62a89 --- /dev/null +++ b/src/database/models/Invasion.ts @@ -0,0 +1,33 @@ +import mongoose from 'mongoose' + +import { IInvasion } from '../entities/IInvasion' + +const InvasionSchema = new mongoose.Schema({ + type: String, + properties: { + PROCESSO: String, + ID: String, + NUMERO: Number, + ANO: Number, + AREA_HA: String, + AREA_K2: String, + FASE: String, + ULT_EVENTO: String, + NOME: String, + SUBS: String, + USO: String, + UF: String, + UC_COD: String, + UC_NOME: String, + UC_NOMEABREV: String, + UC_SIGLA: String, + UC_BIOMA: String, + ANO_ATUAL: Number, + EN_UC_NOME: String, + EN_FASE: String, + EN_SUBS: String, + }, + geometry: {}, +}) + +export const Invasion = mongoose.model('Invasion', InvasionSchema, 'Invasion') diff --git a/src/database/models/ReserveInvasion.ts b/src/database/models/ReserveInvasion.ts new file mode 100644 index 0000000..372b4d3 --- /dev/null +++ b/src/database/models/ReserveInvasion.ts @@ -0,0 +1,39 @@ +/* eslint-disable camelcase */ +import mongoose from 'mongoose' + +import { IReserveInvasion } from '../entities/IReserveInvasion' + +const ReserveInvasionSchema = new mongoose.Schema({ + type: String, + properties: { + PROCESSO: String, + ID: String, + NUMERO: Number, + ANO: Number, + AREA_HA: String, + AREA_K2: String, + FASE: String, + ULT_EVENTO: String, + NOME: String, + SUBS: String, + USO: String, + UF: String, + TI_NOME: String, + TI_ETNIA: String, + TI_MUNICIPIO: String, + TI_UF: String, + TI_SUPERFICIE: String, + TI_FASE: String, + TI_MODALIDADE: String, + ANO_ATUAL: Number, + EN_FASE: String, + EN_SUBS: String, + }, + geometry: {}, +}) + +export const ReserveInvasion = mongoose.model( + 'ReserveInvasion', + ReserveInvasionSchema, + 'ReserveInvasion' +) diff --git a/src/dtos/ISearchDTO.ts b/src/dtos/ISearchDTO.ts new file mode 100644 index 0000000..2bec02f --- /dev/null +++ b/src/dtos/ISearchDTO.ts @@ -0,0 +1,6 @@ +interface ISearchDTO { + type: string + value: string +} + +export { ISearchDTO } diff --git a/src/repositories/IInvasionRepository.ts b/src/repositories/IInvasionRepository.ts new file mode 100644 index 0000000..06d8aba --- /dev/null +++ b/src/repositories/IInvasionRepository.ts @@ -0,0 +1,7 @@ +import { ISearchDTO } from '../dtos/ISearchDTO' + +interface IInvasionRepository { + searchCompany(searchTerm: string): Promise +} + +export { IInvasionRepository } diff --git a/src/repositories/IReserveInvasionRepository.ts b/src/repositories/IReserveInvasionRepository.ts new file mode 100644 index 0000000..aa149ff --- /dev/null +++ b/src/repositories/IReserveInvasionRepository.ts @@ -0,0 +1,7 @@ +import { ISearchDTO } from '../dtos/ISearchDTO' + +interface IReserveInvasionRepository { + searchCompany(searchTerm: string): Promise +} + +export { IReserveInvasionRepository } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts new file mode 100644 index 0000000..fdb16a5 --- /dev/null +++ b/src/repositories/implementations/InvasionRepository.ts @@ -0,0 +1,33 @@ +import { Invasion } from '../../database/models/Invasion' +import { ISearchDTO } from '../../dtos/ISearchDTO' +import { IInvasionRepository } from '../IInvasionRepository' + +class InvasionRepository implements IInvasionRepository { + async searchCompany(searchTerm: string): Promise { + const companies = await Invasion.aggregate([ + { + $match: { + 'properties.NOME': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + }, + }, + { + $project: { name: { $toUpper: '$properties.NOME' } }, + }, + { + $group: { + _id: '$name', + }, + }, + { + $project: { + type: 'company', + value: '$_id', + _id: 0, + }, + }, + ]) + return companies + } +} + +export { InvasionRepository } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts new file mode 100644 index 0000000..2fac2b3 --- /dev/null +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -0,0 +1,33 @@ +import { ReserveInvasion } from '../../database/models/ReserveInvasion' +import { ISearchDTO } from '../../dtos/ISearchDTO' +import { IReserveInvasionRepository } from '../IReserveInvasionRepository' + +class ReserveInvasionRepository implements IReserveInvasionRepository { + async searchCompany(searchTerm: string): Promise { + const companies = await ReserveInvasion.aggregate([ + { + $match: { + 'properties.NOME': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + }, + }, + { + $project: { name: { $toUpper: '$properties.NOME' } }, + }, + { + $group: { + _id: '$name', + }, + }, + { + $project: { + type: 'company', + value: '$_id', + _id: 0, + }, + }, + ]) + return companies + } +} + +export { ReserveInvasionRepository } diff --git a/src/routes/index.ts b/src/routes/index.ts new file mode 100644 index 0000000..4ab2bec --- /dev/null +++ b/src/routes/index.ts @@ -0,0 +1,11 @@ +import { Router } from 'express' + +import { SearchController } from '../services/search/SearchController' + +const router = Router() + +const searchController = new SearchController() + +router.get('/search', searchController.handle) + +export { router } diff --git a/src/services/search/SearchController.ts b/src/services/search/SearchController.ts new file mode 100644 index 0000000..7bdae88 --- /dev/null +++ b/src/services/search/SearchController.ts @@ -0,0 +1,18 @@ +import { Request, Response } from 'express' +import { container } from 'tsyringe' + +import { SearchService } from './SearchService' + +class SearchController { + async handle(request: Request, response: Response): Promise { + const { searchTerm } = request.query + + const searchService = container.resolve(SearchService) + + const results = await searchService.execute(String(searchTerm)) + + return response.json(results) + } +} + +export { SearchController } diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts new file mode 100644 index 0000000..23ca8b7 --- /dev/null +++ b/src/services/search/SearchService.ts @@ -0,0 +1,40 @@ +import { inject, injectable } from 'tsyringe' + +import { ISearchDTO } from '../../dtos/ISearchDTO' +import { IInvasionRepository } from '../../repositories/IInvasionRepository' +import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' + +@injectable() +class SearchService { + constructor( + @inject('ReserveInvasionRepository') + private reserveInvasionRepository: IReserveInvasionRepository, + + @inject('InvasionRepository') + private invasionRepository: IInvasionRepository + ) {} + + async execute(searchTerm: string): Promise { + const reserveCompanies = await this.reserveInvasionRepository.searchCompany( + searchTerm + ) + + const unityCompanies = await this.invasionRepository.searchCompany( + searchTerm + ) + + const companiesMap = new Map() + reserveCompanies.forEach((company) => + companiesMap.set(company.value, company) + ) + unityCompanies.forEach((company) => + companiesMap.set(company.value, company) + ) + + const companies = Array.from(companiesMap.values()) + + return companies + } +} + +export { SearchService } From bffa5e08cfd032519e5ca3efa3773ad6ba481da1 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Tue, 31 Aug 2021 09:26:21 -0300 Subject: [PATCH 006/121] Add Unity --- src/database/entities/IUnity.ts | 29 ++++++++++++++++ src/database/models/Unity.ts | 33 +++++++++++++++++++ src/repositories/IUnityRepository.ts | 7 ++++ .../implementations/UnityRepository.ts | 21 ++++++++++++ src/services/search/SearchService.ts | 13 ++++++-- src/shared/container/index.ts | 7 ++++ 6 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 src/database/entities/IUnity.ts create mode 100644 src/database/models/Unity.ts create mode 100644 src/repositories/IUnityRepository.ts create mode 100644 src/repositories/implementations/UnityRepository.ts diff --git a/src/database/entities/IUnity.ts b/src/database/entities/IUnity.ts new file mode 100644 index 0000000..15b0bc2 --- /dev/null +++ b/src/database/entities/IUnity.ts @@ -0,0 +1,29 @@ +/* eslint-disable camelcase */ +interface IUnity { + type: string + properties: { + codigoCnuc: string + nome: string + geometriaA: string + anoCriacao: number + sigla: string + areaHa: string + areaK2: string + perimetroM: number + atoLegal: string + administra: string + SiglaGrupo: string + UF: string + municipios: string + biomaIBGE: string + biomaCRL: string + CoordRegio: string + fusoAbrang: string + UORG: string + nomeabrev: string + en_nome: string + } + geometry: {} +} + +export { IUnity } diff --git a/src/database/models/Unity.ts b/src/database/models/Unity.ts new file mode 100644 index 0000000..a7638d5 --- /dev/null +++ b/src/database/models/Unity.ts @@ -0,0 +1,33 @@ +/* eslint-disable camelcase */ +import mongoose from 'mongoose' + +import { IUnity } from '../entities/IUnity' + +const UnitySchema = new mongoose.Schema({ + type: String, + properties: { + codigoCnuc: String, + nome: String, + geometriaA: String, + anoCriacao: Number, + sigla: String, + areaHa: String, + areaK2: String, + perimetroM: Number, + atoLegal: String, + administra: String, + SiglaGrupo: String, + UF: String, + municipios: String, + biomaIBGE: String, + biomaCRL: String, + CoordRegio: String, + fusoAbrang: String, + UORG: String, + nomeabrev: String, + en_nome: String, + }, + geometry: {}, +}) + +export const Unity = mongoose.model('Unity', UnitySchema, 'Unity') diff --git a/src/repositories/IUnityRepository.ts b/src/repositories/IUnityRepository.ts new file mode 100644 index 0000000..2d23fa4 --- /dev/null +++ b/src/repositories/IUnityRepository.ts @@ -0,0 +1,7 @@ +import { ISearchDTO } from '../dtos/ISearchDTO' + +interface IUnityRepository { + searchByName(searchTerm: string): Promise +} + +export { IUnityRepository } diff --git a/src/repositories/implementations/UnityRepository.ts b/src/repositories/implementations/UnityRepository.ts new file mode 100644 index 0000000..fa3be6a --- /dev/null +++ b/src/repositories/implementations/UnityRepository.ts @@ -0,0 +1,21 @@ +import { Unity } from '../../database/models/Unity' +import { ISearchDTO } from '../../dtos/ISearchDTO' +import { IUnityRepository } from '../IUnityRepository' + +class UnityRepository implements IUnityRepository { + async searchByName(searchTerm: string): Promise { + const unities = await Unity.find( + { + 'properties.nome': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + }, + { + type: 'unity', + value: '$properties.nome', + _id: 0, + } + ) + return unities + } +} + +export { UnityRepository } diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts index 23ca8b7..008d9d0 100644 --- a/src/services/search/SearchService.ts +++ b/src/services/search/SearchService.ts @@ -3,6 +3,7 @@ import { inject, injectable } from 'tsyringe' import { ISearchDTO } from '../../dtos/ISearchDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { IUnityRepository } from '../../repositories/IUnityRepository' @injectable() class SearchService { @@ -11,7 +12,10 @@ class SearchService { private reserveInvasionRepository: IReserveInvasionRepository, @inject('InvasionRepository') - private invasionRepository: IInvasionRepository + private invasionRepository: IInvasionRepository, + + @inject('UnityRepository') + private unityRepository: IUnityRepository ) {} async execute(searchTerm: string): Promise { @@ -30,10 +34,13 @@ class SearchService { unityCompanies.forEach((company) => companiesMap.set(company.value, company) ) - const companies = Array.from(companiesMap.values()) - return companies + const unities = await this.unityRepository.searchByName(searchTerm) + + const results = companies.concat(unities) + + return results } } diff --git a/src/shared/container/index.ts b/src/shared/container/index.ts index a5a6727..98034cc 100644 --- a/src/shared/container/index.ts +++ b/src/shared/container/index.ts @@ -3,7 +3,9 @@ import { container } from 'tsyringe' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { InvasionRepository } from '../../repositories/implementations/InvasionRepository' import { ReserveInvasionRepository } from '../../repositories/implementations/ReserveInvasionRepository' +import { UnityRepository } from '../../repositories/implementations/UnityRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { IUnityRepository } from '../../repositories/IUnityRepository' container.registerSingleton( 'ReserveInvasionRepository', @@ -14,3 +16,8 @@ container.registerSingleton( 'InvasionRepository', InvasionRepository ) + +container.registerSingleton( + 'UnityRepository', + UnityRepository +) From ce513ce9af3866647ec793c18f17d9903038c1dc Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Tue, 31 Aug 2021 11:00:43 -0300 Subject: [PATCH 007/121] Add Reserve --- src/database/entities/IReserve.ts | 25 ++++++++++++++++ src/database/models/Reserve.ts | 29 +++++++++++++++++++ src/repositories/IReserveRepository.ts | 7 +++++ .../implementations/ReserveRepository.ts | 21 ++++++++++++++ src/services/search/SearchService.ts | 10 +++++-- src/shared/container/index.ts | 7 +++++ 6 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/database/entities/IReserve.ts create mode 100644 src/database/models/Reserve.ts create mode 100644 src/repositories/IReserveRepository.ts create mode 100644 src/repositories/implementations/ReserveRepository.ts diff --git a/src/database/entities/IReserve.ts b/src/database/entities/IReserve.ts new file mode 100644 index 0000000..818f64c --- /dev/null +++ b/src/database/entities/IReserve.ts @@ -0,0 +1,25 @@ +/* eslint-disable camelcase */ +interface IReserve { + type: string + properties: { + gid: number + terrai_cod: number + terrai_nom: string + etnia_nome: string + municipio_: string + uf_sigla: string + superfice: string + superficieK2: string + fase_ti: string + modalidade: string + reestudo_t: string + cr: string + faixa_fron: string + undadm_cod: number + undadm_nom: string + undadm_sig: string + } + geometry: {} +} + +export { IReserve } diff --git a/src/database/models/Reserve.ts b/src/database/models/Reserve.ts new file mode 100644 index 0000000..11a0bfa --- /dev/null +++ b/src/database/models/Reserve.ts @@ -0,0 +1,29 @@ +/* eslint-disable camelcase */ +import mongoose from 'mongoose' + +import { IReserve } from '../entities/IReserve' + +const ReserveSchema = new mongoose.Schema({ + type: String, + properties: { + gid: Number, + terrai_cod: Number, + terrai_nom: String, + etnia_nome: String, + municipio_: String, + uf_sigla: String, + superfice: String, + superficieK2: String, + fase_ti: String, + modalidade: String, + reestudo_t: String, + cr: String, + faixa_fron: String, + undadm_cod: Number, + undadm_nom: String, + undadm_sig: String, + }, + geometry: {}, +}) + +export const Reserve = mongoose.model('Reserve', ReserveSchema, 'Reserve') diff --git a/src/repositories/IReserveRepository.ts b/src/repositories/IReserveRepository.ts new file mode 100644 index 0000000..a8add84 --- /dev/null +++ b/src/repositories/IReserveRepository.ts @@ -0,0 +1,7 @@ +import { ISearchDTO } from '../dtos/ISearchDTO' + +interface IReserveRepository { + searchByName(searchTerm: string): Promise +} + +export { IReserveRepository } diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts new file mode 100644 index 0000000..1a035f8 --- /dev/null +++ b/src/repositories/implementations/ReserveRepository.ts @@ -0,0 +1,21 @@ +import { Reserve } from '../../database/models/Reserve' +import { ISearchDTO } from '../../dtos/ISearchDTO' +import { IReserveRepository } from '../IReserveRepository' + +class ReserveRepository implements IReserveRepository { + async searchByName(searchTerm: string): Promise { + const reserves = await Reserve.find( + { + 'properties.terrai_nom': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + }, + { + type: 'reserve', + value: '$properties.terrai_nom', + _id: 0, + } + ) + return reserves + } +} + +export { ReserveRepository } diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts index 008d9d0..a810965 100644 --- a/src/services/search/SearchService.ts +++ b/src/services/search/SearchService.ts @@ -3,6 +3,7 @@ import { inject, injectable } from 'tsyringe' import { ISearchDTO } from '../../dtos/ISearchDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { IReserveRepository } from '../../repositories/IReserveRepository' import { IUnityRepository } from '../../repositories/IUnityRepository' @injectable() @@ -15,7 +16,10 @@ class SearchService { private invasionRepository: IInvasionRepository, @inject('UnityRepository') - private unityRepository: IUnityRepository + private unityRepository: IUnityRepository, + + @inject('ReserveRepository') + private reserveRepository: IReserveRepository ) {} async execute(searchTerm: string): Promise { @@ -38,7 +42,9 @@ class SearchService { const unities = await this.unityRepository.searchByName(searchTerm) - const results = companies.concat(unities) + const reserves = await this.reserveRepository.searchByName(searchTerm) + + const results = companies.concat(unities, reserves) return results } diff --git a/src/shared/container/index.ts b/src/shared/container/index.ts index 98034cc..626fdd2 100644 --- a/src/shared/container/index.ts +++ b/src/shared/container/index.ts @@ -3,8 +3,10 @@ import { container } from 'tsyringe' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { InvasionRepository } from '../../repositories/implementations/InvasionRepository' import { ReserveInvasionRepository } from '../../repositories/implementations/ReserveInvasionRepository' +import { ReserveRepository } from '../../repositories/implementations/ReserveRepository' import { UnityRepository } from '../../repositories/implementations/UnityRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { IReserveRepository } from '../../repositories/IReserveRepository' import { IUnityRepository } from '../../repositories/IUnityRepository' container.registerSingleton( @@ -21,3 +23,8 @@ container.registerSingleton( 'UnityRepository', UnityRepository ) + +container.registerSingleton( + 'ReserveRepository', + ReserveRepository +) From 6fa60ad9fe88a72db8b0eb5f46d00e6d480fbecf Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 1 Sep 2021 10:55:03 -0300 Subject: [PATCH 008/121] Change entities --- src/database/entities/IInvasion.ts | 7 +------ src/database/entities/ILicense.ts | 20 ++++++++++++++++++ src/database/entities/IReserve.ts | 3 +-- src/database/entities/IReserveInvasion.ts | 6 +----- src/database/entities/IUnity.ts | 4 +--- src/database/models/Invasion.ts | 7 +------ src/database/models/License.ts | 25 +++++++++++++++++++++++ src/database/models/Reserve.ts | 3 +-- src/database/models/ReserveInvasion.ts | 6 +----- src/database/models/Unity.ts | 4 +--- 10 files changed, 53 insertions(+), 32 deletions(-) create mode 100644 src/database/entities/ILicense.ts create mode 100644 src/database/models/License.ts diff --git a/src/database/entities/IInvasion.ts b/src/database/entities/IInvasion.ts index 59e6d3c..678b397 100644 --- a/src/database/entities/IInvasion.ts +++ b/src/database/entities/IInvasion.ts @@ -5,8 +5,7 @@ interface IInvasion { ID: string NUMERO: number ANO: number - AREA_HA: string - AREA_K2: string + AREA_HA: number FASE: string ULT_EVENTO: string NOME: string @@ -18,10 +17,6 @@ interface IInvasion { UC_NOMEABREV: string UC_SIGLA: string UC_BIOMA: string - ANO_ATUAL: number - EN_UC_NOME: string - EN_FASE: string - EN_SUBS: string } geometry: {} } diff --git a/src/database/entities/ILicense.ts b/src/database/entities/ILicense.ts new file mode 100644 index 0000000..0da2af1 --- /dev/null +++ b/src/database/entities/ILicense.ts @@ -0,0 +1,20 @@ +interface ILicense { + type: string + properties: { + PROCESSO: string + NUMERO: number + ANO: number + AREA_HA: number + ID: string + FASE: string + ULT_EVENTO: string + NOME: string + SUBS: string + USO: string + UF: string + DSProcesso: string + } + geometry: {} +} + +export { ILicense } diff --git a/src/database/entities/IReserve.ts b/src/database/entities/IReserve.ts index 818f64c..505fc49 100644 --- a/src/database/entities/IReserve.ts +++ b/src/database/entities/IReserve.ts @@ -8,8 +8,7 @@ interface IReserve { etnia_nome: string municipio_: string uf_sigla: string - superfice: string - superficieK2: string + superfice: number fase_ti: string modalidade: string reestudo_t: string diff --git a/src/database/entities/IReserveInvasion.ts b/src/database/entities/IReserveInvasion.ts index 65e8bb1..c413532 100644 --- a/src/database/entities/IReserveInvasion.ts +++ b/src/database/entities/IReserveInvasion.ts @@ -5,8 +5,7 @@ interface IReserveInvasion { ID: string NUMERO: number ANO: number - AREA_HA: string - AREA_K2: string + AREA_HA: number FASE: string ULT_EVENTO: string NOME: string @@ -20,9 +19,6 @@ interface IReserveInvasion { TI_SUPERFICIE: string TI_FASE: string TI_MODALIDADE: string - ANO_ATUAL: number - EN_FASE: string - EN_SUBS: string } geometry: {} } diff --git a/src/database/entities/IUnity.ts b/src/database/entities/IUnity.ts index 15b0bc2..dc5ffc6 100644 --- a/src/database/entities/IUnity.ts +++ b/src/database/entities/IUnity.ts @@ -7,8 +7,7 @@ interface IUnity { geometriaA: string anoCriacao: number sigla: string - areaHa: string - areaK2: string + areaHa: number perimetroM: number atoLegal: string administra: string @@ -21,7 +20,6 @@ interface IUnity { fusoAbrang: string UORG: string nomeabrev: string - en_nome: string } geometry: {} } diff --git a/src/database/models/Invasion.ts b/src/database/models/Invasion.ts index cf62a89..25a701e 100644 --- a/src/database/models/Invasion.ts +++ b/src/database/models/Invasion.ts @@ -9,8 +9,7 @@ const InvasionSchema = new mongoose.Schema({ ID: String, NUMERO: Number, ANO: Number, - AREA_HA: String, - AREA_K2: String, + AREA_HA: Number, FASE: String, ULT_EVENTO: String, NOME: String, @@ -22,10 +21,6 @@ const InvasionSchema = new mongoose.Schema({ UC_NOMEABREV: String, UC_SIGLA: String, UC_BIOMA: String, - ANO_ATUAL: Number, - EN_UC_NOME: String, - EN_FASE: String, - EN_SUBS: String, }, geometry: {}, }) diff --git a/src/database/models/License.ts b/src/database/models/License.ts new file mode 100644 index 0000000..2712d19 --- /dev/null +++ b/src/database/models/License.ts @@ -0,0 +1,25 @@ +/* eslint-disable camelcase */ +import mongoose from 'mongoose' + +import { ILicense } from '../entities/ILicense' + +const LicenseSchema = new mongoose.Schema({ + type: String, + properties: { + PROCESSO: String, + NUMERO: Number, + ANO: Number, + AREA_HA: Number, + ID: String, + FASE: String, + ULT_EVENTO: String, + NOME: String, + SUBS: String, + USO: String, + UF: String, + DSProcesso: String, + }, + geometry: {}, +}) + +export const License = mongoose.model('License', LicenseSchema, 'License') diff --git a/src/database/models/Reserve.ts b/src/database/models/Reserve.ts index 11a0bfa..9269abb 100644 --- a/src/database/models/Reserve.ts +++ b/src/database/models/Reserve.ts @@ -12,8 +12,7 @@ const ReserveSchema = new mongoose.Schema({ etnia_nome: String, municipio_: String, uf_sigla: String, - superfice: String, - superficieK2: String, + superfice: Number, fase_ti: String, modalidade: String, reestudo_t: String, diff --git a/src/database/models/ReserveInvasion.ts b/src/database/models/ReserveInvasion.ts index 372b4d3..cfbc321 100644 --- a/src/database/models/ReserveInvasion.ts +++ b/src/database/models/ReserveInvasion.ts @@ -10,8 +10,7 @@ const ReserveInvasionSchema = new mongoose.Schema({ ID: String, NUMERO: Number, ANO: Number, - AREA_HA: String, - AREA_K2: String, + AREA_HA: Number, FASE: String, ULT_EVENTO: String, NOME: String, @@ -25,9 +24,6 @@ const ReserveInvasionSchema = new mongoose.Schema({ TI_SUPERFICIE: String, TI_FASE: String, TI_MODALIDADE: String, - ANO_ATUAL: Number, - EN_FASE: String, - EN_SUBS: String, }, geometry: {}, }) diff --git a/src/database/models/Unity.ts b/src/database/models/Unity.ts index a7638d5..3f05e2e 100644 --- a/src/database/models/Unity.ts +++ b/src/database/models/Unity.ts @@ -11,8 +11,7 @@ const UnitySchema = new mongoose.Schema({ geometriaA: String, anoCriacao: Number, sigla: String, - areaHa: String, - areaK2: String, + areaHa: Number, perimetroM: Number, atoLegal: String, administra: String, @@ -25,7 +24,6 @@ const UnitySchema = new mongoose.Schema({ fusoAbrang: String, UORG: String, nomeabrev: String, - en_nome: String, }, geometry: {}, }) From 2b59f552bdd2d1cab5f3167eb8e30cd11ecf16ce Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 2 Sep 2021 11:26:42 -0300 Subject: [PATCH 009/121] Create method to list invasions acording to the filters --- package.json | 2 + src/dtos/IFiltersDTO.ts | 8 ++++ src/dtos/IInvasionDTO.ts | 10 +++++ src/repositories/IInvasionRepository.ts | 3 ++ .../IReserveInvasionRepository.ts | 3 ++ .../implementations/InvasionRepository.ts | 40 ++++++++++++++++-- .../ReserveInvasionRepository.ts | 41 +++++++++++++++++-- src/routes/index.ts | 3 ++ src/server.ts | 4 ++ .../listInvasions/ListInvasionsController.ts | 18 ++++++++ .../listInvasions/ListInvasionsService.ts | 38 +++++++++++++++++ yarn.lock | 20 ++++++++- 12 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 src/dtos/IFiltersDTO.ts create mode 100644 src/dtos/IInvasionDTO.ts create mode 100644 src/services/listInvasions/ListInvasionsController.ts create mode 100644 src/services/listInvasions/ListInvasionsService.ts diff --git a/package.json b/package.json index 22936b6..ce5d092 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "dev": "ts-node-dev --transpile-only --ignore-watch node_modules --respawn src/server.ts" }, "dependencies": { + "cors": "^2.8.5", "dotenv-safe": "^8.2.0", "express": "^4.17.1", "mongoose": "^6.0.0", @@ -16,6 +17,7 @@ "tsyringe": "^4.6.0" }, "devDependencies": { + "@types/cors": "^2.8.12", "@types/dotenv-safe": "^8.1.2", "@types/express": "^4.17.13", "@typescript-eslint/eslint-plugin": "^4.29.3", diff --git a/src/dtos/IFiltersDTO.ts b/src/dtos/IFiltersDTO.ts new file mode 100644 index 0000000..b25b0aa --- /dev/null +++ b/src/dtos/IFiltersDTO.ts @@ -0,0 +1,8 @@ +interface IFiltersDTO { + reserve?: string[] + unity?: string[] + company?: string[] + year?: string[] +} + +export { IFiltersDTO } diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts new file mode 100644 index 0000000..c320eb9 --- /dev/null +++ b/src/dtos/IInvasionDTO.ts @@ -0,0 +1,10 @@ +interface IInvasionDTO { + company: string + process: string + area: number + year: number + territory: string + type: string +} + +export { IInvasionDTO } diff --git a/src/repositories/IInvasionRepository.ts b/src/repositories/IInvasionRepository.ts index 06d8aba..45d8052 100644 --- a/src/repositories/IInvasionRepository.ts +++ b/src/repositories/IInvasionRepository.ts @@ -1,7 +1,10 @@ +import { IFiltersDTO } from '../dtos/IFiltersDTO' +import { IInvasionDTO } from '../dtos/IInvasionDTO' import { ISearchDTO } from '../dtos/ISearchDTO' interface IInvasionRepository { searchCompany(searchTerm: string): Promise + listInvasions(filters: IFiltersDTO): Promise } export { IInvasionRepository } diff --git a/src/repositories/IReserveInvasionRepository.ts b/src/repositories/IReserveInvasionRepository.ts index aa149ff..4d843e0 100644 --- a/src/repositories/IReserveInvasionRepository.ts +++ b/src/repositories/IReserveInvasionRepository.ts @@ -1,7 +1,10 @@ +import { IFiltersDTO } from '../dtos/IFiltersDTO' +import { IInvasionDTO } from '../dtos/IInvasionDTO' import { ISearchDTO } from '../dtos/ISearchDTO' interface IReserveInvasionRepository { searchCompany(searchTerm: string): Promise + listInvasions(filters: IFiltersDTO): Promise } export { IReserveInvasionRepository } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index fdb16a5..3666a96 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -1,8 +1,43 @@ import { Invasion } from '../../database/models/Invasion' +import { IFiltersDTO } from '../../dtos/IFiltersDTO' +import { IInvasionDTO } from '../../dtos/IInvasionDTO' import { ISearchDTO } from '../../dtos/ISearchDTO' import { IInvasionRepository } from '../IInvasionRepository' class InvasionRepository implements IInvasionRepository { + async listInvasions(filters: IFiltersDTO): Promise { + const match: any = {} + + if (filters.unity) { + match['properties.UC_NOME'] = { + $in: filters.unity, + } + } + + if (filters.company) { + match['properties.NOME'] = { + $in: filters.company, + } + } + + if (filters.year) { + match['properties.ANO'] = { + $in: filters.year, + } + } + + const invasions = await Invasion.find(match, { + company: '$properties.NOME', + process: '$properties.PROCESSO', + area: '$properties.AREA_HA', + year: '$properties.ANO', + territory: '$properties.UC_NOME', + type: 'Unidade de Conservação', + _id: 0, + }) + + return invasions + } async searchCompany(searchTerm: string): Promise { const companies = await Invasion.aggregate([ { @@ -10,12 +45,9 @@ class InvasionRepository implements IInvasionRepository { 'properties.NOME': { $regex: new RegExp(`^${searchTerm}`, 'i') }, }, }, - { - $project: { name: { $toUpper: '$properties.NOME' } }, - }, { $group: { - _id: '$name', + _id: '$properties.NOME', }, }, { diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 2fac2b3..be05c18 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -1,8 +1,44 @@ import { ReserveInvasion } from '../../database/models/ReserveInvasion' +import { IFiltersDTO } from '../../dtos/IFiltersDTO' +import { IInvasionDTO } from '../../dtos/IInvasionDTO' import { ISearchDTO } from '../../dtos/ISearchDTO' import { IReserveInvasionRepository } from '../IReserveInvasionRepository' class ReserveInvasionRepository implements IReserveInvasionRepository { + async listInvasions(filters: IFiltersDTO): Promise { + const match: any = {} + + if (filters.reserve) { + match['properties.TI_NOME'] = { + $in: filters.reserve, + } + } + + if (filters.company) { + match['properties.NOME'] = { + $in: filters.company, + } + } + + if (filters.year) { + match['properties.ANO'] = { + $in: filters.year, + } + } + + const invasions = await ReserveInvasion.find(match, { + company: '$properties.NOME', + process: '$properties.PROCESSO', + area: '$properties.AREA_HA', + year: '$properties.ANO', + territory: '$properties.TI_NOME', + type: 'Terra Indígena', + _id: 0, + }) + + return invasions + } + async searchCompany(searchTerm: string): Promise { const companies = await ReserveInvasion.aggregate([ { @@ -10,12 +46,9 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { 'properties.NOME': { $regex: new RegExp(`^${searchTerm}`, 'i') }, }, }, - { - $project: { name: { $toUpper: '$properties.NOME' } }, - }, { $group: { - _id: '$name', + _id: '$properties.NOME', }, }, { diff --git a/src/routes/index.ts b/src/routes/index.ts index 4ab2bec..88f2c76 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,11 +1,14 @@ import { Router } from 'express' +import { ListInvasionsController } from '../services/listInvasions/ListInvasionsController' import { SearchController } from '../services/search/SearchController' const router = Router() const searchController = new SearchController() +const listInvasionsController = new ListInvasionsController() router.get('/search', searchController.handle) +router.post('/invasions', listInvasionsController.handle) export { router } diff --git a/src/server.ts b/src/server.ts index fa014a3..f682067 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,4 +1,5 @@ import 'reflect-metadata' +import cors from 'cors' import express from 'express' import { router } from './routes' @@ -8,6 +9,9 @@ import './shared/container' const app = express() +app.use(cors()) +app.use(express.json()) +app.use(express.urlencoded({ extended: true })) app.use(router) app.listen(3333, () => console.log('Server is running!')) diff --git a/src/services/listInvasions/ListInvasionsController.ts b/src/services/listInvasions/ListInvasionsController.ts new file mode 100644 index 0000000..517f42d --- /dev/null +++ b/src/services/listInvasions/ListInvasionsController.ts @@ -0,0 +1,18 @@ +import { Request, Response } from 'express' +import { container } from 'tsyringe' + +import { ListInvasionsService } from './ListInvasionsService' + +class ListInvasionsController { + async handle(request: Request, response: Response): Promise { + const { filters } = request.body + + const listInvasionsService = container.resolve(ListInvasionsService) + + const invasions = await listInvasionsService.execute(filters) + + return response.json(invasions) + } +} + +export { ListInvasionsController } diff --git a/src/services/listInvasions/ListInvasionsService.ts b/src/services/listInvasions/ListInvasionsService.ts new file mode 100644 index 0000000..c0ef525 --- /dev/null +++ b/src/services/listInvasions/ListInvasionsService.ts @@ -0,0 +1,38 @@ +import { inject, injectable } from 'tsyringe' + +import { IFiltersDTO } from '../../dtos/IFiltersDTO' +import { IInvasionDTO } from '../../dtos/IInvasionDTO' +import { IInvasionRepository } from '../../repositories/IInvasionRepository' +import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' + +@injectable() +class ListInvasionsService { + constructor( + @inject('ReserveInvasionRepository') + private reserveInvasionRepository: IReserveInvasionRepository, + + @inject('InvasionRepository') + private invasionRepository: IInvasionRepository + ) {} + + async execute(filters: IFiltersDTO): Promise { + let reserveInvasions: IInvasionDTO[] = [] + let invasions: IInvasionDTO[] = [] + + if ((!filters.reserve && !filters.unity) || filters.reserve) { + reserveInvasions = await this.reserveInvasionRepository.listInvasions( + filters + ) + } + + if ((!filters.reserve && !filters.unity) || filters.unity) { + invasions = await this.invasionRepository.listInvasions(filters) + } + + const results = invasions.concat(reserveInvasions) + + return results + } +} + +export { ListInvasionsService } diff --git a/yarn.lock b/yarn.lock index 2bf26c8..7c3ef58 100644 --- a/yarn.lock +++ b/yarn.lock @@ -88,6 +88,11 @@ dependencies: "@types/node" "*" +"@types/cors@^2.8.12": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + "@types/dotenv-safe@^8.1.2": version "8.1.2" resolved "https://registry.yarnpkg.com/@types/dotenv-safe/-/dotenv-safe-8.1.2.tgz#72f126969f445af5654efd3167deabc2cbc6c24e" @@ -523,6 +528,14 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -1623,6 +1636,11 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + object-inspect@^1.11.0, object-inspect@^1.9.0: version "1.11.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" @@ -2323,7 +2341,7 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -vary@~1.1.2: +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= From 5f800cd86c75f3743ead6c51e534dfaad7dc84f6 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 2 Sep 2021 13:10:04 -0300 Subject: [PATCH 010/121] Add States in search and filters --- src/dtos/IFiltersDTO.ts | 1 + src/dtos/IInvasionDTO.ts | 1 + .../implementations/InvasionRepository.ts | 11 +++++ .../ReserveInvasionRepository.ts | 11 +++++ src/services/search/SearchService.ts | 5 +- src/utils/states.ts | 46 +++++++++++++++++++ 6 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/utils/states.ts diff --git a/src/dtos/IFiltersDTO.ts b/src/dtos/IFiltersDTO.ts index b25b0aa..272058b 100644 --- a/src/dtos/IFiltersDTO.ts +++ b/src/dtos/IFiltersDTO.ts @@ -1,4 +1,5 @@ interface IFiltersDTO { + state?: string[] reserve?: string[] unity?: string[] company?: string[] diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts index c320eb9..651b65e 100644 --- a/src/dtos/IInvasionDTO.ts +++ b/src/dtos/IInvasionDTO.ts @@ -3,6 +3,7 @@ interface IInvasionDTO { process: string area: number year: number + state: string territory: string type: string } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 3666a96..36afc1e 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -2,6 +2,7 @@ import { Invasion } from '../../database/models/Invasion' import { IFiltersDTO } from '../../dtos/IFiltersDTO' import { IInvasionDTO } from '../../dtos/IInvasionDTO' import { ISearchDTO } from '../../dtos/ISearchDTO' +import { getStateAcronym } from '../../utils/states' import { IInvasionRepository } from '../IInvasionRepository' class InvasionRepository implements IInvasionRepository { @@ -26,11 +27,21 @@ class InvasionRepository implements IInvasionRepository { } } + if (filters.state) { + const acronymsRegex = filters.state + .map((state) => getStateAcronym(state)) + .map((acronym) => new RegExp(`.*${acronym}.*`, 'i')) + match['properties.UF'] = { + $in: acronymsRegex, + } + } + const invasions = await Invasion.find(match, { company: '$properties.NOME', process: '$properties.PROCESSO', area: '$properties.AREA_HA', year: '$properties.ANO', + state: '$properties.UF', territory: '$properties.UC_NOME', type: 'Unidade de Conservação', _id: 0, diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index be05c18..30473a8 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -2,6 +2,7 @@ import { ReserveInvasion } from '../../database/models/ReserveInvasion' import { IFiltersDTO } from '../../dtos/IFiltersDTO' import { IInvasionDTO } from '../../dtos/IInvasionDTO' import { ISearchDTO } from '../../dtos/ISearchDTO' +import { getStateAcronym } from '../../utils/states' import { IReserveInvasionRepository } from '../IReserveInvasionRepository' class ReserveInvasionRepository implements IReserveInvasionRepository { @@ -26,11 +27,21 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { } } + if (filters.state) { + const acronymsRegex = filters.state + .map((state) => getStateAcronym(state)) + .map((acronym) => new RegExp(`.*${acronym}.*`, 'i')) + match['properties.UF'] = { + $in: acronymsRegex, + } + } + const invasions = await ReserveInvasion.find(match, { company: '$properties.NOME', process: '$properties.PROCESSO', area: '$properties.AREA_HA', year: '$properties.ANO', + state: '$properties.UF', territory: '$properties.TI_NOME', type: 'Terra Indígena', _id: 0, diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts index a810965..32dbc81 100644 --- a/src/services/search/SearchService.ts +++ b/src/services/search/SearchService.ts @@ -5,6 +5,7 @@ import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' import { IReserveRepository } from '../../repositories/IReserveRepository' import { IUnityRepository } from '../../repositories/IUnityRepository' +import { searchStates } from '../../utils/states' @injectable() class SearchService { @@ -23,6 +24,8 @@ class SearchService { ) {} async execute(searchTerm: string): Promise { + const states = searchStates(searchTerm) + const reserveCompanies = await this.reserveInvasionRepository.searchCompany( searchTerm ) @@ -44,7 +47,7 @@ class SearchService { const reserves = await this.reserveRepository.searchByName(searchTerm) - const results = companies.concat(unities, reserves) + const results = states.concat(companies, unities, reserves) return results } diff --git a/src/utils/states.ts b/src/utils/states.ts new file mode 100644 index 0000000..417c133 --- /dev/null +++ b/src/utils/states.ts @@ -0,0 +1,46 @@ +import { ISearchDTO } from '../dtos/ISearchDTO' + +const states = new Map([ + ['Acre', 'AC'], + ['Alagoas', 'AL'], + ['Amapá', 'AP'], + ['Amazonas', 'AM'], + ['Bahia', 'BA'], + ['Ceará', 'CE'], + ['Distrito Federal', 'DF'], + ['Espírito Santo', 'ES'], + ['Goiás', 'GO'], + ['Maranhão', 'MA'], + ['Mato Grosso', 'MT'], + ['Mato Grosso do Sul', 'MS'], + ['Minas Gerais', 'MG'], + ['Pará', 'PA'], + ['Paraíba', 'PB'], + ['Paraná', 'PR'], + ['Pernambuco', 'PE'], + ['Piauí', 'PI'], + ['Rio de Janeiro', 'RJ'], + ['Rio Grande do Norte', 'RN'], + ['Rio Grande do Sul', 'RS'], + ['Rondônia', 'RO'], + ['Roraima', 'RR'], + ['Santa Catarina', 'SC'], + ['São Paulo', 'SP'], + ['Sergipe', 'SE'], + ['Tocantins', 'TO'], +]) +const stateNames = Array.from(states.keys()) + +export function searchStates(searchTerm: string): ISearchDTO[] { + const regex = new RegExp(`^${searchTerm}`, 'i') + const results = stateNames + .filter((state) => regex.test(state)) + .map((state) => { + return { type: 'state', value: state } + }) + return results +} + +export function getStateAcronym(state: string): string | undefined { + return states.get(state) +} From 9fe8f895443ad13e6fb5ff4c99d704849c188be9 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 2 Sep 2021 13:19:43 -0300 Subject: [PATCH 011/121] Change states filtering --- src/repositories/implementations/InvasionRepository.ts | 6 +++--- .../implementations/ReserveInvasionRepository.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 36afc1e..350a23b 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -28,9 +28,9 @@ class InvasionRepository implements IInvasionRepository { } if (filters.state) { - const acronymsRegex = filters.state - .map((state) => getStateAcronym(state)) - .map((acronym) => new RegExp(`.*${acronym}.*`, 'i')) + const acronymsRegex = filters.state.map( + (state) => new RegExp(`.*${getStateAcronym(state)}.*`, 'i') + ) match['properties.UF'] = { $in: acronymsRegex, } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 30473a8..6232286 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -28,9 +28,9 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { } if (filters.state) { - const acronymsRegex = filters.state - .map((state) => getStateAcronym(state)) - .map((acronym) => new RegExp(`.*${acronym}.*`, 'i')) + const acronymsRegex = filters.state.map( + (state) => new RegExp(`.*${getStateAcronym(state)}.*`, 'i') + ) match['properties.UF'] = { $in: acronymsRegex, } From 2ae51bf440e97345baeda5d2df1bea5a71a91e92 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 2 Sep 2021 15:49:47 -0300 Subject: [PATCH 012/121] Change Readme --- README.md | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 143 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index eed1200..f06f614 100644 --- a/README.md +++ b/README.md @@ -1 +1,143 @@ -# amazonia-minada-back \ No newline at end of file +# Amazonia Minada API + +**Busca Geral** +---- +Método que permite uma busca geral para Estado, Solicitante (Empresa), Terras Indígenas ou Unidades de Conservação, retornando as opções disponíveis no Banco de Dados que são iniciadas com a string fornecida. + +* **URL:** + + /api/search/:searchTerm + +* **Método:** + + `GET` + +* **Parâmetros na URL:** + + **Obrigatórios:** + + - searchTerm:[string] - Palavra que será utilizada na busca + +* **Parâmetros no Body:** + + Nenhum + +* **Exemplo:** + + /api/search/amaz + +* **Resposta:** + + * **Código:** **200**
+ **Conteúdo:** + + ```javascript + [ + { + "type": "state", + "value": "Amazonas" + }, + { + "type": "company", + "value": "AMAZON GLOBAL CONSULT LTDA" + }, + { + "type": "company", + "value": "Amazonas Exploração e Mineração Ltda." + }, + { + "type": "company", + "value": "AMAZON STONE S.A." + }, + { + "type": "company", + "value": "Amazonas Comercio Atacadista de Joias e Participaçoes Ltda Epp" + } + ] + ``` + **Descrição:** Retorna um array de objetos contendo o tipo de dado [company (solicitante), state (estado), reserve (terra indígena) ou unity (unidade de conservação)] e o valor (nome) das opções que são iniciadas pela string determinada. + + * **Código:** **500**
+ **Conteúdo:** + ```javascript + { + message: 'Internal Server Error' + } + ``` + **Descrição:** Erro interno do servidor. + + +**Listar Requerimentos** +---- +Método que permite uma filtragem dos requerimentos minerários em Unidades de Conservação e em Terras Indígenas. + +* **URL:** + + /api/invasions + +* **Método:** + + `POST` + +* **Parâmetros na URL:** + + Nenhum + +* **Parâmetros no Body:** + + ```javascript + { + "filters": { + "state": [], //Array de strings com o nome dos estados + "company": [], //Array de strings com o nome das empresas + "reserve": [], //Array de strings com o nome das Terras Indígenas + "unity": [], //Array de strings com o nome das Unidades de Conservação + } + } + ``` + **Descrição:** Todos os filtros são parâmetros opcionais e podem ser combinados. + +* **Exemplo:** + + **Rota:** + /api/invasions + + **Body:** + ```javascript + { + "filters": { + "state": ["Amazonas"], + "reserve": ["Andirá-Marau"], + "company": ["José Aparecido da Silva"] + } + } + ``` + +* **Resposta:** + + * **Código:** **200**
+ **Conteúdo:** + + ```javascript + [ + { + "company": "José Aparecido da Silva", + "process": "880039/2009", + "area": 9603.9, + "year": 2009, + "state": "AM", + "territory": "Andirá-Marau", + "type": "Terra Indígena" + } + ] + ``` + **Descrição:** Retorna um array de objetos contendo os dados de cada requerimento que se enquadra nos filtros definidos. + + * **Código:** **500**
+ **Conteúdo:** + ```javascript + { + message: 'Internal Server Error' + } + ``` + **Descrição:** Erro interno do servidor. \ No newline at end of file From 0ee577229de1112d5b2b01b126d683e256116cd4 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 2 Sep 2021 15:50:10 -0300 Subject: [PATCH 013/121] Change search to use route param --- src/routes/index.ts | 2 +- src/server.ts | 2 +- src/services/search/SearchController.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/index.ts b/src/routes/index.ts index 88f2c76..cc8c526 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -8,7 +8,7 @@ const router = Router() const searchController = new SearchController() const listInvasionsController = new ListInvasionsController() -router.get('/search', searchController.handle) +router.get('/search/:searchTerm', searchController.handle) router.post('/invasions', listInvasionsController.handle) export { router } diff --git a/src/server.ts b/src/server.ts index f682067..64a2a74 100644 --- a/src/server.ts +++ b/src/server.ts @@ -12,6 +12,6 @@ const app = express() app.use(cors()) app.use(express.json()) app.use(express.urlencoded({ extended: true })) -app.use(router) +app.use('/api', router) app.listen(3333, () => console.log('Server is running!')) diff --git a/src/services/search/SearchController.ts b/src/services/search/SearchController.ts index 7bdae88..0905549 100644 --- a/src/services/search/SearchController.ts +++ b/src/services/search/SearchController.ts @@ -5,7 +5,7 @@ import { SearchService } from './SearchService' class SearchController { async handle(request: Request, response: Response): Promise { - const { searchTerm } = request.query + const { searchTerm } = request.params const searchService = container.resolve(SearchService) From 5acef1e87e5c3b2dc70af475d612b5d25e480811 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 2 Sep 2021 15:57:13 -0300 Subject: [PATCH 014/121] Change Readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f06f614..061ee25 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "company": [], //Array de strings com o nome das empresas "reserve": [], //Array de strings com o nome das Terras Indígenas "unity": [], //Array de strings com o nome das Unidades de Conservação + "year": [], //Array de inteiros com os anos } } ``` From 70e4b5075292738a8e77252a5eb9dfb1c2bbffda Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 3 Sep 2021 10:01:05 -0300 Subject: [PATCH 015/121] Change server port --- src/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server.ts b/src/server.ts index 64a2a74..c049e16 100644 --- a/src/server.ts +++ b/src/server.ts @@ -14,4 +14,4 @@ app.use(express.json()) app.use(express.urlencoded({ extended: true })) app.use('/api', router) -app.listen(3333, () => console.log('Server is running!')) +app.listen(8080, () => console.log('Server is running!')) From c742ea5b3f873ba782e395829b4f0d352e2c83df Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 3 Sep 2021 10:27:14 -0300 Subject: [PATCH 016/121] Change server port in docker files --- Dockerfile | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index cd97e3f..757351c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,6 @@ RUN npm install COPY . . -EXPOSE 3333 +EXPOSE 8080 CMD ["npm","run","dev"] diff --git a/docker-compose.yml b/docker-compose.yml index ed99a47..93000a7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: volumes: - .:/usr/app ports: - - 3333:3333 + - 8080:8080 links: - database depends_on: From 51889e8af87613fd940866fdd4642958f6f30344 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 3 Sep 2021 11:11:34 -0300 Subject: [PATCH 017/121] Change server port in docker files --- Dockerfile | 2 +- docker-compose.yml | 2 +- src/server.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 757351c..466f847 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,6 @@ RUN npm install COPY . . -EXPOSE 8080 +EXPOSE 5000 CMD ["npm","run","dev"] diff --git a/docker-compose.yml b/docker-compose.yml index 93000a7..0c09c8b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: volumes: - .:/usr/app ports: - - 8080:8080 + - 5000:5000 links: - database depends_on: diff --git a/src/server.ts b/src/server.ts index c049e16..04a9b06 100644 --- a/src/server.ts +++ b/src/server.ts @@ -14,4 +14,4 @@ app.use(express.json()) app.use(express.urlencoded({ extended: true })) app.use('/api', router) -app.listen(8080, () => console.log('Server is running!')) +app.listen(5000, () => console.log('Server is running!')) From 733b9dd456c6717eea1615402e2b5c4cd77571b7 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Fri, 3 Sep 2021 12:21:06 -0300 Subject: [PATCH 018/121] Add ranking DTO --- src/dtos/IRankingDTO.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/dtos/IRankingDTO.ts diff --git a/src/dtos/IRankingDTO.ts b/src/dtos/IRankingDTO.ts new file mode 100644 index 0000000..2412577 --- /dev/null +++ b/src/dtos/IRankingDTO.ts @@ -0,0 +1,6 @@ +interface IRankingDTO { + x: string + y: number +} + +export { IRankingDTO } From 9e5735080666b0f34c6b66ef81f6f634cbc93d9a Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 3 Sep 2021 20:13:39 -0300 Subject: [PATCH 019/121] Change dev script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ce5d092..ea69193 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "author": "Iago Machado ", "license": "MIT", "scripts": { - "dev": "ts-node-dev --transpile-only --ignore-watch node_modules --respawn src/server.ts" + "dev": "ts-node-dev --poll --transpile-only --ignore-watch node_modules --respawn src/server.ts" }, "dependencies": { "cors": "^2.8.5", From 107322916d420667533211a1271530fe8e363e5d Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 6 Sep 2021 11:31:51 -0300 Subject: [PATCH 020/121] Create statistics method --- README.md | 80 ++++++++++++++++++- src/dtos/IStatisticsDTO.ts | 14 ++++ .../implementations/InvasionRepository.ts | 24 +++--- .../ReserveInvasionRepository.ts | 24 +++--- src/routes/index.ts | 3 + .../getStatistics/GetStatisticsController.ts | 18 +++++ .../getStatistics/GetStatisticsService.ts | 62 ++++++++++++++ 7 files changed, 203 insertions(+), 22 deletions(-) create mode 100644 src/dtos/IStatisticsDTO.ts create mode 100644 src/services/getStatistics/GetStatisticsController.ts create mode 100644 src/services/getStatistics/GetStatisticsService.ts diff --git a/README.md b/README.md index 061ee25..7eba1ef 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Método que permite uma busca geral para Estado, Solicitante (Empresa), Terras I **Conteúdo:** ```javascript { - message: 'Internal Server Error' + "message": "Internal Server Error" } ``` **Descrição:** Erro interno do servidor. @@ -138,7 +138,83 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C **Conteúdo:** ```javascript { - message: 'Internal Server Error' + "message": "Internal Server Error" + } + ``` + **Descrição:** Erro interno do servidor. + +**Estatísticas** +---- +Método que retorna as estatísticas gerais (número de requerimentos e área) de Terras Indígenas e Unidades de Conservação de acordo com os filtros. + +* **URL:** + + /api/statistics + +* **Método:** + + `POST` + +* **Parâmetros na URL:** + + Nenhum + +* **Parâmetros no Body:** + + ```javascript + { + "filters": { + "state": [], //Array de strings com o nome dos estados + "company": [], //Array de strings com o nome das empresas + "reserve": [], //Array de strings com o nome das Terras Indígenas + "unity": [], //Array de strings com o nome das Unidades de Conservação + "year": [], //Array de inteiros com os anos + } + } + ``` + **Descrição:** Todos os filtros são parâmetros opcionais e podem ser combinados. + +* **Exemplo:** + + **Rota:** + /api/statistics + + **Body:** + ```javascript + { + "filters": { + "state": ["Amazonas"], + "reserve": ["Andirá-Marau"] + } + } + ``` + +* **Resposta:** + + * **Código:** **200**
+ **Conteúdo:** + + ```javascript + { + "requirementsIncidence": { + "reserve": 19, + "unity": 0, + "total": 19 + }, + "requiredArea": { + "reserve": 40742.13, + "unity": 0, + "total": 40742.13 + } + } + ``` + **Descrição:** Retorna um objeto contendo as estatísticas dos requerimentos que se enquadram nos filtros definidos. + + * **Código:** **500**
+ **Conteúdo:** + ```javascript + { + "message": "Internal Server Error" } ``` **Descrição:** Erro interno do servidor. \ No newline at end of file diff --git a/src/dtos/IStatisticsDTO.ts b/src/dtos/IStatisticsDTO.ts new file mode 100644 index 0000000..b83e59b --- /dev/null +++ b/src/dtos/IStatisticsDTO.ts @@ -0,0 +1,14 @@ +interface IStatisticsDTO { + requirementsIncidence: { + reserve: number + unity: number + total: number + } + requiredArea: { + reserve: number + unity: number + total: number + } +} + +export { IStatisticsDTO } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 350a23b..6c07cdd 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -36,16 +36,20 @@ class InvasionRepository implements IInvasionRepository { } } - const invasions = await Invasion.find(match, { - company: '$properties.NOME', - process: '$properties.PROCESSO', - area: '$properties.AREA_HA', - year: '$properties.ANO', - state: '$properties.UF', - territory: '$properties.UC_NOME', - type: 'Unidade de Conservação', - _id: 0, - }) + const invasions = await Invasion.find( + match, + { + company: '$properties.NOME', + process: '$properties.PROCESSO', + area: '$properties.AREA_HA', + year: '$properties.ANO', + state: '$properties.UF', + territory: '$properties.UC_NOME', + type: 'Unidade de Conservação', + _id: 0, + }, + { lean: true } + ) return invasions } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 6232286..61d3c0a 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -36,16 +36,20 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { } } - const invasions = await ReserveInvasion.find(match, { - company: '$properties.NOME', - process: '$properties.PROCESSO', - area: '$properties.AREA_HA', - year: '$properties.ANO', - state: '$properties.UF', - territory: '$properties.TI_NOME', - type: 'Terra Indígena', - _id: 0, - }) + const invasions = await ReserveInvasion.find( + match, + { + company: '$properties.NOME', + process: '$properties.PROCESSO', + area: '$properties.AREA_HA', + year: '$properties.ANO', + state: '$properties.UF', + territory: '$properties.TI_NOME', + type: 'Terra Indígena', + _id: 0, + }, + { lean: true } + ) return invasions } diff --git a/src/routes/index.ts b/src/routes/index.ts index cc8c526..980f013 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,5 +1,6 @@ import { Router } from 'express' +import { GetStatisticsController } from '../services/getStatistics/GetStatisticsController' import { ListInvasionsController } from '../services/listInvasions/ListInvasionsController' import { SearchController } from '../services/search/SearchController' @@ -7,8 +8,10 @@ const router = Router() const searchController = new SearchController() const listInvasionsController = new ListInvasionsController() +const getStatisticsController = new GetStatisticsController() router.get('/search/:searchTerm', searchController.handle) router.post('/invasions', listInvasionsController.handle) +router.post('/statistics', getStatisticsController.handle) export { router } diff --git a/src/services/getStatistics/GetStatisticsController.ts b/src/services/getStatistics/GetStatisticsController.ts new file mode 100644 index 0000000..e84daa1 --- /dev/null +++ b/src/services/getStatistics/GetStatisticsController.ts @@ -0,0 +1,18 @@ +import { Request, Response } from 'express' +import { container } from 'tsyringe' + +import { GetStatisticsService } from './GetStatisticsService' + +class GetStatisticsController { + async handle(request: Request, response: Response): Promise { + const { filters } = request.body + + const getStatisticsService = container.resolve(GetStatisticsService) + + const statistics = await getStatisticsService.execute(filters) + + return response.json(statistics) + } +} + +export { GetStatisticsController } diff --git a/src/services/getStatistics/GetStatisticsService.ts b/src/services/getStatistics/GetStatisticsService.ts new file mode 100644 index 0000000..a2ac763 --- /dev/null +++ b/src/services/getStatistics/GetStatisticsService.ts @@ -0,0 +1,62 @@ +import { inject, injectable } from 'tsyringe' + +import { IFiltersDTO } from '../../dtos/IFiltersDTO' +import { IStatisticsDTO } from '../../dtos/IStatisticsDTO' +import { IInvasionRepository } from '../../repositories/IInvasionRepository' +import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' + +@injectable() +class GetStatisticsService { + constructor( + @inject('ReserveInvasionRepository') + private reserveInvasionRepository: IReserveInvasionRepository, + + @inject('InvasionRepository') + private invasionRepository: IInvasionRepository + ) {} + + async execute(filters: IFiltersDTO): Promise { + const statistics: IStatisticsDTO = { + requirementsIncidence: { + reserve: 0, + unity: 0, + total: 0, + }, + requiredArea: { + reserve: 0.0, + unity: 0.0, + total: 0.0, + }, + } + + if ((!filters.reserve && !filters.unity) || filters.reserve) { + const reserveInvasions = + await this.reserveInvasionRepository.listInvasions(filters) + statistics.requirementsIncidence.reserve = reserveInvasions.length + + let sumArea = 0.0 + reserveInvasions.forEach((invasion) => (sumArea += invasion.area || 0)) + statistics.requiredArea.reserve = parseFloat(sumArea.toFixed(2)) + } + + if ((!filters.reserve && !filters.unity) || filters.unity) { + const invasions = await this.invasionRepository.listInvasions(filters) + statistics.requirementsIncidence.unity = invasions.length + + let sumArea = 0.0 + invasions.forEach((invasion) => (sumArea += invasion.area || 0)) + statistics.requiredArea.unity = parseFloat(sumArea.toFixed(2)) + } + + statistics.requirementsIncidence.total = + statistics.requirementsIncidence.reserve + + statistics.requirementsIncidence.unity + + statistics.requiredArea.total = + statistics.requiredArea.reserve + statistics.requiredArea.unity + + return statistics + } +} + +export { GetStatisticsService } From 02b2e0aa11c93d4033143fb860cd629567cc8da8 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 6 Sep 2021 12:01:23 -0300 Subject: [PATCH 021/121] Create dockerignore --- .dockerignore | 4 ++++ Dockerfile | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6dd488b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +node_modules +.git +.vscode +sysbkp \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 466f847..69f8b64 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node +FROM node:latest WORKDIR /usr/app From 85ecb79787d69f39e59f7f9d7d0b1ab9e68e5507 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 6 Sep 2021 12:13:17 -0300 Subject: [PATCH 022/121] Change ts-node-dev path in dev script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ea69193..b8f13b6 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "author": "Iago Machado ", "license": "MIT", "scripts": { - "dev": "ts-node-dev --poll --transpile-only --ignore-watch node_modules --respawn src/server.ts" + "dev": "./node_modules/.bin/ts-node-dev --transpile-only --ignore-watch node_modules --respawn src/server.ts" }, "dependencies": { "cors": "^2.8.5", From 68797679cd0ee874af9c9fd99b9da65bd5386f79 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Wed, 8 Sep 2021 12:08:50 -0300 Subject: [PATCH 023/121] Add Dto for ranking requests --- src/dtos/IRankingDTO.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dtos/IRankingDTO.ts b/src/dtos/IRankingDTO.ts index 2412577..c9813c7 100644 --- a/src/dtos/IRankingDTO.ts +++ b/src/dtos/IRankingDTO.ts @@ -1,6 +1,12 @@ -interface IRankingDTO { +interface IResponseRankingDTO { x: string y: number } -export { IRankingDTO } +interface IRequestRankingDTO { + territoryType: string + page: number + dataType: string +} + +export { IRequestRankingDTO, IResponseRankingDTO } From 472300ae477752b8adab09e6ef1056381c52951a Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Wed, 8 Sep 2021 12:09:11 -0300 Subject: [PATCH 024/121] Add method signature on the interface --- src/repositories/IInvasionRepository.ts | 5 +++++ src/repositories/IReserveInvasionRepository.ts | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/repositories/IInvasionRepository.ts b/src/repositories/IInvasionRepository.ts index 45d8052..4b07cd6 100644 --- a/src/repositories/IInvasionRepository.ts +++ b/src/repositories/IInvasionRepository.ts @@ -1,10 +1,15 @@ import { IFiltersDTO } from '../dtos/IFiltersDTO' import { IInvasionDTO } from '../dtos/IInvasionDTO' +import { IRequestRankingDTO, IResponseRankingDTO } from '../dtos/IRankingDTO' import { ISearchDTO } from '../dtos/ISearchDTO' interface IInvasionRepository { searchCompany(searchTerm: string): Promise listInvasions(filters: IFiltersDTO): Promise + invasionRanking({ + territoryType, + dataType, + }: IRequestRankingDTO): Promise } export { IInvasionRepository } diff --git a/src/repositories/IReserveInvasionRepository.ts b/src/repositories/IReserveInvasionRepository.ts index 4d843e0..91d9c32 100644 --- a/src/repositories/IReserveInvasionRepository.ts +++ b/src/repositories/IReserveInvasionRepository.ts @@ -1,10 +1,15 @@ import { IFiltersDTO } from '../dtos/IFiltersDTO' import { IInvasionDTO } from '../dtos/IInvasionDTO' +import { IRequestRankingDTO, IResponseRankingDTO } from '../dtos/IRankingDTO' import { ISearchDTO } from '../dtos/ISearchDTO' interface IReserveInvasionRepository { searchCompany(searchTerm: string): Promise listInvasions(filters: IFiltersDTO): Promise + reserveInvasionRanking({ + territoryType, + dataType, + }: IRequestRankingDTO): Promise } export { IReserveInvasionRepository } From a9e68ddaca277f7890ad6d19f26f497570e32c54 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Wed, 8 Sep 2021 12:09:34 -0300 Subject: [PATCH 025/121] Add ranking method --- .../implementations/InvasionRepository.ts | 31 +++++++++++++++++ .../ReserveInvasionRepository.ts | 33 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 350a23b..a764488 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -1,7 +1,9 @@ import { Invasion } from '../../database/models/Invasion' import { IFiltersDTO } from '../../dtos/IFiltersDTO' import { IInvasionDTO } from '../../dtos/IInvasionDTO' +import { IRequestRankingDTO, IResponseRankingDTO } from '../../dtos/IRankingDTO' import { ISearchDTO } from '../../dtos/ISearchDTO' +import { rankingFilter } from '../../utils/rankingFilter' import { getStateAcronym } from '../../utils/states' import { IInvasionRepository } from '../IInvasionRepository' @@ -71,6 +73,35 @@ class InvasionRepository implements IInvasionRepository { ]) return companies } + + async invasionRanking({ + territoryType, + dataType, + }: IRequestRankingDTO): Promise { + const propertie = rankingFilter[territoryType] + let aggregation + if (dataType === 'frequency') { + aggregation = 1 + } else if (dataType === 'value') { + aggregation = '$properties.AREA_HA' + } + const territories = await Invasion.aggregate([ + { + $group: { + _id: propertie, + count: { $sum: aggregation }, + }, + }, + { + $project: { + x: '$_id', + y: '$count', + _id: 0, + }, + }, + ]) + return territories + } } export { InvasionRepository } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 6232286..3b82264 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -1,7 +1,9 @@ import { ReserveInvasion } from '../../database/models/ReserveInvasion' import { IFiltersDTO } from '../../dtos/IFiltersDTO' import { IInvasionDTO } from '../../dtos/IInvasionDTO' +import { IRequestRankingDTO, IResponseRankingDTO } from '../../dtos/IRankingDTO' import { ISearchDTO } from '../../dtos/ISearchDTO' +import { rankingFilter } from '../../utils/rankingFilter' import { getStateAcronym } from '../../utils/states' import { IReserveInvasionRepository } from '../IReserveInvasionRepository' @@ -72,6 +74,37 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { ]) return companies } + + async reserveInvasionRanking({ + territoryType, + dataType, + }: IRequestRankingDTO): Promise { + const propertie = rankingFilter[territoryType] + let aggregation + if (dataType === 'frequency') { + aggregation = 1 + } else if (dataType === 'value') { + aggregation = '$properties.AREA_HA' + } + const territories = await ReserveInvasion.aggregate([ + { + $group: { + _id: propertie, + count: { $sum: aggregation }, + }, + }, + { $sort: { count: -1 } }, + { + $project: { + x: '$_id', + y: '$count', + _id: 0, + }, + }, + ]) + + return territories + } } export { ReserveInvasionRepository } From e18d8d4b61bf8ed3972dddd5ce18094ee8f2278e Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Wed, 8 Sep 2021 12:09:44 -0300 Subject: [PATCH 026/121] Add ranking service --- .../InvasionRankingService.ts | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/services/invasionFrequencyRanking/InvasionRankingService.ts diff --git a/src/services/invasionFrequencyRanking/InvasionRankingService.ts b/src/services/invasionFrequencyRanking/InvasionRankingService.ts new file mode 100644 index 0000000..a150a96 --- /dev/null +++ b/src/services/invasionFrequencyRanking/InvasionRankingService.ts @@ -0,0 +1,132 @@ +import { inject, injectable } from 'tsyringe' + +import { IRequestRankingDTO, IResponseRankingDTO } from '../../dtos/IRankingDTO' +import { IInvasionRepository } from '../../repositories/IInvasionRepository' +import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { paginate } from '../../utils/pagination' +import { getStateFromAcronym } from '../../utils/states' + +@injectable() +class InvasionFrequencyService { + constructor( + @inject('ReserveInvasionRepository') + private reserveInvasionRepository: IReserveInvasionRepository, + @inject('InvasionRepository') + private invasionRepository: IInvasionRepository + ) {} + + async execute({ territoryType, page, dataType }: IRequestRankingDTO) { + const name = + dataType === 'frequency' ? 'requirementsIncidence' : 'requiredArea' + if (territoryType === 'state' || territoryType === 'company') { + const reserveResults = + await this.reserveInvasionRepository.reserveInvasionRanking({ + territoryType, + page, + dataType, + }) + const invasionResults = await this.invasionRepository.invasionRanking({ + territoryType, + page, + dataType, + }) + return await this.formatDoubleRanking( + reserveResults, + invasionResults, + territoryType, + page + ) + } else if (territoryType === 'unity') { + const results = await this.invasionRepository.invasionRanking({ + territoryType, + page, + dataType, + }) + return await this.formatSingleRanking(results, name, page) + } else if (territoryType === 'reserve') { + const results = + await this.reserveInvasionRepository.reserveInvasionRanking({ + territoryType, + page, + dataType, + }) + return await this.formatSingleRanking(results, name, page) + } + } + + async formatSingleRanking( + results: IResponseRankingDTO[], + name: string, + page: number + ) { + const x: string[] = [] + const y: number[] = [] + const pos: number[] = [] + results.forEach((invasion, i) => { + x.push(invasion.x) + y.push(invasion.y) + pos.push(i + 1) + }) + return { + x: paginate(x, page), + position: paginate(pos, page), + series: [{ name: name, data: paginate(y, page) }], + pageAmount: Math.ceil(y.length / 5), + } + } + + async formatDoubleRanking( + invasionResults: IResponseRankingDTO[], + reserveResults: IResponseRankingDTO[], + territoryType: string, + page: number + ) { + const x: string[] = [] + const invasionY: number[] = [] + const reserveY: number[] = [] + const newRanking: any[] = [] + const pos: number[] = [] + invasionResults.forEach((invasion) => { + const reserve = reserveResults.find((reserve) => reserve.x === invasion.x) + newRanking.push({ + name: invasion.x, + invasionValue: invasion.y, + reserveValue: reserve?.y || 0, + total: (reserve?.y || 0) + invasion.y, + }) + }) + newRanking + .sort((a, b) => { + if (a.total > b.total) return -1 + if (a.total < b.total) return 1 + return 0 + }) + .forEach((element, i) => { + if (territoryType === 'state') { + x.push(getStateFromAcronym(element.name)) + } else { + x.push(element.name) + } + invasionY.push(element.invasionValue) + reserveY.push(element.reserveValue) + pos.push(i + 1) + }) + return { + x: paginate(x, page), + position: paginate(pos, page), + series: [ + { + name: 'indigenousLand', + data: paginate(invasionY, page), + }, + { + name: 'protectedArea', + data: paginate(reserveY, page), + }, + ], + pageAmount: Math.ceil(newRanking.length / 5), + } + } +} + +export { InvasionFrequencyService } From 83c800efcd7a0169088feb2f15e81f46e1751d97 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Wed, 8 Sep 2021 12:09:55 -0300 Subject: [PATCH 027/121] Add ranking method controller --- .../InvasionRankingController.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/services/invasionFrequencyRanking/InvasionRankingController.ts diff --git a/src/services/invasionFrequencyRanking/InvasionRankingController.ts b/src/services/invasionFrequencyRanking/InvasionRankingController.ts new file mode 100644 index 0000000..cd16ab8 --- /dev/null +++ b/src/services/invasionFrequencyRanking/InvasionRankingController.ts @@ -0,0 +1,20 @@ +import { Request, Response } from 'express' +import { container } from 'tsyringe' + +import { InvasionFrequencyService } from './InvasionRankingService' + +class InvasionFrequencyController { + async handle(request: Request, response: Response): Promise { + const { territoryType, dataType } = request.params + const { page } = request.query + const invasionFrequencyService = container.resolve(InvasionFrequencyService) + const rankingData = await invasionFrequencyService.execute({ + territoryType, + dataType, + page: Number(page), + }) + return response.status(200).json(rankingData) + } +} + +export { InvasionFrequencyController } From b0d44472c6b4cc28b236e6fbfaf598e569c6a172 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Wed, 8 Sep 2021 12:10:06 -0300 Subject: [PATCH 028/121] Add ranking route --- src/routes/index.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/routes/index.ts b/src/routes/index.ts index cc8c526..31f8d6a 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,5 +1,6 @@ import { Router } from 'express' +import { InvasionFrequencyController } from '../services/invasionFrequencyRanking/InvasionRankingController' import { ListInvasionsController } from '../services/listInvasions/ListInvasionsController' import { SearchController } from '../services/search/SearchController' @@ -7,8 +8,13 @@ const router = Router() const searchController = new SearchController() const listInvasionsController = new ListInvasionsController() +const invasionFrequencyController = new InvasionFrequencyController() router.get('/search/:searchTerm', searchController.handle) router.post('/invasions', listInvasionsController.handle) +router.get( + '/invasions/ranking/:territoryType/:dataType', + invasionFrequencyController.handle +) export { router } From 4598e090073ff3d1c2f29e33ca4ee7618dd71399 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Wed, 8 Sep 2021 12:10:17 -0300 Subject: [PATCH 029/121] Add method to paginate ranking --- src/utils/pagination.ts | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/utils/pagination.ts diff --git a/src/utils/pagination.ts b/src/utils/pagination.ts new file mode 100644 index 0000000..80975b3 --- /dev/null +++ b/src/utils/pagination.ts @@ -0,0 +1,4 @@ +function paginate(array: any[], page: number) { + return array.slice((page - 1) * 5, page * 5) +} +export { paginate } From 689fdac401c4210b0df8982849dde611f770f083 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Wed, 8 Sep 2021 12:10:47 -0300 Subject: [PATCH 030/121] Add method to get ranking filter property --- src/utils/rankingFilter.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/utils/rankingFilter.ts diff --git a/src/utils/rankingFilter.ts b/src/utils/rankingFilter.ts new file mode 100644 index 0000000..808de51 --- /dev/null +++ b/src/utils/rankingFilter.ts @@ -0,0 +1,12 @@ +type filterOptions = { + [key: string]: string +} + +const rankingFilter: filterOptions = { + state: '$properties.UF', + reserve: '$properties.TI_NOME', + unity: '$properties.UC_NOME', + company: '$properties.NOME', +} + +export { rankingFilter } From 863f5f77c4001ebac693bc0a07be908ecebc0038 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Wed, 8 Sep 2021 12:11:02 -0300 Subject: [PATCH 031/121] Add mthod to get state name from its acronym --- src/utils/states.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/utils/states.ts b/src/utils/states.ts index 417c133..8400bd9 100644 --- a/src/utils/states.ts +++ b/src/utils/states.ts @@ -44,3 +44,7 @@ export function searchStates(searchTerm: string): ISearchDTO[] { export function getStateAcronym(state: string): string | undefined { return states.get(state) } + +export function getStateFromAcronym(acronym: string): string { + return stateNames.find((key) => states.get(key) === acronym) || acronym +} From e34e7836311e16e5519d2c99e709855cd82fd3fa Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Thu, 9 Sep 2021 10:14:57 -0300 Subject: [PATCH 032/121] Change directory name --- .../InvasionRankingController.ts | 0 .../InvasionRankingService.ts | 6 ++---- 2 files changed, 2 insertions(+), 4 deletions(-) rename src/services/{invasionFrequencyRanking => invasionRanking}/InvasionRankingController.ts (100%) rename src/services/{invasionFrequencyRanking => invasionRanking}/InvasionRankingService.ts (94%) diff --git a/src/services/invasionFrequencyRanking/InvasionRankingController.ts b/src/services/invasionRanking/InvasionRankingController.ts similarity index 100% rename from src/services/invasionFrequencyRanking/InvasionRankingController.ts rename to src/services/invasionRanking/InvasionRankingController.ts diff --git a/src/services/invasionFrequencyRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts similarity index 94% rename from src/services/invasionFrequencyRanking/InvasionRankingService.ts rename to src/services/invasionRanking/InvasionRankingService.ts index a150a96..8ab45a0 100644 --- a/src/services/invasionFrequencyRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -16,8 +16,6 @@ class InvasionFrequencyService { ) {} async execute({ territoryType, page, dataType }: IRequestRankingDTO) { - const name = - dataType === 'frequency' ? 'requirementsIncidence' : 'requiredArea' if (territoryType === 'state' || territoryType === 'company') { const reserveResults = await this.reserveInvasionRepository.reserveInvasionRanking({ @@ -42,7 +40,7 @@ class InvasionFrequencyService { page, dataType, }) - return await this.formatSingleRanking(results, name, page) + return await this.formatSingleRanking(results, dataType, page) } else if (territoryType === 'reserve') { const results = await this.reserveInvasionRepository.reserveInvasionRanking({ @@ -50,7 +48,7 @@ class InvasionFrequencyService { page, dataType, }) - return await this.formatSingleRanking(results, name, page) + return await this.formatSingleRanking(results, dataType, page) } } From 3b19b527ed4f739913b89496d4b2e56a27924d2b Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Thu, 9 Sep 2021 10:15:22 -0300 Subject: [PATCH 033/121] change dataTypes name --- src/repositories/implementations/InvasionRepository.ts | 4 ++-- src/repositories/implementations/ReserveInvasionRepository.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 6a8e5e8..b43b439 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -84,9 +84,9 @@ class InvasionRepository implements IInvasionRepository { }: IRequestRankingDTO): Promise { const propertie = rankingFilter[territoryType] let aggregation - if (dataType === 'frequency') { + if (dataType === 'incidenceRequirements') { aggregation = 1 - } else if (dataType === 'value') { + } else if (dataType === 'requiredArea') { aggregation = '$properties.AREA_HA' } const territories = await Invasion.aggregate([ diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index b232124..130cd49 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -85,9 +85,9 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { }: IRequestRankingDTO): Promise { const propertie = rankingFilter[territoryType] let aggregation - if (dataType === 'frequency') { + if (dataType === 'incidenceRequirements') { aggregation = 1 - } else if (dataType === 'value') { + } else if (dataType === 'requiredArea') { aggregation = '$properties.AREA_HA' } const territories = await ReserveInvasion.aggregate([ From d14b289b9e7ba53a2405361a99ede093e5c43fe3 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Thu, 9 Sep 2021 10:16:05 -0300 Subject: [PATCH 034/121] Resolve merge conflict --- src/routes/index.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/routes/index.ts b/src/routes/index.ts index 91d228a..352bb7b 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,7 +1,7 @@ import { Router } from 'express' import { GetStatisticsController } from '../services/getStatistics/GetStatisticsController' -import { InvasionFrequencyController } from '../services/invasionFrequencyRanking/InvasionRankingController' +import { InvasionFrequencyController } from '../services/invasionRanking/InvasionRankingController' import { ListInvasionsController } from '../services/listInvasions/ListInvasionsController' import { SearchController } from '../services/search/SearchController' @@ -10,6 +10,7 @@ const router = Router() const searchController = new SearchController() const listInvasionsController = new ListInvasionsController() const invasionFrequencyController = new InvasionFrequencyController() +const getStatisticsController = new GetStatisticsController() router.get('/search/:searchTerm', searchController.handle) router.post('/invasions', listInvasionsController.handle) @@ -17,10 +18,6 @@ router.get( '/invasions/ranking/:territoryType/:dataType', invasionFrequencyController.handle ) -const getStatisticsController = new GetStatisticsController() - -router.get('/search/:searchTerm', searchController.handle) -router.post('/invasions', listInvasionsController.handle) router.post('/statistics', getStatisticsController.handle) export { router } From b01c04620d976027e17188be8fe9ef5fb4932612 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Thu, 9 Sep 2021 10:16:17 -0300 Subject: [PATCH 035/121] Add ranking documentation --- README.md | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7eba1ef..567905d 100644 --- a/README.md +++ b/README.md @@ -217,4 +217,88 @@ Método que retorna as estatísticas gerais (número de requerimentos e área) d "message": "Internal Server Error" } ``` - **Descrição:** Erro interno do servidor. \ No newline at end of file + **Descrição:** Erro interno do servidor. + +**Ranking de frequência e de área** +---- +Método que retorna o ranking de acordo com o território e o tipo de dado especificado + +* **URL:** + + /api/invasions/ranking/:territoryType/:dataType + +* **Método:** + + `GET` + +* **Parâmetros na URL:** + + - territoryType:[string] - Tipo de território a ser utilizado na construção do ranking('company', 'state', 'unity', 'reserve'). + - dataType:[string] - Tipo de dado a ser retornado, 'incidenceRequiriments' para a frequencia de requerimentos em território e 'requiredArea' para área total dos requerimentos por território. + - page?:[number] - Número da página de registros a ser retornada, retorna todos os registros caso um número não seja informado. + +* **Parâmetros no Body:** + + Nenhum + +* **Exemplo:** + + **Rota:** + /api/invasions/ranking/company/value?page=1 + +* **Resposta:** + + * **Código:** **200**
+ **Conteúdo:** + + ```javascript + { + "x": [ + "VALE S.A.", + "MINERAÇÃO SERRA MORENA LTDA", + "Iguape Sociedade de Mineração Iguape Ltda", + "Rio Grande Mineração S A", + "Mineração Guanhães Ltda" + ], + "position": [ + 1, + 2, + 3, + 4, + 5 + ], + "series": [ + { + "name": "indigenousLand", + "data": [ + 447938.31, + 469529.25, + 446421.21, + 429561.29, + 276058.67 + ] + }, + { + "name": "protectedArea", + "data": [ + 112761.6, + 49983.95, + 0, + 7460.83, + 80000 + ] + } + ], + "pageAmount": 125 + } + ``` + **Descrição:** Retorna um array de series que contém os valores de cada tipo de dado, um array com as respectivas posições e um com os nomes dos territórios. + + * **Código:** **500**
+ **Conteúdo:** + ```javascript + { + "message": "Internal Server Error" + } + ``` + **Descrição:** Erro interno do servidor. From 51afe5747ca179888dfba5436730f4111cd26777 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 9 Sep 2021 10:42:04 -0300 Subject: [PATCH 036/121] Create pagination function and add pagination to invasion listing --- src/dtos/IPaginationDTO.ts | 6 ++++++ .../implementations/ReserveRepository.ts | 2 +- .../implementations/UnityRepository.ts | 2 +- .../listInvasions/ListInvasionsController.ts | 8 ++++++-- .../listInvasions/ListInvasionsService.ts | 15 +++++++++++++-- src/utils/pagination.ts | 14 ++++++++++++++ 6 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 src/dtos/IPaginationDTO.ts create mode 100644 src/utils/pagination.ts diff --git a/src/dtos/IPaginationDTO.ts b/src/dtos/IPaginationDTO.ts new file mode 100644 index 0000000..3451654 --- /dev/null +++ b/src/dtos/IPaginationDTO.ts @@ -0,0 +1,6 @@ +interface IPaginationDTO { + values: any[] + pages: number +} + +export { IPaginationDTO } diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts index 1a035f8..dcff10e 100644 --- a/src/repositories/implementations/ReserveRepository.ts +++ b/src/repositories/implementations/ReserveRepository.ts @@ -13,7 +13,7 @@ class ReserveRepository implements IReserveRepository { value: '$properties.terrai_nom', _id: 0, } - ) + ).sort({ value: 1 }) return reserves } } diff --git a/src/repositories/implementations/UnityRepository.ts b/src/repositories/implementations/UnityRepository.ts index fa3be6a..d6c6fcf 100644 --- a/src/repositories/implementations/UnityRepository.ts +++ b/src/repositories/implementations/UnityRepository.ts @@ -13,7 +13,7 @@ class UnityRepository implements IUnityRepository { value: '$properties.nome', _id: 0, } - ) + ).sort({ value: 1 }) return unities } } diff --git a/src/services/listInvasions/ListInvasionsController.ts b/src/services/listInvasions/ListInvasionsController.ts index 517f42d..615d422 100644 --- a/src/services/listInvasions/ListInvasionsController.ts +++ b/src/services/listInvasions/ListInvasionsController.ts @@ -5,11 +5,15 @@ import { ListInvasionsService } from './ListInvasionsService' class ListInvasionsController { async handle(request: Request, response: Response): Promise { - const { filters } = request.body + const { filters, page, pageSize } = request.body const listInvasionsService = container.resolve(ListInvasionsService) - const invasions = await listInvasionsService.execute(filters) + const invasions = await listInvasionsService.execute( + filters, + page, + pageSize + ) return response.json(invasions) } diff --git a/src/services/listInvasions/ListInvasionsService.ts b/src/services/listInvasions/ListInvasionsService.ts index c0ef525..09de46d 100644 --- a/src/services/listInvasions/ListInvasionsService.ts +++ b/src/services/listInvasions/ListInvasionsService.ts @@ -2,8 +2,10 @@ import { inject, injectable } from 'tsyringe' import { IFiltersDTO } from '../../dtos/IFiltersDTO' import { IInvasionDTO } from '../../dtos/IInvasionDTO' +import { IPaginationDTO } from '../../dtos/IPaginationDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { paginate } from '../../utils/pagination' @injectable() class ListInvasionsService { @@ -15,7 +17,11 @@ class ListInvasionsService { private invasionRepository: IInvasionRepository ) {} - async execute(filters: IFiltersDTO): Promise { + async execute( + filters: IFiltersDTO, + page: number = 1, + pageSize: number = 10 + ): Promise { let reserveInvasions: IInvasionDTO[] = [] let invasions: IInvasionDTO[] = [] @@ -30,8 +36,13 @@ class ListInvasionsService { } const results = invasions.concat(reserveInvasions) + const sortedResults = results.sort((a, b) => { + if (a.company > b.company) return 1 + if (a.company < b.company) return -1 + return 0 + }) - return results + return paginate(sortedResults, page, pageSize) } } diff --git a/src/utils/pagination.ts b/src/utils/pagination.ts new file mode 100644 index 0000000..dabcd3c --- /dev/null +++ b/src/utils/pagination.ts @@ -0,0 +1,14 @@ +import { IPaginationDTO } from '../dtos/IPaginationDTO' + +export function paginate( + values: any[], + page: number, + pageSize: number +): IPaginationDTO { + const arraySize = values.length + const pages = Math.ceil(arraySize / pageSize) + const offset = (page - 1) * pageSize + + const pageValues = values.slice(offset, offset + pageSize) + return { values: pageValues, pages } +} From 94aff2b5f18214f141739b4cdf1fbca743c15f0c Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Thu, 9 Sep 2021 10:47:23 -0300 Subject: [PATCH 037/121] Change pagination method --- .../invasionRanking/InvasionRankingService.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index 8ab45a0..d501fe7 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -66,10 +66,10 @@ class InvasionFrequencyService { pos.push(i + 1) }) return { - x: paginate(x, page), - position: paginate(pos, page), - series: [{ name: name, data: paginate(y, page) }], - pageAmount: Math.ceil(y.length / 5), + x: paginate(x, page, 5).values, + position: paginate(pos, page, 5).values, + series: [{ name: name, data: paginate(y, page, 5).values }], + pageAmount: paginate(pos, page, 5).pages, } } @@ -110,19 +110,19 @@ class InvasionFrequencyService { pos.push(i + 1) }) return { - x: paginate(x, page), - position: paginate(pos, page), + x: paginate(x, page, 5).values, + position: paginate(pos, page, 5).values, series: [ { name: 'indigenousLand', - data: paginate(invasionY, page), + data: paginate(invasionY, page, 5).values, }, { name: 'protectedArea', - data: paginate(reserveY, page), + data: paginate(reserveY, page, 5).values, }, ], - pageAmount: Math.ceil(newRanking.length / 5), + pageAmount: paginate(pos, page, 5).pages, } } } From b66022fc920474cc8a0e3ffd73702871c3938ddc Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 9 Sep 2021 11:04:13 -0300 Subject: [PATCH 038/121] Change pagination params to query --- src/repositories/implementations/ReserveRepository.ts | 2 +- src/services/listInvasions/ListInvasionsController.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts index dcff10e..1a035f8 100644 --- a/src/repositories/implementations/ReserveRepository.ts +++ b/src/repositories/implementations/ReserveRepository.ts @@ -13,7 +13,7 @@ class ReserveRepository implements IReserveRepository { value: '$properties.terrai_nom', _id: 0, } - ).sort({ value: 1 }) + ) return reserves } } diff --git a/src/services/listInvasions/ListInvasionsController.ts b/src/services/listInvasions/ListInvasionsController.ts index 615d422..ddf0138 100644 --- a/src/services/listInvasions/ListInvasionsController.ts +++ b/src/services/listInvasions/ListInvasionsController.ts @@ -5,14 +5,15 @@ import { ListInvasionsService } from './ListInvasionsService' class ListInvasionsController { async handle(request: Request, response: Response): Promise { - const { filters, page, pageSize } = request.body + const { filters } = request.body + const { page, pageSize } = request.query const listInvasionsService = container.resolve(ListInvasionsService) const invasions = await listInvasionsService.execute( filters, - page, - pageSize + Number(page) || undefined, + Number(pageSize) || undefined ) return response.json(invasions) From 46bd511afc742a8506dd14fc9b2a54e43393b461 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 9 Sep 2021 11:11:58 -0300 Subject: [PATCH 039/121] Change Readme --- README.md | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 567905d..cb76c61 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,8 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C * **Parâmetros na URL:** - Nenhum + - page?:[number] - Número da página de registros a ser retornada, retorna a primeira página caso um número não seja informado. + - pageSize?:[number] - Número de requerimentos por página, caso não seja informado são retornados 10 por página. * **Parâmetros no Body:** @@ -101,15 +102,14 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C * **Exemplo:** **Rota:** - /api/invasions + /api/invasions?page=1&pageSize=2 **Body:** ```javascript { "filters": { "state": ["Amazonas"], - "reserve": ["Andirá-Marau"], - "company": ["José Aparecido da Silva"] + "reserve": ["Andirá-Marau"] } } ``` @@ -120,19 +120,31 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C **Conteúdo:** ```javascript - [ - { - "company": "José Aparecido da Silva", - "process": "880039/2009", - "area": 9603.9, - "year": 2009, - "state": "AM", - "territory": "Andirá-Marau", - "type": "Terra Indígena" - } - ] + { + "values": [ + { + "company": "Falcon Metais Ltda", + "process": "880816/2008", + "area": 9928.68, + "year": 2008, + "state": "AM", + "territory": "Andirá-Marau", + "type": "Terra Indígena" + }, + { + "company": "Falcon Metais Ltda", + "process": "880819/2008", + "area": 9932.87, + "year": 2008, + "state": "AM", + "territory": "Andirá-Marau", + "type": "Terra Indígena" + } + ], + "pages": 10 + } ``` - **Descrição:** Retorna um array de objetos contendo os dados de cada requerimento que se enquadra nos filtros definidos. + **Descrição:** Retorna um array de objetos contendo os dados de cada requerimento que se enquadra nos filtros definidos e o número de páginas. * **Código:** **500**
**Conteúdo:** From 1ca4e6b8be49de6e27fbdf705db6fb5c12c126a0 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Thu, 9 Sep 2021 14:26:10 -0300 Subject: [PATCH 040/121] Change object key to id --- src/services/invasionRanking/InvasionRankingService.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index d501fe7..3f065a3 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -68,7 +68,7 @@ class InvasionFrequencyService { return { x: paginate(x, page, 5).values, position: paginate(pos, page, 5).values, - series: [{ name: name, data: paginate(y, page, 5).values }], + series: [{ id: name, data: paginate(y, page, 5).values }], pageAmount: paginate(pos, page, 5).pages, } } @@ -114,11 +114,11 @@ class InvasionFrequencyService { position: paginate(pos, page, 5).values, series: [ { - name: 'indigenousLand', + id: 'indigenousLand', data: paginate(invasionY, page, 5).values, }, { - name: 'protectedArea', + id: 'protectedArea', data: paginate(reserveY, page, 5).values, }, ], From 10bf13f5addcbff4be3955a88e9d03a7c82844fa Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 9 Sep 2021 14:26:48 -0300 Subject: [PATCH 041/121] Create error handler --- package.json | 1 + src/errors/AppError.ts | 10 ++++++++++ src/errors/index.ts | 18 ++++++++++++++++++ src/server.ts | 3 +++ yarn.lock | 5 +++++ 5 files changed, 37 insertions(+) create mode 100644 src/errors/AppError.ts create mode 100644 src/errors/index.ts diff --git a/package.json b/package.json index b8f13b6..401d1c5 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "cors": "^2.8.5", "dotenv-safe": "^8.2.0", "express": "^4.17.1", + "express-async-errors": "^3.1.1", "mongoose": "^6.0.0", "reflect-metadata": "^0.1.13", "tsyringe": "^4.6.0" diff --git a/src/errors/AppError.ts b/src/errors/AppError.ts new file mode 100644 index 0000000..4a78b69 --- /dev/null +++ b/src/errors/AppError.ts @@ -0,0 +1,10 @@ +export class AppError { + public readonly message: string + + public readonly statusCode: number + + constructor(message: string, statusCode = 400) { + this.message = message + this.statusCode = statusCode + } +} diff --git a/src/errors/index.ts b/src/errors/index.ts new file mode 100644 index 0000000..81fae9e --- /dev/null +++ b/src/errors/index.ts @@ -0,0 +1,18 @@ +import { NextFunction, Request, Response } from 'express' + +import { AppError } from './AppError' + +export function handleErrors( + error: Error, + request: Request, + response: Response, + next: NextFunction +) { + if (error instanceof AppError) { + return response.status(error.statusCode).json({ message: error.message }) + } + + return response.status(500).json({ + message: `Internal server error - ${error.message}`, + }) +} diff --git a/src/server.ts b/src/server.ts index 04a9b06..a78e3a4 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,7 +1,9 @@ import 'reflect-metadata' import cors from 'cors' import express from 'express' +import 'express-async-errors' +import { handleErrors } from './errors' import { router } from './routes' import './database' @@ -13,5 +15,6 @@ app.use(cors()) app.use(express.json()) app.use(express.urlencoded({ extended: true })) app.use('/api', router) +app.use(handleErrors) app.listen(5000, () => console.log('Server is running!')) diff --git a/yarn.lock b/yarn.lock index 7c3ef58..f7ddacf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -940,6 +940,11 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +express-async-errors@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/express-async-errors/-/express-async-errors-3.1.1.tgz#6053236d61d21ddef4892d6bd1d736889fc9da41" + integrity sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng== + express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" From 987a6b0b5eea90527e8a3a735db33136c94283c4 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Thu, 9 Sep 2021 14:38:55 -0300 Subject: [PATCH 042/121] Change if ti ternary operation --- .../implementations/InvasionRepository.ts | 11 ++++------- .../implementations/ReserveInvasionRepository.ts | 11 ++++------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index b43b439..7d4d69c 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -83,17 +83,14 @@ class InvasionRepository implements IInvasionRepository { dataType, }: IRequestRankingDTO): Promise { const propertie = rankingFilter[territoryType] - let aggregation - if (dataType === 'incidenceRequirements') { - aggregation = 1 - } else if (dataType === 'requiredArea') { - aggregation = '$properties.AREA_HA' - } const territories = await Invasion.aggregate([ { $group: { _id: propertie, - count: { $sum: aggregation }, + count: { + $sum: + dataType === 'incidenceRequirements' ? 1 : '$properties.AREA_HA', + }, }, }, { diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 130cd49..ceaf44c 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -84,17 +84,14 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { dataType, }: IRequestRankingDTO): Promise { const propertie = rankingFilter[territoryType] - let aggregation - if (dataType === 'incidenceRequirements') { - aggregation = 1 - } else if (dataType === 'requiredArea') { - aggregation = '$properties.AREA_HA' - } const territories = await ReserveInvasion.aggregate([ { $group: { _id: propertie, - count: { $sum: aggregation }, + count: { + $sum: + dataType === 'incidenceRequirements' ? 1 : '$properties.AREA_HA', + }, }, }, { $sort: { count: -1 } }, From ed909590242d797da714fbac67a34d90385a7714 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 9 Sep 2021 15:27:45 -0300 Subject: [PATCH 043/121] Check empty filters --- src/repositories/implementations/InvasionRepository.ts | 8 ++++---- .../implementations/ReserveInvasionRepository.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index b43b439..20ba766 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -11,25 +11,25 @@ class InvasionRepository implements IInvasionRepository { async listInvasions(filters: IFiltersDTO): Promise { const match: any = {} - if (filters.unity) { + if (filters.unity && filters.unity.length > 0) { match['properties.UC_NOME'] = { $in: filters.unity, } } - if (filters.company) { + if (filters.company && filters.company.length > 0) { match['properties.NOME'] = { $in: filters.company, } } - if (filters.year) { + if (filters.year && filters.year.length > 0) { match['properties.ANO'] = { $in: filters.year, } } - if (filters.state) { + if (filters.state && filters.state.length > 0) { const acronymsRegex = filters.state.map( (state) => new RegExp(`.*${getStateAcronym(state)}.*`, 'i') ) diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 130cd49..52425c9 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -11,25 +11,25 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { async listInvasions(filters: IFiltersDTO): Promise { const match: any = {} - if (filters.reserve) { + if (filters.reserve && filters.reserve.length > 0) { match['properties.TI_NOME'] = { $in: filters.reserve, } } - if (filters.company) { + if (filters.company && filters.company.length > 0) { match['properties.NOME'] = { $in: filters.company, } } - if (filters.year) { + if (filters.year && filters.year.length > 0) { match['properties.ANO'] = { $in: filters.year, } } - if (filters.state) { + if (filters.state && filters.state.length > 0) { const acronymsRegex = filters.state.map( (state) => new RegExp(`.*${getStateAcronym(state)}.*`, 'i') ) From 9d53c6d8c7a715f98d28aaf8f60a801e6cfd9eb9 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 9 Sep 2021 16:09:37 -0300 Subject: [PATCH 044/121] Create new filters --- src/dtos/IFiltersDTO.ts | 2 ++ src/dtos/IInvasionDTO.ts | 1 + src/dtos/IPaginationDTO.ts | 1 + src/repositories/implementations/InvasionRepository.ts | 3 ++- src/repositories/implementations/ReserveInvasionRepository.ts | 3 ++- src/utils/pagination.ts | 2 +- 6 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/dtos/IFiltersDTO.ts b/src/dtos/IFiltersDTO.ts index 272058b..d0949b6 100644 --- a/src/dtos/IFiltersDTO.ts +++ b/src/dtos/IFiltersDTO.ts @@ -4,6 +4,8 @@ interface IFiltersDTO { unity?: string[] company?: string[] year?: string[] + enableUnity: boolean + enableReserve: boolean } export { IFiltersDTO } diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts index 651b65e..58d6437 100644 --- a/src/dtos/IInvasionDTO.ts +++ b/src/dtos/IInvasionDTO.ts @@ -4,6 +4,7 @@ interface IInvasionDTO { area: number year: number state: string + miningProcess: string territory: string type: string } diff --git a/src/dtos/IPaginationDTO.ts b/src/dtos/IPaginationDTO.ts index 3451654..d5a636d 100644 --- a/src/dtos/IPaginationDTO.ts +++ b/src/dtos/IPaginationDTO.ts @@ -1,6 +1,7 @@ interface IPaginationDTO { values: any[] pages: number + results: number } export { IPaginationDTO } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 20ba766..f157cc5 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -47,7 +47,8 @@ class InvasionRepository implements IInvasionRepository { year: '$properties.ANO', state: '$properties.UF', territory: '$properties.UC_NOME', - type: 'Unidade de Conservação', + miningProcess: '$properties.FASE', + type: 'protectedArea', _id: 0, }, { lean: true } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 52425c9..14e348c 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -47,7 +47,8 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { year: '$properties.ANO', state: '$properties.UF', territory: '$properties.TI_NOME', - type: 'Terra Indígena', + miningProcess: '$properties.FASE', + type: 'indigenousLand', _id: 0, }, { lean: true } diff --git a/src/utils/pagination.ts b/src/utils/pagination.ts index dabcd3c..d9dd35c 100644 --- a/src/utils/pagination.ts +++ b/src/utils/pagination.ts @@ -10,5 +10,5 @@ export function paginate( const offset = (page - 1) * pageSize const pageValues = values.slice(offset, offset + pageSize) - return { values: pageValues, pages } + return { values: pageValues, pages, results: arraySize } } From 57c1c096a736c17561bf750d53b9924a21b3af3f Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 9 Sep 2021 16:12:11 -0300 Subject: [PATCH 045/121] Add enable unity and reserve filters in liting --- src/services/listInvasions/ListInvasionsService.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/services/listInvasions/ListInvasionsService.ts b/src/services/listInvasions/ListInvasionsService.ts index 09de46d..3a56150 100644 --- a/src/services/listInvasions/ListInvasionsService.ts +++ b/src/services/listInvasions/ListInvasionsService.ts @@ -25,13 +25,19 @@ class ListInvasionsService { let reserveInvasions: IInvasionDTO[] = [] let invasions: IInvasionDTO[] = [] - if ((!filters.reserve && !filters.unity) || filters.reserve) { + if ( + ((!filters.reserve && !filters.unity) || filters.reserve) && + filters.enableReserve + ) { reserveInvasions = await this.reserveInvasionRepository.listInvasions( filters ) } - if ((!filters.reserve && !filters.unity) || filters.unity) { + if ( + ((!filters.reserve && !filters.unity) || filters.unity) && + filters.enableUnity + ) { invasions = await this.invasionRepository.listInvasions(filters) } From ff339dd42d0fb3f6ae1d51a3e59df95ee310946a Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 9 Sep 2021 16:25:55 -0300 Subject: [PATCH 046/121] Change filters --- README.md | 5 ++++- src/dtos/IFiltersDTO.ts | 2 -- src/services/listInvasions/ListInvasionsController.ts | 4 +++- src/services/listInvasions/ListInvasionsService.ts | 6 ++++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cb76c61..0e92063 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,8 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "unity": [], //Array de strings com o nome das Unidades de Conservação "year": [], //Array de inteiros com os anos } + "enableUnity": true, //Boolean para ativar/desativar dados de ucs + "enableReserve": true, //Boolean para ativar/desativar dados de Terras Indígenas } ``` **Descrição:** Todos os filtros são parâmetros opcionais e podem ser combinados. @@ -109,8 +111,9 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C { "filters": { "state": ["Amazonas"], - "reserve": ["Andirá-Marau"] + "reserve": ["Andirá-Marau"], } + "enableReserve": true } ``` diff --git a/src/dtos/IFiltersDTO.ts b/src/dtos/IFiltersDTO.ts index d0949b6..272058b 100644 --- a/src/dtos/IFiltersDTO.ts +++ b/src/dtos/IFiltersDTO.ts @@ -4,8 +4,6 @@ interface IFiltersDTO { unity?: string[] company?: string[] year?: string[] - enableUnity: boolean - enableReserve: boolean } export { IFiltersDTO } diff --git a/src/services/listInvasions/ListInvasionsController.ts b/src/services/listInvasions/ListInvasionsController.ts index ddf0138..480b3bd 100644 --- a/src/services/listInvasions/ListInvasionsController.ts +++ b/src/services/listInvasions/ListInvasionsController.ts @@ -5,13 +5,15 @@ import { ListInvasionsService } from './ListInvasionsService' class ListInvasionsController { async handle(request: Request, response: Response): Promise { - const { filters } = request.body + const { filters, enableUnity, enableReserve } = request.body const { page, pageSize } = request.query const listInvasionsService = container.resolve(ListInvasionsService) const invasions = await listInvasionsService.execute( filters, + enableUnity, + enableReserve, Number(page) || undefined, Number(pageSize) || undefined ) diff --git a/src/services/listInvasions/ListInvasionsService.ts b/src/services/listInvasions/ListInvasionsService.ts index 3a56150..52b653a 100644 --- a/src/services/listInvasions/ListInvasionsService.ts +++ b/src/services/listInvasions/ListInvasionsService.ts @@ -19,6 +19,8 @@ class ListInvasionsService { async execute( filters: IFiltersDTO, + enableUnity: boolean = true, + enableReserve: boolean = true, page: number = 1, pageSize: number = 10 ): Promise { @@ -27,7 +29,7 @@ class ListInvasionsService { if ( ((!filters.reserve && !filters.unity) || filters.reserve) && - filters.enableReserve + enableReserve ) { reserveInvasions = await this.reserveInvasionRepository.listInvasions( filters @@ -36,7 +38,7 @@ class ListInvasionsService { if ( ((!filters.reserve && !filters.unity) || filters.unity) && - filters.enableUnity + enableUnity ) { invasions = await this.invasionRepository.listInvasions(filters) } From 1f1cce29a5b56f7b8dcfbd65236b39746156354f Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 9 Sep 2021 16:32:23 -0300 Subject: [PATCH 047/121] Return id of requirements --- README.md | 4 ++-- src/dtos/IInvasionDTO.ts | 1 + src/repositories/implementations/InvasionRepository.ts | 1 + src/repositories/implementations/ReserveInvasionRepository.ts | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0e92063..10a91c4 100644 --- a/README.md +++ b/README.md @@ -95,8 +95,8 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "unity": [], //Array de strings com o nome das Unidades de Conservação "year": [], //Array de inteiros com os anos } - "enableUnity": true, //Boolean para ativar/desativar dados de ucs - "enableReserve": true, //Boolean para ativar/desativar dados de Terras Indígenas + "enableUnity": true, //Boolean para ativar/desativar dados de ucs (default: true) + "enableReserve": true, //Boolean para ativar/desativar dados de Terras Indígenas (default: true) } ``` **Descrição:** Todos os filtros são parâmetros opcionais e podem ser combinados. diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts index 58d6437..2060622 100644 --- a/src/dtos/IInvasionDTO.ts +++ b/src/dtos/IInvasionDTO.ts @@ -1,4 +1,5 @@ interface IInvasionDTO { + id: string company: string process: string area: number diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index f157cc5..6572d14 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -49,6 +49,7 @@ class InvasionRepository implements IInvasionRepository { territory: '$properties.UC_NOME', miningProcess: '$properties.FASE', type: 'protectedArea', + id: '$_id', _id: 0, }, { lean: true } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 14e348c..8a1feb5 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -49,6 +49,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { territory: '$properties.TI_NOME', miningProcess: '$properties.FASE', type: 'indigenousLand', + id: '$_id', _id: 0, }, { lean: true } From f134ab0b9107bd7e325672583b9b9f20cfae4d20 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 9 Sep 2021 16:46:00 -0300 Subject: [PATCH 048/121] Change Readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 10a91c4..664a19b 100644 --- a/README.md +++ b/README.md @@ -145,9 +145,10 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C } ], "pages": 10 + "results": 20 } ``` - **Descrição:** Retorna um array de objetos contendo os dados de cada requerimento que se enquadra nos filtros definidos e o número de páginas. + **Descrição:** Retorna um array de objetos contendo os dados de cada requerimento que se enquadra nos filtros definidos, o número de páginas e a quantidade de requerimentos. * **Código:** **500**
**Conteúdo:** From b9c8dbebc240dc2f64290375f8ff7d8a4c51410a Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 10 Sep 2021 09:25:23 -0300 Subject: [PATCH 049/121] Sort invasions by year for listing --- src/services/listInvasions/ListInvasionsService.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/services/listInvasions/ListInvasionsService.ts b/src/services/listInvasions/ListInvasionsService.ts index 52b653a..3682f18 100644 --- a/src/services/listInvasions/ListInvasionsService.ts +++ b/src/services/listInvasions/ListInvasionsService.ts @@ -45,9 +45,7 @@ class ListInvasionsService { const results = invasions.concat(reserveInvasions) const sortedResults = results.sort((a, b) => { - if (a.company > b.company) return 1 - if (a.company < b.company) return -1 - return 0 + return b.year - a.year }) return paginate(sortedResults, page, pageSize) From 6d20213296f7401ac2e537f1be739ace1d0e1df2 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 10 Sep 2021 09:37:07 -0300 Subject: [PATCH 050/121] Change Readme --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 664a19b..2414f34 100644 --- a/README.md +++ b/README.md @@ -126,22 +126,26 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C { "values": [ { + "id": "601cc05d3bd42e00190c8ff5", "company": "Falcon Metais Ltda", "process": "880816/2008", "area": 9928.68, "year": 2008, "state": "AM", "territory": "Andirá-Marau", - "type": "Terra Indígena" + "type": "Terra Indígena", + "miningProcess": "REQUERIMENTO DE PESQUISA" }, { + "id": "5fae1a510a4baf00bf57cf7c", "company": "Falcon Metais Ltda", "process": "880819/2008", "area": 9932.87, "year": 2008, "state": "AM", "territory": "Andirá-Marau", - "type": "Terra Indígena" + "type": "Terra Indígena", + "miningProcess": "REQUERIMENTO DE PESQUISA" } ], "pages": 10 From 58be7d4ca418f5e12c8c41cc5ba314219542a44f Mon Sep 17 00:00:00 2001 From: Iago Machado <38327929+iagomachadocs@users.noreply.github.com> Date: Fri, 10 Sep 2021 09:39:47 -0300 Subject: [PATCH 051/121] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2414f34..d7b3757 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "reserve": [], //Array de strings com o nome das Terras Indígenas "unity": [], //Array de strings com o nome das Unidades de Conservação "year": [], //Array de inteiros com os anos - } + }, "enableUnity": true, //Boolean para ativar/desativar dados de ucs (default: true) "enableReserve": true, //Boolean para ativar/desativar dados de Terras Indígenas (default: true) } From a92ab134c4b98b04e75d88211d9e7a78eb24d916 Mon Sep 17 00:00:00 2001 From: Iago Machado <38327929+iagomachadocs@users.noreply.github.com> Date: Fri, 10 Sep 2021 09:41:16 -0300 Subject: [PATCH 052/121] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d7b3757..acb04ef 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "filters": { "state": ["Amazonas"], "reserve": ["Andirá-Marau"], - } + }, "enableReserve": true } ``` @@ -148,7 +148,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "miningProcess": "REQUERIMENTO DE PESQUISA" } ], - "pages": 10 + "pages": 10, "results": 20 } ``` From 82f01c85eb4f904b01d536b9caf2453111d5d76f Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Tue, 14 Sep 2021 10:22:22 -0300 Subject: [PATCH 053/121] Group requirements by process number in listing --- src/dtos/IInvasionDTO.ts | 1 - .../implementations/InvasionRepository.ts | 39 ++++++++++++------- .../ReserveInvasionRepository.ts | 39 ++++++++++++------- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts index 2060622..58d6437 100644 --- a/src/dtos/IInvasionDTO.ts +++ b/src/dtos/IInvasionDTO.ts @@ -1,5 +1,4 @@ interface IInvasionDTO { - id: string company: string process: string area: number diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 6572d14..844c716 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -38,22 +38,33 @@ class InvasionRepository implements IInvasionRepository { } } - const invasions = await Invasion.find( - match, + const invasions = await Invasion.aggregate([ + { $match: match }, { - company: '$properties.NOME', - process: '$properties.PROCESSO', - area: '$properties.AREA_HA', - year: '$properties.ANO', - state: '$properties.UF', - territory: '$properties.UC_NOME', - miningProcess: '$properties.FASE', - type: 'protectedArea', - id: '$_id', - _id: 0, + $group: { + _id: '$properties.PROCESSO', + company: { $first: '$properties.NOME' }, + area: { $sum: '$properties.AREA_HA' }, + year: { $first: '$properties.ANO' }, + state: { $first: '$properties.UF' }, + territory: { $first: '$properties.UC_NOME' }, + miningProcess: { $first: '$properties.FASE' }, + }, + }, + { + $project: { + company: '$company', + process: '$_id', + area: '$area', + year: '$year', + state: '$state', + miningProcess: '$miningProcess', + territory: '$territory', + type: 'protectedArea', + _id: 0, + }, }, - { lean: true } - ) + ]) return invasions } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 8a1feb5..10fe696 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -38,22 +38,33 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { } } - const invasions = await ReserveInvasion.find( - match, + const invasions = await ReserveInvasion.aggregate([ + { $match: match }, { - company: '$properties.NOME', - process: '$properties.PROCESSO', - area: '$properties.AREA_HA', - year: '$properties.ANO', - state: '$properties.UF', - territory: '$properties.TI_NOME', - miningProcess: '$properties.FASE', - type: 'indigenousLand', - id: '$_id', - _id: 0, + $group: { + _id: '$properties.PROCESSO', + company: { $first: '$properties.NOME' }, + area: { $sum: '$properties.AREA_HA' }, + year: { $first: '$properties.ANO' }, + state: { $first: '$properties.UF' }, + territory: { $first: '$properties.TI_NOME' }, + miningProcess: { $first: '$properties.FASE' }, + }, + }, + { + $project: { + company: '$company', + process: '$_id', + area: '$area', + year: '$year', + state: '$state', + miningProcess: '$miningProcess', + territory: '$territory', + type: 'indigenousLand', + _id: 0, + }, }, - { lean: true } - ) + ]) return invasions } From 5a618b72e491fb94a8a9848a9d8368d00871596d Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 15 Sep 2021 10:13:43 -0300 Subject: [PATCH 054/121] Create License repository --- src/repositories/ILicenseRepository.ts | 7 +++++ .../implementations/LicenseRepository.ts | 30 +++++++++++++++++++ src/shared/container/index.ts | 7 +++++ 3 files changed, 44 insertions(+) create mode 100644 src/repositories/ILicenseRepository.ts create mode 100644 src/repositories/implementations/LicenseRepository.ts diff --git a/src/repositories/ILicenseRepository.ts b/src/repositories/ILicenseRepository.ts new file mode 100644 index 0000000..c353956 --- /dev/null +++ b/src/repositories/ILicenseRepository.ts @@ -0,0 +1,7 @@ +import { ISearchDTO } from '../dtos/ISearchDTO' + +interface ILicenseRepository { + searchSubstance(searchTerm: string): Promise +} + +export { ILicenseRepository } diff --git a/src/repositories/implementations/LicenseRepository.ts b/src/repositories/implementations/LicenseRepository.ts new file mode 100644 index 0000000..21b4a94 --- /dev/null +++ b/src/repositories/implementations/LicenseRepository.ts @@ -0,0 +1,30 @@ +import { License } from '../../database/models/License' +import { ISearchDTO } from '../../dtos/ISearchDTO' +import { ILicenseRepository } from '../ILicenseRepository' + +class LicenseRepository implements ILicenseRepository { + async searchSubstance(searchTerm: string): Promise { + const substances = await License.aggregate([ + { + $match: { + 'properties.SUBS': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + }, + }, + { + $group: { + _id: '$properties.SUBS', + }, + }, + { + $project: { + type: 'substance', + value: '$_id', + _id: 0, + }, + }, + ]) + return substances + } +} + +export { LicenseRepository } diff --git a/src/shared/container/index.ts b/src/shared/container/index.ts index 626fdd2..442d257 100644 --- a/src/shared/container/index.ts +++ b/src/shared/container/index.ts @@ -1,7 +1,9 @@ import { container } from 'tsyringe' import { IInvasionRepository } from '../../repositories/IInvasionRepository' +import { ILicenseRepository } from '../../repositories/ILicenseRepository' import { InvasionRepository } from '../../repositories/implementations/InvasionRepository' +import { LicenseRepository } from '../../repositories/implementations/LicenseRepository' import { ReserveInvasionRepository } from '../../repositories/implementations/ReserveInvasionRepository' import { ReserveRepository } from '../../repositories/implementations/ReserveRepository' import { UnityRepository } from '../../repositories/implementations/UnityRepository' @@ -28,3 +30,8 @@ container.registerSingleton( 'ReserveRepository', ReserveRepository ) + +container.registerSingleton( + 'LicenseRepository', + LicenseRepository +) From 9585979e6a6cd71868d3fea13065029e0cac9030 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 15 Sep 2021 10:14:46 -0300 Subject: [PATCH 055/121] Add substance in search --- src/services/search/SearchService.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts index 32dbc81..5084a25 100644 --- a/src/services/search/SearchService.ts +++ b/src/services/search/SearchService.ts @@ -2,6 +2,7 @@ import { inject, injectable } from 'tsyringe' import { ISearchDTO } from '../../dtos/ISearchDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' +import { ILicenseRepository } from '../../repositories/ILicenseRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' import { IReserveRepository } from '../../repositories/IReserveRepository' import { IUnityRepository } from '../../repositories/IUnityRepository' @@ -20,7 +21,10 @@ class SearchService { private unityRepository: IUnityRepository, @inject('ReserveRepository') - private reserveRepository: IReserveRepository + private reserveRepository: IReserveRepository, + + @inject('LicenseRepository') + private licenseRepository: ILicenseRepository ) {} async execute(searchTerm: string): Promise { @@ -47,7 +51,9 @@ class SearchService { const reserves = await this.reserveRepository.searchByName(searchTerm) - const results = states.concat(companies, unities, reserves) + const substances = await this.licenseRepository.searchSubstance(searchTerm) + + const results = states.concat(companies, unities, reserves, substances) return results } From 3a0b87cc7de7501a4a753a0149da2e534064de26 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 15 Sep 2021 10:23:04 -0300 Subject: [PATCH 056/121] Change Readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index acb04ef..92fbde8 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Busca Geral** ---- -Método que permite uma busca geral para Estado, Solicitante (Empresa), Terras Indígenas ou Unidades de Conservação, retornando as opções disponíveis no Banco de Dados que são iniciadas com a string fornecida. +Método que permite uma busca geral para Substância, Estado, Solicitante (Empresa), Terras Indígenas ou Unidades de Conservação, retornando as opções disponíveis no Banco de Dados que são iniciadas com a string fornecida. * **URL:** @@ -55,7 +55,7 @@ Método que permite uma busca geral para Estado, Solicitante (Empresa), Terras I } ] ``` - **Descrição:** Retorna um array de objetos contendo o tipo de dado [company (solicitante), state (estado), reserve (terra indígena) ou unity (unidade de conservação)] e o valor (nome) das opções que são iniciadas pela string determinada. + **Descrição:** Retorna um array de objetos contendo o tipo de dado [substance (substância), company (solicitante), state (estado), reserve (terra indígena) ou unity (unidade de conservação)] e o valor (nome) das opções que são iniciadas pela string determinada. * **Código:** **500**
**Conteúdo:** From 8541d4b08157059e0204aa338495ce9f6a0e1e2d Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 15 Sep 2021 11:51:49 -0300 Subject: [PATCH 057/121] Add substance in listing --- src/dtos/IFiltersDTO.ts | 1 + src/dtos/IInvasionDTO.ts | 1 + src/repositories/implementations/InvasionRepository.ts | 8 ++++++++ .../implementations/ReserveInvasionRepository.ts | 8 ++++++++ 4 files changed, 18 insertions(+) diff --git a/src/dtos/IFiltersDTO.ts b/src/dtos/IFiltersDTO.ts index 272058b..3ba817c 100644 --- a/src/dtos/IFiltersDTO.ts +++ b/src/dtos/IFiltersDTO.ts @@ -4,6 +4,7 @@ interface IFiltersDTO { unity?: string[] company?: string[] year?: string[] + substance?: string[] } export { IFiltersDTO } diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts index 58d6437..d1da86c 100644 --- a/src/dtos/IInvasionDTO.ts +++ b/src/dtos/IInvasionDTO.ts @@ -5,6 +5,7 @@ interface IInvasionDTO { year: number state: string miningProcess: string + substance: string territory: string type: string } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 844c716..048533b 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -38,6 +38,12 @@ class InvasionRepository implements IInvasionRepository { } } + if (filters.substance && filters.substance.length > 0) { + match['properties.SUBS'] = { + $in: filters.substance, + } + } + const invasions = await Invasion.aggregate([ { $match: match }, { @@ -49,6 +55,7 @@ class InvasionRepository implements IInvasionRepository { state: { $first: '$properties.UF' }, territory: { $first: '$properties.UC_NOME' }, miningProcess: { $first: '$properties.FASE' }, + substance: { $first: '$properties.SUBS' }, }, }, { @@ -61,6 +68,7 @@ class InvasionRepository implements IInvasionRepository { miningProcess: '$miningProcess', territory: '$territory', type: 'protectedArea', + substance: '$substance', _id: 0, }, }, diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 10fe696..3b96673 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -38,6 +38,12 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { } } + if (filters.substance && filters.substance.length > 0) { + match['properties.SUBS'] = { + $in: filters.substance, + } + } + const invasions = await ReserveInvasion.aggregate([ { $match: match }, { @@ -49,6 +55,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { state: { $first: '$properties.UF' }, territory: { $first: '$properties.TI_NOME' }, miningProcess: { $first: '$properties.FASE' }, + substance: { $first: '$properties.SUBS' }, }, }, { @@ -61,6 +68,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { miningProcess: '$miningProcess', territory: '$territory', type: 'indigenousLand', + substance: '$substance', _id: 0, }, }, From 7bcb4a45903073283366d402b8464604a4524350 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 15 Sep 2021 12:03:15 -0300 Subject: [PATCH 058/121] Change return of ranking --- README.md | 4 ++-- src/services/invasionRanking/InvasionRankingService.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 92fbde8..9fd4fe5 100644 --- a/README.md +++ b/README.md @@ -289,7 +289,7 @@ Método que retorna o ranking de acordo com o território e o tipo de dado espec ], "series": [ { - "name": "indigenousLand", + "id": "indigenousLand", "data": [ 447938.31, 469529.25, @@ -299,7 +299,7 @@ Método que retorna o ranking de acordo com o território e o tipo de dado espec ] }, { - "name": "protectedArea", + "id": "protectedArea", "data": [ 112761.6, 49983.95, diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index d501fe7..3f065a3 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -68,7 +68,7 @@ class InvasionFrequencyService { return { x: paginate(x, page, 5).values, position: paginate(pos, page, 5).values, - series: [{ name: name, data: paginate(y, page, 5).values }], + series: [{ id: name, data: paginate(y, page, 5).values }], pageAmount: paginate(pos, page, 5).pages, } } @@ -114,11 +114,11 @@ class InvasionFrequencyService { position: paginate(pos, page, 5).values, series: [ { - name: 'indigenousLand', + id: 'indigenousLand', data: paginate(invasionY, page, 5).values, }, { - name: 'protectedArea', + id: 'protectedArea', data: paginate(reserveY, page, 5).values, }, ], From 6042c10367dc375e22c061dd8bc5633c61af79d0 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 15 Sep 2021 12:20:54 -0300 Subject: [PATCH 059/121] Add dataType in ranking return --- README.md | 3 ++- src/services/invasionRanking/InvasionRankingService.ts | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9fd4fe5..4c49f9a 100644 --- a/README.md +++ b/README.md @@ -309,7 +309,8 @@ Método que retorna o ranking de acordo com o território e o tipo de dado espec ] } ], - "pageAmount": 125 + "pageAmount": 125, + "dataType": "requiredArea" } ``` **Descrição:** Retorna um array de series que contém os valores de cada tipo de dado, um array com as respectivas posições e um com os nomes dos territórios. diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index 3f065a3..f4df4cd 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -31,6 +31,7 @@ class InvasionFrequencyService { return await this.formatDoubleRanking( reserveResults, invasionResults, + dataType, territoryType, page ) @@ -70,12 +71,14 @@ class InvasionFrequencyService { position: paginate(pos, page, 5).values, series: [{ id: name, data: paginate(y, page, 5).values }], pageAmount: paginate(pos, page, 5).pages, + dataType: name, } } async formatDoubleRanking( invasionResults: IResponseRankingDTO[], reserveResults: IResponseRankingDTO[], + dataType: string, territoryType: string, page: number ) { @@ -123,6 +126,7 @@ class InvasionFrequencyService { }, ], pageAmount: paginate(pos, page, 5).pages, + dataType, } } } From 2b8c616c12f52fa33a1da01d340a999cb612bc51 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 15 Sep 2021 16:10:26 -0300 Subject: [PATCH 060/121] Change id in the return of ranking --- .../invasionRanking/InvasionRankingService.ts | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index f4df4cd..6624f23 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -41,7 +41,12 @@ class InvasionFrequencyService { page, dataType, }) - return await this.formatSingleRanking(results, dataType, page) + return await this.formatSingleRanking( + results, + dataType, + 'protectedArea', + page + ) } else if (territoryType === 'reserve') { const results = await this.reserveInvasionRepository.reserveInvasionRanking({ @@ -49,13 +54,19 @@ class InvasionFrequencyService { page, dataType, }) - return await this.formatSingleRanking(results, dataType, page) + return await this.formatSingleRanking( + results, + dataType, + 'indigenousLand', + page + ) } } async formatSingleRanking( results: IResponseRankingDTO[], - name: string, + dataType: string, + id: string, page: number ) { const x: string[] = [] @@ -69,9 +80,9 @@ class InvasionFrequencyService { return { x: paginate(x, page, 5).values, position: paginate(pos, page, 5).values, - series: [{ id: name, data: paginate(y, page, 5).values }], + series: [{ id, data: paginate(y, page, 5).values }], pageAmount: paginate(pos, page, 5).pages, - dataType: name, + dataType, } } From 8330318984701bcec6703694fec91e561b8446f4 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 16 Sep 2021 09:26:34 -0300 Subject: [PATCH 061/121] Change Readme --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4c49f9a..359ad60 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "reserve": [], //Array de strings com o nome das Terras Indígenas "unity": [], //Array de strings com o nome das Unidades de Conservação "year": [], //Array de inteiros com os anos + "substance": [], //Array de strings com o nome das substâncias }, "enableUnity": true, //Boolean para ativar/desativar dados de ucs (default: true) "enableReserve": true, //Boolean para ativar/desativar dados de Terras Indígenas (default: true) @@ -126,7 +127,6 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C { "values": [ { - "id": "601cc05d3bd42e00190c8ff5", "company": "Falcon Metais Ltda", "process": "880816/2008", "area": 9928.68, @@ -134,10 +134,10 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "state": "AM", "territory": "Andirá-Marau", "type": "Terra Indígena", - "miningProcess": "REQUERIMENTO DE PESQUISA" + "miningProcess": "REQUERIMENTO DE PESQUISA", + "substance": "OURO" }, { - "id": "5fae1a510a4baf00bf57cf7c", "company": "Falcon Metais Ltda", "process": "880819/2008", "area": 9932.87, @@ -145,7 +145,8 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "state": "AM", "territory": "Andirá-Marau", "type": "Terra Indígena", - "miningProcess": "REQUERIMENTO DE PESQUISA" + "miningProcess": "REQUERIMENTO DE PESQUISA", + "substance": "OURO" } ], "pages": 10, @@ -189,6 +190,7 @@ Método que retorna as estatísticas gerais (número de requerimentos e área) d "reserve": [], //Array de strings com o nome das Terras Indígenas "unity": [], //Array de strings com o nome das Unidades de Conservação "year": [], //Array de inteiros com os anos + "substance": [], //Array de strings com o nome das substâncias } } ``` From f092a6c1fa2fefdbb0eb9dc8cd4a284ef7fcb0d2 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 16 Sep 2021 09:43:49 -0300 Subject: [PATCH 062/121] Change companies search to licenses collection --- src/repositories/ILicenseRepository.ts | 1 + .../implementations/LicenseRepository.ts | 22 +++++++++++++++++++ src/services/search/SearchService.ts | 17 +------------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/repositories/ILicenseRepository.ts b/src/repositories/ILicenseRepository.ts index c353956..3cb6e54 100644 --- a/src/repositories/ILicenseRepository.ts +++ b/src/repositories/ILicenseRepository.ts @@ -2,6 +2,7 @@ import { ISearchDTO } from '../dtos/ISearchDTO' interface ILicenseRepository { searchSubstance(searchTerm: string): Promise + searchCompany(searchTerm: string): Promise } export { ILicenseRepository } diff --git a/src/repositories/implementations/LicenseRepository.ts b/src/repositories/implementations/LicenseRepository.ts index 21b4a94..ec90d04 100644 --- a/src/repositories/implementations/LicenseRepository.ts +++ b/src/repositories/implementations/LicenseRepository.ts @@ -3,6 +3,28 @@ import { ISearchDTO } from '../../dtos/ISearchDTO' import { ILicenseRepository } from '../ILicenseRepository' class LicenseRepository implements ILicenseRepository { + async searchCompany(searchTerm: string): Promise { + const companies = await License.aggregate([ + { + $match: { + 'properties.NOME': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + }, + }, + { + $group: { + _id: '$properties.NOME', + }, + }, + { + $project: { + type: 'company', + value: '$_id', + _id: 0, + }, + }, + ]) + return companies + } async searchSubstance(searchTerm: string): Promise { const substances = await License.aggregate([ { diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts index 5084a25..8cd6cfd 100644 --- a/src/services/search/SearchService.ts +++ b/src/services/search/SearchService.ts @@ -30,22 +30,7 @@ class SearchService { async execute(searchTerm: string): Promise { const states = searchStates(searchTerm) - const reserveCompanies = await this.reserveInvasionRepository.searchCompany( - searchTerm - ) - - const unityCompanies = await this.invasionRepository.searchCompany( - searchTerm - ) - - const companiesMap = new Map() - reserveCompanies.forEach((company) => - companiesMap.set(company.value, company) - ) - unityCompanies.forEach((company) => - companiesMap.set(company.value, company) - ) - const companies = Array.from(companiesMap.values()) + const companies = await this.licenseRepository.searchCompany(searchTerm) const unities = await this.unityRepository.searchByName(searchTerm) From 0f7dccac81cc74726f0ffcdd9e135204e2aebbd2 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Thu, 16 Sep 2021 11:53:04 -0300 Subject: [PATCH 063/121] Sort reserve ranking --- src/repositories/implementations/InvasionRepository.ts | 1 + src/services/invasionRanking/InvasionRankingService.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 7d4d69c..8d10e1c 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -93,6 +93,7 @@ class InvasionRepository implements IInvasionRepository { }, }, }, + { $sort: { count: -1 } }, { $project: { x: '$_id', diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index 3f065a3..fc65b4a 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -55,7 +55,7 @@ class InvasionFrequencyService { async formatSingleRanking( results: IResponseRankingDTO[], name: string, - page: number + page = 1 ) { const x: string[] = [] const y: number[] = [] @@ -77,7 +77,7 @@ class InvasionFrequencyService { invasionResults: IResponseRankingDTO[], reserveResults: IResponseRankingDTO[], territoryType: string, - page: number + page = 1 ) { const x: string[] = [] const invasionY: number[] = [] From c1f2add14bd919f3165281c60d450fc04d15faa4 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 16 Sep 2021 12:34:20 -0300 Subject: [PATCH 064/121] Create method to list reserve homologation phase options --- README.md | 51 +++++++++++++++++++ src/repositories/IReserveRepository.ts | 1 + .../implementations/ReserveRepository.ts | 5 ++ src/routes/index.ts | 3 ++ .../GetReservesPhaseController.ts | 16 ++++++ .../GetReservesPhaseService.ts | 20 ++++++++ 6 files changed, 96 insertions(+) create mode 100644 src/services/getReservesPhase/GetReservesPhaseController.ts create mode 100644 src/services/getReservesPhase/GetReservesPhaseService.ts diff --git a/README.md b/README.md index 359ad60..3e9a20c 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,57 @@ Método que retorna as estatísticas gerais (número de requerimentos e área) d ``` **Descrição:** Erro interno do servidor. +**Listar Fases do Processo de Homologação das Terras Indígenas** +---- +Método que retorna as opções de fase do processo de homologação de terras indígenas. + +* **URL:** + + /api/reserves/phase + +* **Método:** + + `GET` + +* **Parâmetros na URL:** + + Nenhum + +* **Parâmetros no Body:** + + Nenhum + +* **Exemplo:** + + **Rota:** + /api/reserves/phase + +* **Resposta:** + + * **Código:** **200**
+ **Conteúdo:** + + ```javascript + [ + "Declarada", + "Delimitada", + "Em Estudo", + "Encaminhada RI", + "Homologada", + "Regularizada" + ] + ``` + **Descrição:** Retorna um array contendo as opções das fases do processo de homologação de terras indígenas. + + * **Código:** **500**
+ **Conteúdo:** + ```javascript + { + "message": "Internal Server Error" + } + ``` + **Descrição:** Erro interno do servidor. + **Ranking de frequência e de área** ---- Método que retorna o ranking de acordo com o território e o tipo de dado especificado diff --git a/src/repositories/IReserveRepository.ts b/src/repositories/IReserveRepository.ts index a8add84..5da63c0 100644 --- a/src/repositories/IReserveRepository.ts +++ b/src/repositories/IReserveRepository.ts @@ -2,6 +2,7 @@ import { ISearchDTO } from '../dtos/ISearchDTO' interface IReserveRepository { searchByName(searchTerm: string): Promise + getHomologationPhases(): Promise } export { IReserveRepository } diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts index 1a035f8..c352e71 100644 --- a/src/repositories/implementations/ReserveRepository.ts +++ b/src/repositories/implementations/ReserveRepository.ts @@ -16,6 +16,11 @@ class ReserveRepository implements IReserveRepository { ) return reserves } + + async getHomologationPhases(): Promise { + const homologationPhases = await Reserve.distinct('properties.fase_ti') + return homologationPhases + } } export { ReserveRepository } diff --git a/src/routes/index.ts b/src/routes/index.ts index 352bb7b..c45e368 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,5 +1,6 @@ import { Router } from 'express' +import { GetReservesPhaseController } from '../services/getReservesPhase/GetReservesPhaseController' import { GetStatisticsController } from '../services/getStatistics/GetStatisticsController' import { InvasionFrequencyController } from '../services/invasionRanking/InvasionRankingController' import { ListInvasionsController } from '../services/listInvasions/ListInvasionsController' @@ -11,6 +12,7 @@ const searchController = new SearchController() const listInvasionsController = new ListInvasionsController() const invasionFrequencyController = new InvasionFrequencyController() const getStatisticsController = new GetStatisticsController() +const getReservesPhaseController = new GetReservesPhaseController() router.get('/search/:searchTerm', searchController.handle) router.post('/invasions', listInvasionsController.handle) @@ -19,5 +21,6 @@ router.get( invasionFrequencyController.handle ) router.post('/statistics', getStatisticsController.handle) +router.get('/reserves/phase', getReservesPhaseController.handle) export { router } diff --git a/src/services/getReservesPhase/GetReservesPhaseController.ts b/src/services/getReservesPhase/GetReservesPhaseController.ts new file mode 100644 index 0000000..eb3c84a --- /dev/null +++ b/src/services/getReservesPhase/GetReservesPhaseController.ts @@ -0,0 +1,16 @@ +import { Request, Response } from 'express' +import { container } from 'tsyringe' + +import { GetReservesPhaseService } from './GetReservesPhaseService' + +class GetReservesPhaseController { + async handle(request: Request, response: Response): Promise { + const getReservesPhaseService = container.resolve(GetReservesPhaseService) + + const homologationPhases = await getReservesPhaseService.execute() + + return response.json(homologationPhases) + } +} + +export { GetReservesPhaseController } diff --git a/src/services/getReservesPhase/GetReservesPhaseService.ts b/src/services/getReservesPhase/GetReservesPhaseService.ts new file mode 100644 index 0000000..caaacfb --- /dev/null +++ b/src/services/getReservesPhase/GetReservesPhaseService.ts @@ -0,0 +1,20 @@ +import { inject, injectable } from 'tsyringe' + +import { IReserveRepository } from '../../repositories/IReserveRepository' + +@injectable() +class GetReservesPhaseService { + constructor( + @inject('ReserveRepository') + private reserveRepository: IReserveRepository + ) {} + + async execute(): Promise { + const homologationPhases = + await this.reserveRepository.getHomologationPhases() + + return homologationPhases + } +} + +export { GetReservesPhaseService } From 1df56d652d39bf6a35f1bfe22846f51dcc8cc462 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Thu, 16 Sep 2021 12:50:02 -0300 Subject: [PATCH 065/121] Change datatype name --- src/repositories/implementations/InvasionRepository.ts | 3 +-- src/repositories/implementations/ReserveInvasionRepository.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index d8a6304..73c5411 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -109,8 +109,7 @@ class InvasionRepository implements IInvasionRepository { $group: { _id: propertie, count: { - $sum: - dataType === 'incidenceRequirements' ? 1 : '$properties.AREA_HA', + $sum: dataType === 'requiredArea' ? '$properties.AREA_HA' : 1, }, }, }, diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 24f4e0a..1850da9 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -110,8 +110,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { $group: { _id: propertie, count: { - $sum: - dataType === 'incidenceRequirements' ? 1 : '$properties.AREA_HA', + $sum: dataType === 'requiredArea' ? '$properties.AREA_HA' : 1, }, }, }, From 8ac4be594c74e66a22874dea429ace0be3009bae Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 20 Sep 2021 09:48:19 -0300 Subject: [PATCH 066/121] Add reserve homologation phase filter --- README.md | 8 ++++++-- src/dtos/IFiltersDTO.ts | 1 + src/dtos/IInvasionDTO.ts | 1 + .../implementations/ReserveInvasionRepository.ts | 8 ++++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3e9a20c..7e6a695 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "unity": [], //Array de strings com o nome das Unidades de Conservação "year": [], //Array de inteiros com os anos "substance": [], //Array de strings com o nome das substâncias + "reservePhase": [], //Array de strings com as fases do processo de homologação das terras indígenas }, "enableUnity": true, //Boolean para ativar/desativar dados de ucs (default: true) "enableReserve": true, //Boolean para ativar/desativar dados de Terras Indígenas (default: true) @@ -133,7 +134,8 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "year": 2008, "state": "AM", "territory": "Andirá-Marau", - "type": "Terra Indígena", + "reservePhase": "Regularizada", + "type": "indigenousLand", "miningProcess": "REQUERIMENTO DE PESQUISA", "substance": "OURO" }, @@ -144,7 +146,8 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "year": 2008, "state": "AM", "territory": "Andirá-Marau", - "type": "Terra Indígena", + "reservePhase": "Regularizada", + "type": "indigenousLand", "miningProcess": "REQUERIMENTO DE PESQUISA", "substance": "OURO" } @@ -191,6 +194,7 @@ Método que retorna as estatísticas gerais (número de requerimentos e área) d "unity": [], //Array de strings com o nome das Unidades de Conservação "year": [], //Array de inteiros com os anos "substance": [], //Array de strings com o nome das substâncias + "reservePhase": [], //Array de strings com as fases do processo de homologação das terras indígenas } } ``` diff --git a/src/dtos/IFiltersDTO.ts b/src/dtos/IFiltersDTO.ts index 3ba817c..74afaa4 100644 --- a/src/dtos/IFiltersDTO.ts +++ b/src/dtos/IFiltersDTO.ts @@ -5,6 +5,7 @@ interface IFiltersDTO { company?: string[] year?: string[] substance?: string[] + reservePhase?: string[] } export { IFiltersDTO } diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts index d1da86c..a7dffb6 100644 --- a/src/dtos/IInvasionDTO.ts +++ b/src/dtos/IInvasionDTO.ts @@ -7,6 +7,7 @@ interface IInvasionDTO { miningProcess: string substance: string territory: string + reservePhase?: string type: string } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 1850da9..5e27f9c 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -44,6 +44,12 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { } } + if (filters.reservePhase && filters.reservePhase.length > 0) { + match['properties.TI_FASE'] = { + $in: filters.reservePhase, + } + } + const invasions = await ReserveInvasion.aggregate([ { $match: match }, { @@ -54,6 +60,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { year: { $first: '$properties.ANO' }, state: { $first: '$properties.UF' }, territory: { $first: '$properties.TI_NOME' }, + reservePhase: { $first: '$properties.TI_FASE' }, miningProcess: { $first: '$properties.FASE' }, substance: { $first: '$properties.SUBS' }, }, @@ -67,6 +74,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { state: '$state', miningProcess: '$miningProcess', territory: '$territory', + reservePhase: '$reservePhase', type: 'indigenousLand', substance: '$substance', _id: 0, From be7ea1a4f003fefada8741993c697357d4f910e9 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 20 Sep 2021 11:09:32 -0300 Subject: [PATCH 067/121] Add reserve ethnicity in search --- src/repositories/IReserveRepository.ts | 1 + .../implementations/ReserveRepository.ts | 25 +++++++++++++++++++ src/services/search/SearchService.ts | 10 +++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/repositories/IReserveRepository.ts b/src/repositories/IReserveRepository.ts index 5da63c0..9623589 100644 --- a/src/repositories/IReserveRepository.ts +++ b/src/repositories/IReserveRepository.ts @@ -2,6 +2,7 @@ import { ISearchDTO } from '../dtos/ISearchDTO' interface IReserveRepository { searchByName(searchTerm: string): Promise + searchEthnicity(searchTerm: string): Promise getHomologationPhases(): Promise } diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts index c352e71..8e87c3f 100644 --- a/src/repositories/implementations/ReserveRepository.ts +++ b/src/repositories/implementations/ReserveRepository.ts @@ -17,6 +17,31 @@ class ReserveRepository implements IReserveRepository { return reserves } + async searchEthnicity(searchTerm: string): Promise { + const ethnicities: ISearchDTO[] = await Reserve.aggregate([ + { + $project: { + ethnicity: { + $split: ['$properties.etnia_nome', ', '], + }, + }, + }, + { $unwind: '$ethnicity' }, + { $project: { ethnicity: { $trim: { input: '$ethnicity' } } } }, + { $group: { _id: '$ethnicity' } }, + { $match: { _id: { $regex: new RegExp(`^${searchTerm}`, 'i') } } }, + { + $project: { + type: 'ethnicity', + value: '$_id', + _id: 0, + }, + }, + { $sort: { value: 1 } }, + ]) + return ethnicities + } + async getHomologationPhases(): Promise { const homologationPhases = await Reserve.distinct('properties.fase_ti') return homologationPhases diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts index 8cd6cfd..4e98ca8 100644 --- a/src/services/search/SearchService.ts +++ b/src/services/search/SearchService.ts @@ -38,7 +38,15 @@ class SearchService { const substances = await this.licenseRepository.searchSubstance(searchTerm) - const results = states.concat(companies, unities, reserves, substances) + const ethnicities = await this.reserveRepository.searchEthnicity(searchTerm) + + const results = states.concat( + companies, + unities, + reserves, + substances, + ethnicities + ) return results } From 56233eabd2a5d279de6dce90478156ec5850e361 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 20 Sep 2021 11:44:09 -0300 Subject: [PATCH 068/121] Add reserve ethnicity filter --- README.md | 8 ++++++-- src/dtos/IFiltersDTO.ts | 1 + src/dtos/IInvasionDTO.ts | 1 + .../implementations/ReserveInvasionRepository.ts | 11 +++++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7e6a695..0203800 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Busca Geral** ---- -Método que permite uma busca geral para Substância, Estado, Solicitante (Empresa), Terras Indígenas ou Unidades de Conservação, retornando as opções disponíveis no Banco de Dados que são iniciadas com a string fornecida. +Método que permite uma busca geral para Substância, Estado, Solicitante (Empresa), Terras Indígenas, Unidades de Conservação ou Etnias de Terras Indígenas, retornando as opções disponíveis no Banco de Dados que são iniciadas com a string fornecida. * **URL:** @@ -55,7 +55,7 @@ Método que permite uma busca geral para Substância, Estado, Solicitante (Empre } ] ``` - **Descrição:** Retorna um array de objetos contendo o tipo de dado [substance (substância), company (solicitante), state (estado), reserve (terra indígena) ou unity (unidade de conservação)] e o valor (nome) das opções que são iniciadas pela string determinada. + **Descrição:** Retorna um array de objetos contendo o tipo de dado [substance (substância), company (solicitante), state (estado), reserve (terra indígena), unity (unidade de conservação) ou ethnicity (etnia de terras indígenas)] e o valor (nome) das opções que são iniciadas pela string determinada. * **Código:** **500**
**Conteúdo:** @@ -96,6 +96,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "year": [], //Array de inteiros com os anos "substance": [], //Array de strings com o nome das substâncias "reservePhase": [], //Array de strings com as fases do processo de homologação das terras indígenas + "reserveEthnicity": [], //Array de strings com o nome das etinias de terras indígenas }, "enableUnity": true, //Boolean para ativar/desativar dados de ucs (default: true) "enableReserve": true, //Boolean para ativar/desativar dados de Terras Indígenas (default: true) @@ -135,6 +136,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "state": "AM", "territory": "Andirá-Marau", "reservePhase": "Regularizada", + "reserveEthnicity": "Múra", "type": "indigenousLand", "miningProcess": "REQUERIMENTO DE PESQUISA", "substance": "OURO" @@ -147,6 +149,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "state": "AM", "territory": "Andirá-Marau", "reservePhase": "Regularizada", + "reserveEthnicity": "Múra", "type": "indigenousLand", "miningProcess": "REQUERIMENTO DE PESQUISA", "substance": "OURO" @@ -195,6 +198,7 @@ Método que retorna as estatísticas gerais (número de requerimentos e área) d "year": [], //Array de inteiros com os anos "substance": [], //Array de strings com o nome das substâncias "reservePhase": [], //Array de strings com as fases do processo de homologação das terras indígenas + "reserveEthnicity": [], //Array de strings com o nome das etinias de terras indígenas } } ``` diff --git a/src/dtos/IFiltersDTO.ts b/src/dtos/IFiltersDTO.ts index 74afaa4..ff9fc9d 100644 --- a/src/dtos/IFiltersDTO.ts +++ b/src/dtos/IFiltersDTO.ts @@ -6,6 +6,7 @@ interface IFiltersDTO { year?: string[] substance?: string[] reservePhase?: string[] + reserveEthnicity?: string[] } export { IFiltersDTO } diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts index a7dffb6..d3478bd 100644 --- a/src/dtos/IInvasionDTO.ts +++ b/src/dtos/IInvasionDTO.ts @@ -8,6 +8,7 @@ interface IInvasionDTO { substance: string territory: string reservePhase?: string + reserveEthnicity?: string type: string } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 5e27f9c..cf54021 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -50,6 +50,15 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { } } + if (filters.reserveEthnicity && filters.reserveEthnicity.length > 0) { + const ethnicitiesRegex = filters.reserveEthnicity.map( + (ethnicity) => new RegExp(`.*${ethnicity}.*`, 'i') + ) + match['properties.TI_ETNIA'] = { + $in: ethnicitiesRegex, + } + } + const invasions = await ReserveInvasion.aggregate([ { $match: match }, { @@ -61,6 +70,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { state: { $first: '$properties.UF' }, territory: { $first: '$properties.TI_NOME' }, reservePhase: { $first: '$properties.TI_FASE' }, + reserveEthnicity: { $first: '$properties.TI_ETNIA' }, miningProcess: { $first: '$properties.FASE' }, substance: { $first: '$properties.SUBS' }, }, @@ -75,6 +85,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { miningProcess: '$miningProcess', territory: '$territory', reservePhase: '$reservePhase', + reserveEthnicity: '$reserveEthnicity', type: 'indigenousLand', substance: '$substance', _id: 0, From 20c87a6ab5d20334982e7b5a1a98012c5c7dc5bc Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 20 Sep 2021 12:45:11 -0300 Subject: [PATCH 069/121] Create method to list requirements phase options --- README.md | 57 +++++++++++++++++++ src/repositories/IInvasionRepository.ts | 1 + .../IReserveInvasionRepository.ts | 1 + .../implementations/InvasionRepository.ts | 5 ++ .../ReserveInvasionRepository.ts | 5 ++ src/routes/index.ts | 3 + .../GetRequirementsPhaseController.ts | 17 ++++++ .../GetRequirementsPhaseService.ts | 36 ++++++++++++ 8 files changed, 125 insertions(+) create mode 100644 src/services/getRequirementsPhase/GetRequirementsPhaseController.ts create mode 100644 src/services/getRequirementsPhase/GetRequirementsPhaseService.ts diff --git a/README.md b/README.md index 0203800..27dc619 100644 --- a/README.md +++ b/README.md @@ -300,6 +300,63 @@ Método que retorna as opções de fase do processo de homologação de terras i ``` **Descrição:** Erro interno do servidor. +**Listar Fases do Requerimento de Mineração** +---- +Método que retorna as opções de fase do requerimento de mineração. + +* **URL:** + + /api/invasions/phase + +* **Método:** + + `GET` + +* **Parâmetros na URL:** + + Nenhum + +* **Parâmetros no Body:** + + Nenhum + +* **Exemplo:** + + **Rota:** + /api/invasions/phase + +* **Resposta:** + + * **Código:** **200**
+ **Conteúdo:** + + ```javascript + [ + "APTO PARA DISPONIBILIDADE", + "AUTORIZAÇÃO DE PESQUISA", + "CONCESSÃO DE LAVRA", + "DIREITO DE REQUERER A LAVRA", + "DISPONIBILIDADE", + "LAVRA GARIMPEIRA", + "LICENCIAMENTO", + "REQUERIMENTO DE LAVRA", + "REQUERIMENTO DE LAVRA GARIMPEIRA", + "REQUERIMENTO DE LICENCIAMENTO", + "REQUERIMENTO DE PESQUISA", + "REQUERIMENTO DE REGISTRO DE EXTRAÇÃO" + ] + ``` + **Descrição:** Retorna um array contendo as opções das fases dos requerimentos de mineração. + + * **Código:** **500**
+ **Conteúdo:** + ```javascript + { + "message": "Internal Server Error" + } + ``` + **Descrição:** Erro interno do servidor. + **Ranking de frequência e de área** ---- Método que retorna o ranking de acordo com o território e o tipo de dado especificado diff --git a/src/repositories/IInvasionRepository.ts b/src/repositories/IInvasionRepository.ts index 4b07cd6..fc99b76 100644 --- a/src/repositories/IInvasionRepository.ts +++ b/src/repositories/IInvasionRepository.ts @@ -10,6 +10,7 @@ interface IInvasionRepository { territoryType, dataType, }: IRequestRankingDTO): Promise + getRequirementsPhase(): Promise } export { IInvasionRepository } diff --git a/src/repositories/IReserveInvasionRepository.ts b/src/repositories/IReserveInvasionRepository.ts index 91d9c32..501be45 100644 --- a/src/repositories/IReserveInvasionRepository.ts +++ b/src/repositories/IReserveInvasionRepository.ts @@ -10,6 +10,7 @@ interface IReserveInvasionRepository { territoryType, dataType, }: IRequestRankingDTO): Promise + getRequirementsPhase(): Promise } export { IReserveInvasionRepository } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 73c5411..59f75ec 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -124,6 +124,11 @@ class InvasionRepository implements IInvasionRepository { ]) return territories } + + async getRequirementsPhase(): Promise { + const requirementsPhase = await Invasion.distinct('properties.FASE') + return requirementsPhase + } } export { InvasionRepository } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index cf54021..a07fc13 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -145,6 +145,11 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { return territories } + + async getRequirementsPhase(): Promise { + const requirementsPhase = await ReserveInvasion.distinct('properties.FASE') + return requirementsPhase + } } export { ReserveInvasionRepository } diff --git a/src/routes/index.ts b/src/routes/index.ts index c45e368..261fae5 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,5 +1,6 @@ import { Router } from 'express' +import { GetRequirementsPhaseController } from '../services/getRequirementsPhase/GetRequirementsPhaseController' import { GetReservesPhaseController } from '../services/getReservesPhase/GetReservesPhaseController' import { GetStatisticsController } from '../services/getStatistics/GetStatisticsController' import { InvasionFrequencyController } from '../services/invasionRanking/InvasionRankingController' @@ -13,6 +14,7 @@ const listInvasionsController = new ListInvasionsController() const invasionFrequencyController = new InvasionFrequencyController() const getStatisticsController = new GetStatisticsController() const getReservesPhaseController = new GetReservesPhaseController() +const getRequirementsPhaseController = new GetRequirementsPhaseController() router.get('/search/:searchTerm', searchController.handle) router.post('/invasions', listInvasionsController.handle) @@ -20,6 +22,7 @@ router.get( '/invasions/ranking/:territoryType/:dataType', invasionFrequencyController.handle ) +router.get('/invasions/phase', getRequirementsPhaseController.handle) router.post('/statistics', getStatisticsController.handle) router.get('/reserves/phase', getReservesPhaseController.handle) diff --git a/src/services/getRequirementsPhase/GetRequirementsPhaseController.ts b/src/services/getRequirementsPhase/GetRequirementsPhaseController.ts new file mode 100644 index 0000000..4ecf95b --- /dev/null +++ b/src/services/getRequirementsPhase/GetRequirementsPhaseController.ts @@ -0,0 +1,17 @@ +import { Request, Response } from 'express' +import { container } from 'tsyringe' + +import { GetRequirementsPhaseService } from './GetRequirementsPhaseService' + +class GetRequirementsPhaseController { + async handle(request: Request, response: Response): Promise { + const getRequirementsPhaseService = container.resolve( + GetRequirementsPhaseService + ) + const requirementsPhase = await getRequirementsPhaseService.execute() + + return response.json(requirementsPhase) + } +} + +export { GetRequirementsPhaseController } diff --git a/src/services/getRequirementsPhase/GetRequirementsPhaseService.ts b/src/services/getRequirementsPhase/GetRequirementsPhaseService.ts new file mode 100644 index 0000000..37534d6 --- /dev/null +++ b/src/services/getRequirementsPhase/GetRequirementsPhaseService.ts @@ -0,0 +1,36 @@ +import { inject, injectable } from 'tsyringe' + +import { IInvasionRepository } from '../../repositories/IInvasionRepository' +import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' + +@injectable() +class GetRequirementsPhaseService { + constructor( + @inject('ReserveInvasionRepository') + private reserveInvasionRepository: IReserveInvasionRepository, + + @inject('InvasionRepository') + private invasionRepository: IInvasionRepository + ) {} + + async execute(): Promise { + const reserveRequirementsPhase = + await this.reserveInvasionRepository.getRequirementsPhase() + + const unityRequirementsPhase = + await this.invasionRepository.getRequirementsPhase() + + const requirementsPhase = new Set([ + ...reserveRequirementsPhase, + ...unityRequirementsPhase, + ]) + + const requirementsPhaseArray = Array.from(requirementsPhase).filter( + (phase) => phase !== 'DADO NÃO CADASTRADO' + ) + + return requirementsPhaseArray + } +} + +export { GetRequirementsPhaseService } From ce05436dd0757057df1f63341cfef06df9ace085 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 20 Sep 2021 12:48:14 -0300 Subject: [PATCH 070/121] Change readme --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index 27dc619..a620e57 100644 --- a/README.md +++ b/README.md @@ -269,11 +269,6 @@ Método que retorna as opções de fase do processo de homologação de terras i Nenhum -* **Exemplo:** - - **Rota:** - /api/reserves/phase - * **Resposta:** * **Código:** **200**
@@ -320,11 +315,6 @@ Método que retorna as opções de fase do requerimento de mineração. Nenhum -* **Exemplo:** - - **Rota:** - /api/invasions/phase - * **Resposta:** * **Código:** **200**
From 80b6db4648f6d6a5419c12a131923493e510625f Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 20 Sep 2021 14:08:41 -0300 Subject: [PATCH 071/121] Add requirement phase filter --- README.md | 2 ++ src/dtos/IFiltersDTO.ts | 1 + src/dtos/IInvasionDTO.ts | 1 + src/repositories/implementations/InvasionRepository.ts | 6 ++++++ .../implementations/ReserveInvasionRepository.ts | 6 ++++++ 5 files changed, 16 insertions(+) diff --git a/README.md b/README.md index a620e57..5ded98c 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "substance": [], //Array de strings com o nome das substâncias "reservePhase": [], //Array de strings com as fases do processo de homologação das terras indígenas "reserveEthnicity": [], //Array de strings com o nome das etinias de terras indígenas + "requirementPhase": [], //Array de strings com as fases dos requerimentos de mineração }, "enableUnity": true, //Boolean para ativar/desativar dados de ucs (default: true) "enableReserve": true, //Boolean para ativar/desativar dados de Terras Indígenas (default: true) @@ -199,6 +200,7 @@ Método que retorna as estatísticas gerais (número de requerimentos e área) d "substance": [], //Array de strings com o nome das substâncias "reservePhase": [], //Array de strings com as fases do processo de homologação das terras indígenas "reserveEthnicity": [], //Array de strings com o nome das etinias de terras indígenas + "requirementPhase": [], //Array de strings com as fases dos requerimentos de mineração } } ``` diff --git a/src/dtos/IFiltersDTO.ts b/src/dtos/IFiltersDTO.ts index ff9fc9d..69a79a8 100644 --- a/src/dtos/IFiltersDTO.ts +++ b/src/dtos/IFiltersDTO.ts @@ -5,6 +5,7 @@ interface IFiltersDTO { company?: string[] year?: string[] substance?: string[] + requirementPhase?: string[] reservePhase?: string[] reserveEthnicity?: string[] } diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts index d3478bd..c115213 100644 --- a/src/dtos/IInvasionDTO.ts +++ b/src/dtos/IInvasionDTO.ts @@ -6,6 +6,7 @@ interface IInvasionDTO { state: string miningProcess: string substance: string + requirementPhase: string territory: string reservePhase?: string reserveEthnicity?: string diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 59f75ec..41c5e38 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -44,6 +44,12 @@ class InvasionRepository implements IInvasionRepository { } } + if (filters.requirementPhase && filters.requirementPhase.length > 0) { + match['properties.FASE'] = { + $in: filters.requirementPhase, + } + } + const invasions = await Invasion.aggregate([ { $match: match }, { diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index a07fc13..222e8aa 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -59,6 +59,12 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { } } + if (filters.requirementPhase && filters.requirementPhase.length > 0) { + match['properties.FASE'] = { + $in: filters.requirementPhase, + } + } + const invasions = await ReserveInvasion.aggregate([ { $match: match }, { From aa9a3077b3b30487583e9c0117bf00df015800f9 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 20 Sep 2021 15:35:59 -0300 Subject: [PATCH 072/121] Implement csv download in listing --- package.json | 2 ++ src/dtos/IInvasionDTO.ts | 1 - .../listInvasions/ListInvasionsController.ts | 20 +++++++++--- .../listInvasions/ListInvasionsService.ts | 10 ++---- yarn.lock | 31 +++++++++++++++++++ 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 401d1c5..b967812 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dotenv-safe": "^8.2.0", "express": "^4.17.1", "express-async-errors": "^3.1.1", + "json2csv": "^5.0.6", "mongoose": "^6.0.0", "reflect-metadata": "^0.1.13", "tsyringe": "^4.6.0" @@ -21,6 +22,7 @@ "@types/cors": "^2.8.12", "@types/dotenv-safe": "^8.1.2", "@types/express": "^4.17.13", + "@types/json2csv": "^5.0.3", "@typescript-eslint/eslint-plugin": "^4.29.3", "@typescript-eslint/parser": "^4.29.3", "eslint": "^7.32.0", diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts index c115213..d3478bd 100644 --- a/src/dtos/IInvasionDTO.ts +++ b/src/dtos/IInvasionDTO.ts @@ -6,7 +6,6 @@ interface IInvasionDTO { state: string miningProcess: string substance: string - requirementPhase: string territory: string reservePhase?: string reserveEthnicity?: string diff --git a/src/services/listInvasions/ListInvasionsController.ts b/src/services/listInvasions/ListInvasionsController.ts index 480b3bd..46c5592 100644 --- a/src/services/listInvasions/ListInvasionsController.ts +++ b/src/services/listInvasions/ListInvasionsController.ts @@ -1,24 +1,34 @@ import { Request, Response } from 'express' +import json2csv from 'json2csv' import { container } from 'tsyringe' +import { paginate } from '../../utils/pagination' import { ListInvasionsService } from './ListInvasionsService' class ListInvasionsController { async handle(request: Request, response: Response): Promise { const { filters, enableUnity, enableReserve } = request.body - const { page, pageSize } = request.query + const { page, pageSize, output } = request.query const listInvasionsService = container.resolve(ListInvasionsService) const invasions = await listInvasionsService.execute( filters, enableUnity, - enableReserve, - Number(page) || undefined, - Number(pageSize) || undefined + enableReserve ) - return response.json(invasions) + if (output === 'csv') { + const data = json2csv.parse(invasions) + return response.attachment('invasions.csv').status(200).send(data) + } + + const pageNumber = Number(page) || 1 + const pageSizeNumber = Number(pageSize) || 10 + + const paginatedInvasions = paginate(invasions, pageNumber, pageSizeNumber) + + return response.json(paginatedInvasions) } } diff --git a/src/services/listInvasions/ListInvasionsService.ts b/src/services/listInvasions/ListInvasionsService.ts index 3682f18..4dff91e 100644 --- a/src/services/listInvasions/ListInvasionsService.ts +++ b/src/services/listInvasions/ListInvasionsService.ts @@ -2,10 +2,8 @@ import { inject, injectable } from 'tsyringe' import { IFiltersDTO } from '../../dtos/IFiltersDTO' import { IInvasionDTO } from '../../dtos/IInvasionDTO' -import { IPaginationDTO } from '../../dtos/IPaginationDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' -import { paginate } from '../../utils/pagination' @injectable() class ListInvasionsService { @@ -20,10 +18,8 @@ class ListInvasionsService { async execute( filters: IFiltersDTO, enableUnity: boolean = true, - enableReserve: boolean = true, - page: number = 1, - pageSize: number = 10 - ): Promise { + enableReserve: boolean = true + ): Promise { let reserveInvasions: IInvasionDTO[] = [] let invasions: IInvasionDTO[] = [] @@ -48,7 +44,7 @@ class ListInvasionsService { return b.year - a.year }) - return paginate(sortedResults, page, pageSize) + return sortedResults } } diff --git a/yarn.lock b/yarn.lock index f7ddacf..0e1fd68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -124,6 +124,13 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== +"@types/json2csv@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/json2csv/-/json2csv-5.0.3.tgz#759514772a90e35b08c10808dedeaf52248af418" + integrity sha512-ZJEv6SzhPhgpBpxZU4n/TZekbZqI4EcyXXRwms1lAITG2kIAtj85PfNYafUOY1zy8bWs5ujaub0GU4copaA0sw== + dependencies: + "@types/node" "*" + "@types/mime@^1": version "1.3.2" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" @@ -501,6 +508,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +commander@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -1416,6 +1428,15 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= +json2csv@^5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/json2csv/-/json2csv-5.0.6.tgz#590e0e1b9579e59baa53bda0c0d840f4d8009687" + integrity sha512-0/4Lv6IenJV0qj2oBdgPIAmFiKKnh8qh7bmLFJ+/ZZHLjSeiL3fKKGX3UryvKPbxFbhV+JcYo9KUC19GJ/Z/4A== + dependencies: + commander "^6.1.0" + jsonparse "^1.3.1" + lodash.get "^4.4.2" + json5@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" @@ -1423,6 +1444,11 @@ json5@^2.2.0: dependencies: minimist "^1.2.5" +jsonparse@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + kareem@2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.3.2.tgz#78c4508894985b8d38a0dc15e1a8e11078f2ca93" @@ -1459,6 +1485,11 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" From 7dd3b7c37d5abd4d1c2abb7702ab8dcf26d02fbb Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 20 Sep 2021 15:39:14 -0300 Subject: [PATCH 073/121] Change readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5ded98c..0ea5d67 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C - page?:[number] - Número da página de registros a ser retornada, retorna a primeira página caso um número não seja informado. - pageSize?:[number] - Número de requerimentos por página, caso não seja informado são retornados 10 por página. + - output?:[string] - Formato de saída (permitidos: csv). * **Parâmetros no Body:** From 57ccdaecf5fcfdfb907b9eec3262bdbb3bf98ded Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Tue, 21 Sep 2021 11:22:48 -0300 Subject: [PATCH 074/121] Add filters to ranking documentation --- README.md | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3e9a20c..5a85714 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,16 @@ Método que retorna as opções de fase do processo de homologação de terras i **Rota:** /api/reserves/phase + **Body:** + ```javascript + { + "filters": { + "state": ["Amazonas"], + "reserve": ["Andirá-Marau"] + } + } + ``` + * **Resposta:** * **Código:** **200**
@@ -302,17 +312,28 @@ Método que retorna o ranking de acordo com o território e o tipo de dado espec * **Método:** - `GET` + `POST` * **Parâmetros na URL:** - territoryType:[string] - Tipo de território a ser utilizado na construção do ranking('company', 'state', 'unity', 'reserve'). - - dataType:[string] - Tipo de dado a ser retornado, 'incidenceRequiriments' para a frequencia de requerimentos em território e 'requiredArea' para área total dos requerimentos por território. + - dataType:[string] - Tipo de dado a ser retornado, 'requirementsIncidence' para a frequencia de requerimentos em território e 'requiredArea' para área total dos requerimentos por território. - page?:[number] - Número da página de registros a ser retornada, retorna todos os registros caso um número não seja informado. * **Parâmetros no Body:** - Nenhum + ```javascript + { + "filters": { + "state": [], //Array de strings com o nome dos estados + "company": [], //Array de strings com o nome das empresas + "reserve": [], //Array de strings com o nome das Terras Indígenas + "unity": [], //Array de strings com o nome das Unidades de Conservação + "year": [], //Array de inteiros com os anos + "substance": [], //Array de strings com o nome das substâncias + } + } + ``` * **Exemplo:** From 86a2cdfd308ed1c9638d5a376994f0af907dc389 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Tue, 21 Sep 2021 11:23:33 -0300 Subject: [PATCH 075/121] Add filters to object interfcae --- src/dtos/IRankingDTO.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dtos/IRankingDTO.ts b/src/dtos/IRankingDTO.ts index c9813c7..f85c4f1 100644 --- a/src/dtos/IRankingDTO.ts +++ b/src/dtos/IRankingDTO.ts @@ -1,3 +1,5 @@ +import { IFiltersDTO } from './IFiltersDTO' + interface IResponseRankingDTO { x: string y: number @@ -7,6 +9,7 @@ interface IRequestRankingDTO { territoryType: string page: number dataType: string + filters: IFiltersDTO } export { IRequestRankingDTO, IResponseRankingDTO } From 679ecd8709b796b41a577e9a13b9718f245b8baa Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Tue, 21 Sep 2021 11:24:21 -0300 Subject: [PATCH 076/121] Create function to return the match object to query --- .../implementations/InvasionRepository.ts | 77 +++++++++++-------- .../ReserveInvasionRepository.ts | 77 +++++++++++-------- 2 files changed, 86 insertions(+), 68 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 73c5411..3b25c9b 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -9,40 +9,7 @@ import { IInvasionRepository } from '../IInvasionRepository' class InvasionRepository implements IInvasionRepository { async listInvasions(filters: IFiltersDTO): Promise { - const match: any = {} - - if (filters.unity && filters.unity.length > 0) { - match['properties.UC_NOME'] = { - $in: filters.unity, - } - } - - if (filters.company && filters.company.length > 0) { - match['properties.NOME'] = { - $in: filters.company, - } - } - - if (filters.year && filters.year.length > 0) { - match['properties.ANO'] = { - $in: filters.year, - } - } - - if (filters.state && filters.state.length > 0) { - const acronymsRegex = filters.state.map( - (state) => new RegExp(`.*${getStateAcronym(state)}.*`, 'i') - ) - match['properties.UF'] = { - $in: acronymsRegex, - } - } - - if (filters.substance && filters.substance.length > 0) { - match['properties.SUBS'] = { - $in: filters.substance, - } - } + const match = await this.getMatchProperty(filters) const invasions = await Invasion.aggregate([ { $match: match }, @@ -102,9 +69,12 @@ class InvasionRepository implements IInvasionRepository { async invasionRanking({ territoryType, dataType, + filters, }: IRequestRankingDTO): Promise { const propertie = rankingFilter[territoryType] + const match = await this.getMatchProperty(filters) const territories = await Invasion.aggregate([ + { $match: match }, { $group: { _id: propertie, @@ -124,6 +94,45 @@ class InvasionRepository implements IInvasionRepository { ]) return territories } + + private async getMatchProperty(filters: IFiltersDTO) { + const match: any = {} + + if (filters.unity && filters.unity.length > 0) { + match['properties.UC_NOME'] = { + $in: filters.unity, + } + } + + if (filters.company && filters.company.length > 0) { + match['properties.NOME'] = { + $in: filters.company, + } + } + + if (filters.year && filters.year.length > 0) { + match['properties.ANO'] = { + $in: filters.year, + } + } + + if (filters.state && filters.state.length > 0) { + const acronymsRegex = filters.state.map( + (state) => new RegExp(`.*${getStateAcronym(state)}.*`, 'i') + ) + match['properties.UF'] = { + $in: acronymsRegex, + } + } + + if (filters.substance && filters.substance.length > 0) { + match['properties.SUBS'] = { + $in: filters.substance, + } + } + + return match + } } export { InvasionRepository } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 1850da9..4734c4e 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -9,40 +9,7 @@ import { IReserveInvasionRepository } from '../IReserveInvasionRepository' class ReserveInvasionRepository implements IReserveInvasionRepository { async listInvasions(filters: IFiltersDTO): Promise { - const match: any = {} - - if (filters.reserve && filters.reserve.length > 0) { - match['properties.TI_NOME'] = { - $in: filters.reserve, - } - } - - if (filters.company && filters.company.length > 0) { - match['properties.NOME'] = { - $in: filters.company, - } - } - - if (filters.year && filters.year.length > 0) { - match['properties.ANO'] = { - $in: filters.year, - } - } - - if (filters.state && filters.state.length > 0) { - const acronymsRegex = filters.state.map( - (state) => new RegExp(`.*${getStateAcronym(state)}.*`, 'i') - ) - match['properties.UF'] = { - $in: acronymsRegex, - } - } - - if (filters.substance && filters.substance.length > 0) { - match['properties.SUBS'] = { - $in: filters.substance, - } - } + const match = await this.getMatchProperty(filters) const invasions = await ReserveInvasion.aggregate([ { $match: match }, @@ -103,9 +70,12 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { async reserveInvasionRanking({ territoryType, dataType, + filters, }: IRequestRankingDTO): Promise { const propertie = rankingFilter[territoryType] + const match = await this.getMatchProperty(filters) const territories = await ReserveInvasion.aggregate([ + { $match: match }, { $group: { _id: propertie, @@ -126,6 +96,45 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { return territories } + + private async getMatchProperty(filters: IFiltersDTO) { + const match: any = {} + + if (filters.reserve && filters.reserve.length > 0) { + match['properties.TI_NOME'] = { + $in: filters.reserve, + } + } + + if (filters.company && filters.company.length > 0) { + match['properties.NOME'] = { + $in: filters.company, + } + } + + if (filters.year && filters.year.length > 0) { + match['properties.ANO'] = { + $in: filters.year, + } + } + + if (filters.state && filters.state.length > 0) { + const acronymsRegex = filters.state.map( + (state) => new RegExp(`.*${getStateAcronym(state)}.*`, 'i') + ) + match['properties.UF'] = { + $in: acronymsRegex, + } + } + + if (filters.substance && filters.substance.length > 0) { + match['properties.SUBS'] = { + $in: filters.substance, + } + } + + return match + } } export { ReserveInvasionRepository } From 4d8386aff4db8b5bec23d9da1f62bc8aa3fc1490 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Tue, 21 Sep 2021 11:24:31 -0300 Subject: [PATCH 077/121] Change method type --- src/routes/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/index.ts b/src/routes/index.ts index c45e368..6ee9d6d 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -16,7 +16,7 @@ const getReservesPhaseController = new GetReservesPhaseController() router.get('/search/:searchTerm', searchController.handle) router.post('/invasions', listInvasionsController.handle) -router.get( +router.post( '/invasions/ranking/:territoryType/:dataType', invasionFrequencyController.handle ) From 63c19c153715fdf183c384b878f365a635f36729 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Tue, 21 Sep 2021 11:27:02 -0300 Subject: [PATCH 078/121] Add filter to object DTO --- .../invasionRanking/InvasionRankingController.ts | 2 ++ .../invasionRanking/InvasionRankingService.ts | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/services/invasionRanking/InvasionRankingController.ts b/src/services/invasionRanking/InvasionRankingController.ts index cd16ab8..c72b1a2 100644 --- a/src/services/invasionRanking/InvasionRankingController.ts +++ b/src/services/invasionRanking/InvasionRankingController.ts @@ -6,12 +6,14 @@ import { InvasionFrequencyService } from './InvasionRankingService' class InvasionFrequencyController { async handle(request: Request, response: Response): Promise { const { territoryType, dataType } = request.params + const { filters } = request.body const { page } = request.query const invasionFrequencyService = container.resolve(InvasionFrequencyService) const rankingData = await invasionFrequencyService.execute({ territoryType, dataType, page: Number(page), + filters, }) return response.status(200).json(rankingData) } diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index c41118d..c6591e2 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -15,18 +15,25 @@ class InvasionFrequencyService { private invasionRepository: IInvasionRepository ) {} - async execute({ territoryType, page, dataType }: IRequestRankingDTO) { + async execute({ + territoryType, + page, + dataType, + filters, + }: IRequestRankingDTO) { if (territoryType === 'state' || territoryType === 'company') { const reserveResults = await this.reserveInvasionRepository.reserveInvasionRanking({ territoryType, page, dataType, + filters, }) const invasionResults = await this.invasionRepository.invasionRanking({ territoryType, page, dataType, + filters, }) return await this.formatDoubleRanking( reserveResults, @@ -40,6 +47,7 @@ class InvasionFrequencyService { territoryType, page, dataType, + filters, }) return await this.formatSingleRanking( results, @@ -53,6 +61,7 @@ class InvasionFrequencyService { territoryType, page, dataType, + filters, }) return await this.formatSingleRanking( results, From bb2dcb1ac2460137b100588c803ae4bd065b3b32 Mon Sep 17 00:00:00 2001 From: Neto1904 Date: Wed, 22 Sep 2021 10:45:20 -0300 Subject: [PATCH 079/121] Complete function to get match property --- .../implementations/InvasionRepository.ts | 12 +++--- .../ReserveInvasionRepository.ts | 42 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 720aa09..156ec2e 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -11,12 +11,6 @@ class InvasionRepository implements IInvasionRepository { async listInvasions(filters: IFiltersDTO): Promise { const match = await this.getMatchProperty(filters) - if (filters.requirementPhase && filters.requirementPhase.length > 0) { - match['properties.FASE'] = { - $in: filters.requirementPhase, - } - } - const invasions = await Invasion.aggregate([ { $match: match }, { @@ -137,6 +131,12 @@ class InvasionRepository implements IInvasionRepository { } } + if (filters.requirementPhase && filters.requirementPhase.length > 0) { + match['properties.FASE'] = { + $in: filters.requirementPhase, + } + } + return match } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 521e124..526f8cf 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -11,27 +11,6 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { async listInvasions(filters: IFiltersDTO): Promise { const match = await this.getMatchProperty(filters) - if (filters.reservePhase && filters.reservePhase.length > 0) { - match['properties.TI_FASE'] = { - $in: filters.reservePhase, - } - } - - if (filters.reserveEthnicity && filters.reserveEthnicity.length > 0) { - const ethnicitiesRegex = filters.reserveEthnicity.map( - (ethnicity) => new RegExp(`.*${ethnicity}.*`, 'i') - ) - match['properties.TI_ETNIA'] = { - $in: ethnicitiesRegex, - } - } - - if (filters.requirementPhase && filters.requirementPhase.length > 0) { - match['properties.FASE'] = { - $in: filters.requirementPhase, - } - } - const invasions = await ReserveInvasion.aggregate([ { $match: match }, { @@ -158,6 +137,27 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { } } + if (filters.reservePhase && filters.reservePhase.length > 0) { + match['properties.TI_FASE'] = { + $in: filters.reservePhase, + } + } + + if (filters.reserveEthnicity && filters.reserveEthnicity.length > 0) { + const ethnicitiesRegex = filters.reserveEthnicity.map( + (ethnicity) => new RegExp(`.*${ethnicity}.*`, 'i') + ) + match['properties.TI_ETNIA'] = { + $in: ethnicitiesRegex, + } + } + + if (filters.requirementPhase && filters.requirementPhase.length > 0) { + match['properties.FASE'] = { + $in: filters.requirementPhase, + } + } + return match } From a7eb66824211943822332cb3666d72c8eaa2d578 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 22 Sep 2021 11:05:55 -0300 Subject: [PATCH 080/121] Create function to group invasions by process --- src/utils/group.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/utils/group.ts diff --git a/src/utils/group.ts b/src/utils/group.ts new file mode 100644 index 0000000..fb4cee1 --- /dev/null +++ b/src/utils/group.ts @@ -0,0 +1,18 @@ +import { IInvasionDTO } from '../dtos/IInvasionDTO' + +export function groupInvasions( + reserveInvasions: IInvasionDTO[], + invasions: IInvasionDTO[] +): IInvasionDTO[] { + const invasionsMap = new Map() + + reserveInvasions.forEach((invasion: IInvasionDTO) => + invasionsMap.set(invasion.process, invasion) + ) + + invasions.forEach((invasion: IInvasionDTO) => + invasionsMap.set(invasion.process, invasion) + ) + + return Array.from(invasionsMap.values()) +} From 5ccccaa2142daf30c857a3b5dca8a977f9dfcd2d Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 22 Sep 2021 11:30:25 -0300 Subject: [PATCH 081/121] Change statistics to handle duplicated requirements --- .../getStatistics/GetStatisticsService.ts | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/services/getStatistics/GetStatisticsService.ts b/src/services/getStatistics/GetStatisticsService.ts index a2ac763..0b37c3e 100644 --- a/src/services/getStatistics/GetStatisticsService.ts +++ b/src/services/getStatistics/GetStatisticsService.ts @@ -1,9 +1,11 @@ import { inject, injectable } from 'tsyringe' import { IFiltersDTO } from '../../dtos/IFiltersDTO' +import { IInvasionDTO } from '../../dtos/IInvasionDTO' import { IStatisticsDTO } from '../../dtos/IStatisticsDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { groupInvasions } from '../../utils/group' @injectable() class GetStatisticsService { @@ -29,9 +31,13 @@ class GetStatisticsService { }, } + let reserveInvasions: IInvasionDTO[] = [] + let invasions: IInvasionDTO[] = [] + if ((!filters.reserve && !filters.unity) || filters.reserve) { - const reserveInvasions = - await this.reserveInvasionRepository.listInvasions(filters) + reserveInvasions = await this.reserveInvasionRepository.listInvasions( + filters + ) statistics.requirementsIncidence.reserve = reserveInvasions.length let sumArea = 0.0 @@ -40,7 +46,7 @@ class GetStatisticsService { } if ((!filters.reserve && !filters.unity) || filters.unity) { - const invasions = await this.invasionRepository.listInvasions(filters) + invasions = await this.invasionRepository.listInvasions(filters) statistics.requirementsIncidence.unity = invasions.length let sumArea = 0.0 @@ -48,12 +54,13 @@ class GetStatisticsService { statistics.requiredArea.unity = parseFloat(sumArea.toFixed(2)) } - statistics.requirementsIncidence.total = - statistics.requirementsIncidence.reserve + - statistics.requirementsIncidence.unity + const groupedInvasions = groupInvasions(reserveInvasions, invasions) + + statistics.requirementsIncidence.total = groupedInvasions.length - statistics.requiredArea.total = - statistics.requiredArea.reserve + statistics.requiredArea.unity + let sumArea = 0.0 + groupedInvasions.forEach((invasion) => (sumArea += invasion.area || 0)) + statistics.requiredArea.total = parseFloat(sumArea.toFixed(2)) return statistics } From 74a027b10d69e0f07c22fa4017b35b8ef898f0c2 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 22 Sep 2021 16:00:08 -0300 Subject: [PATCH 082/121] Change listing order to sort by year and by process --- .../implementations/InvasionRepository.ts | 7 ++-- .../ReserveInvasionRepository.ts | 36 +++++++++++++++++-- .../listInvasions/ListInvasionsService.ts | 13 ++++++- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 156ec2e..b1ce1ce 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -9,7 +9,7 @@ import { IInvasionRepository } from '../IInvasionRepository' class InvasionRepository implements IInvasionRepository { async listInvasions(filters: IFiltersDTO): Promise { - const match = await this.getMatchProperty(filters) + const match = this.getMatchProperty(filters) const invasions = await Invasion.aggregate([ { $match: match }, @@ -39,6 +39,7 @@ class InvasionRepository implements IInvasionRepository { _id: 0, }, }, + { $sort: { year: -1, process: 1 } }, ]) return invasions @@ -72,7 +73,7 @@ class InvasionRepository implements IInvasionRepository { filters, }: IRequestRankingDTO): Promise { const propertie = rankingFilter[territoryType] - const match = await this.getMatchProperty(filters) + const match = this.getMatchProperty(filters) const territories = await Invasion.aggregate([ { $match: match }, { @@ -95,7 +96,7 @@ class InvasionRepository implements IInvasionRepository { return territories } - private async getMatchProperty(filters: IFiltersDTO) { + private getMatchProperty(filters: IFiltersDTO) { const match: any = {} if (filters.unity && filters.unity.length > 0) { diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 526f8cf..5c75f0c 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -3,13 +3,42 @@ import { IFiltersDTO } from '../../dtos/IFiltersDTO' import { IInvasionDTO } from '../../dtos/IInvasionDTO' import { IRequestRankingDTO, IResponseRankingDTO } from '../../dtos/IRankingDTO' import { ISearchDTO } from '../../dtos/ISearchDTO' +import { IShapeDTO } from '../../dtos/IShapeDTO' import { rankingFilter } from '../../utils/rankingFilter' import { getStateAcronym } from '../../utils/states' import { IReserveInvasionRepository } from '../IReserveInvasionRepository' class ReserveInvasionRepository implements IReserveInvasionRepository { + async getShape(filters: IFiltersDTO): Promise { + const match = this.getMatchProperty(filters) + const invasions: IShapeDTO[] = await ReserveInvasion.aggregate([ + { $match: match }, + { + $project: { + _id: 0, + type: '$type', + properties: { + company: '$properties.NOME', + process: '$properties.PROCESSO', + area: '$properties.AREA_HA', + year: '$properties.ANO', + state: '$properties.UF', + miningProcess: '$properties.FASE', + territory: '$properties.TI_NOME', + reservePhase: '$properties.TI_FASE', + reserveEthnicity: '$properties.TI_ETNIA', + type: 'indigenousLand', + substance: '$properties.SUBS', + }, + geometry: '$geometry', + }, + }, + ]) + return invasions + } + async listInvasions(filters: IFiltersDTO): Promise { - const match = await this.getMatchProperty(filters) + const match = this.getMatchProperty(filters) const invasions = await ReserveInvasion.aggregate([ { $match: match }, @@ -43,6 +72,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { _id: 0, }, }, + { $sort: { year: -1, process: 1 } }, ]) return invasions @@ -77,7 +107,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { filters, }: IRequestRankingDTO): Promise { const propertie = rankingFilter[territoryType] - const match = await this.getMatchProperty(filters) + const match = this.getMatchProperty(filters) const territories = await ReserveInvasion.aggregate([ { $match: match }, { @@ -101,7 +131,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { return territories } - private async getMatchProperty(filters: IFiltersDTO) { + private getMatchProperty(filters: IFiltersDTO) { const match: any = {} if (filters.reserve && filters.reserve.length > 0) { diff --git a/src/services/listInvasions/ListInvasionsService.ts b/src/services/listInvasions/ListInvasionsService.ts index 4dff91e..b087d20 100644 --- a/src/services/listInvasions/ListInvasionsService.ts +++ b/src/services/listInvasions/ListInvasionsService.ts @@ -41,7 +41,18 @@ class ListInvasionsService { const results = invasions.concat(reserveInvasions) const sortedResults = results.sort((a, b) => { - return b.year - a.year + if (b.year > a.year) { + return 1 + } else if (b.year < a.year) { + return -1 + } else { + if (b.process > a.process) { + return 1 + } else if (b.process < a.process) { + return -1 + } + return 0 + } }) return sortedResults From eb3e144bf7aa39e8e5765f9fd76a372e68a5475f Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 23 Sep 2021 12:26:42 -0300 Subject: [PATCH 083/121] Create method to return requirements shape --- README.md | 108 ++++++++++++++++++ package.json | 2 + src/dtos/IShapeDTO.ts | 10 ++ src/repositories/IInvasionRepository.ts | 2 + .../IReserveInvasionRepository.ts | 2 + .../implementations/InvasionRepository.ts | 24 ++++ .../ReserveInvasionRepository.ts | 25 ++-- src/routes/index.ts | 3 + .../GetInvasionsShapeController.ts | 21 ++++ .../GetInvasionsShapeService.ts | 60 ++++++++++ yarn.lock | 10 ++ 11 files changed, 253 insertions(+), 14 deletions(-) create mode 100644 src/dtos/IShapeDTO.ts create mode 100644 src/services/getInvasionsShape/GetInvasionsShapeController.ts create mode 100644 src/services/getInvasionsShape/GetInvasionsShapeService.ts diff --git a/README.md b/README.md index d83c78a..2ec37a9 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,114 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C ``` **Descrição:** Erro interno do servidor. +**Shape dos Requerimentos** +---- +Método que retorna os shapes dos requerimentos minerários em Unidades de Conservação e em Terras Indígenas de acordo com os filtros. + +* **URL:** + + /api/invasions/shape + +* **Método:** + + `POST` + +* **Parâmetros na URL:** + + Nenhum + +* **Parâmetros no Body:** + + ```javascript + { + "filters": { + "state": [], //Array de strings com o nome dos estados + "company": [], //Array de strings com o nome das empresas + "reserve": [], //Array de strings com o nome das Terras Indígenas + "unity": [], //Array de strings com o nome das Unidades de Conservação + "year": [], //Array de inteiros com os anos + "substance": [], //Array de strings com o nome das substâncias + "reservePhase": [], //Array de strings com as fases do processo de homologação das terras indígenas + "reserveEthnicity": [], //Array de strings com o nome das etinias de terras indígenas + "requirementPhase": [], //Array de strings com as fases dos requerimentos de mineração + }, + "enableUnity": true, //Boolean para ativar/desativar dados de ucs (default: true) + "enableReserve": true, //Boolean para ativar/desativar dados de Terras Indígenas (default: true) + } + ``` + **Descrição:** Todos os filtros são parâmetros opcionais e podem ser combinados. + +* **Exemplo:** + + **Body:** + ```javascript + { + "filters": { + "company": ["Willian Araújo dos Santos"], + "state": ["Amazonas"], + "year": [2021], + "substance": ["MINÉRIO DE ESTANHO"] + }, + "enableReserve": false + } + ``` + +* **Resposta:** + + * **Código:** **200**
+ **Conteúdo:** + + ```javascript + { + "reserve": { + "type": "FeatureCollection", + "features": [] + }, + "unity": { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -65.12691752799992, + -0.32426850299992793 + ], + ... + ] + ] + }, + "properties": { + "company": "Willian Araújo dos Santos", + "process": "880084/2021", + "area": 176.54, + "year": 2021, + "state": "AM", + "miningProcess": "REQUERIMENTO DE PESQUISA", + "territory": "PARQUE NACIONAL DO PICO DA NEBLINA", + "type": "protectedArea", + "substance": "MINÉRIO DE ESTANHO" + } + }, + ... + ] + } + } + ``` + **Descrição:** Retorna um objeto que contém os requerimentos em terras indígenas (reserve) e os requerimentos em unidades de conservação (unity) como FeatureCollections. + + * **Código:** **500**
+ **Conteúdo:** + ```javascript + { + "message": "Internal Server Error" + } + ``` + **Descrição:** Erro interno do servidor. + **Estatísticas** ---- Método que retorna as estatísticas gerais (número de requerimentos e área) de Terras Indígenas e Unidades de Conservação de acordo com os filtros. diff --git a/package.json b/package.json index b967812..9f1446f 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dotenv-safe": "^8.2.0", "express": "^4.17.1", "express-async-errors": "^3.1.1", + "geojson": "^0.5.0", "json2csv": "^5.0.6", "mongoose": "^6.0.0", "reflect-metadata": "^0.1.13", @@ -22,6 +23,7 @@ "@types/cors": "^2.8.12", "@types/dotenv-safe": "^8.1.2", "@types/express": "^4.17.13", + "@types/geojson": "^7946.0.8", "@types/json2csv": "^5.0.3", "@typescript-eslint/eslint-plugin": "^4.29.3", "@typescript-eslint/parser": "^4.29.3", diff --git a/src/dtos/IShapeDTO.ts b/src/dtos/IShapeDTO.ts new file mode 100644 index 0000000..6a76225 --- /dev/null +++ b/src/dtos/IShapeDTO.ts @@ -0,0 +1,10 @@ +import { IInvasionDTO } from './IInvasionDTO' + +interface IShapeDTO extends IInvasionDTO { + geometry: { + type: string + coordinates: any + } +} + +export { IShapeDTO } diff --git a/src/repositories/IInvasionRepository.ts b/src/repositories/IInvasionRepository.ts index fc99b76..aac2bb6 100644 --- a/src/repositories/IInvasionRepository.ts +++ b/src/repositories/IInvasionRepository.ts @@ -2,6 +2,7 @@ import { IFiltersDTO } from '../dtos/IFiltersDTO' import { IInvasionDTO } from '../dtos/IInvasionDTO' import { IRequestRankingDTO, IResponseRankingDTO } from '../dtos/IRankingDTO' import { ISearchDTO } from '../dtos/ISearchDTO' +import { IShapeDTO } from '../dtos/IShapeDTO' interface IInvasionRepository { searchCompany(searchTerm: string): Promise @@ -11,6 +12,7 @@ interface IInvasionRepository { dataType, }: IRequestRankingDTO): Promise getRequirementsPhase(): Promise + getShape(filters: IFiltersDTO): Promise } export { IInvasionRepository } diff --git a/src/repositories/IReserveInvasionRepository.ts b/src/repositories/IReserveInvasionRepository.ts index 501be45..ca81e24 100644 --- a/src/repositories/IReserveInvasionRepository.ts +++ b/src/repositories/IReserveInvasionRepository.ts @@ -2,6 +2,7 @@ import { IFiltersDTO } from '../dtos/IFiltersDTO' import { IInvasionDTO } from '../dtos/IInvasionDTO' import { IRequestRankingDTO, IResponseRankingDTO } from '../dtos/IRankingDTO' import { ISearchDTO } from '../dtos/ISearchDTO' +import { IShapeDTO } from '../dtos/IShapeDTO' interface IReserveInvasionRepository { searchCompany(searchTerm: string): Promise @@ -11,6 +12,7 @@ interface IReserveInvasionRepository { dataType, }: IRequestRankingDTO): Promise getRequirementsPhase(): Promise + getShape(filters: IFiltersDTO): Promise } export { IReserveInvasionRepository } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index b1ce1ce..b82a42d 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -3,11 +3,35 @@ import { IFiltersDTO } from '../../dtos/IFiltersDTO' import { IInvasionDTO } from '../../dtos/IInvasionDTO' import { IRequestRankingDTO, IResponseRankingDTO } from '../../dtos/IRankingDTO' import { ISearchDTO } from '../../dtos/ISearchDTO' +import { IShapeDTO } from '../../dtos/IShapeDTO' import { rankingFilter } from '../../utils/rankingFilter' import { getStateAcronym } from '../../utils/states' import { IInvasionRepository } from '../IInvasionRepository' class InvasionRepository implements IInvasionRepository { + async getShape(filters: IFiltersDTO): Promise { + const match = this.getMatchProperty(filters) + const invasions: IShapeDTO[] = await Invasion.aggregate([ + { $match: match }, + { + $project: { + _id: 0, + company: '$properties.NOME', + process: '$properties.PROCESSO', + area: '$properties.AREA_HA', + year: '$properties.ANO', + state: '$properties.UF', + miningProcess: '$properties.FASE', + territory: '$properties.UC_NOME', + type: 'protectedArea', + substance: '$properties.SUBS', + geometry: '$geometry', + }, + }, + ]) + return invasions + } + async listInvasions(filters: IFiltersDTO): Promise { const match = this.getMatchProperty(filters) diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 5c75f0c..b9563c5 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -16,20 +16,17 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { { $project: { _id: 0, - type: '$type', - properties: { - company: '$properties.NOME', - process: '$properties.PROCESSO', - area: '$properties.AREA_HA', - year: '$properties.ANO', - state: '$properties.UF', - miningProcess: '$properties.FASE', - territory: '$properties.TI_NOME', - reservePhase: '$properties.TI_FASE', - reserveEthnicity: '$properties.TI_ETNIA', - type: 'indigenousLand', - substance: '$properties.SUBS', - }, + company: '$properties.NOME', + process: '$properties.PROCESSO', + area: '$properties.AREA_HA', + year: '$properties.ANO', + state: '$properties.UF', + miningProcess: '$properties.FASE', + territory: '$properties.TI_NOME', + reservePhase: '$properties.TI_FASE', + reserveEthnicity: '$properties.TI_ETNIA', + type: 'indigenousLand', + substance: '$properties.SUBS', geometry: '$geometry', }, }, diff --git a/src/routes/index.ts b/src/routes/index.ts index c6cdcb6..a758038 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,5 +1,6 @@ import { Router } from 'express' +import { GetInvasionsShapeController } from '../services/getInvasionsShape/GetInvasionsShapeController' import { GetRequirementsPhaseController } from '../services/getRequirementsPhase/GetRequirementsPhaseController' import { GetReservesPhaseController } from '../services/getReservesPhase/GetReservesPhaseController' import { GetStatisticsController } from '../services/getStatistics/GetStatisticsController' @@ -15,6 +16,7 @@ const invasionFrequencyController = new InvasionFrequencyController() const getStatisticsController = new GetStatisticsController() const getReservesPhaseController = new GetReservesPhaseController() const getRequirementsPhaseController = new GetRequirementsPhaseController() +const getInvasionsShapeController = new GetInvasionsShapeController() router.get('/search/:searchTerm', searchController.handle) router.post('/invasions', listInvasionsController.handle) @@ -23,6 +25,7 @@ router.post( invasionFrequencyController.handle ) router.get('/invasions/phase', getRequirementsPhaseController.handle) +router.post('/invasions/shape', getInvasionsShapeController.handle) router.post('/statistics', getStatisticsController.handle) router.get('/reserves/phase', getReservesPhaseController.handle) diff --git a/src/services/getInvasionsShape/GetInvasionsShapeController.ts b/src/services/getInvasionsShape/GetInvasionsShapeController.ts new file mode 100644 index 0000000..ce8db32 --- /dev/null +++ b/src/services/getInvasionsShape/GetInvasionsShapeController.ts @@ -0,0 +1,21 @@ +import { Request, Response } from 'express' +import { container } from 'tsyringe' + +import { GetInvasionsShapeService } from './GetInvasionsShapeService' + +class GetInvasionsShapeController { + async handle(request: Request, response: Response): Promise { + const { filters, enableUnity, enableReserve } = request.body + + const getInvasionsShapeService = container.resolve(GetInvasionsShapeService) + + const shapes = await getInvasionsShapeService.execute( + filters, + enableUnity, + enableReserve + ) + return response.json(shapes) + } +} + +export { GetInvasionsShapeController } diff --git a/src/services/getInvasionsShape/GetInvasionsShapeService.ts b/src/services/getInvasionsShape/GetInvasionsShapeService.ts new file mode 100644 index 0000000..65967e0 --- /dev/null +++ b/src/services/getInvasionsShape/GetInvasionsShapeService.ts @@ -0,0 +1,60 @@ +import { inject, injectable } from 'tsyringe' + +import { IFiltersDTO } from '../../dtos/IFiltersDTO' +import { IShapeDTO } from '../../dtos/IShapeDTO' +import { IInvasionRepository } from '../../repositories/IInvasionRepository' +import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' + +const geojson = require('geojson') + +@injectable() +class GetInvasionsShapeService { + constructor( + @inject('ReserveInvasionRepository') + private reserveInvasionRepository: IReserveInvasionRepository, + + @inject('InvasionRepository') + private invasionRepository: IInvasionRepository + ) {} + + async execute( + filters: IFiltersDTO, + enableUnity: boolean = true, + enableReserve: boolean = true + ): Promise { + let reserveInvasions: IShapeDTO[] = [] + let invasions: IShapeDTO[] = [] + if ( + ((!filters.reserve && !filters.unity) || filters.reserve) && + enableReserve + ) { + reserveInvasions = await this.reserveInvasionRepository.getShape(filters) + } + + if ( + ((!filters.reserve && !filters.unity) || filters.unity) && + enableUnity + ) { + invasions = await this.invasionRepository.getShape(filters) + } + + invasions = invasions.map((invasion) => { + invasion.geometry.coordinates = JSON.parse(invasion.geometry.coordinates) + return invasion + }) + + reserveInvasions = reserveInvasions.map((invasion) => { + invasion.geometry.coordinates = JSON.parse(invasion.geometry.coordinates) + return invasion + }) + + const reserveInvasionsShape = geojson.parse(reserveInvasions, { + GeoJSON: 'geometry', + }) + const invasionsShape = geojson.parse(invasions, { GeoJSON: 'geometry' }) + + return { reserve: reserveInvasionsShape, unity: invasionsShape } + } +} + +export { GetInvasionsShapeService } diff --git a/yarn.lock b/yarn.lock index 0e1fd68..1921c15 100644 --- a/yarn.lock +++ b/yarn.lock @@ -119,6 +119,11 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/geojson@^7946.0.8": + version "7946.0.8" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" + integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== + "@types/json-schema@^7.0.7": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" @@ -1108,6 +1113,11 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +geojson@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0" + integrity sha1-PNbJY5m+ZbVu5VWWEW/pGRznAcA= + get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" From a267d7affa03a28fc9f5e5c3da9321e9bf240586 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 24 Sep 2021 14:32:18 -0300 Subject: [PATCH 084/121] Add filters validation with yup --- package.json | 4 +- src/dtos/IFiltersDTO.ts | 2 +- src/errors/index.ts | 26 +++++--- src/server.ts | 4 +- .../GetInvasionsShapeController.ts | 3 + .../getStatistics/GetStatisticsController.ts | 3 + .../listInvasions/ListInvasionsController.ts | 10 ++++ src/yup/schemas/filterSchema.ts | 18 ++++++ yarn.lock | 60 +++++++++++++++++++ 9 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 src/yup/schemas/filterSchema.ts diff --git a/package.json b/package.json index 9f1446f..fff385a 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "json2csv": "^5.0.6", "mongoose": "^6.0.0", "reflect-metadata": "^0.1.13", - "tsyringe": "^4.6.0" + "tsyringe": "^4.6.0", + "yup": "^0.32.9" }, "devDependencies": { "@types/cors": "^2.8.12", @@ -25,6 +26,7 @@ "@types/express": "^4.17.13", "@types/geojson": "^7946.0.8", "@types/json2csv": "^5.0.3", + "@types/yup": "^0.29.13", "@typescript-eslint/eslint-plugin": "^4.29.3", "@typescript-eslint/parser": "^4.29.3", "eslint": "^7.32.0", diff --git a/src/dtos/IFiltersDTO.ts b/src/dtos/IFiltersDTO.ts index 69a79a8..f4fd80a 100644 --- a/src/dtos/IFiltersDTO.ts +++ b/src/dtos/IFiltersDTO.ts @@ -3,7 +3,7 @@ interface IFiltersDTO { reserve?: string[] unity?: string[] company?: string[] - year?: string[] + year?: number[] substance?: string[] requirementPhase?: string[] reservePhase?: string[] diff --git a/src/errors/index.ts b/src/errors/index.ts index 81fae9e..e897620 100644 --- a/src/errors/index.ts +++ b/src/errors/index.ts @@ -1,15 +1,27 @@ -import { NextFunction, Request, Response } from 'express' +import { ErrorRequestHandler } from 'express' +import { ValidationError } from 'yup' import { AppError } from './AppError' -export function handleErrors( - error: Error, - request: Request, - response: Response, - next: NextFunction -) { +interface IValidationErrors { + [key: string]: string[] +} + +export const errorHandler: ErrorRequestHandler = ( + error, + request, + response, + next +) => { if (error instanceof AppError) { return response.status(error.statusCode).json({ message: error.message }) + } else if (error instanceof ValidationError) { + const errors: IValidationErrors = {} + + error.inner.forEach((error) => { + errors[String(error.path)] = error.errors + }) + return response.status(400).json({ message: 'Validation fails', errors }) } return response.status(500).json({ diff --git a/src/server.ts b/src/server.ts index a78e3a4..fdda241 100644 --- a/src/server.ts +++ b/src/server.ts @@ -3,7 +3,7 @@ import cors from 'cors' import express from 'express' import 'express-async-errors' -import { handleErrors } from './errors' +import { errorHandler } from './errors' import { router } from './routes' import './database' @@ -15,6 +15,6 @@ app.use(cors()) app.use(express.json()) app.use(express.urlencoded({ extended: true })) app.use('/api', router) -app.use(handleErrors) +app.use(errorHandler) app.listen(5000, () => console.log('Server is running!')) diff --git a/src/services/getInvasionsShape/GetInvasionsShapeController.ts b/src/services/getInvasionsShape/GetInvasionsShapeController.ts index ce8db32..c72a617 100644 --- a/src/services/getInvasionsShape/GetInvasionsShapeController.ts +++ b/src/services/getInvasionsShape/GetInvasionsShapeController.ts @@ -1,12 +1,15 @@ import { Request, Response } from 'express' import { container } from 'tsyringe' +import { filterSchema } from '../../yup/schemas/filterSchema' import { GetInvasionsShapeService } from './GetInvasionsShapeService' class GetInvasionsShapeController { async handle(request: Request, response: Response): Promise { const { filters, enableUnity, enableReserve } = request.body + await filterSchema.validate(filters, { abortEarly: false }) + const getInvasionsShapeService = container.resolve(GetInvasionsShapeService) const shapes = await getInvasionsShapeService.execute( diff --git a/src/services/getStatistics/GetStatisticsController.ts b/src/services/getStatistics/GetStatisticsController.ts index e84daa1..e783b0d 100644 --- a/src/services/getStatistics/GetStatisticsController.ts +++ b/src/services/getStatistics/GetStatisticsController.ts @@ -1,12 +1,15 @@ import { Request, Response } from 'express' import { container } from 'tsyringe' +import { filterSchema } from '../../yup/schemas/filterSchema' import { GetStatisticsService } from './GetStatisticsService' class GetStatisticsController { async handle(request: Request, response: Response): Promise { const { filters } = request.body + await filterSchema.validate(filters, { abortEarly: false }) + const getStatisticsService = container.resolve(GetStatisticsService) const statistics = await getStatisticsService.execute(filters) diff --git a/src/services/listInvasions/ListInvasionsController.ts b/src/services/listInvasions/ListInvasionsController.ts index 46c5592..86596fa 100644 --- a/src/services/listInvasions/ListInvasionsController.ts +++ b/src/services/listInvasions/ListInvasionsController.ts @@ -1,8 +1,10 @@ import { Request, Response } from 'express' import json2csv from 'json2csv' import { container } from 'tsyringe' +import * as yup from 'yup' import { paginate } from '../../utils/pagination' +import { filterSchema } from '../../yup/schemas/filterSchema' import { ListInvasionsService } from './ListInvasionsService' class ListInvasionsController { @@ -10,6 +12,14 @@ class ListInvasionsController { const { filters, enableUnity, enableReserve } = request.body const { page, pageSize, output } = request.query + const schema = yup.object().shape({ + filters: filterSchema, + enableUnity: yup.boolean(), + enableReserve: yup.boolean(), + }) + + await schema.validate(request.body, { abortEarly: false }) + const listInvasionsService = container.resolve(ListInvasionsService) const invasions = await listInvasionsService.execute( diff --git a/src/yup/schemas/filterSchema.ts b/src/yup/schemas/filterSchema.ts new file mode 100644 index 0000000..303126e --- /dev/null +++ b/src/yup/schemas/filterSchema.ts @@ -0,0 +1,18 @@ +import * as yup from 'yup' + +const filterSchema = yup + .object() + .shape({ + state: yup.array().of(yup.string()), + reserve: yup.array().of(yup.string()), + unity: yup.array().of(yup.string()), + company: yup.array().of(yup.string()), + year: yup.array().of(yup.number()), + substance: yup.array().of(yup.string()), + requirementPhase: yup.array().of(yup.string()), + reservePhase: yup.array().of(yup.string()), + reserveEthnicity: yup.array().of(yup.string()), + }) + .noUnknown(true) + .strict() +export { filterSchema } diff --git a/yarn.lock b/yarn.lock index 1921c15..7f0761b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,13 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/runtime@^7.10.5": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" + integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== + dependencies: + regenerator-runtime "^0.13.4" + "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" @@ -136,6 +143,11 @@ dependencies: "@types/node" "*" +"@types/lodash@^4.14.165": + version "4.14.173" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.173.tgz#9d3b674c67a26cf673756f6aca7b429f237f91ed" + integrity sha512-vv0CAYoaEjCw/mLy96GBTnRoZrSxkGE0BKzKimdR8P3OzrNYNvBgtW7p055A+E8C31vXNUhWKoFCbhq7gbyhFg== + "@types/mime@^1": version "1.3.2" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" @@ -187,6 +199,11 @@ "@types/node" "*" "@types/webidl-conversions" "*" +"@types/yup@^0.29.13": + version "0.29.13" + resolved "https://registry.yarnpkg.com/@types/yup/-/yup-0.29.13.tgz#21b137ba60841307a3c8a1050d3bf4e63ad561e9" + integrity sha512-qRyuv+P/1t1JK1rA+elmK1MmCL1BapEzKKfbEhDBV/LMMse4lmhZ/XbgETI39JveDJRpLjmToOI6uFtMW/WR2g== + "@typescript-eslint/eslint-plugin@^4.29.3": version "4.29.3" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.3.tgz#95cb8029a8bd8bd9c7f4ab95074a7cb2115adefa" @@ -1490,6 +1507,11 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +lodash-es@^4.17.15: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -1510,6 +1532,11 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= +lodash@^4.17.20: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -1657,6 +1684,11 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +nanoclone@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4" + integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -1864,6 +1896,11 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +property-expr@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.4.tgz#37b925478e58965031bb612ec5b3260f8241e910" + integrity sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg== + proxy-addr@~2.0.5: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -1931,6 +1968,11 @@ reflect-metadata@^0.1.13: resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + regexp-clone@1.0.0, regexp-clone@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-1.0.0.tgz#222db967623277056260b992626354a04ce9bf63" @@ -2244,6 +2286,11 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA= + tr46@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" @@ -2447,3 +2494,16 @@ yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yup@^0.32.9: + version "0.32.9" + resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.9.tgz#9367bec6b1b0e39211ecbca598702e106019d872" + integrity sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg== + dependencies: + "@babel/runtime" "^7.10.5" + "@types/lodash" "^4.14.165" + lodash "^4.17.20" + lodash-es "^4.17.15" + nanoclone "^0.2.1" + property-expr "^2.0.4" + toposort "^2.0.2" From 2416155e860a7d976af4edc42fd10a246caaec05 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 24 Sep 2021 17:02:01 -0300 Subject: [PATCH 085/121] Fix bug in reserve search, grouping by name to avoid duplication --- .../implementations/ReserveRepository.ts | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts index 8e87c3f..8be07b1 100644 --- a/src/repositories/implementations/ReserveRepository.ts +++ b/src/repositories/implementations/ReserveRepository.ts @@ -4,16 +4,27 @@ import { IReserveRepository } from '../IReserveRepository' class ReserveRepository implements IReserveRepository { async searchByName(searchTerm: string): Promise { - const reserves = await Reserve.find( + const reserves = await Reserve.aggregate([ { - 'properties.terrai_nom': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + $match: { + 'properties.terrai_nom': { + $regex: new RegExp(`^${searchTerm}`, 'i'), + }, + }, + }, + { + $group: { + _id: '$properties.terrai_nom', + }, }, { - type: 'reserve', - value: '$properties.terrai_nom', - _id: 0, - } - ) + $project: { + type: 'reserve', + value: '$_id', + _id: 0, + }, + }, + ]) return reserves } From 78998e67bd0b40de802cf26c544373b9d3c4ced9 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 27 Sep 2021 12:33:46 -0300 Subject: [PATCH 086/121] Add ethnicity ranking --- README.md | 13 +++-- src/dtos/IRankingDTO.ts | 2 +- src/repositories/IInvasionRepository.ts | 2 +- .../IReserveInvasionRepository.ts | 7 ++- .../implementations/InvasionRepository.ts | 6 +- .../ReserveInvasionRepository.ts | 55 ++++++++++++++++++- src/routes/index.ts | 8 +-- .../InvasionRankingController.ts | 16 +++--- .../invasionRanking/InvasionRankingService.ts | 53 ++++++++---------- 9 files changed, 105 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 2ec37a9..7166d49 100644 --- a/README.md +++ b/README.md @@ -475,11 +475,11 @@ Método que retorna as opções de fase do requerimento de mineração. **Ranking de frequência e de área** ---- -Método que retorna o ranking de acordo com o território e o tipo de dado especificado +Método que retorna o ranking de acordo com a propiedade e o tipo de dado especificado * **URL:** - /api/invasions/ranking/:territoryType/:dataType + /api/invasions/ranking/:propertyType/:dataType * **Método:** @@ -487,9 +487,9 @@ Método que retorna o ranking de acordo com o território e o tipo de dado espec * **Parâmetros na URL:** - - territoryType:[string] - Tipo de território a ser utilizado na construção do ranking('company', 'state', 'unity', 'reserve'). + - propertyType:[string] - Tipo de propriedade a ser utilizada na construção do ranking ('company', 'state', 'unity', 'reserve', 'ethnicity'). - dataType:[string] - Tipo de dado a ser retornado, 'requirementsIncidence' para a frequencia de requerimentos em território e 'requiredArea' para área total dos requerimentos por território. - - page?:[number] - Número da página de registros a ser retornada, retorna todos os registros caso um número não seja informado. + - page?:[number] - Número da página de registros a ser retornada, retorna a primeira página caso um número não seja informado. * **Parâmetros no Body:** @@ -502,6 +502,9 @@ Método que retorna o ranking de acordo com o território e o tipo de dado espec "unity": [], //Array de strings com o nome das Unidades de Conservação "year": [], //Array de inteiros com os anos "substance": [], //Array de strings com o nome das substâncias + "reservePhase": [], //Array de strings com as fases do processo de homologação das terras indígenas + "reserveEthnicity": [], //Array de strings com o nome das etinias de terras indígenas + "requirementPhase": [], //Array de strings com as fases dos requerimentos de mineração } } ``` @@ -509,7 +512,7 @@ Método que retorna o ranking de acordo com o território e o tipo de dado espec * **Exemplo:** **Rota:** - /api/invasions/ranking/company/value?page=1 + /api/invasions/ranking/company/requiredArea?page=1 * **Resposta:** diff --git a/src/dtos/IRankingDTO.ts b/src/dtos/IRankingDTO.ts index f85c4f1..15f44c4 100644 --- a/src/dtos/IRankingDTO.ts +++ b/src/dtos/IRankingDTO.ts @@ -6,7 +6,7 @@ interface IResponseRankingDTO { } interface IRequestRankingDTO { - territoryType: string + propertyType: string page: number dataType: string filters: IFiltersDTO diff --git a/src/repositories/IInvasionRepository.ts b/src/repositories/IInvasionRepository.ts index aac2bb6..52a6994 100644 --- a/src/repositories/IInvasionRepository.ts +++ b/src/repositories/IInvasionRepository.ts @@ -8,7 +8,7 @@ interface IInvasionRepository { searchCompany(searchTerm: string): Promise listInvasions(filters: IFiltersDTO): Promise invasionRanking({ - territoryType, + propertyType, dataType, }: IRequestRankingDTO): Promise getRequirementsPhase(): Promise diff --git a/src/repositories/IReserveInvasionRepository.ts b/src/repositories/IReserveInvasionRepository.ts index ca81e24..bd1adc1 100644 --- a/src/repositories/IReserveInvasionRepository.ts +++ b/src/repositories/IReserveInvasionRepository.ts @@ -8,9 +8,14 @@ interface IReserveInvasionRepository { searchCompany(searchTerm: string): Promise listInvasions(filters: IFiltersDTO): Promise reserveInvasionRanking({ - territoryType, + propertyType, dataType, + filters, }: IRequestRankingDTO): Promise + ethnicityRanking( + dataType: string, + filters: IFiltersDTO + ): Promise getRequirementsPhase(): Promise getShape(filters: IFiltersDTO): Promise } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index b82a42d..bb4b35a 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -92,17 +92,17 @@ class InvasionRepository implements IInvasionRepository { } async invasionRanking({ - territoryType, + propertyType, dataType, filters, }: IRequestRankingDTO): Promise { - const propertie = rankingFilter[territoryType] + const property = rankingFilter[propertyType] const match = this.getMatchProperty(filters) const territories = await Invasion.aggregate([ { $match: match }, { $group: { - _id: propertie, + _id: property, count: { $sum: dataType === 'requiredArea' ? '$properties.AREA_HA' : 1, }, diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index b9563c5..2d1326a 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -98,18 +98,67 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { return companies } + async ethnicityRanking( + dataType: string, + filters: IFiltersDTO + ): Promise { + const match = this.getMatchProperty(filters) + const ethnicities = await ReserveInvasion.aggregate([ + { $match: match }, + { + $group: { + _id: '$properties.PROCESSO', + area: { $sum: '$properties.AREA_HA' }, + ethnicity: { $first: '$properties.TI_ETNIA' }, + }, + }, + { + $project: { + ethnicity: { + $split: ['$ethnicity', ', '], + }, + area: 1, + }, + }, + { $unwind: '$ethnicity' }, + { + $project: { + ethnicity: { $trim: { input: '$ethnicity' } }, + area: 1, + }, + }, + { + $group: { + _id: '$ethnicity', + count: { + $sum: dataType === 'requiredArea' ? '$area' : 1, + }, + }, + }, + { $sort: { count: -1 } }, + { + $project: { + x: '$_id', + y: '$count', + _id: 0, + }, + }, + ]) + return ethnicities + } + async reserveInvasionRanking({ - territoryType, + propertyType, dataType, filters, }: IRequestRankingDTO): Promise { - const propertie = rankingFilter[territoryType] + const property = rankingFilter[propertyType] const match = this.getMatchProperty(filters) const territories = await ReserveInvasion.aggregate([ { $match: match }, { $group: { - _id: propertie, + _id: property, count: { $sum: dataType === 'requiredArea' ? '$properties.AREA_HA' : 1, }, diff --git a/src/routes/index.ts b/src/routes/index.ts index a758038..7f4f2d6 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -4,7 +4,7 @@ import { GetInvasionsShapeController } from '../services/getInvasionsShape/GetIn import { GetRequirementsPhaseController } from '../services/getRequirementsPhase/GetRequirementsPhaseController' import { GetReservesPhaseController } from '../services/getReservesPhase/GetReservesPhaseController' import { GetStatisticsController } from '../services/getStatistics/GetStatisticsController' -import { InvasionFrequencyController } from '../services/invasionRanking/InvasionRankingController' +import { InvasionRankingController } from '../services/invasionRanking/InvasionRankingController' import { ListInvasionsController } from '../services/listInvasions/ListInvasionsController' import { SearchController } from '../services/search/SearchController' @@ -12,7 +12,7 @@ const router = Router() const searchController = new SearchController() const listInvasionsController = new ListInvasionsController() -const invasionFrequencyController = new InvasionFrequencyController() +const invasionRankingController = new InvasionRankingController() const getStatisticsController = new GetStatisticsController() const getReservesPhaseController = new GetReservesPhaseController() const getRequirementsPhaseController = new GetRequirementsPhaseController() @@ -21,8 +21,8 @@ const getInvasionsShapeController = new GetInvasionsShapeController() router.get('/search/:searchTerm', searchController.handle) router.post('/invasions', listInvasionsController.handle) router.post( - '/invasions/ranking/:territoryType/:dataType', - invasionFrequencyController.handle + '/invasions/ranking/:propertyType/:dataType', + invasionRankingController.handle ) router.get('/invasions/phase', getRequirementsPhaseController.handle) router.post('/invasions/shape', getInvasionsShapeController.handle) diff --git a/src/services/invasionRanking/InvasionRankingController.ts b/src/services/invasionRanking/InvasionRankingController.ts index c72b1a2..00717a9 100644 --- a/src/services/invasionRanking/InvasionRankingController.ts +++ b/src/services/invasionRanking/InvasionRankingController.ts @@ -1,22 +1,22 @@ import { Request, Response } from 'express' import { container } from 'tsyringe' -import { InvasionFrequencyService } from './InvasionRankingService' +import { InvasionRankingService } from './InvasionRankingService' -class InvasionFrequencyController { +class InvasionRankingController { async handle(request: Request, response: Response): Promise { - const { territoryType, dataType } = request.params + const { propertyType, dataType } = request.params const { filters } = request.body const { page } = request.query - const invasionFrequencyService = container.resolve(InvasionFrequencyService) - const rankingData = await invasionFrequencyService.execute({ - territoryType, + const invasionRankingService = container.resolve(InvasionRankingService) + const rankingData = await invasionRankingService.execute({ + propertyType, dataType, - page: Number(page), + page: Number(page) || 1, filters, }) return response.status(200).json(rankingData) } } -export { InvasionFrequencyController } +export { InvasionRankingController } diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index c6591e2..9d61e91 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -7,7 +7,7 @@ import { paginate } from '../../utils/pagination' import { getStateFromAcronym } from '../../utils/states' @injectable() -class InvasionFrequencyService { +class InvasionRankingService { constructor( @inject('ReserveInvasionRepository') private reserveInvasionRepository: IReserveInvasionRepository, @@ -15,64 +15,55 @@ class InvasionFrequencyService { private invasionRepository: IInvasionRepository ) {} - async execute({ - territoryType, - page, - dataType, - filters, - }: IRequestRankingDTO) { - if (territoryType === 'state' || territoryType === 'company') { + async execute({ propertyType, page, dataType, filters }: IRequestRankingDTO) { + if (propertyType === 'state' || propertyType === 'company') { const reserveResults = await this.reserveInvasionRepository.reserveInvasionRanking({ - territoryType, + propertyType, page, dataType, filters, }) const invasionResults = await this.invasionRepository.invasionRanking({ - territoryType, + propertyType, page, dataType, filters, }) - return await this.formatDoubleRanking( + return this.formatDoubleRanking( reserveResults, invasionResults, dataType, - territoryType, + propertyType, page ) - } else if (territoryType === 'unity') { + } else if (propertyType === 'unity') { const results = await this.invasionRepository.invasionRanking({ - territoryType, + propertyType, page, dataType, filters, }) - return await this.formatSingleRanking( - results, - page, - dataType, - 'protectedArea' - ) - } else if (territoryType === 'reserve') { + return this.formatSingleRanking(results, page, dataType, 'protectedArea') + } else if (propertyType === 'reserve') { const results = await this.reserveInvasionRepository.reserveInvasionRanking({ - territoryType, + propertyType, page, dataType, filters, }) - return await this.formatSingleRanking( - results, - page, + return this.formatSingleRanking(results, page, dataType, 'indigenousLand') + } else if (propertyType === 'ethnicity') { + const results = await this.reserveInvasionRepository.ethnicityRanking( dataType, - 'indigenousLand' + filters ) + return this.formatSingleRanking(results, page, dataType, 'indigenousLand') } } - async formatSingleRanking( + formatSingleRanking( results: IResponseRankingDTO[], page = 1, dataType: string, @@ -95,11 +86,11 @@ class InvasionFrequencyService { } } - async formatDoubleRanking( + formatDoubleRanking( invasionResults: IResponseRankingDTO[], reserveResults: IResponseRankingDTO[], dataType: string, - territoryType: string, + propertyType: string, page = 1 ) { const x: string[] = [] @@ -123,7 +114,7 @@ class InvasionFrequencyService { return 0 }) .forEach((element, i) => { - if (territoryType === 'state') { + if (propertyType === 'state') { x.push(getStateFromAcronym(element.name)) } else { x.push(element.name) @@ -151,4 +142,4 @@ class InvasionFrequencyService { } } -export { InvasionFrequencyService } +export { InvasionRankingService } From caf8457de63b6ee7b05e4bb754576d2acc0e1f4e Mon Sep 17 00:00:00 2001 From: Iago Machado <38327929+iagomachadocs@users.noreply.github.com> Date: Mon, 27 Sep 2021 13:38:09 -0300 Subject: [PATCH 087/121] Update README.md --- README.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/README.md b/README.md index 7166d49..cc7799c 100644 --- a/README.md +++ b/README.md @@ -380,21 +380,6 @@ Método que retorna as opções de fase do processo de homologação de terras i Nenhum -* **Exemplo:** - - **Rota:** - /api/reserves/phase - - **Body:** - ```javascript - { - "filters": { - "state": ["Amazonas"], - "reserve": ["Andirá-Marau"] - } - } - ``` - * **Resposta:** * **Código:** **200**
@@ -561,7 +546,7 @@ Método que retorna o ranking de acordo com a propiedade e o tipo de dado especi "dataType": "requiredArea" } ``` - **Descrição:** Retorna um array de series que contém os valores de cada tipo de dado, um array com as respectivas posições e um com os nomes dos territórios. + **Descrição:** Retorna um array de series que contém os valores de cada tipo de dado, um array com as respectivas posições e um com os valores da propriedade escolhida. * **Código:** **500**
**Conteúdo:** From 1ba416c0fda1822c6b862c27a7e0a7adaaca3a11 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 27 Sep 2021 14:19:36 -0300 Subject: [PATCH 088/121] =?UTF-8?q?Comment=20states=20out=20of=20Amaz?= =?UTF-8?q?=C3=B4nia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/states.ts | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/utils/states.ts b/src/utils/states.ts index 8400bd9..42f0428 100644 --- a/src/utils/states.ts +++ b/src/utils/states.ts @@ -2,31 +2,31 @@ import { ISearchDTO } from '../dtos/ISearchDTO' const states = new Map([ ['Acre', 'AC'], - ['Alagoas', 'AL'], + // ['Alagoas', 'AL'], ['Amapá', 'AP'], ['Amazonas', 'AM'], - ['Bahia', 'BA'], - ['Ceará', 'CE'], - ['Distrito Federal', 'DF'], - ['Espírito Santo', 'ES'], - ['Goiás', 'GO'], + // ['Bahia', 'BA'], + // ['Ceará', 'CE'], + // ['Distrito Federal', 'DF'], + // ['Espírito Santo', 'ES'], + // ['Goiás', 'GO'], ['Maranhão', 'MA'], ['Mato Grosso', 'MT'], - ['Mato Grosso do Sul', 'MS'], - ['Minas Gerais', 'MG'], + // ['Mato Grosso do Sul', 'MS'], + // ['Minas Gerais', 'MG'], ['Pará', 'PA'], - ['Paraíba', 'PB'], - ['Paraná', 'PR'], - ['Pernambuco', 'PE'], - ['Piauí', 'PI'], - ['Rio de Janeiro', 'RJ'], - ['Rio Grande do Norte', 'RN'], - ['Rio Grande do Sul', 'RS'], + // ['Paraíba', 'PB'], + // ['Paraná', 'PR'], + // ['Pernambuco', 'PE'], + // ['Piauí', 'PI'], + // ['Rio de Janeiro', 'RJ'], + // ['Rio Grande do Norte', 'RN'], + // ['Rio Grande do Sul', 'RS'], ['Rondônia', 'RO'], ['Roraima', 'RR'], - ['Santa Catarina', 'SC'], - ['São Paulo', 'SP'], - ['Sergipe', 'SE'], + // ['Santa Catarina', 'SC'], + // ['São Paulo', 'SP'], + // ['Sergipe', 'SE'], ['Tocantins', 'TO'], ]) const stateNames = Array.from(states.keys()) From 9b86e64398aeb805815cc0e1302f09e14ea25057 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Tue, 28 Sep 2021 09:32:18 -0300 Subject: [PATCH 089/121] Change unity and reserve verification in the filters --- .../getInvasionsShape/GetInvasionsShapeService.ts | 6 ++++-- src/services/getStatistics/GetStatisticsService.ts | 10 ++++++++-- src/services/listInvasions/ListInvasionsService.ts | 6 ++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/services/getInvasionsShape/GetInvasionsShapeService.ts b/src/services/getInvasionsShape/GetInvasionsShapeService.ts index 65967e0..ea9c3f2 100644 --- a/src/services/getInvasionsShape/GetInvasionsShapeService.ts +++ b/src/services/getInvasionsShape/GetInvasionsShapeService.ts @@ -25,14 +25,16 @@ class GetInvasionsShapeService { let reserveInvasions: IShapeDTO[] = [] let invasions: IShapeDTO[] = [] if ( - ((!filters.reserve && !filters.unity) || filters.reserve) && + (!(filters.unity && filters.unity.length > 0) || + (filters.reserve && filters.reserve.length > 0)) && enableReserve ) { reserveInvasions = await this.reserveInvasionRepository.getShape(filters) } if ( - ((!filters.reserve && !filters.unity) || filters.unity) && + (!(filters.reserve && filters.reserve.length > 0) || + (filters.unity && filters.unity.length > 0)) && enableUnity ) { invasions = await this.invasionRepository.getShape(filters) diff --git a/src/services/getStatistics/GetStatisticsService.ts b/src/services/getStatistics/GetStatisticsService.ts index 0b37c3e..6ad5356 100644 --- a/src/services/getStatistics/GetStatisticsService.ts +++ b/src/services/getStatistics/GetStatisticsService.ts @@ -34,7 +34,10 @@ class GetStatisticsService { let reserveInvasions: IInvasionDTO[] = [] let invasions: IInvasionDTO[] = [] - if ((!filters.reserve && !filters.unity) || filters.reserve) { + if ( + !(filters.unity && filters.unity.length > 0) || + (filters.reserve && filters.reserve.length > 0) + ) { reserveInvasions = await this.reserveInvasionRepository.listInvasions( filters ) @@ -45,7 +48,10 @@ class GetStatisticsService { statistics.requiredArea.reserve = parseFloat(sumArea.toFixed(2)) } - if ((!filters.reserve && !filters.unity) || filters.unity) { + if ( + !(filters.reserve && filters.reserve.length > 0) || + (filters.unity && filters.unity.length > 0) + ) { invasions = await this.invasionRepository.listInvasions(filters) statistics.requirementsIncidence.unity = invasions.length diff --git a/src/services/listInvasions/ListInvasionsService.ts b/src/services/listInvasions/ListInvasionsService.ts index b087d20..e393f76 100644 --- a/src/services/listInvasions/ListInvasionsService.ts +++ b/src/services/listInvasions/ListInvasionsService.ts @@ -24,7 +24,8 @@ class ListInvasionsService { let invasions: IInvasionDTO[] = [] if ( - ((!filters.reserve && !filters.unity) || filters.reserve) && + (!(filters.unity && filters.unity.length > 0) || + (filters.reserve && filters.reserve.length > 0)) && enableReserve ) { reserveInvasions = await this.reserveInvasionRepository.listInvasions( @@ -33,7 +34,8 @@ class ListInvasionsService { } if ( - ((!filters.reserve && !filters.unity) || filters.unity) && + (!(filters.reserve && filters.reserve.length > 0) || + (filters.unity && filters.unity.length > 0)) && enableUnity ) { invasions = await this.invasionRepository.listInvasions(filters) From c2ec52f7d93795a914435b2d7ee5d99206ea3993 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Tue, 28 Sep 2021 12:02:19 -0300 Subject: [PATCH 090/121] Ignore NaN values in ranking --- src/repositories/implementations/InvasionRepository.ts | 5 +++++ .../implementations/ReserveInvasionRepository.ts | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index bb4b35a..46dba49 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -100,6 +100,11 @@ class InvasionRepository implements IInvasionRepository { const match = this.getMatchProperty(filters) const territories = await Invasion.aggregate([ { $match: match }, + { + $match: { + 'properties.AREA_HA': { $ne: NaN }, + }, + }, { $group: { _id: property, diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 2d1326a..2b95abe 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -156,6 +156,11 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { const match = this.getMatchProperty(filters) const territories = await ReserveInvasion.aggregate([ { $match: match }, + { + $match: { + 'properties.AREA_HA': { $ne: NaN }, + }, + }, { $group: { _id: property, From 4c0ad122ad1eea1293d3aca73d4f3b57a12a6d43 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 29 Sep 2021 09:52:15 -0300 Subject: [PATCH 091/121] Change NaN verification in rankings --- .../implementations/InvasionRepository.ts | 12 +++++++----- .../ReserveInvasionRepository.ts | 19 ++++++++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 46dba49..5b1d1e8 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -98,13 +98,15 @@ class InvasionRepository implements IInvasionRepository { }: IRequestRankingDTO): Promise { const property = rankingFilter[propertyType] const match = this.getMatchProperty(filters) + + if (dataType === 'requiredArea') { + match['properties.AREA_HA'] = { + $ne: NaN, + } + } + const territories = await Invasion.aggregate([ { $match: match }, - { - $match: { - 'properties.AREA_HA': { $ne: NaN }, - }, - }, { $group: { _id: property, diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 2b95abe..2973204 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -103,6 +103,13 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { filters: IFiltersDTO ): Promise { const match = this.getMatchProperty(filters) + + if (dataType === 'requiredArea') { + match['properties.AREA_HA'] = { + $ne: NaN, + } + } + const ethnicities = await ReserveInvasion.aggregate([ { $match: match }, { @@ -154,13 +161,15 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { }: IRequestRankingDTO): Promise { const property = rankingFilter[propertyType] const match = this.getMatchProperty(filters) + + if (dataType === 'requiredArea') { + match['properties.AREA_HA'] = { + $ne: NaN, + } + } + const territories = await ReserveInvasion.aggregate([ { $match: match }, - { - $match: { - 'properties.AREA_HA': { $ne: NaN }, - }, - }, { $group: { _id: property, From 35c7503f6dd46911dbc534179787c7ebcdec351d Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 29 Sep 2021 11:37:07 -0300 Subject: [PATCH 092/121] Change companies search to unity and reserve collections --- src/services/search/SearchService.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts index 4e98ca8..58e492d 100644 --- a/src/services/search/SearchService.ts +++ b/src/services/search/SearchService.ts @@ -30,7 +30,25 @@ class SearchService { async execute(searchTerm: string): Promise { const states = searchStates(searchTerm) - const companies = await this.licenseRepository.searchCompany(searchTerm) + const reserveCompanies = await this.reserveInvasionRepository.searchCompany( + searchTerm + ) + + const unityCompanies = await this.invasionRepository.searchCompany( + searchTerm + ) + + const companiesMap = new Map() + reserveCompanies.forEach((company) => + companiesMap.set(company.value, company) + ) + unityCompanies.forEach((company) => + companiesMap.set(company.value, company) + ) + const companies = Array.from(companiesMap.values()).sort( + (company1, company2) => + company1.value.toLowerCase() > company2.value.toLowerCase() ? 1 : -1 + ) const unities = await this.unityRepository.searchByName(searchTerm) From ddc96190b668ae71c0c14f723fe336ea61f73921 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 29 Sep 2021 11:48:08 -0300 Subject: [PATCH 093/121] Add sort in search --- src/repositories/implementations/ReserveRepository.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts index 8be07b1..e1374bc 100644 --- a/src/repositories/implementations/ReserveRepository.ts +++ b/src/repositories/implementations/ReserveRepository.ts @@ -24,6 +24,7 @@ class ReserveRepository implements IReserveRepository { _id: 0, }, }, + { $sort: { value: 1 } }, ]) return reserves } From 72b294fadd21af648890bf9eb5dcce63cdaaffe8 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 29 Sep 2021 13:52:13 -0300 Subject: [PATCH 094/121] Change substances search --- src/repositories/IInvasionRepository.ts | 1 + .../IReserveInvasionRepository.ts | 1 + .../implementations/InvasionRepository.ts | 23 ++++++++++ .../ReserveInvasionRepository.ts | 23 ++++++++++ src/services/search/SearchService.ts | 42 +++++++++++++------ 5 files changed, 78 insertions(+), 12 deletions(-) diff --git a/src/repositories/IInvasionRepository.ts b/src/repositories/IInvasionRepository.ts index 52a6994..532fb7d 100644 --- a/src/repositories/IInvasionRepository.ts +++ b/src/repositories/IInvasionRepository.ts @@ -6,6 +6,7 @@ import { IShapeDTO } from '../dtos/IShapeDTO' interface IInvasionRepository { searchCompany(searchTerm: string): Promise + searchSubstance(searchTerm: string): Promise listInvasions(filters: IFiltersDTO): Promise invasionRanking({ propertyType, diff --git a/src/repositories/IReserveInvasionRepository.ts b/src/repositories/IReserveInvasionRepository.ts index bd1adc1..0e7d46c 100644 --- a/src/repositories/IReserveInvasionRepository.ts +++ b/src/repositories/IReserveInvasionRepository.ts @@ -6,6 +6,7 @@ import { IShapeDTO } from '../dtos/IShapeDTO' interface IReserveInvasionRepository { searchCompany(searchTerm: string): Promise + searchSubstance(searchTerm: string): Promise listInvasions(filters: IFiltersDTO): Promise reserveInvasionRanking({ propertyType, diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 5b1d1e8..0b685d4 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -91,6 +91,29 @@ class InvasionRepository implements IInvasionRepository { return companies } + async searchSubstance(searchTerm: string): Promise { + const substances = await Invasion.aggregate([ + { + $match: { + 'properties.SUBS': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + }, + }, + { + $group: { + _id: '$properties.SUBS', + }, + }, + { + $project: { + type: 'substance', + value: '$_id', + _id: 0, + }, + }, + ]) + return substances + } + async invasionRanking({ propertyType, dataType, diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 2973204..b2ac57e 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -34,6 +34,29 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { return invasions } + async searchSubstance(searchTerm: string): Promise { + const substances = await ReserveInvasion.aggregate([ + { + $match: { + 'properties.SUBS': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + }, + }, + { + $group: { + _id: '$properties.SUBS', + }, + }, + { + $project: { + type: 'substance', + value: '$_id', + _id: 0, + }, + }, + ]) + return substances + } + async listInvasions(filters: IFiltersDTO): Promise { const match = this.getMatchProperty(filters) diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts index 58e492d..e720c7a 100644 --- a/src/services/search/SearchService.ts +++ b/src/services/search/SearchService.ts @@ -38,23 +38,20 @@ class SearchService { searchTerm ) - const companiesMap = new Map() - reserveCompanies.forEach((company) => - companiesMap.set(company.value, company) - ) - unityCompanies.forEach((company) => - companiesMap.set(company.value, company) - ) - const companies = Array.from(companiesMap.values()).sort( - (company1, company2) => - company1.value.toLowerCase() > company2.value.toLowerCase() ? 1 : -1 - ) + const companies = this.groupResults(reserveCompanies, unityCompanies) const unities = await this.unityRepository.searchByName(searchTerm) const reserves = await this.reserveRepository.searchByName(searchTerm) - const substances = await this.licenseRepository.searchSubstance(searchTerm) + const reserveSubstances = + await this.reserveInvasionRepository.searchSubstance(searchTerm) + + const unitySubstances = await this.invasionRepository.searchSubstance( + searchTerm + ) + + const substances = this.groupResults(reserveSubstances, unitySubstances) const ethnicities = await this.reserveRepository.searchEthnicity(searchTerm) @@ -68,6 +65,27 @@ class SearchService { return results } + + private groupResults( + reserveResults: ISearchDTO[], + unityResults: ISearchDTO[] + ): ISearchDTO[] { + const resultsMap = new Map() + + reserveResults.forEach((result) => { + resultsMap.set(result.value, result) + }) + + unityResults.forEach((result) => { + resultsMap.set(result.value, result) + }) + + const results = Array.from(resultsMap.values()).sort((a, b) => + a.value.toLowerCase() > b.value.toLowerCase() ? 1 : -1 + ) + + return results + } } export { SearchService } From c3bafe921e50d67921033aec651cd1c29eae3998 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 30 Sep 2021 11:36:25 -0300 Subject: [PATCH 095/121] =?UTF-8?q?Change=20searches=20to=20dont=20return?= =?UTF-8?q?=20DADO=20N=C3=83O=20CADASTRADO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/repositories/implementations/InvasionRepository.ts | 10 ++++++++-- src/repositories/implementations/LicenseRepository.ts | 10 ++++++++-- .../implementations/ReserveInvasionRepository.ts | 10 ++++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 0b685d4..4994a56 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -72,7 +72,10 @@ class InvasionRepository implements IInvasionRepository { const companies = await Invasion.aggregate([ { $match: { - 'properties.NOME': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + 'properties.NOME': { + $regex: new RegExp(`^${searchTerm}`, 'i'), + $ne: 'DADO NÃO CADASTRADO', + }, }, }, { @@ -95,7 +98,10 @@ class InvasionRepository implements IInvasionRepository { const substances = await Invasion.aggregate([ { $match: { - 'properties.SUBS': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + 'properties.SUBS': { + $regex: new RegExp(`^${searchTerm}`, 'i'), + $ne: 'DADO NÃO CADASTRADO', + }, }, }, { diff --git a/src/repositories/implementations/LicenseRepository.ts b/src/repositories/implementations/LicenseRepository.ts index ec90d04..01b7953 100644 --- a/src/repositories/implementations/LicenseRepository.ts +++ b/src/repositories/implementations/LicenseRepository.ts @@ -7,7 +7,10 @@ class LicenseRepository implements ILicenseRepository { const companies = await License.aggregate([ { $match: { - 'properties.NOME': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + 'properties.NOME': { + $regex: new RegExp(`^${searchTerm}`, 'i'), + $ne: 'DADO NÃO CADASTRADO', + }, }, }, { @@ -29,7 +32,10 @@ class LicenseRepository implements ILicenseRepository { const substances = await License.aggregate([ { $match: { - 'properties.SUBS': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + 'properties.SUBS': { + $regex: new RegExp(`^${searchTerm}`, 'i'), + $ne: 'DADO NÃO CADASTRADO', + }, }, }, { diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index b2ac57e..70e37f3 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -38,7 +38,10 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { const substances = await ReserveInvasion.aggregate([ { $match: { - 'properties.SUBS': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + 'properties.SUBS': { + $regex: new RegExp(`^${searchTerm}`, 'i'), + $ne: 'DADO NÃO CADASTRADO', + }, }, }, { @@ -102,7 +105,10 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { const companies = await ReserveInvasion.aggregate([ { $match: { - 'properties.NOME': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + 'properties.NOME': { + $regex: new RegExp(`^${searchTerm}`, 'i'), + $ne: 'DADO NÃO CADASTRADO', + }, }, }, { From 4df7cb45cd7d6aedc0934786f832c0047261565d Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 30 Sep 2021 14:07:42 -0300 Subject: [PATCH 096/121] Add sort order in ranking --- README.md | 1 + src/dtos/IRankingDTO.ts | 1 + src/errors/index.ts | 1 + src/repositories/IInvasionRepository.ts | 2 ++ .../IReserveInvasionRepository.ts | 2 ++ .../implementations/InvasionRepository.ts | 3 ++- .../ReserveInvasionRepository.ts | 6 +++-- .../InvasionRankingController.ts | 3 ++- .../invasionRanking/InvasionRankingService.ts | 22 +++++++++++++++---- 9 files changed, 33 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index cc7799c..e3b1258 100644 --- a/README.md +++ b/README.md @@ -475,6 +475,7 @@ Método que retorna o ranking de acordo com a propiedade e o tipo de dado especi - propertyType:[string] - Tipo de propriedade a ser utilizada na construção do ranking ('company', 'state', 'unity', 'reserve', 'ethnicity'). - dataType:[string] - Tipo de dado a ser retornado, 'requirementsIncidence' para a frequencia de requerimentos em território e 'requiredArea' para área total dos requerimentos por território. - page?:[number] - Número da página de registros a ser retornada, retorna a primeira página caso um número não seja informado. + - sortOrder?[string] - Ordem de ordenação do ranking ('ASC' ou 'DESC'). Default: 'DESC'. * **Parâmetros no Body:** diff --git a/src/dtos/IRankingDTO.ts b/src/dtos/IRankingDTO.ts index 15f44c4..b37711d 100644 --- a/src/dtos/IRankingDTO.ts +++ b/src/dtos/IRankingDTO.ts @@ -9,6 +9,7 @@ interface IRequestRankingDTO { propertyType: string page: number dataType: string + sortOrder: string filters: IFiltersDTO } diff --git a/src/errors/index.ts b/src/errors/index.ts index e897620..3a64cbd 100644 --- a/src/errors/index.ts +++ b/src/errors/index.ts @@ -23,6 +23,7 @@ export const errorHandler: ErrorRequestHandler = ( }) return response.status(400).json({ message: 'Validation fails', errors }) } + console.log(error) return response.status(500).json({ message: `Internal server error - ${error.message}`, diff --git a/src/repositories/IInvasionRepository.ts b/src/repositories/IInvasionRepository.ts index 532fb7d..de376d7 100644 --- a/src/repositories/IInvasionRepository.ts +++ b/src/repositories/IInvasionRepository.ts @@ -11,6 +11,8 @@ interface IInvasionRepository { invasionRanking({ propertyType, dataType, + sortOrder, + filters, }: IRequestRankingDTO): Promise getRequirementsPhase(): Promise getShape(filters: IFiltersDTO): Promise diff --git a/src/repositories/IReserveInvasionRepository.ts b/src/repositories/IReserveInvasionRepository.ts index 0e7d46c..7f2dff8 100644 --- a/src/repositories/IReserveInvasionRepository.ts +++ b/src/repositories/IReserveInvasionRepository.ts @@ -11,10 +11,12 @@ interface IReserveInvasionRepository { reserveInvasionRanking({ propertyType, dataType, + sortOrder, filters, }: IRequestRankingDTO): Promise ethnicityRanking( dataType: string, + sortOrder: string, filters: IFiltersDTO ): Promise getRequirementsPhase(): Promise diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 4994a56..e73212f 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -123,6 +123,7 @@ class InvasionRepository implements IInvasionRepository { async invasionRanking({ propertyType, dataType, + sortOrder, filters, }: IRequestRankingDTO): Promise { const property = rankingFilter[propertyType] @@ -144,7 +145,7 @@ class InvasionRepository implements IInvasionRepository { }, }, }, - { $sort: { count: -1 } }, + { $sort: { count: sortOrder === 'ASC' ? 1 : -1 } }, { $project: { x: '$_id', diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 70e37f3..c6bf4f3 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -129,6 +129,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { async ethnicityRanking( dataType: string, + sortOrder: string, filters: IFiltersDTO ): Promise { const match = this.getMatchProperty(filters) @@ -171,7 +172,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { }, }, }, - { $sort: { count: -1 } }, + { $sort: { count: sortOrder === 'ASC' ? 1 : -1 } }, { $project: { x: '$_id', @@ -186,6 +187,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { async reserveInvasionRanking({ propertyType, dataType, + sortOrder, filters, }: IRequestRankingDTO): Promise { const property = rankingFilter[propertyType] @@ -207,7 +209,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { }, }, }, - { $sort: { count: -1 } }, + { $sort: { count: sortOrder === 'ASC' ? 1 : -1 } }, { $project: { x: '$_id', diff --git a/src/services/invasionRanking/InvasionRankingController.ts b/src/services/invasionRanking/InvasionRankingController.ts index 00717a9..c07154b 100644 --- a/src/services/invasionRanking/InvasionRankingController.ts +++ b/src/services/invasionRanking/InvasionRankingController.ts @@ -7,12 +7,13 @@ class InvasionRankingController { async handle(request: Request, response: Response): Promise { const { propertyType, dataType } = request.params const { filters } = request.body - const { page } = request.query + const { page, sortOrder } = request.query const invasionRankingService = container.resolve(InvasionRankingService) const rankingData = await invasionRankingService.execute({ propertyType, dataType, page: Number(page) || 1, + sortOrder: String(sortOrder), filters, }) return response.status(200).json(rankingData) diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index 9d61e91..1b848b5 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -15,19 +15,27 @@ class InvasionRankingService { private invasionRepository: IInvasionRepository ) {} - async execute({ propertyType, page, dataType, filters }: IRequestRankingDTO) { + async execute({ + propertyType, + page, + dataType, + sortOrder, + filters, + }: IRequestRankingDTO) { if (propertyType === 'state' || propertyType === 'company') { const reserveResults = await this.reserveInvasionRepository.reserveInvasionRanking({ propertyType, page, dataType, + sortOrder, filters, }) const invasionResults = await this.invasionRepository.invasionRanking({ propertyType, page, dataType, + sortOrder, filters, }) return this.formatDoubleRanking( @@ -35,6 +43,7 @@ class InvasionRankingService { invasionResults, dataType, propertyType, + sortOrder, page ) } else if (propertyType === 'unity') { @@ -42,6 +51,7 @@ class InvasionRankingService { propertyType, page, dataType, + sortOrder, filters, }) return this.formatSingleRanking(results, page, dataType, 'protectedArea') @@ -51,12 +61,14 @@ class InvasionRankingService { propertyType, page, dataType, + sortOrder, filters, }) return this.formatSingleRanking(results, page, dataType, 'indigenousLand') } else if (propertyType === 'ethnicity') { const results = await this.reserveInvasionRepository.ethnicityRanking( dataType, + sortOrder, filters ) return this.formatSingleRanking(results, page, dataType, 'indigenousLand') @@ -91,6 +103,7 @@ class InvasionRankingService { reserveResults: IResponseRankingDTO[], dataType: string, propertyType: string, + sortOrder: string, page = 1 ) { const x: string[] = [] @@ -109,9 +122,10 @@ class InvasionRankingService { }) newRanking .sort((a, b) => { - if (a.total > b.total) return -1 - if (a.total < b.total) return 1 - return 0 + if (sortOrder === 'ASC') { + return a.total - b.total + } + return b.total - a.total }) .forEach((element, i) => { if (propertyType === 'state') { From 7ddcd4d3fac1535e7d47731e7ebb63c3ebbd9f18 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 30 Sep 2021 14:37:24 -0300 Subject: [PATCH 097/121] Change ethnicity type in search --- README.md | 2 +- src/repositories/implementations/ReserveRepository.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e3b1258..09f42f3 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Método que permite uma busca geral para Substância, Estado, Solicitante (Empre } ] ``` - **Descrição:** Retorna um array de objetos contendo o tipo de dado [substance (substância), company (solicitante), state (estado), reserve (terra indígena), unity (unidade de conservação) ou ethnicity (etnia de terras indígenas)] e o valor (nome) das opções que são iniciadas pela string determinada. + **Descrição:** Retorna um array de objetos contendo o tipo de dado [substance (substância), company (solicitante), state (estado), reserve (terra indígena), unity (unidade de conservação) ou reserveEthnicity (etnia de terras indígenas)] e o valor (nome) das opções que são iniciadas pela string determinada. * **Código:** **500**
**Conteúdo:** diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts index e1374bc..2e02d2e 100644 --- a/src/repositories/implementations/ReserveRepository.ts +++ b/src/repositories/implementations/ReserveRepository.ts @@ -44,7 +44,7 @@ class ReserveRepository implements IReserveRepository { { $match: { _id: { $regex: new RegExp(`^${searchTerm}`, 'i') } } }, { $project: { - type: 'ethnicity', + type: 'reserveEthnicity', value: '$_id', _id: 0, }, From 724c7ba0c3fbc52cd650aca7f70a1f5134414a98 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 30 Sep 2021 15:56:36 -0300 Subject: [PATCH 098/121] Fix bug in filtering --- .../GetInvasionsShapeService.ts | 16 ++++----- .../getStatistics/GetStatisticsService.ts | 14 ++++---- .../listInvasions/ListInvasionsService.ts | 16 ++++----- src/utils/listVerification.ts | 35 +++++++++++++++++++ 4 files changed, 53 insertions(+), 28 deletions(-) create mode 100644 src/utils/listVerification.ts diff --git a/src/services/getInvasionsShape/GetInvasionsShapeService.ts b/src/services/getInvasionsShape/GetInvasionsShapeService.ts index ea9c3f2..e35e985 100644 --- a/src/services/getInvasionsShape/GetInvasionsShapeService.ts +++ b/src/services/getInvasionsShape/GetInvasionsShapeService.ts @@ -4,6 +4,10 @@ import { IFiltersDTO } from '../../dtos/IFiltersDTO' import { IShapeDTO } from '../../dtos/IShapeDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { + checkIfShouldListReserveInvasions, + checkIfShouldListUnityInvasions, +} from '../../utils/listVerification' const geojson = require('geojson') @@ -24,19 +28,11 @@ class GetInvasionsShapeService { ): Promise { let reserveInvasions: IShapeDTO[] = [] let invasions: IShapeDTO[] = [] - if ( - (!(filters.unity && filters.unity.length > 0) || - (filters.reserve && filters.reserve.length > 0)) && - enableReserve - ) { + if (checkIfShouldListReserveInvasions(filters) && enableReserve) { reserveInvasions = await this.reserveInvasionRepository.getShape(filters) } - if ( - (!(filters.reserve && filters.reserve.length > 0) || - (filters.unity && filters.unity.length > 0)) && - enableUnity - ) { + if (checkIfShouldListUnityInvasions(filters) && enableUnity) { invasions = await this.invasionRepository.getShape(filters) } diff --git a/src/services/getStatistics/GetStatisticsService.ts b/src/services/getStatistics/GetStatisticsService.ts index 6ad5356..aeb8cd3 100644 --- a/src/services/getStatistics/GetStatisticsService.ts +++ b/src/services/getStatistics/GetStatisticsService.ts @@ -6,6 +6,10 @@ import { IStatisticsDTO } from '../../dtos/IStatisticsDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' import { groupInvasions } from '../../utils/group' +import { + checkIfShouldListReserveInvasions, + checkIfShouldListUnityInvasions, +} from '../../utils/listVerification' @injectable() class GetStatisticsService { @@ -34,10 +38,7 @@ class GetStatisticsService { let reserveInvasions: IInvasionDTO[] = [] let invasions: IInvasionDTO[] = [] - if ( - !(filters.unity && filters.unity.length > 0) || - (filters.reserve && filters.reserve.length > 0) - ) { + if (checkIfShouldListReserveInvasions(filters)) { reserveInvasions = await this.reserveInvasionRepository.listInvasions( filters ) @@ -48,10 +49,7 @@ class GetStatisticsService { statistics.requiredArea.reserve = parseFloat(sumArea.toFixed(2)) } - if ( - !(filters.reserve && filters.reserve.length > 0) || - (filters.unity && filters.unity.length > 0) - ) { + if (checkIfShouldListUnityInvasions(filters)) { invasions = await this.invasionRepository.listInvasions(filters) statistics.requirementsIncidence.unity = invasions.length diff --git a/src/services/listInvasions/ListInvasionsService.ts b/src/services/listInvasions/ListInvasionsService.ts index e393f76..572e56a 100644 --- a/src/services/listInvasions/ListInvasionsService.ts +++ b/src/services/listInvasions/ListInvasionsService.ts @@ -4,6 +4,10 @@ import { IFiltersDTO } from '../../dtos/IFiltersDTO' import { IInvasionDTO } from '../../dtos/IInvasionDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { + checkIfShouldListReserveInvasions, + checkIfShouldListUnityInvasions, +} from '../../utils/listVerification' @injectable() class ListInvasionsService { @@ -23,21 +27,13 @@ class ListInvasionsService { let reserveInvasions: IInvasionDTO[] = [] let invasions: IInvasionDTO[] = [] - if ( - (!(filters.unity && filters.unity.length > 0) || - (filters.reserve && filters.reserve.length > 0)) && - enableReserve - ) { + if (checkIfShouldListReserveInvasions(filters) && enableReserve) { reserveInvasions = await this.reserveInvasionRepository.listInvasions( filters ) } - if ( - (!(filters.reserve && filters.reserve.length > 0) || - (filters.unity && filters.unity.length > 0)) && - enableUnity - ) { + if (checkIfShouldListUnityInvasions(filters) && enableUnity) { invasions = await this.invasionRepository.listInvasions(filters) } diff --git a/src/utils/listVerification.ts b/src/utils/listVerification.ts new file mode 100644 index 0000000..f532e3c --- /dev/null +++ b/src/utils/listVerification.ts @@ -0,0 +1,35 @@ +import { IFiltersDTO } from '../dtos/IFiltersDTO' + +/** + * This function check when reserve invasions should be listed according to the filters. + * Ex: When some unity is given and none reserve filter (reserve, reserveEthnicity or reservePhase) + * is specified, then reserve invasions shouldn't be listed. + */ +export function checkIfShouldListReserveInvasions( + filters: IFiltersDTO +): boolean { + return ( + !(filters.unity && filters.unity.length > 0) || + (filters.reserve && filters.reserve.length > 0) || + (filters.reserveEthnicity && filters.reserveEthnicity.length > 0) || + (filters.reservePhase && filters.reservePhase.length > 0) || + false + ) +} + +/** + * This function check when unity invasions should be listed according to the filters + * Ex: When some reserve filter is given (reserve, reserveEthnicity or reservePhase) + * and no unity is specified, then unity invasions shouldn't be listed. + */ +export function checkIfShouldListUnityInvasions(filters: IFiltersDTO): boolean { + return ( + !( + (filters.reserve && filters.reserve.length > 0) || + (filters.reserveEthnicity && filters.reserveEthnicity.length > 0) || + (filters.reservePhase && filters.reservePhase.length > 0) + ) || + (filters.unity && filters.unity.length > 0) || + false + ) +} From b313b2e88f6440d5d5e61620335b23169b1bf38e Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 30 Sep 2021 16:25:52 -0300 Subject: [PATCH 099/121] Change ranking to return only entries allowed by the filters --- .../invasionRanking/InvasionRankingService.ts | 92 +++++++++++++------ 1 file changed, 64 insertions(+), 28 deletions(-) diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index 1b848b5..ae36ef4 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -3,6 +3,10 @@ import { inject, injectable } from 'tsyringe' import { IRequestRankingDTO, IResponseRankingDTO } from '../../dtos/IRankingDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { + checkIfShouldListReserveInvasions, + checkIfShouldListUnityInvasions, +} from '../../utils/listVerification' import { paginate } from '../../utils/pagination' import { getStateFromAcronym } from '../../utils/states' @@ -23,55 +27,87 @@ class InvasionRankingService { filters, }: IRequestRankingDTO) { if (propertyType === 'state' || propertyType === 'company') { - const reserveResults = - await this.reserveInvasionRepository.reserveInvasionRanking({ + let reserveResults: IResponseRankingDTO[] = [] + if (checkIfShouldListReserveInvasions(filters)) { + reserveResults = + await this.reserveInvasionRepository.reserveInvasionRanking({ + propertyType, + page, + dataType, + sortOrder, + filters, + }) + } + + let invasionResults: IResponseRankingDTO[] = [] + if (checkIfShouldListUnityInvasions(filters)) { + invasionResults = await this.invasionRepository.invasionRanking({ propertyType, page, dataType, sortOrder, filters, }) - const invasionResults = await this.invasionRepository.invasionRanking({ - propertyType, - page, - dataType, - sortOrder, - filters, - }) + } + return this.formatDoubleRanking( - reserveResults, invasionResults, + reserveResults, dataType, propertyType, sortOrder, page ) } else if (propertyType === 'unity') { - const results = await this.invasionRepository.invasionRanking({ - propertyType, - page, - dataType, - sortOrder, - filters, - }) - return this.formatSingleRanking(results, page, dataType, 'protectedArea') - } else if (propertyType === 'reserve') { - const results = - await this.reserveInvasionRepository.reserveInvasionRanking({ + if (checkIfShouldListUnityInvasions(filters)) { + const results = await this.invasionRepository.invasionRanking({ propertyType, page, dataType, sortOrder, filters, }) - return this.formatSingleRanking(results, page, dataType, 'indigenousLand') + return this.formatSingleRanking( + results, + page, + dataType, + 'protectedArea' + ) + } + return null + } else if (propertyType === 'reserve') { + if (checkIfShouldListReserveInvasions(filters)) { + const results = + await this.reserveInvasionRepository.reserveInvasionRanking({ + propertyType, + page, + dataType, + sortOrder, + filters, + }) + return this.formatSingleRanking( + results, + page, + dataType, + 'indigenousLand' + ) + } + return null } else if (propertyType === 'ethnicity') { - const results = await this.reserveInvasionRepository.ethnicityRanking( - dataType, - sortOrder, - filters - ) - return this.formatSingleRanking(results, page, dataType, 'indigenousLand') + if (checkIfShouldListReserveInvasions(filters)) { + const results = await this.reserveInvasionRepository.ethnicityRanking( + dataType, + sortOrder, + filters + ) + return this.formatSingleRanking( + results, + page, + dataType, + 'indigenousLand' + ) + } + return null } } From c2df717d3a78731fc279e8452749364a361cd7e5 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 30 Sep 2021 17:07:27 -0300 Subject: [PATCH 100/121] Fix bug in ranking --- .../invasionRanking/InvasionRankingService.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index ae36ef4..0aac62f 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -50,6 +50,22 @@ class InvasionRankingService { }) } + if (reserveResults.length === 0) { + return this.formatSingleRanking( + invasionResults, + page, + dataType, + 'protectedArea' + ) + } else if (invasionResults.length === 0) { + return this.formatSingleRanking( + reserveResults, + page, + dataType, + 'indigenousLand' + ) + } + return this.formatDoubleRanking( invasionResults, reserveResults, From 5a13b15929f728bb8f2e4521b36f7716753c5914 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 30 Sep 2021 17:19:29 -0300 Subject: [PATCH 101/121] Fix bug in ranking --- .../invasionRanking/InvasionRankingService.ts | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index 0aac62f..ad3f8db 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -55,14 +55,16 @@ class InvasionRankingService { invasionResults, page, dataType, - 'protectedArea' + 'protectedArea', + propertyType ) } else if (invasionResults.length === 0) { return this.formatSingleRanking( reserveResults, page, dataType, - 'indigenousLand' + 'indigenousLand', + propertyType ) } @@ -87,7 +89,8 @@ class InvasionRankingService { results, page, dataType, - 'protectedArea' + 'protectedArea', + propertyType ) } return null @@ -105,7 +108,8 @@ class InvasionRankingService { results, page, dataType, - 'indigenousLand' + 'indigenousLand', + propertyType ) } return null @@ -120,7 +124,8 @@ class InvasionRankingService { results, page, dataType, - 'indigenousLand' + 'indigenousLand', + propertyType ) } return null @@ -131,13 +136,18 @@ class InvasionRankingService { results: IResponseRankingDTO[], page = 1, dataType: string, - id: string + id: string, + propertyType: string ) { const x: string[] = [] const y: number[] = [] const pos: number[] = [] results.forEach((invasion, i) => { - x.push(invasion.x) + if (propertyType === 'state') { + x.push(getStateFromAcronym(invasion.x)) + } else { + x.push(invasion.x) + } y.push(invasion.y) pos.push(i + 1) }) From 865f3fb8bca38f808d7ee4d61986f3090b8bab56 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 1 Oct 2021 12:22:19 -0300 Subject: [PATCH 102/121] Add miningProcessType property in invasions list --- src/dtos/IInvasionDTO.ts | 1 + .../listInvasions/ListInvasionsService.ts | 6 +++++- src/utils/miningProcess.ts | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/utils/miningProcess.ts diff --git a/src/dtos/IInvasionDTO.ts b/src/dtos/IInvasionDTO.ts index d3478bd..6f145eb 100644 --- a/src/dtos/IInvasionDTO.ts +++ b/src/dtos/IInvasionDTO.ts @@ -5,6 +5,7 @@ interface IInvasionDTO { year: number state: string miningProcess: string + miningProcessType?: string substance: string territory: string reservePhase?: string diff --git a/src/services/listInvasions/ListInvasionsService.ts b/src/services/listInvasions/ListInvasionsService.ts index 572e56a..da7f6f8 100644 --- a/src/services/listInvasions/ListInvasionsService.ts +++ b/src/services/listInvasions/ListInvasionsService.ts @@ -8,6 +8,7 @@ import { checkIfShouldListReserveInvasions, checkIfShouldListUnityInvasions, } from '../../utils/listVerification' +import { getMiningProcessType } from '../../utils/miningProcess' @injectable() class ListInvasionsService { @@ -37,7 +38,10 @@ class ListInvasionsService { invasions = await this.invasionRepository.listInvasions(filters) } - const results = invasions.concat(reserveInvasions) + const results = invasions.concat(reserveInvasions).map((invasion) => { + invasion.miningProcessType = getMiningProcessType(invasion.miningProcess) + return invasion + }) const sortedResults = results.sort((a, b) => { if (b.year > a.year) { return 1 diff --git a/src/utils/miningProcess.ts b/src/utils/miningProcess.ts new file mode 100644 index 0000000..87c6ebf --- /dev/null +++ b/src/utils/miningProcess.ts @@ -0,0 +1,17 @@ +const miningProcessObject = new Map([ + ['CONCESSÃO DE LAVRA', 'miningConcession'], + ['LAVRA GARIMPEIRA', 'smallScaleMining'], + ['AUTORIZAÇÃO DE PESQUISA', 'miningResearchAuthorization'], + ['REQUERIMENTO DE PESQUISA', 'miningResearchRequest'], + ['REQUERIMENTO DE LAVRA GARIMPEIRA', 'smallScaleMiningRequest'], + ['REQUERIMENTO DE LAVRA', 'smallScaleMiningRequest'], + ['DIREITO DE REQUERER A LAVRA', 'smallScaleMiningRequest'], + ['APTO PARA DISPONIBILIDADE', 'availableMiningArea'], + ['DISPONIBILIDADE', 'availableMiningArea'], +]) + +export function getMiningProcessType( + miningProcess: string +): string | undefined { + return miningProcessObject.get(miningProcess) +} From 9adccca0fedfaa7b07d4c63ede8f7f42681c5861 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 1 Oct 2021 12:28:37 -0300 Subject: [PATCH 103/121] Change readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 09f42f3..0ac92bb 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "reserveEthnicity": "Múra", "type": "indigenousLand", "miningProcess": "REQUERIMENTO DE PESQUISA", + "miningProcessType": "miningResearchRequest", "substance": "OURO" }, { @@ -154,6 +155,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "reserveEthnicity": "Múra", "type": "indigenousLand", "miningProcess": "REQUERIMENTO DE PESQUISA", + "miningProcessType": "miningResearchRequest", "substance": "OURO" } ], From 4bb0e2d9b134bae28ef7da21ddea83b19174e102 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 1 Oct 2021 14:21:25 -0300 Subject: [PATCH 104/121] Change rankings to return null when there is no entries --- .../invasionRanking/InvasionRankingService.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index ad3f8db..63e4e16 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -50,7 +50,9 @@ class InvasionRankingService { }) } - if (reserveResults.length === 0) { + if (reserveResults.length === 0 && invasionResults.length === 0) { + return null + } else if (reserveResults.length === 0) { return this.formatSingleRanking( invasionResults, page, @@ -85,6 +87,11 @@ class InvasionRankingService { sortOrder, filters, }) + + if (results.length === 0) { + return null + } + return this.formatSingleRanking( results, page, @@ -104,6 +111,9 @@ class InvasionRankingService { sortOrder, filters, }) + if (results.length === 0) { + return null + } return this.formatSingleRanking( results, page, @@ -120,6 +130,9 @@ class InvasionRankingService { sortOrder, filters ) + if (results.length === 0) { + return null + } return this.formatSingleRanking( results, page, From 3e634feb311a47fddb5decbcb7b80570e8f5f34a Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 1 Oct 2021 14:21:41 -0300 Subject: [PATCH 105/121] Change readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ac92bb..1ec8f78 100644 --- a/README.md +++ b/README.md @@ -549,7 +549,7 @@ Método que retorna o ranking de acordo com a propiedade e o tipo de dado especi "dataType": "requiredArea" } ``` - **Descrição:** Retorna um array de series que contém os valores de cada tipo de dado, um array com as respectivas posições e um com os valores da propriedade escolhida. + **Descrição:** Retorna um array de series que contém os valores de cada tipo de dado, um array com as respectivas posições e um com os valores da propriedade escolhida. OBS: quando os filtros resultam em um ranking vazio para uma determinada propriedade o retorno é null. * **Código:** **500**
**Conteúdo:** From 330e7508df75a46d06ca42c7bd3b811aac6bcf13 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Fri, 1 Oct 2021 15:11:55 -0300 Subject: [PATCH 106/121] Fix bug in ranking --- src/services/invasionRanking/InvasionRankingService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index 63e4e16..cefcac0 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -217,11 +217,11 @@ class InvasionRankingService { position: paginate(pos, page, 5).values, series: [ { - id: 'indigenousLand', + id: 'protectedArea', data: paginate(invasionY, page, 5).values, }, { - id: 'protectedArea', + id: 'indigenousLand', data: paginate(reserveY, page, 5).values, }, ], From 6d8017582ba28f407209196b38fef2effd9753d8 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 4 Oct 2021 14:15:13 -0300 Subject: [PATCH 107/121] Change database connection to the address defined in .env --- .env.example | 3 ++- docker-compose.yml | 1 + src/database/entities/IInvasion.ts | 6 +++++ src/database/entities/IReserveInvasion.ts | 6 +++++ src/database/index.ts | 14 ++++++++-- src/database/models/Invasion.ts | 26 ++++++++++++++++++- src/database/models/License.ts | 2 +- src/database/models/Reserve.ts | 2 +- src/database/models/ReserveInvasion.ts | 26 +++++++++++++++++-- src/database/models/Unity.ts | 2 +- .../GetInvasionsShapeService.ts | 10 ------- 11 files changed, 79 insertions(+), 19 deletions(-) diff --git a/.env.example b/.env.example index c59bee5..a6db756 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,3 @@ MONGO_DB_USERNAME= -MONGO_DB_PASSWORD= \ No newline at end of file +MONGO_DB_PASSWORD= +MONGO_DB_ADDRESS= \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 0c09c8b..e1dae12 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,6 +19,7 @@ services: environment: MONGO_DB_USERNAME: ${MONGO_DB_USERNAME} MONGO_DB_PASSWORD: ${MONGO_DB_PASSWORD} + MONGO_DB_ADDRESS: ${MONGO_DB_ADDRESS} database: image: mongo diff --git a/src/database/entities/IInvasion.ts b/src/database/entities/IInvasion.ts index 678b397..494e38c 100644 --- a/src/database/entities/IInvasion.ts +++ b/src/database/entities/IInvasion.ts @@ -1,3 +1,4 @@ +/* eslint-disable camelcase */ interface IInvasion { type: string properties: { @@ -19,6 +20,11 @@ interface IInvasion { UC_BIOMA: string } geometry: {} + tweeted: boolean + created_at: Date + last_action: string + last_update_at: Date + changes: [] } export { IInvasion } diff --git a/src/database/entities/IReserveInvasion.ts b/src/database/entities/IReserveInvasion.ts index c413532..acf7351 100644 --- a/src/database/entities/IReserveInvasion.ts +++ b/src/database/entities/IReserveInvasion.ts @@ -1,3 +1,4 @@ +/* eslint-disable camelcase */ interface IReserveInvasion { type: string properties: { @@ -21,6 +22,11 @@ interface IReserveInvasion { TI_MODALIDADE: string } geometry: {} + tweeted: boolean + created_at: Date + last_action: string + last_update_at: Date + changes: [] } export { IReserveInvasion } diff --git a/src/database/index.ts b/src/database/index.ts index 8ee4b43..b7ca769 100644 --- a/src/database/index.ts +++ b/src/database/index.ts @@ -5,9 +5,19 @@ dotenv.config() async function main() { await mongoose.connect( - `mongodb://${process.env.MONGO_DB_USERNAME}:${process.env.MONGO_DB_PASSWORD}@database:27017/infoamdm?authSource=admin` + `mongodb://${process.env.MONGO_DB_USERNAME}:${ + process.env.MONGO_DB_PASSWORD + }@${ + !process.env.MONGO_DB_ADDRESS ? 'database' : process.env.MONGO_DB_ADDRESS + }:27017/icfj?authSource=admin` + ) + console.log( + `Database connected to ${ + !process.env.MONGO_DB_ADDRESS + ? 'database container' + : process.env.MONGO_DB_ADDRESS + }!` ) - console.log('Database connected!') } main().catch((err) => console.log(err)) diff --git a/src/database/models/Invasion.ts b/src/database/models/Invasion.ts index 25a701e..116a730 100644 --- a/src/database/models/Invasion.ts +++ b/src/database/models/Invasion.ts @@ -1,3 +1,4 @@ +/* eslint-disable camelcase */ import mongoose from 'mongoose' import { IInvasion } from '../entities/IInvasion' @@ -23,6 +24,29 @@ const InvasionSchema = new mongoose.Schema({ UC_BIOMA: String, }, geometry: {}, + tweeted: { + type: Boolean, + default: false, + }, + created_at: { + type: Date, + default: new Date(), + }, + last_action: String, + last_update_at: { + type: Date, + default: new Date(), + }, + changes: [ + { + _id: false, + timestamp: { + type: Date, + default: new Date(), + }, + changes: String, + }, + ], }) -export const Invasion = mongoose.model('Invasion', InvasionSchema, 'Invasion') +export const Invasion = mongoose.model('Invasion', InvasionSchema) diff --git a/src/database/models/License.ts b/src/database/models/License.ts index 2712d19..d89b5d5 100644 --- a/src/database/models/License.ts +++ b/src/database/models/License.ts @@ -22,4 +22,4 @@ const LicenseSchema = new mongoose.Schema({ geometry: {}, }) -export const License = mongoose.model('License', LicenseSchema, 'License') +export const License = mongoose.model('License', LicenseSchema) diff --git a/src/database/models/Reserve.ts b/src/database/models/Reserve.ts index 9269abb..9ab9049 100644 --- a/src/database/models/Reserve.ts +++ b/src/database/models/Reserve.ts @@ -25,4 +25,4 @@ const ReserveSchema = new mongoose.Schema({ geometry: {}, }) -export const Reserve = mongoose.model('Reserve', ReserveSchema, 'Reserve') +export const Reserve = mongoose.model('Reserve', ReserveSchema) diff --git a/src/database/models/ReserveInvasion.ts b/src/database/models/ReserveInvasion.ts index cfbc321..3b53e98 100644 --- a/src/database/models/ReserveInvasion.ts +++ b/src/database/models/ReserveInvasion.ts @@ -26,10 +26,32 @@ const ReserveInvasionSchema = new mongoose.Schema({ TI_MODALIDADE: String, }, geometry: {}, + tweeted: { + type: Boolean, + default: false, + }, + created_at: { + type: Date, + default: new Date(), + }, + last_action: String, + last_update_at: { + type: Date, + default: new Date(), + }, + changes: [ + { + _id: false, + timestamp: { + type: Date, + default: new Date(), + }, + changes: String, + }, + ], }) export const ReserveInvasion = mongoose.model( 'ReserveInvasion', - ReserveInvasionSchema, - 'ReserveInvasion' + ReserveInvasionSchema ) diff --git a/src/database/models/Unity.ts b/src/database/models/Unity.ts index 3f05e2e..1d2f314 100644 --- a/src/database/models/Unity.ts +++ b/src/database/models/Unity.ts @@ -28,4 +28,4 @@ const UnitySchema = new mongoose.Schema({ geometry: {}, }) -export const Unity = mongoose.model('Unity', UnitySchema, 'Unity') +export const Unity = mongoose.model('Unity', UnitySchema) diff --git a/src/services/getInvasionsShape/GetInvasionsShapeService.ts b/src/services/getInvasionsShape/GetInvasionsShapeService.ts index e35e985..112e798 100644 --- a/src/services/getInvasionsShape/GetInvasionsShapeService.ts +++ b/src/services/getInvasionsShape/GetInvasionsShapeService.ts @@ -36,16 +36,6 @@ class GetInvasionsShapeService { invasions = await this.invasionRepository.getShape(filters) } - invasions = invasions.map((invasion) => { - invasion.geometry.coordinates = JSON.parse(invasion.geometry.coordinates) - return invasion - }) - - reserveInvasions = reserveInvasions.map((invasion) => { - invasion.geometry.coordinates = JSON.parse(invasion.geometry.coordinates) - return invasion - }) - const reserveInvasionsShape = geojson.parse(reserveInvasions, { GeoJSON: 'geometry', }) From 3fbd6d83ff0d12f78157aaec5cebcd6ef8a95059 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 4 Oct 2021 15:01:05 -0300 Subject: [PATCH 108/121] Change search to look for the search term in any position --- .../implementations/InvasionRepository.ts | 4 ++-- .../implementations/LicenseRepository.ts | 4 ++-- .../ReserveInvasionRepository.ts | 4 ++-- .../implementations/ReserveRepository.ts | 4 ++-- .../implementations/UnityRepository.ts | 21 ++++++++++++------- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index e73212f..69e868a 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -73,7 +73,7 @@ class InvasionRepository implements IInvasionRepository { { $match: { 'properties.NOME': { - $regex: new RegExp(`^${searchTerm}`, 'i'), + $regex: new RegExp(`.*${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, @@ -99,7 +99,7 @@ class InvasionRepository implements IInvasionRepository { { $match: { 'properties.SUBS': { - $regex: new RegExp(`^${searchTerm}`, 'i'), + $regex: new RegExp(`.*${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, diff --git a/src/repositories/implementations/LicenseRepository.ts b/src/repositories/implementations/LicenseRepository.ts index 01b7953..55dbba4 100644 --- a/src/repositories/implementations/LicenseRepository.ts +++ b/src/repositories/implementations/LicenseRepository.ts @@ -8,7 +8,7 @@ class LicenseRepository implements ILicenseRepository { { $match: { 'properties.NOME': { - $regex: new RegExp(`^${searchTerm}`, 'i'), + $regex: new RegExp(`.*${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, @@ -33,7 +33,7 @@ class LicenseRepository implements ILicenseRepository { { $match: { 'properties.SUBS': { - $regex: new RegExp(`^${searchTerm}`, 'i'), + $regex: new RegExp(`.*${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index c6bf4f3..849baee 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -39,7 +39,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { { $match: { 'properties.SUBS': { - $regex: new RegExp(`^${searchTerm}`, 'i'), + $regex: new RegExp(`.*${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, @@ -106,7 +106,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { { $match: { 'properties.NOME': { - $regex: new RegExp(`^${searchTerm}`, 'i'), + $regex: new RegExp(`.*${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts index 2e02d2e..8cb77db 100644 --- a/src/repositories/implementations/ReserveRepository.ts +++ b/src/repositories/implementations/ReserveRepository.ts @@ -8,7 +8,7 @@ class ReserveRepository implements IReserveRepository { { $match: { 'properties.terrai_nom': { - $regex: new RegExp(`^${searchTerm}`, 'i'), + $regex: new RegExp(`.*${searchTerm}.*`, 'i'), }, }, }, @@ -41,7 +41,7 @@ class ReserveRepository implements IReserveRepository { { $unwind: '$ethnicity' }, { $project: { ethnicity: { $trim: { input: '$ethnicity' } } } }, { $group: { _id: '$ethnicity' } }, - { $match: { _id: { $regex: new RegExp(`^${searchTerm}`, 'i') } } }, + { $match: { _id: { $regex: new RegExp(`.*${searchTerm}.*`, 'i') } } }, { $project: { type: 'reserveEthnicity', diff --git a/src/repositories/implementations/UnityRepository.ts b/src/repositories/implementations/UnityRepository.ts index d6c6fcf..d168259 100644 --- a/src/repositories/implementations/UnityRepository.ts +++ b/src/repositories/implementations/UnityRepository.ts @@ -4,16 +4,23 @@ import { IUnityRepository } from '../IUnityRepository' class UnityRepository implements IUnityRepository { async searchByName(searchTerm: string): Promise { - const unities = await Unity.find( + const unities = await Unity.aggregate([ { - 'properties.nome': { $regex: new RegExp(`^${searchTerm}`, 'i') }, + $match: { + 'properties.nome': { + $regex: new RegExp(`.*${searchTerm}.*`, 'i'), + }, + }, }, { - type: 'unity', - value: '$properties.nome', - _id: 0, - } - ).sort({ value: 1 }) + $project: { + type: 'unity', + value: '$properties.nome', + _id: 0, + }, + }, + { $sort: { value: 1 } }, + ]) return unities } } From 809705648921d673505b2bf54ed7d0a3d86c3760 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 4 Oct 2021 15:47:02 -0300 Subject: [PATCH 109/121] Change search regex --- src/errors/index.ts | 1 - src/repositories/implementations/InvasionRepository.ts | 4 ++-- src/repositories/implementations/LicenseRepository.ts | 4 ++-- .../implementations/ReserveInvasionRepository.ts | 4 ++-- src/repositories/implementations/ReserveRepository.ts | 8 ++++++-- src/repositories/implementations/UnityRepository.ts | 2 +- 6 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/errors/index.ts b/src/errors/index.ts index 3a64cbd..e897620 100644 --- a/src/errors/index.ts +++ b/src/errors/index.ts @@ -23,7 +23,6 @@ export const errorHandler: ErrorRequestHandler = ( }) return response.status(400).json({ message: 'Validation fails', errors }) } - console.log(error) return response.status(500).json({ message: `Internal server error - ${error.message}`, diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 69e868a..4d0955a 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -73,7 +73,7 @@ class InvasionRepository implements IInvasionRepository { { $match: { 'properties.NOME': { - $regex: new RegExp(`.*${searchTerm}.*`, 'i'), + $regex: new RegExp(`^${searchTerm}|.* ${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, @@ -99,7 +99,7 @@ class InvasionRepository implements IInvasionRepository { { $match: { 'properties.SUBS': { - $regex: new RegExp(`.*${searchTerm}.*`, 'i'), + $regex: new RegExp(`^${searchTerm}|.* ${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, diff --git a/src/repositories/implementations/LicenseRepository.ts b/src/repositories/implementations/LicenseRepository.ts index 55dbba4..9e23841 100644 --- a/src/repositories/implementations/LicenseRepository.ts +++ b/src/repositories/implementations/LicenseRepository.ts @@ -8,7 +8,7 @@ class LicenseRepository implements ILicenseRepository { { $match: { 'properties.NOME': { - $regex: new RegExp(`.*${searchTerm}.*`, 'i'), + $regex: new RegExp(`^${searchTerm}|.* ${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, @@ -33,7 +33,7 @@ class LicenseRepository implements ILicenseRepository { { $match: { 'properties.SUBS': { - $regex: new RegExp(`.*${searchTerm}.*`, 'i'), + $regex: new RegExp(`^${searchTerm}|.* ${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 849baee..e3dc55e 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -39,7 +39,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { { $match: { 'properties.SUBS': { - $regex: new RegExp(`.*${searchTerm}.*`, 'i'), + $regex: new RegExp(`^${searchTerm}|.* ${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, @@ -106,7 +106,7 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { { $match: { 'properties.NOME': { - $regex: new RegExp(`.*${searchTerm}.*`, 'i'), + $regex: new RegExp(`^${searchTerm}|.* ${searchTerm}.*`, 'i'), $ne: 'DADO NÃO CADASTRADO', }, }, diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts index 8cb77db..9fbbaab 100644 --- a/src/repositories/implementations/ReserveRepository.ts +++ b/src/repositories/implementations/ReserveRepository.ts @@ -8,7 +8,7 @@ class ReserveRepository implements IReserveRepository { { $match: { 'properties.terrai_nom': { - $regex: new RegExp(`.*${searchTerm}.*`, 'i'), + $regex: new RegExp(`^${searchTerm}|.* ${searchTerm}.*`, 'i'), }, }, }, @@ -41,7 +41,11 @@ class ReserveRepository implements IReserveRepository { { $unwind: '$ethnicity' }, { $project: { ethnicity: { $trim: { input: '$ethnicity' } } } }, { $group: { _id: '$ethnicity' } }, - { $match: { _id: { $regex: new RegExp(`.*${searchTerm}.*`, 'i') } } }, + { + $match: { + _id: { $regex: new RegExp(`^${searchTerm}|.* ${searchTerm}.*`, 'i') }, + }, + }, { $project: { type: 'reserveEthnicity', diff --git a/src/repositories/implementations/UnityRepository.ts b/src/repositories/implementations/UnityRepository.ts index d168259..5f0629a 100644 --- a/src/repositories/implementations/UnityRepository.ts +++ b/src/repositories/implementations/UnityRepository.ts @@ -8,7 +8,7 @@ class UnityRepository implements IUnityRepository { { $match: { 'properties.nome': { - $regex: new RegExp(`.*${searchTerm}.*`, 'i'), + $regex: new RegExp(`^${searchTerm}|.* ${searchTerm}.*`, 'i'), }, }, }, From 15da74a73de7d82128af549f8c0d8d989c429213 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 4 Oct 2021 15:52:49 -0300 Subject: [PATCH 110/121] Trim search term before search --- src/services/search/SearchService.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts index e720c7a..9154e58 100644 --- a/src/services/search/SearchService.ts +++ b/src/services/search/SearchService.ts @@ -28,6 +28,8 @@ class SearchService { ) {} async execute(searchTerm: string): Promise { + searchTerm = searchTerm.trim() + const states = searchStates(searchTerm) const reserveCompanies = await this.reserveInvasionRepository.searchCompany( From 388f60704df452a9541b34a0c2cf4641b090a60d Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 4 Oct 2021 16:22:01 -0300 Subject: [PATCH 111/121] Change requirements phase listing to type/value format --- src/repositories/IInvasionRepository.ts | 2 +- .../IReserveInvasionRepository.ts | 2 +- .../implementations/InvasionRepository.ts | 24 +++++++++++++++-- .../ReserveInvasionRepository.ts | 24 +++++++++++++++-- .../GetRequirementsPhaseService.ts | 14 +++++----- src/services/search/SearchService.ts | 26 +++---------------- src/utils/group.ts | 22 ++++++++++++++++ 7 files changed, 79 insertions(+), 35 deletions(-) diff --git a/src/repositories/IInvasionRepository.ts b/src/repositories/IInvasionRepository.ts index de376d7..ed31018 100644 --- a/src/repositories/IInvasionRepository.ts +++ b/src/repositories/IInvasionRepository.ts @@ -14,7 +14,7 @@ interface IInvasionRepository { sortOrder, filters, }: IRequestRankingDTO): Promise - getRequirementsPhase(): Promise + getRequirementsPhase(): Promise getShape(filters: IFiltersDTO): Promise } diff --git a/src/repositories/IReserveInvasionRepository.ts b/src/repositories/IReserveInvasionRepository.ts index 7f2dff8..784035d 100644 --- a/src/repositories/IReserveInvasionRepository.ts +++ b/src/repositories/IReserveInvasionRepository.ts @@ -19,7 +19,7 @@ interface IReserveInvasionRepository { sortOrder: string, filters: IFiltersDTO ): Promise - getRequirementsPhase(): Promise + getRequirementsPhase(): Promise getShape(filters: IFiltersDTO): Promise } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 4d0955a..95b2bb7 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -202,8 +202,28 @@ class InvasionRepository implements IInvasionRepository { return match } - async getRequirementsPhase(): Promise { - const requirementsPhase = await Invasion.distinct('properties.FASE') + async getRequirementsPhase(): Promise { + const requirementsPhase = await Invasion.aggregate([ + { + $match: { + 'properties.FASE': { + $ne: null, + }, + }, + }, + { + $group: { + _id: '$properties.FASE', + }, + }, + { + $project: { + type: 'requirementPhase', + value: '$_id', + _id: 0, + }, + }, + ]) return requirementsPhase } } diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index e3dc55e..9c0e1e8 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -282,8 +282,28 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { return match } - async getRequirementsPhase(): Promise { - const requirementsPhase = await ReserveInvasion.distinct('properties.FASE') + async getRequirementsPhase(): Promise { + const requirementsPhase = await ReserveInvasion.aggregate([ + { + $match: { + 'properties.FASE': { + $ne: null, + }, + }, + }, + { + $group: { + _id: '$properties.FASE', + }, + }, + { + $project: { + type: 'requirementPhase', + value: '$_id', + _id: 0, + }, + }, + ]) return requirementsPhase } } diff --git a/src/services/getRequirementsPhase/GetRequirementsPhaseService.ts b/src/services/getRequirementsPhase/GetRequirementsPhaseService.ts index 37534d6..74cad23 100644 --- a/src/services/getRequirementsPhase/GetRequirementsPhaseService.ts +++ b/src/services/getRequirementsPhase/GetRequirementsPhaseService.ts @@ -1,7 +1,9 @@ import { inject, injectable } from 'tsyringe' +import { ISearchDTO } from '../../dtos/ISearchDTO' import { IInvasionRepository } from '../../repositories/IInvasionRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { groupResults } from '../../utils/group' @injectable() class GetRequirementsPhaseService { @@ -13,20 +15,20 @@ class GetRequirementsPhaseService { private invasionRepository: IInvasionRepository ) {} - async execute(): Promise { + async execute(): Promise { const reserveRequirementsPhase = await this.reserveInvasionRepository.getRequirementsPhase() const unityRequirementsPhase = await this.invasionRepository.getRequirementsPhase() - const requirementsPhase = new Set([ - ...reserveRequirementsPhase, - ...unityRequirementsPhase, - ]) + const requirementsPhase = groupResults( + reserveRequirementsPhase, + unityRequirementsPhase + ) const requirementsPhaseArray = Array.from(requirementsPhase).filter( - (phase) => phase !== 'DADO NÃO CADASTRADO' + (phase) => phase.value !== 'DADO NÃO CADASTRADO' ) return requirementsPhaseArray diff --git a/src/services/search/SearchService.ts b/src/services/search/SearchService.ts index 9154e58..516f213 100644 --- a/src/services/search/SearchService.ts +++ b/src/services/search/SearchService.ts @@ -6,6 +6,7 @@ import { ILicenseRepository } from '../../repositories/ILicenseRepository' import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' import { IReserveRepository } from '../../repositories/IReserveRepository' import { IUnityRepository } from '../../repositories/IUnityRepository' +import { groupResults } from '../../utils/group' import { searchStates } from '../../utils/states' @injectable() @@ -40,7 +41,7 @@ class SearchService { searchTerm ) - const companies = this.groupResults(reserveCompanies, unityCompanies) + const companies = groupResults(reserveCompanies, unityCompanies) const unities = await this.unityRepository.searchByName(searchTerm) @@ -53,7 +54,7 @@ class SearchService { searchTerm ) - const substances = this.groupResults(reserveSubstances, unitySubstances) + const substances = groupResults(reserveSubstances, unitySubstances) const ethnicities = await this.reserveRepository.searchEthnicity(searchTerm) @@ -67,27 +68,6 @@ class SearchService { return results } - - private groupResults( - reserveResults: ISearchDTO[], - unityResults: ISearchDTO[] - ): ISearchDTO[] { - const resultsMap = new Map() - - reserveResults.forEach((result) => { - resultsMap.set(result.value, result) - }) - - unityResults.forEach((result) => { - resultsMap.set(result.value, result) - }) - - const results = Array.from(resultsMap.values()).sort((a, b) => - a.value.toLowerCase() > b.value.toLowerCase() ? 1 : -1 - ) - - return results - } } export { SearchService } diff --git a/src/utils/group.ts b/src/utils/group.ts index fb4cee1..59443f0 100644 --- a/src/utils/group.ts +++ b/src/utils/group.ts @@ -1,4 +1,5 @@ import { IInvasionDTO } from '../dtos/IInvasionDTO' +import { ISearchDTO } from '../dtos/ISearchDTO' export function groupInvasions( reserveInvasions: IInvasionDTO[], @@ -16,3 +17,24 @@ export function groupInvasions( return Array.from(invasionsMap.values()) } + +export function groupResults( + reserveResults: ISearchDTO[], + unityResults: ISearchDTO[] +): ISearchDTO[] { + const resultsMap = new Map() + + reserveResults.forEach((result) => { + resultsMap.set(result.value, result) + }) + + unityResults.forEach((result) => { + resultsMap.set(result.value, result) + }) + + const results = Array.from(resultsMap.values()).sort((a, b) => + a.value.toLowerCase() > b.value.toLowerCase() ? 1 : -1 + ) + + return results +} From 9e8a7506eb9462f012a72ca39d0c22fe8d3aa2d7 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Mon, 4 Oct 2021 16:26:25 -0300 Subject: [PATCH 112/121] Change readme --- README.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 1ec8f78..a89485a 100644 --- a/README.md +++ b/README.md @@ -435,18 +435,19 @@ Método que retorna as opções de fase do requerimento de mineração. ```javascript [ - "APTO PARA DISPONIBILIDADE", - "AUTORIZAÇÃO DE PESQUISA", - "CONCESSÃO DE LAVRA", - "DIREITO DE REQUERER A LAVRA", - "DISPONIBILIDADE", - "LAVRA GARIMPEIRA", - "LICENCIAMENTO", - "REQUERIMENTO DE LAVRA", - "REQUERIMENTO DE LAVRA GARIMPEIRA", - "REQUERIMENTO DE LICENCIAMENTO", - "REQUERIMENTO DE PESQUISA", - "REQUERIMENTO DE REGISTRO DE EXTRAÇÃO" + { + "type": "requirementPhase", + "value": "APTO PARA DISPONIBILIDADE" + }, + { + "type": "requirementPhase", + "value": "AUTORIZAÇÃO DE PESQUISA" + }, + { + "type": "requirementPhase", + "value": "CONCESSÃO DE LAVRA" + }, + ... ] ``` **Descrição:** Retorna um array contendo as opções das fases dos requerimentos de mineração. From 8724056edaff8585e381da4057c0c3c41a5eaddf Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Tue, 5 Oct 2021 16:33:51 -0300 Subject: [PATCH 113/121] Change the output of reserve phases method to type/value format --- README.md | 30 +++++++++++++++---- src/repositories/IReserveRepository.ts | 2 +- .../implementations/ReserveRepository.ts | 20 +++++++++++-- .../GetReservesPhaseService.ts | 3 +- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a89485a..68d2ed4 100644 --- a/README.md +++ b/README.md @@ -389,12 +389,30 @@ Método que retorna as opções de fase do processo de homologação de terras i ```javascript [ - "Declarada", - "Delimitada", - "Em Estudo", - "Encaminhada RI", - "Homologada", - "Regularizada" + { + "type": "reservePhase", + "value": "Declarada" + }, + { + "type": "reservePhase", + "value": "Delimitada" + }, + { + "type": "reservePhase", + "value": "Em Estudo" + }, + { + "type": "reservePhase", + "value": "Encaminhada RI" + }, + { + "type": "reservePhase", + "value": "Homologada" + }, + { + "type": "reservePhase", + "value": "Regularizada" + } ] ``` **Descrição:** Retorna um array contendo as opções das fases do processo de homologação de terras indígenas. diff --git a/src/repositories/IReserveRepository.ts b/src/repositories/IReserveRepository.ts index 9623589..7570a7e 100644 --- a/src/repositories/IReserveRepository.ts +++ b/src/repositories/IReserveRepository.ts @@ -3,7 +3,7 @@ import { ISearchDTO } from '../dtos/ISearchDTO' interface IReserveRepository { searchByName(searchTerm: string): Promise searchEthnicity(searchTerm: string): Promise - getHomologationPhases(): Promise + getHomologationPhases(): Promise } export { IReserveRepository } diff --git a/src/repositories/implementations/ReserveRepository.ts b/src/repositories/implementations/ReserveRepository.ts index 9fbbaab..26ed9c4 100644 --- a/src/repositories/implementations/ReserveRepository.ts +++ b/src/repositories/implementations/ReserveRepository.ts @@ -58,8 +58,24 @@ class ReserveRepository implements IReserveRepository { return ethnicities } - async getHomologationPhases(): Promise { - const homologationPhases = await Reserve.distinct('properties.fase_ti') + async getHomologationPhases(): Promise { + const homologationPhases = await Reserve.aggregate([ + { + $group: { + _id: '$properties.fase_ti', + }, + }, + { + $project: { + type: 'reservePhase', + value: '$_id', + _id: 0, + }, + }, + { + $sort: { value: 1 }, + }, + ]) return homologationPhases } } diff --git a/src/services/getReservesPhase/GetReservesPhaseService.ts b/src/services/getReservesPhase/GetReservesPhaseService.ts index caaacfb..d911684 100644 --- a/src/services/getReservesPhase/GetReservesPhaseService.ts +++ b/src/services/getReservesPhase/GetReservesPhaseService.ts @@ -1,5 +1,6 @@ import { inject, injectable } from 'tsyringe' +import { ISearchDTO } from '../../dtos/ISearchDTO' import { IReserveRepository } from '../../repositories/IReserveRepository' @injectable() @@ -9,7 +10,7 @@ class GetReservesPhaseService { private reserveRepository: IReserveRepository ) {} - async execute(): Promise { + async execute(): Promise { const homologationPhases = await this.reserveRepository.getHomologationPhases() From fe3f8e36bb18caa5c6696948b252f92c6443a28f Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Tue, 5 Oct 2021 16:54:16 -0300 Subject: [PATCH 114/121] Add options to enable/disable reverve or unity data in ranking --- README.md | 6 ++++-- .../InvasionRankingController.ts | 20 +++++++++++------- .../invasionRanking/InvasionRankingService.ts | 21 ++++++++++--------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 68d2ed4..e257343 100644 --- a/README.md +++ b/README.md @@ -512,7 +512,9 @@ Método que retorna o ranking de acordo com a propiedade e o tipo de dado especi "reservePhase": [], //Array de strings com as fases do processo de homologação das terras indígenas "reserveEthnicity": [], //Array de strings com o nome das etinias de terras indígenas "requirementPhase": [], //Array de strings com as fases dos requerimentos de mineração - } + }, + "enableUnity": true, //Boolean para ativar/desativar dados de ucs (default: true) + "enableReserve": true, //Boolean para ativar/desativar dados de Terras Indígenas (default: true) } ``` @@ -568,7 +570,7 @@ Método que retorna o ranking de acordo com a propiedade e o tipo de dado especi "dataType": "requiredArea" } ``` - **Descrição:** Retorna um array de series que contém os valores de cada tipo de dado, um array com as respectivas posições e um com os valores da propriedade escolhida. OBS: quando os filtros resultam em um ranking vazio para uma determinada propriedade o retorno é null. + **Descrição:** Retorna um array de series que contém os valores de cada tipo de dado, um array com as respectivas posições e um com os valores da propriedade escolhida. OBS: quando os filtros resultam em um ranking vazio o retorno é null. * **Código:** **500**
**Conteúdo:** diff --git a/src/services/invasionRanking/InvasionRankingController.ts b/src/services/invasionRanking/InvasionRankingController.ts index c07154b..d510663 100644 --- a/src/services/invasionRanking/InvasionRankingController.ts +++ b/src/services/invasionRanking/InvasionRankingController.ts @@ -6,16 +6,20 @@ import { InvasionRankingService } from './InvasionRankingService' class InvasionRankingController { async handle(request: Request, response: Response): Promise { const { propertyType, dataType } = request.params - const { filters } = request.body + const { filters, enableUnity, enableReserve } = request.body const { page, sortOrder } = request.query const invasionRankingService = container.resolve(InvasionRankingService) - const rankingData = await invasionRankingService.execute({ - propertyType, - dataType, - page: Number(page) || 1, - sortOrder: String(sortOrder), - filters, - }) + const rankingData = await invasionRankingService.execute( + { + propertyType, + dataType, + page: Number(page) || 1, + sortOrder: String(sortOrder), + filters, + }, + enableUnity, + enableReserve + ) return response.status(200).json(rankingData) } } diff --git a/src/services/invasionRanking/InvasionRankingService.ts b/src/services/invasionRanking/InvasionRankingService.ts index cefcac0..ede7bc5 100644 --- a/src/services/invasionRanking/InvasionRankingService.ts +++ b/src/services/invasionRanking/InvasionRankingService.ts @@ -19,13 +19,11 @@ class InvasionRankingService { private invasionRepository: IInvasionRepository ) {} - async execute({ - propertyType, - page, - dataType, - sortOrder, - filters, - }: IRequestRankingDTO) { + async execute( + { propertyType, page, dataType, sortOrder, filters }: IRequestRankingDTO, + enableUnity: boolean = true, + enableReserve: boolean = true + ) { if (propertyType === 'state' || propertyType === 'company') { let reserveResults: IResponseRankingDTO[] = [] if (checkIfShouldListReserveInvasions(filters)) { @@ -50,9 +48,12 @@ class InvasionRankingService { }) } - if (reserveResults.length === 0 && invasionResults.length === 0) { + if ( + (reserveResults.length === 0 && invasionResults.length === 0) || + (!enableUnity && !enableReserve) + ) { return null - } else if (reserveResults.length === 0) { + } else if (reserveResults.length === 0 || !enableReserve) { return this.formatSingleRanking( invasionResults, page, @@ -60,7 +61,7 @@ class InvasionRankingService { 'protectedArea', propertyType ) - } else if (invasionResults.length === 0) { + } else if (invasionResults.length === 0 || !enableUnity) { return this.formatSingleRanking( reserveResults, page, From b4413f33e0f0d34b53399aed8e89e90f59482685 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Tue, 5 Oct 2021 16:57:24 -0300 Subject: [PATCH 115/121] Change readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e257343..db979d5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Busca Geral** ---- -Método que permite uma busca geral para Substância, Estado, Solicitante (Empresa), Terras Indígenas, Unidades de Conservação ou Etnias de Terras Indígenas, retornando as opções disponíveis no Banco de Dados que são iniciadas com a string fornecida. +Método que permite uma busca geral para Substância, Estado, Solicitante (Empresa), Terras Indígenas, Unidades de Conservação ou Etnias de Terras Indígenas, retornando as opções disponíveis no Banco de Dados que são iniciadas ou que possuem alguma palavra iniciada com a string fornecida. * **URL:** From 3abba71fec1ed69d865b3b640ef644f516e7155a Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Tue, 5 Oct 2021 18:00:12 -0300 Subject: [PATCH 116/121] Create method to list years options --- README.md | 60 +++++++++++++++++++ src/dtos/ISearchDTO.ts | 2 +- src/repositories/IInvasionRepository.ts | 1 + .../IReserveInvasionRepository.ts | 1 + .../implementations/InvasionRepository.ts | 18 ++++++ .../ReserveInvasionRepository.ts | 18 ++++++ src/routes/index.ts | 3 + src/services/getYears/GetYearsController.ts | 16 +++++ src/services/getYears/GetYearsService.ts | 27 +++++++++ src/utils/group.ts | 11 ++-- 10 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 src/services/getYears/GetYearsController.ts create mode 100644 src/services/getYears/GetYearsService.ts diff --git a/README.md b/README.md index db979d5..e89d334 100644 --- a/README.md +++ b/README.md @@ -426,6 +426,66 @@ Método que retorna as opções de fase do processo de homologação de terras i ``` **Descrição:** Erro interno do servidor. +**Listar Anos** +---- +Método que retorna as opções de anos que contém requerimentos em ucs ou terras indígenas no banco de dados. + +* **URL:** + + /api/invasions/years + +* **Método:** + + `GET` + +* **Parâmetros na URL:** + + Nenhum + +* **Parâmetros no Body:** + + Nenhum + +* **Resposta:** + + * **Código:** **200**
+ **Conteúdo:** + + ```javascript + [ + { + "type": "year", + "value": 2017 + }, + { + "type": "year", + "value": 2018 + }, + { + "type": "year", + "value": 2019 + }, + { + "type": "year", + "value": 2020 + }, + { + "type": "year", + "value": 2021 + } + ] + ``` + **Descrição:** Retorna um array contendo as opções de anos. + + * **Código:** **500**
+ **Conteúdo:** + ```javascript + { + "message": "Internal Server Error" + } + ``` + **Descrição:** Erro interno do servidor. + **Listar Fases do Requerimento de Mineração** ---- Método que retorna as opções de fase do requerimento de mineração. diff --git a/src/dtos/ISearchDTO.ts b/src/dtos/ISearchDTO.ts index 2bec02f..2f0af98 100644 --- a/src/dtos/ISearchDTO.ts +++ b/src/dtos/ISearchDTO.ts @@ -1,6 +1,6 @@ interface ISearchDTO { type: string - value: string + value: string | number } export { ISearchDTO } diff --git a/src/repositories/IInvasionRepository.ts b/src/repositories/IInvasionRepository.ts index ed31018..93816e5 100644 --- a/src/repositories/IInvasionRepository.ts +++ b/src/repositories/IInvasionRepository.ts @@ -15,6 +15,7 @@ interface IInvasionRepository { filters, }: IRequestRankingDTO): Promise getRequirementsPhase(): Promise + getYears(): Promise getShape(filters: IFiltersDTO): Promise } diff --git a/src/repositories/IReserveInvasionRepository.ts b/src/repositories/IReserveInvasionRepository.ts index 784035d..0d4c40d 100644 --- a/src/repositories/IReserveInvasionRepository.ts +++ b/src/repositories/IReserveInvasionRepository.ts @@ -19,6 +19,7 @@ interface IReserveInvasionRepository { sortOrder: string, filters: IFiltersDTO ): Promise + getYears(): Promise getRequirementsPhase(): Promise getShape(filters: IFiltersDTO): Promise } diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 95b2bb7..0ebd520 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -157,6 +157,24 @@ class InvasionRepository implements IInvasionRepository { return territories } + async getYears(): Promise { + const years = await Invasion.aggregate([ + { + $group: { + _id: '$properties.ANO', + }, + }, + { + $project: { + type: 'year', + value: '$_id', + _id: 0, + }, + }, + ]) + return years + } + private getMatchProperty(filters: IFiltersDTO) { const match: any = {} diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 9c0e1e8..953fd2c 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -222,6 +222,24 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { return territories } + async getYears(): Promise { + const years = await ReserveInvasion.aggregate([ + { + $group: { + _id: '$properties.ANO', + }, + }, + { + $project: { + type: 'year', + value: '$_id', + _id: 0, + }, + }, + ]) + return years + } + private getMatchProperty(filters: IFiltersDTO) { const match: any = {} diff --git a/src/routes/index.ts b/src/routes/index.ts index 7f4f2d6..92ab993 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -4,6 +4,7 @@ import { GetInvasionsShapeController } from '../services/getInvasionsShape/GetIn import { GetRequirementsPhaseController } from '../services/getRequirementsPhase/GetRequirementsPhaseController' import { GetReservesPhaseController } from '../services/getReservesPhase/GetReservesPhaseController' import { GetStatisticsController } from '../services/getStatistics/GetStatisticsController' +import { GetYearsController } from '../services/getYears/GetYearsController' import { InvasionRankingController } from '../services/invasionRanking/InvasionRankingController' import { ListInvasionsController } from '../services/listInvasions/ListInvasionsController' import { SearchController } from '../services/search/SearchController' @@ -17,6 +18,7 @@ const getStatisticsController = new GetStatisticsController() const getReservesPhaseController = new GetReservesPhaseController() const getRequirementsPhaseController = new GetRequirementsPhaseController() const getInvasionsShapeController = new GetInvasionsShapeController() +const getYearsController = new GetYearsController() router.get('/search/:searchTerm', searchController.handle) router.post('/invasions', listInvasionsController.handle) @@ -25,6 +27,7 @@ router.post( invasionRankingController.handle ) router.get('/invasions/phase', getRequirementsPhaseController.handle) +router.get('/invasions/years', getYearsController.handle) router.post('/invasions/shape', getInvasionsShapeController.handle) router.post('/statistics', getStatisticsController.handle) router.get('/reserves/phase', getReservesPhaseController.handle) diff --git a/src/services/getYears/GetYearsController.ts b/src/services/getYears/GetYearsController.ts new file mode 100644 index 0000000..5db48d5 --- /dev/null +++ b/src/services/getYears/GetYearsController.ts @@ -0,0 +1,16 @@ +import { Request, Response } from 'express' +import { container } from 'tsyringe' + +import { GetYearsService } from './GetYearsService' + +class GetYearsController { + async handle(request: Request, response: Response): Promise { + const getYearsService = container.resolve(GetYearsService) + + const years = await getYearsService.execute() + + return response.json(years) + } +} + +export { GetYearsController } diff --git a/src/services/getYears/GetYearsService.ts b/src/services/getYears/GetYearsService.ts new file mode 100644 index 0000000..0aff299 --- /dev/null +++ b/src/services/getYears/GetYearsService.ts @@ -0,0 +1,27 @@ +import { inject, injectable } from 'tsyringe' + +import { ISearchDTO } from '../../dtos/ISearchDTO' +import { IInvasionRepository } from '../../repositories/IInvasionRepository' +import { IReserveInvasionRepository } from '../../repositories/IReserveInvasionRepository' +import { groupResults } from '../../utils/group' + +@injectable() +class GetYearsService { + constructor( + @inject('ReserveInvasionRepository') + private reserveInvasionRepository: IReserveInvasionRepository, + + @inject('InvasionRepository') + private invasionRepository: IInvasionRepository + ) {} + + async execute(): Promise { + const reserveYears = await this.reserveInvasionRepository.getYears() + const unityYears = await this.invasionRepository.getYears() + + const results = groupResults(reserveYears, unityYears) + return results + } +} + +export { GetYearsService } diff --git a/src/utils/group.ts b/src/utils/group.ts index 59443f0..b2931c7 100644 --- a/src/utils/group.ts +++ b/src/utils/group.ts @@ -22,7 +22,7 @@ export function groupResults( reserveResults: ISearchDTO[], unityResults: ISearchDTO[] ): ISearchDTO[] { - const resultsMap = new Map() + const resultsMap = new Map() reserveResults.forEach((result) => { resultsMap.set(result.value, result) @@ -32,9 +32,12 @@ export function groupResults( resultsMap.set(result.value, result) }) - const results = Array.from(resultsMap.values()).sort((a, b) => - a.value.toLowerCase() > b.value.toLowerCase() ? 1 : -1 - ) + const results = Array.from(resultsMap.values()).sort((a, b) => { + if (typeof a.value === 'string' && typeof b.value === 'string') { + return a.value.toLowerCase() > b.value.toLowerCase() ? 1 : -1 + } + return a.value > b.value ? 1 : -1 + }) return results } From 41965ff754cbe65eced3b76ac4c7fda865721cc1 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Wed, 6 Oct 2021 11:06:35 -0300 Subject: [PATCH 117/121] Change ranking to group requirements by the process number before counting --- .../implementations/InvasionRepository.ts | 11 ++++++++++- .../implementations/ReserveInvasionRepository.ts | 11 ++++++++++- src/utils/rankingFilter.ts | 8 ++++---- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/repositories/implementations/InvasionRepository.ts b/src/repositories/implementations/InvasionRepository.ts index 0ebd520..394e953 100644 --- a/src/repositories/implementations/InvasionRepository.ts +++ b/src/repositories/implementations/InvasionRepository.ts @@ -137,11 +137,20 @@ class InvasionRepository implements IInvasionRepository { const territories = await Invasion.aggregate([ { $match: match }, + { + $group: { + _id: '$properties.PROCESSO', + AREA_HA: { $sum: '$properties.AREA_HA' }, + UF: { $first: '$properties.UF' }, + UC_NOME: { $first: '$properties.UC_NOME' }, + NOME: { $first: '$properties.NOME' }, + }, + }, { $group: { _id: property, count: { - $sum: dataType === 'requiredArea' ? '$properties.AREA_HA' : 1, + $sum: dataType === 'requiredArea' ? '$AREA_HA' : 1, }, }, }, diff --git a/src/repositories/implementations/ReserveInvasionRepository.ts b/src/repositories/implementations/ReserveInvasionRepository.ts index 953fd2c..5fb62a7 100644 --- a/src/repositories/implementations/ReserveInvasionRepository.ts +++ b/src/repositories/implementations/ReserveInvasionRepository.ts @@ -201,11 +201,20 @@ class ReserveInvasionRepository implements IReserveInvasionRepository { const territories = await ReserveInvasion.aggregate([ { $match: match }, + { + $group: { + _id: '$properties.PROCESSO', + AREA_HA: { $sum: '$properties.AREA_HA' }, + UF: { $first: '$properties.UF' }, + TI_NOME: { $first: '$properties.TI_NOME' }, + NOME: { $first: '$properties.NOME' }, + }, + }, { $group: { _id: property, count: { - $sum: dataType === 'requiredArea' ? '$properties.AREA_HA' : 1, + $sum: dataType === 'requiredArea' ? '$AREA_HA' : 1, }, }, }, diff --git a/src/utils/rankingFilter.ts b/src/utils/rankingFilter.ts index 808de51..8ec0011 100644 --- a/src/utils/rankingFilter.ts +++ b/src/utils/rankingFilter.ts @@ -3,10 +3,10 @@ type filterOptions = { } const rankingFilter: filterOptions = { - state: '$properties.UF', - reserve: '$properties.TI_NOME', - unity: '$properties.UC_NOME', - company: '$properties.NOME', + state: '$UF', + reserve: '$TI_NOME', + unity: '$UC_NOME', + company: '$NOME', } export { rankingFilter } From f6c64e6db516eecdaea742dbd2875a5130591a5d Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 7 Oct 2021 12:02:27 -0300 Subject: [PATCH 118/121] Create dockerized production version --- Dockerfile | 20 +++++++++++++------- Dockerfile.dev | 13 +++++++++++++ docker-compose-dev.yml | 40 ++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 34 +++++++++------------------------- package.json | 4 +++- src/errors/index.ts | 3 ++- 6 files changed, 80 insertions(+), 34 deletions(-) create mode 100644 Dockerfile.dev create mode 100644 docker-compose-dev.yml diff --git a/Dockerfile b/Dockerfile index 69f8b64..a251b4a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,19 @@ -FROM node:latest - +FROM node AS build WORKDIR /usr/app - COPY package.json ./ - +COPY tsconfig.json ./ +COPY src ./src RUN npm install +RUN npm run build -COPY . . - +FROM node +WORKDIR /usr/app +COPY package.json ./ +RUN npm install --production +COPY --from=build /usr/app/dist ./dist +COPY .env.example ./ +COPY .env ./ +RUN npm install pm2 -g EXPOSE 5000 +CMD ["pm2-runtime", "dist/server.js"] -CMD ["npm","run","dev"] diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..69f8b64 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,13 @@ +FROM node:latest + +WORKDIR /usr/app + +COPY package.json ./ + +RUN npm install + +COPY . . + +EXPOSE 5000 + +CMD ["npm","run","dev"] diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml new file mode 100644 index 0000000..37e2485 --- /dev/null +++ b/docker-compose-dev.yml @@ -0,0 +1,40 @@ +version: '2' + +services: + server: + container_name: amazonia-minada-back-dev + restart: always + build: + context: . + dockerfile: Dockerfile.dev + working_dir: /usr/app + command: npm run dev + volumes: + - .:/usr/app + ports: + - 5000:5000 + links: + - database + depends_on: + - database + env_file: + - .env + environment: + MONGO_DB_USERNAME: ${MONGO_DB_USERNAME} + MONGO_DB_PASSWORD: ${MONGO_DB_PASSWORD} + MONGO_DB_ADDRESS: ${MONGO_DB_ADDRESS} + + database: + image: mongo + container_name: mongodb + volumes: + - ./sysbkp/data:/data + ports: + - 27017:27017 + restart: always + env_file: + - .env + environment: + MONGO_INITDB_ROOT_USERNAME: ${MONGO_DB_USERNAME} + MONGO_INITDB_ROOT_PASSWORD: ${MONGO_DB_PASSWORD} + TZ: America/Sao_Paulo \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index e1dae12..1271654 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,36 +1,20 @@ -version: '2' - services: server: - build: . - container_name: infoamazonia + container_name: amazonia-minada-back + restart: always + build: + context: . + args: + - NODE_ENV=production + - TZ=America/Sao_Paulo working_dir: /usr/app - command: npm run dev - volumes: - - .:/usr/app ports: - 5000:5000 - links: - - database - depends_on: - - database env_file: - .env environment: MONGO_DB_USERNAME: ${MONGO_DB_USERNAME} MONGO_DB_PASSWORD: ${MONGO_DB_PASSWORD} MONGO_DB_ADDRESS: ${MONGO_DB_ADDRESS} - - database: - image: mongo - container_name: mongodb - volumes: - - ./sysbkp/data:/data - ports: - - 27017:27017 - restart: always - env_file: - - .env - environment: - MONGO_INITDB_ROOT_USERNAME: ${MONGO_DB_USERNAME} - MONGO_INITDB_ROOT_PASSWORD: ${MONGO_DB_PASSWORD} \ No newline at end of file + NODE_ENV: production + TZ: America/Sao_Paulo \ No newline at end of file diff --git a/package.json b/package.json index fff385a..6b2ef40 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "author": "Iago Machado ", "license": "MIT", "scripts": { - "dev": "./node_modules/.bin/ts-node-dev --transpile-only --ignore-watch node_modules --respawn src/server.ts" + "dev": "./node_modules/.bin/ts-node-dev --transpile-only --ignore-watch node_modules --respawn src/server.ts", + "build": "tsc -p .", + "production": "pm2-runtime dist/server.js" }, "dependencies": { "cors": "^2.8.5", diff --git a/src/errors/index.ts b/src/errors/index.ts index e897620..a3d19d8 100644 --- a/src/errors/index.ts +++ b/src/errors/index.ts @@ -23,8 +23,9 @@ export const errorHandler: ErrorRequestHandler = ( }) return response.status(400).json({ message: 'Validation fails', errors }) } + console.log(error) return response.status(500).json({ - message: `Internal server error - ${error.message}`, + message: `Internal server error`, }) } From 5ba93bf60eac2d6d20216c3fa42b6f941c997093 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 7 Oct 2021 12:16:17 -0300 Subject: [PATCH 119/121] Change timezone in develop docker-compose --- docker-compose-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 37e2485..b4eab28 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -23,6 +23,7 @@ services: MONGO_DB_USERNAME: ${MONGO_DB_USERNAME} MONGO_DB_PASSWORD: ${MONGO_DB_PASSWORD} MONGO_DB_ADDRESS: ${MONGO_DB_ADDRESS} + TZ: America/Sao_Paulo database: image: mongo From f5b1dbeace84f5a1f5baa7bdf10ab30ebc477a02 Mon Sep 17 00:00:00 2001 From: Iago Machado Date: Thu, 7 Oct 2021 12:21:06 -0300 Subject: [PATCH 120/121] Set version number in production docker-compose --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 1271654..20830dc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,5 @@ +version: '2' + services: server: container_name: amazonia-minada-back From 54d822b9c805a867f54629f39899569554b31592 Mon Sep 17 00:00:00 2001 From: Iago Machado <38327929+iagomachadocs@users.noreply.github.com> Date: Thu, 7 Oct 2021 17:04:56 -0300 Subject: [PATCH 121/121] Update README.md --- README.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e89d334..de80f92 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,27 @@ # Amazonia Minada API +Esse repositório contém o código fonte da API REST do Amazônia Minada, projeto do Infoamazônia que monitora os requerimentos minerários em unidades de conservação integral e em terras indígenas na Amazônia Legal brasileira. Essa API contém métodos que calculam estatísticas a respeito dos requerimentos minerários coletados pelo [bot do Amazônia Minada](https://github.com/InfoAmazonia/amazonia-minada), a partir dos dados fornecidos pela Agência Nacional de Mineração (ANM), em termos da área declarada (área total dos requerimentos) e da incidência (quantidade de requerimentos). + +**Como executar** +--- +Para colocar o servidor em execução, inicialmente é necessário criar um arquivo .env com as configurações do banco de dados MongoDB do Amazônia Minada, do qual serão extraídos os dados. + + $ cp .env.example .env + +Preencha as informações necessárias no arquivo .env. Em seguida, para rodar a aplicação em ambiente de produção utilizando o docker, execute: + + $ docker-compose up -d --build + +Para executar em ambiente de desenvolvimento, execute o comando para instalar as dependências: + + $ yarn install + +Em seguida, rode o container de desenvolvimento: + + $ docker-compose -f docker-compose-dev.yml up -d --build + +# Documentação da API + **Busca Geral** ---- Método que permite uma busca geral para Substância, Estado, Solicitante (Empresa), Terras Indígenas, Unidades de Conservação ou Etnias de Terras Indígenas, retornando as opções disponíveis no Banco de Dados que são iniciadas ou que possuem alguma palavra iniciada com a string fornecida. @@ -69,7 +91,7 @@ Método que permite uma busca geral para Substância, Estado, Solicitante (Empre **Listar Requerimentos** ---- -Método que permite uma filtragem dos requerimentos minerários em Unidades de Conservação e em Terras Indígenas. +Método que permite uma filtragem dos requerimentos minerários em Unidades de Conservação e em Terras Indígenas. Os requerimentos são agrupados pelo número do processo e aqueles que possuem o mesmo número tem seus valores de área somados. * **URL:** @@ -163,7 +185,7 @@ Método que permite uma filtragem dos requerimentos minerários em Unidades de C "results": 20 } ``` - **Descrição:** Retorna um array de objetos contendo os dados de cada requerimento que se enquadra nos filtros definidos, o número de páginas e a quantidade de requerimentos. + **Descrição:** Retorna um array de objetos contendo os dados de cada requerimento que se enquadra nos filtros definidos, o número de páginas e a quantidade de requerimentos. OBS: Caso o parâmetro output seja definido, o retorno é um arquivo do tipo especificado. * **Código:** **500**
**Conteúdo:** @@ -284,7 +306,7 @@ Método que retorna os shapes dos requerimentos minerários em Unidades de Conse **Estatísticas** ---- -Método que retorna as estatísticas gerais (número de requerimentos e área) de Terras Indígenas e Unidades de Conservação de acordo com os filtros. +Método que retorna as estatísticas gerais (número de requerimentos e área total requerida) de Terras Indígenas e Unidades de Conservação de acordo com os filtros. Os requerimentos são agrupados pelo número do processo e aqueles que possuem o mesmo número tem seus valores de área somados. * **URL:**